44 #include "DenseFieldIO.h"
50 using namespace boost;
68 const int DenseFieldIO::k_versionNumber(1);
69 const std::string DenseFieldIO::k_versionAttrName(
"version");
70 const std::string DenseFieldIO::k_extentsStr(
"extents");
71 const std::string DenseFieldIO::k_extentsMinStr(
"extents_min");
72 const std::string DenseFieldIO::k_extentsMaxStr(
"extents_max");
73 const std::string DenseFieldIO::k_dataWindowStr(
"data_window");
74 const std::string DenseFieldIO::k_dataWindowMinStr(
"data_window_min");
75 const std::string DenseFieldIO::k_dataWindowMaxStr(
"data_window_max");
76 const std::string DenseFieldIO::k_componentsStr(
"components");
77 const std::string DenseFieldIO::k_bitsPerComponentStr(
"bits_per_component");
78 const std::string DenseFieldIO::k_dataStr(
"data");
83 DenseFieldIO::read(hid_t layerGroup,
const std::string &,
92 throw BadHdf5IdException(
"Bad layer group in DenseFieldIO::read");
95 if (!
readAttribute(layerGroup, k_versionAttrName, 1, version))
96 throw MissingAttributeException(
"Couldn't find attribute " +
99 if (version != k_versionNumber)
100 throw UnsupportedVersionException(
"DenseField version not supported: " +
101 lexical_cast<std::string>(version));
103 if (!
readAttribute(layerGroup, k_extentsStr, 6, extents.min.x))
104 throw MissingAttributeException(
"Couldn't find attribute " +
107 if (!
readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x))
108 throw MissingAttributeException(
"Couldn't find attribute " +
111 if (!
readAttribute(layerGroup, k_componentsStr, 1, components))
112 throw MissingAttributeException(
"Couldn't find attribute " +
117 if (dataSet.id() < 0)
118 throw OpenDataSetException(
"Couldn't open data set: " + k_dataStr);
122 H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
124 if (dataSpace.id() < 0)
125 throw GetDataSpaceException(
"Couldn't get data space");
127 if (dataType.id() < 0)
128 throw GetDataTypeException(
"Couldn't get data type");
132 V3i size(dataW.size() +
V3i(1));
133 int calculatedTotal = size.x * size.y * size.z;
134 int reportedSize = dims[0] / components;
136 if (calculatedTotal != reportedSize)
137 throw FileIntegrityException(
"Data size doesn't match number of voxels");
144 bool isHalf, isFloat, isDouble;
145 isHalf = H5Tequal(dataType, H5T_NATIVE_SHORT);
146 isFloat = H5Tequal(dataType, H5T_NATIVE_FLOAT);
147 isDouble = H5Tequal(dataType, H5T_NATIVE_DOUBLE);
149 if (isHalf && components == 1 && typeEnum ==
DataTypeHalf)
150 result = readData<half>(dataSet.id(), extents, dataW);
152 result = readData<float>(dataSet.id(), extents, dataW);
154 result = readData<double>(dataSet.id(), extents, dataW);
156 result = readData<V3h>(dataSet.id(), extents, dataW);
158 result = readData<V3f>(dataSet.id(), extents, dataW);
160 result = readData<V3d>(dataSet.id(), extents, dataW);
168 DenseFieldIO::read(
const OgIGroup &lg,
const std::string &,
171 Box3i extents, dataW;
174 throw MissingGroupException(
"Invalid group in DenseFieldIO::read()");
180 if (!versionAttr.isValid()) {
181 throw MissingAttributeException(
"Couldn't find attribute " +
185 int version = versionAttr.value();
186 if (version != k_versionNumber) {
187 throw UnsupportedVersionException(
"DenseField version not supported: " +
188 lexical_cast<std::string>(version));
194 lg.findAttribute<
veci32_t>(k_extentsMinStr);
196 lg.findAttribute<
veci32_t>(k_extentsMaxStr);
197 if (!extMinAttr.isValid()) {
198 throw MissingAttributeException(
"Couldn't find attribute " +
201 if (!extMaxAttr.isValid()) {
202 throw MissingAttributeException(
"Couldn't find attribute " +
206 extents.min = extMinAttr.value();
207 extents.max = extMaxAttr.value();
212 lg.findAttribute<
veci32_t>(k_dataWindowMinStr);
214 lg.findAttribute<
veci32_t>(k_dataWindowMaxStr);
215 if (!dwMinAttr.isValid()) {
216 throw MissingAttributeException(
"Couldn't find attribute " +
219 if (!dwMaxAttr.isValid()) {
220 throw MissingAttributeException(
"Couldn't find attribute " +
224 dataW.min = dwMinAttr.value();
225 dataW.max = dwMaxAttr.value();
230 lg.findAttribute<
int>(k_componentsStr);
231 if (!numComponentsAttr.isValid()) {
232 throw MissingAttributeException(
"Couldn't find attribute " +
240 OgDataType typeOnDisk = lg.datasetType(k_dataStr);
242 if (typeEnum == typeOnDisk) {
244 result = readData<float16_t>(lg, extents, dataW);
246 result = readData<float32_t>(lg, extents, dataW);
248 result = readData<float64_t>(lg, extents, dataW);
250 result = readData<vec16_t>(lg, extents, dataW);
252 result = readData<vec32_t>(lg, extents, dataW);
254 result = readData<vec64_t>(lg, extents, dataW);
267 if (layerGroup == -1)
268 throw BadHdf5IdException(
"Bad layer group in DenseFieldIO::write");
273 throw WriteAttributeException(
"Couldn't write attribute " +
292 success = writeInternal<float>(layerGroup, floatField);
294 else if (halfField) {
295 success = writeInternal<half>(layerGroup, halfField);
297 else if (doubleField) {
298 success = writeInternal<double>(layerGroup, doubleField);
300 else if (vecFloatField) {
301 success = writeInternal<V3f>(layerGroup, vecFloatField);
303 else if (vecHalfField) {
304 success = writeInternal<V3h>(layerGroup, vecHalfField);
306 else if (vecDoubleField) {
307 success = writeInternal<V3d>(layerGroup, vecDoubleField);
310 throw WriteLayerException(
"DenseFieldIO does not support the given "
311 "DenseField template parameter");
343 success = writeInternal<float>(layerGroup, floatField);
345 else if (halfField) {
346 success = writeInternal<half>(layerGroup, halfField);
348 else if (doubleField) {
349 success = writeInternal<double>(layerGroup, doubleField);
351 else if (vecFloatField) {
352 success = writeInternal<V3f>(layerGroup, vecFloatField);
354 else if (vecHalfField) {
355 success = writeInternal<V3h>(layerGroup, vecHalfField);
357 else if (vecDoubleField) {
358 success = writeInternal<V3d>(layerGroup, vecDoubleField);
361 throw WriteLayerException(
"DenseFieldIO does not support the given "
362 "DenseField template parameter");
373 template <
class Data_T>
374 bool DenseFieldIO::writeInternal(hid_t layerGroup,
388 hsize_t totalSize[1];
389 totalSize[0] = size[0] * size[1] * size[2] * components;
392 hsize_t preferredChunkSize = 4096 * 16;
393 const hsize_t chunkSize =
std::min(preferredChunkSize, totalSize[0] / 2);
400 { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z };
403 throw WriteAttributeException(
"Couldn't write attribute " + k_extentsStr);
409 { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z };
411 if (!
writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) {
412 throw WriteAttributeException(
"Couldn't write attribute " + k_dataWindowStr);
417 if (!
writeAttribute(layerGroup, k_componentsStr, 1, components)) {
418 throw WriteAttributeException(
"Couldn't write attribute " + k_componentsStr);
424 if (!
writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) {
433 if (dataSpace.id() < 0) {
434 throw CreateDataSpaceException(
"Couldn't create data space in "
435 "DenseFieldIO::writeInternal");
440 H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL);
444 hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
446 herr_t status = H5Pset_deflate(dcpl, 9);
450 status = H5Pset_chunk(dcpl, 1, &chunkSize);
459 H5P_DEFAULT, dcpl, H5P_DEFAULT);
461 if (dataSet.id() < 0) {
462 throw CreateDataSetException(
"Couldn't create data set in "
463 "DenseFieldIO::writeInternal");
468 if (!writeData<Data_T>(dataSet.id(), field, Data_T(0.0f))) {
469 throw WriteLayerException(
"Error writing layer");
477 template <
class Data_T>
478 bool DenseFieldIO::writeInternal(OgOGroup &layerGroup,
509 const size_t length = memSize[0] * memSize[1] * memSize[2];
512 data.addData(length, &(*field->
begin()));
519 template <
class Data_T>
520 bool DenseFieldIO::writeData(hid_t dataSet,
526 hid_t err = H5Dwrite(dataSet,
529 H5P_DEFAULT, &(*field->
begin()));
532 throw Exc::WriteLayerException(
"Error writing layer in "
533 "DenseFieldIO::writeData");
541 template <
class Data_T>
543 DenseFieldIO::readData(hid_t dataSet,
const Box3i &extents,
const Box3i &dataW)
546 field->
setSize(extents, dataW);
549 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->
begin())) < 0)
551 std::string typeName =
"DenseField<" +
553 throw Exc::Hdf5DataReadException(
"Couldn't read " + typeName +
" data");
561 template <
class Data_T>
563 DenseFieldIO::readData(
const OgIGroup &layerGroup,
const Box3i &extents,
567 field->
setSize(extents, dataW);
571 if (!data.isValid()) {
572 throw Exc::ReadDataException(
"DenseFieldIO::readData() couldn't open "
577 if (!data.getData(0, &(*field->
begin()), OGAWA_THREAD)) {
578 throw Exc::ReadDataException(
"DenseFieldIO::readData() couldn't read "