15 size_t pos = content.find(attr_name +
"=\"");
16 if (pos == std::string::npos)
19 size_t start = pos + attr_name.length() + 2;
20 size_t end = content.find(
"\"", start);
21 if (end == std::string::npos)
24 return content.substr(start, end - start);
28 std::ifstream file(filename, std::ios::binary);
29 if (!file.is_open()) {
30 throw std::runtime_error(
"Could not open file: " + filename);
51 std::string header_buffer;
53 bool found_marker =
false;
70 std::vector<char> buffer(8192);
71 file.read(buffer.data(), buffer.size());
72 std::string header(buffer.data(), file.gcount());
76 if (extent_str.empty())
77 throw std::runtime_error(
"Could not find WholeExtent in VTI header");
79 int x1, x2, y1, y2, z1, z2;
80 std::stringstream ss_ext(extent_str);
81 ss_ext >> x1 >> x2 >> y1 >> y2 >> z1 >> z2;
82 data.resolution = {x2 - x1 + 1, y2 - y1 + 1, z2 - z1 + 1};
86 std::stringstream ss_org(origin_str);
87 ss_org >> data.origin[0] >> data.origin[1] >> data.origin[2];
91 std::stringstream ss_spc(spacing_str);
92 ss_spc >> data.spacing[0] >> data.spacing[1] >> data.spacing[2];
96 std::string appended_tag =
"<AppendedData encoding=\"raw\">";
97 size_t tag_pos = header.find(appended_tag);
98 if (tag_pos == std::string::npos)
99 throw std::runtime_error(
"Could not find AppendedData tag");
104 size_t underscore_pos = header.find(
"_", tag_pos);
105 if (underscore_pos == std::string::npos) {
109 throw std::runtime_error(
"Could not find binary data marker '_' in first 8KB");
114 file.seekg(underscore_pos + 1, std::ios::beg);
117 uint64_t data_bytes = 0;
118 file.read(
reinterpret_cast<char *
>(&data_bytes),
sizeof(uint64_t));
122 throw std::runtime_error(
"Failed to read data_bytes (UInt64) from file.");
128 const size_t expected_bytes = data.size() *
sizeof(float);
129 if (data_bytes != expected_bytes) {
130 throw std::runtime_error(
"VTI appended data length (" + std::to_string(data_bytes) +
131 " bytes) does not match WholeExtent x Float32 (" +
132 std::to_string(expected_bytes) +
" bytes) in " + filename +
133 ": expected one uncompressed Float32 array (raw appended encoding)");
136 data.sdf_values.resize(data.size());
137 file.read(
reinterpret_cast<char *
>(data.sdf_values.data()), data_bytes);
138 if (file.gcount() !=
static_cast<std::streamsize
>(data_bytes)) {
139 throw std::runtime_error(
"VTI file " + filename +
" is truncated: read " +
140 std::to_string(file.gcount()) +
" of " + std::to_string(data_bytes) +