36 #ifndef VIGRA_HDF5IMPEX_HXX
37 #define VIGRA_HDF5IMPEX_HXX
43 #define H5Gcreate_vers 2
44 #define H5Gopen_vers 2
45 #define H5Dopen_vers 2
46 #define H5Dcreate_vers 2
47 #define H5Acreate_vers 2
51 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
53 # define H5Gopen(a, b, c) H5Gopen(a, b)
56 # define H5Gcreate(a, b, c, d, e) H5Gcreate(a, b, 1)
59 # define H5Dopen(a, b, c) H5Dopen(a, b)
62 # define H5Dcreate(a, b, c, d, e, f, g) H5Dcreate(a, b, c, d, f)
65 # define H5Acreate(a, b, c, d, e, f) H5Acreate(a, b, c, d, e)
67 # ifndef H5Pset_obj_track_times
68 # define H5Pset_obj_track_times(a, b) do {} while (0)
76 #include "multi_array.hxx"
77 #include "multi_iterator_coupled.hxx"
78 #include "multi_impex.hxx"
100 inline bool isHDF5(
char const * filename)
103 return _access(filename, 0) != -1 && H5Fis_hdf5(filename);
105 return access(filename, F_OK) == 0 && H5Fis_hdf5(filename);
130 H5E_auto2_t old_func_;
131 void *old_client_data_;
139 , old_client_data_(0)
141 H5Eget_auto2(H5E_DEFAULT, &old_func_, &old_client_data_);
142 H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
147 H5Eset_auto2(H5E_DEFAULT, old_func_, old_client_data_);
192 typedef herr_t (*Destructor)(hid_t);
196 Destructor destructor_;
227 HDF5Handle(hid_t h, Destructor destructor,
const char * error_message)
229 destructor_(destructor)
232 vigra_fail(error_message);
240 : handle_( h.handle_ ),
241 destructor_(h.destructor_)
252 if(h.handle_ != handle_)
256 destructor_ = h.destructor_;
278 if(handle_ && destructor_)
279 res = (*destructor_)(handle_);
300 void reset(hid_t h, Destructor destructor,
const char * error_message)
303 vigra_fail(error_message);
308 destructor_ = destructor;
318 std::swap(handle_, h.handle_);
319 std::swap(destructor_, h.destructor_);
337 operator hid_t()
const
346 return handle_ == h.handle_;
360 return handle_ != h.handle_;
413 typedef herr_t (*Destructor)(hid_t);
417 Destructor destructor_;
452 destructor_(destructor),
456 vigra_fail(error_message);
458 refcount_ =
new size_t(1);
465 : handle_( h.handle_ ),
466 destructor_(h.destructor_),
467 refcount_(h.refcount_)
479 if(h.handle_ != handle_)
483 destructor_ = h.destructor_;
484 refcount_ = h.refcount_;
515 res = (*destructor_)(handle_);
529 void reset(hid_t h, Destructor destructor,
const char * error_message)
532 vigra_fail(error_message);
537 destructor_ = destructor;
539 refcount_ =
new size_t(1);
567 std::swap(handle_, h.handle_);
568 std::swap(destructor_, h.destructor_);
569 std::swap(refcount_, h.refcount_);
587 operator hid_t()
const
596 return handle_ == h.handle_;
610 return handle_ != h.handle_;
657 enum PixelType { UINT8, UINT16, UINT32, UINT64,
658 INT8, INT16, INT32, INT64,
671 VIGRA_EXPORT
HDF5ImportInfo(
const char* filePath,
const char* pathInFile );
673 VIGRA_EXPORT ~HDF5ImportInfo();
677 VIGRA_EXPORT
const std::string&
getFilePath()
const;
753 VIGRA_EXPORT PixelType
pixelType()
const;
757 std::string m_filename, m_path, m_pixeltype;
758 hssize_t m_dimensions;
766 struct HDF5TypeTraits
768 static hid_t getH5DataType()
770 std::runtime_error(
"getH5DataType(): invalid type");
774 static int numberOfBands()
776 std::runtime_error(
"numberOfBands(): invalid type");
782 inline hid_t getH5DataType()
784 return HDF5TypeTraits<T>::getH5DataType();
787 #define VIGRA_H5_DATATYPE(type, h5type) \
789 struct HDF5TypeTraits<type> \
791 static hid_t getH5DataType() \
795 static int numberOfBands() \
799 typedef type value_type; \
802 struct HDF5TypeTraits<TinyVector<type, M> > \
804 static hid_t getH5DataType() \
808 static int numberOfBands() \
812 typedef type value_type; \
815 struct HDF5TypeTraits<RGBValue<type> > \
817 static hid_t getH5DataType() \
821 static int numberOfBands() \
825 typedef type value_type; \
828 VIGRA_H5_DATATYPE(
char, H5T_NATIVE_CHAR)
829 VIGRA_H5_DATATYPE(
signed char, H5T_NATIVE_SCHAR)
830 VIGRA_H5_DATATYPE(
unsigned char, H5T_NATIVE_UCHAR)
831 VIGRA_H5_DATATYPE(
signed short, H5T_NATIVE_SHORT)
832 VIGRA_H5_DATATYPE(
unsigned short, H5T_NATIVE_USHORT)
833 VIGRA_H5_DATATYPE(
signed int, H5T_NATIVE_INT)
834 VIGRA_H5_DATATYPE(
unsigned int, H5T_NATIVE_UINT)
835 VIGRA_H5_DATATYPE(
signed long, H5T_NATIVE_LONG)
836 VIGRA_H5_DATATYPE(
unsigned long, H5T_NATIVE_ULONG)
837 VIGRA_H5_DATATYPE(
signed long long, H5T_NATIVE_LLONG)
838 VIGRA_H5_DATATYPE(
unsigned long long, H5T_NATIVE_ULLONG)
839 VIGRA_H5_DATATYPE(
float, H5T_NATIVE_FLOAT)
840 VIGRA_H5_DATATYPE(
double, H5T_NATIVE_DOUBLE)
841 VIGRA_H5_DATATYPE(
long double, H5T_NATIVE_LDOUBLE)
845 struct HDF5TypeTraits<
char*>
847 static hid_t getH5DataType()
849 hid_t stringtype = H5Tcopy (H5T_C_S1);
850 H5Tset_size(stringtype, H5T_VARIABLE);
854 static int numberOfBands()
861 struct HDF5TypeTraits<const char*>
863 static hid_t getH5DataType()
865 hid_t stringtype = H5Tcopy (H5T_C_S1);
866 H5Tset_size(stringtype, H5T_VARIABLE);
870 static int numberOfBands()
876 #undef VIGRA_H5_DATATYPE
880 inline hid_t getH5DataType<FFTWComplex<float> >()
882 hid_t complex_id = H5Tcreate (H5T_COMPOUND,
sizeof (FFTWComplex<float>));
883 H5Tinsert (complex_id,
"real", 0, H5T_NATIVE_FLOAT);
884 H5Tinsert (complex_id,
"imaginary",
sizeof(
float), H5T_NATIVE_FLOAT);
889 inline hid_t getH5DataType<FFTWComplex<double> >()
891 hid_t complex_id = H5Tcreate (H5T_COMPOUND,
sizeof (FFTWComplex<double>));
892 H5Tinsert (complex_id,
"real", 0, H5T_NATIVE_DOUBLE);
893 H5Tinsert (complex_id,
"imaginary",
sizeof(
double), H5T_NATIVE_DOUBLE);
902 void HDF5_ls_insert(
void*,
const std::string &);
907 VIGRA_EXPORT H5O_type_t HDF5_get_type(hid_t,
const char*);
908 extern "C" VIGRA_EXPORT herr_t HDF5_ls_inserter_callback(hid_t,
const char*,
const H5L_info_t*,
void*);
909 extern "C" VIGRA_EXPORT herr_t HDF5_listAttributes_inserter_callback(hid_t,
const char*,
const H5A_info_t*,
void*);
966 virtual void insert(
const std::string &) = 0;
967 virtual ~ls_closure() {}
971 struct lsOpData :
public ls_closure
973 std::vector<std::string> & objects;
974 lsOpData(std::vector<std::string> & o) : objects(o) {}
975 void insert(
const std::string & x)
977 objects.push_back(x);
982 template<
class Container>
983 struct ls_container_data :
public ls_closure
986 ls_container_data(Container & o) : objects(o) {}
987 void insert(
const std::string & x)
989 objects.insert(std::string(x));
996 friend void HDF5_ls_insert(
void*,
const std::string &);
1011 ReadOnly = OpenReadOnly,
1031 : track_time(track_creation_times ? 1 : 0),
1044 : track_time(track_creation_times ? 1 : 0)
1046 open(filePath, mode);
1067 const std::string & pathname =
"",
1068 bool read_only =
false)
1069 : fileHandle_(fileHandle),
1070 read_only_(read_only)
1077 cGroupHandle_ =
HDF5Handle(openCreateGroup_(pathname), &H5Gclose,
1078 "HDF5File(fileHandle, pathname): Failed to open group");
1081 hbool_t track_times_tmp;
1082 HDF5Handle plist_id(H5Fget_create_plist(fileHandle_), &H5Pclose,
1083 "HDF5File(fileHandle, pathname): Failed to open file creation property list");
1084 herr_t status = H5Pget_obj_track_times(plist_id, &track_times_tmp );
1085 vigra_postcondition(status >= 0,
1086 "HDF5File(fileHandle, pathname): cannot access track time attribute");
1087 track_time = track_times_tmp;
1095 : fileHandle_(other.fileHandle_),
1096 track_time(other.track_time),
1097 read_only_(other.read_only_)
1099 cGroupHandle_ =
HDF5Handle(openCreateGroup_(other.currentGroupName_()), &H5Gclose,
1100 "HDF5File(HDF5File const &): Failed to open group.");
1123 fileHandle_ = other.fileHandle_;
1124 cGroupHandle_ =
HDF5Handle(openCreateGroup_(other.currentGroupName_()), &H5Gclose,
1125 "HDF5File::operator=(): Failed to open group.");
1126 track_time = other.track_time;
1127 read_only_ = other.read_only_;
1132 int file_use_count()
const
1139 return fileHandle_ != 0;
1142 bool isReadOnly()
const
1147 void setReadOnly(
bool stat=
true)
1159 std::string errorMessage =
"HDF5File.open(): Could not open or create file '" + filePath +
"'.";
1160 fileHandle_ =
HDF5HandleShared(createFile_(filePath, mode), &H5Fclose, errorMessage.c_str());
1161 cGroupHandle_ =
HDF5Handle(openCreateGroup_(
"/"), &H5Gclose,
"HDF5File.open(): Failed to open root group.");
1162 setReadOnly(mode == OpenReadOnly);
1169 bool success = cGroupHandle_.
close() >= 0 && fileHandle_.
close() >= 0;
1170 vigra_postcondition(success,
"HDF5File.close() failed.");
1177 std::string message =
"HDF5File::root(): Could not open group '/'.";
1178 cGroupHandle_ =
HDF5Handle(H5Gopen(fileHandle_,
"/", H5P_DEFAULT),&H5Gclose,message.c_str());
1184 inline void cd(std::string groupName)
1195 std::string groupName = currentGroupName_();
1198 if(groupName ==
"/"){
1202 size_t lastSlash = groupName.find_last_of(
'/');
1204 std::string parentGroup (groupName.begin(), groupName.begin()+lastSlash+1);
1217 std::string groupName = currentGroupName_();
1219 for(
int i = 0; i<levels; i++)
1224 if(groupName != currentGroupName_())
1236 inline void mkdir(std::string groupName)
1238 vigra_precondition(!isReadOnly(),
1239 "HDF5File::mkdir(): file is read-only.");
1241 std::string message =
"HDF5File::mkdir(): Could not create group '" + groupName +
"'.\n";
1246 HDF5Handle(openCreateGroup_(groupName.c_str()),&H5Gclose,message.c_str());
1253 inline void cd_mk(std::string groupName)
1255 vigra_precondition(!isReadOnly(),
1256 "HDF5File::cd_mk(): file is read-only.");
1258 std::string message =
"HDF5File::cd_mk(): Could not create group '" + groupName +
"'.";
1263 cGroupHandle_ =
HDF5Handle(openCreateGroup_(groupName.c_str()),&H5Gclose,message.c_str());
1267 void ls_H5Literate(ls_closure & data)
const
1269 H5Literate(cGroupHandle_, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
1270 HDF5_ls_inserter_callback, static_cast<void*>(&data));
1278 inline std::vector<std::string>
ls()
const
1280 std::vector<std::string> list;
1281 lsOpData data(list);
1282 ls_H5Literate(data);
1299 template<
class Container>
1300 void ls(Container & cont)
const
1302 ls_container_data<Container> data(cont);
1303 ls_H5Literate(data);
1308 inline std::string
pwd()
const
1310 return currentGroupName_();
1326 return (H5Lexists(fileHandle_, datasetName.c_str(), H5P_DEFAULT) > 0);
1337 return getDatasetDimensions_(datasetHandle);
1340 hssize_t getDatasetDimensions_(hid_t dataset)
const
1342 std::string errorMessage =
"HDF5File::getDatasetDimensions(): Unable to access dataspace.";
1343 HDF5Handle dataspaceHandle(H5Dget_space(dataset), &H5Sclose, errorMessage.c_str());
1346 return H5Sget_simple_extent_ndims(dataspaceHandle);
1368 std::string errorMessage =
"HDF5File::getDatasetShape(): Unable to open dataset '" + datasetName +
"'.";
1369 HDF5Handle datasetHandle =
HDF5Handle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
1371 errorMessage =
"HDF5File::getDatasetShape(): Unable to access dataspace.";
1372 HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose, errorMessage.c_str());
1379 H5Sget_simple_extent_dims(dataspaceHandle, shape.
data(), maxdims.
data());
1382 std::reverse(shape.
begin(), shape.
end());
1407 hid_t datatype = H5Dget_type(datasetHandle);
1408 H5T_class_t dataclass = H5Tget_class(datatype);
1409 size_t datasize = H5Tget_size(datatype);
1410 H5T_sign_t datasign = H5Tget_sign(datatype);
1412 if(dataclass == H5T_FLOAT)
1416 else if(datasize == 8)
1419 else if(dataclass == H5T_INTEGER)
1421 if(datasign == H5T_SGN_NONE)
1425 else if(datasize == 2)
1427 else if(datasize == 4)
1429 else if(datasize == 8)
1436 else if(datasize == 2)
1438 else if(datasize == 4)
1440 else if(datasize == 8)
1451 std::string errorMessage =
"HDF5File::getDatasetHandle(): Unable to open dataset '" + datasetName +
"'.";
1459 std::string errorMessage =
"HDF5File::getDatasetHandle(): Unable to open dataset '" + datasetName +
"'.";
1466 std::string function_name =
"HDF5File::getGroupHandle()")
1468 std::string errorMessage = function_name +
": Group '" + group_name +
"' not found.";
1474 vigra_precondition(group_name ==
"/" || H5Lexists(fileHandle_, group_name.c_str(), H5P_DEFAULT) != 0,
1475 errorMessage.c_str());
1478 return HDF5Handle(openCreateGroup_(group_name), &H5Gclose,
"Internal error");
1482 void ls_H5Aiterate(std::string
const & group_or_dataset, ls_closure & data)
const
1484 H5O_type_t h5_type = get_object_type_(group_or_dataset);
1485 vigra_precondition(h5_type == H5O_TYPE_GROUP || h5_type == H5O_TYPE_DATASET,
1486 "HDF5File::listAttributes(): object \"" + group_or_dataset +
"\" is neither a group nor a dataset.");
1488 HDF5Handle object_handle(h5_type == H5O_TYPE_GROUP
1489 ? const_cast<HDF5File*>(
this)->openCreateGroup_(group_or_dataset)
1490 : getDatasetHandle_(group_or_dataset),
1491 h5_type == H5O_TYPE_GROUP
1494 "HDF5File::listAttributes(): unable to open object.");
1496 H5Aiterate2(object_handle, H5_INDEX_NAME, H5_ITER_NATIVE, &n,
1497 HDF5_listAttributes_inserter_callback, static_cast<void*>(&data));
1505 inline std::vector<std::string>
listAttributes(std::string
const & group_or_dataset)
const
1507 std::vector<std::string> list;
1508 lsOpData data(list);
1509 ls_H5Aiterate(group_or_dataset, data);
1519 template<
class Container>
1520 void listAttributes(std::string
const & group_or_dataset, Container & container)
const
1522 ls_container_data<Container> data(container);
1523 ls_H5Aiterate(group_or_dataset, data);
1530 std::string message =
"HDF5File::getAttributeHandle(): Attribute '" + attribute_name +
"' not found.";
1532 &H5Aclose, message.c_str());
1540 template<
unsigned int N,
class T,
class Str
ide>
1542 std::string attribute_name,
1548 write_attribute_(object_name, attribute_name, array, detail::getH5DataType<T>(), 1);
1551 template<
unsigned int N,
class T,
int SIZE,
class Str
ide>
1553 std::string attributeName,
1559 write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), SIZE);
1562 template<
unsigned int N,
class T,
class Str
ide>
1564 std::string attributeName,
1565 const MultiArrayView<N, RGBValue<T>, Stride> & array)
1570 write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 3);
1576 inline void writeAttribute(std::string object_name, std::string attribute_name,
char data)
1577 { writeAtomicAttribute(object_name,attribute_name,data); }
1578 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed char data)
1579 { writeAtomicAttribute(datasetName,attributeName,data); }
1580 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed short data)
1581 { writeAtomicAttribute(datasetName,attributeName,data); }
1582 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed int data)
1583 { writeAtomicAttribute(datasetName,attributeName,data); }
1584 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed long data)
1585 { writeAtomicAttribute(datasetName,attributeName,data); }
1586 inline void writeAttribute(std::string datasetName, std::string attributeName,
signed long long data)
1587 { writeAtomicAttribute(datasetName,attributeName,data); }
1588 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned char data)
1589 { writeAtomicAttribute(datasetName,attributeName,data); }
1590 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned short data)
1591 { writeAtomicAttribute(datasetName,attributeName,data); }
1592 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned int data)
1593 { writeAtomicAttribute(datasetName,attributeName,data); }
1594 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned long data)
1595 { writeAtomicAttribute(datasetName,attributeName,data); }
1596 inline void writeAttribute(std::string datasetName, std::string attributeName,
unsigned long long data)
1597 { writeAtomicAttribute(datasetName,attributeName,data); }
1598 inline void writeAttribute(std::string datasetName, std::string attributeName,
float data)
1599 { writeAtomicAttribute(datasetName,attributeName,data); }
1600 inline void writeAttribute(std::string datasetName, std::string attributeName,
double data)
1601 { writeAtomicAttribute(datasetName,attributeName,data); }
1602 inline void writeAttribute(std::string datasetName, std::string attributeName,
long double data)
1603 { writeAtomicAttribute(datasetName,attributeName,data); }
1604 inline void writeAttribute(std::string datasetName, std::string attributeName,
const char* data)
1605 { writeAtomicAttribute(datasetName,attributeName,data); }
1606 inline void writeAttribute(std::string datasetName, std::string attributeName, std::string
const & data)
1607 { writeAtomicAttribute(datasetName,attributeName,data.c_str()); }
1614 htri_t exists = H5Aexists_by_name(fileHandle_, obj_path.c_str(),
1615 attribute_name.c_str(), H5P_DEFAULT);
1616 vigra_precondition(exists >= 0,
"HDF5File::existsAttribute(): "
1617 "object '" + object_name +
"' "
1627 template<
unsigned int N,
class T,
class Str
ide>
1629 std::string attribute_name,
1635 read_attribute_(object_name, attribute_name, array, detail::getH5DataType<T>(), 1);
1638 template<
unsigned int N,
class T,
int SIZE,
class Str
ide>
1640 std::string attributeName,
1646 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), SIZE);
1649 template<
unsigned int N,
class T,
class Str
ide>
1651 std::string attributeName,
1652 MultiArrayView<N, RGBValue<T>, Stride> array)
1657 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 3);
1663 inline void readAttribute(std::string object_name, std::string attribute_name,
char &data)
1664 { readAtomicAttribute(object_name,attribute_name,data); }
1665 inline void readAttribute(std::string datasetName, std::string attributeName,
signed char &data)
1666 { readAtomicAttribute(datasetName,attributeName,data); }
1667 inline void readAttribute(std::string datasetName, std::string attributeName,
signed short &data)
1668 { readAtomicAttribute(datasetName,attributeName,data); }
1669 inline void readAttribute(std::string datasetName, std::string attributeName,
signed int &data)
1670 { readAtomicAttribute(datasetName,attributeName,data); }
1671 inline void readAttribute(std::string datasetName, std::string attributeName,
signed long &data)
1672 { readAtomicAttribute(datasetName,attributeName,data); }
1673 inline void readAttribute(std::string datasetName, std::string attributeName,
signed long long &data)
1674 { readAtomicAttribute(datasetName,attributeName,data); }
1675 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned char &data)
1676 { readAtomicAttribute(datasetName,attributeName,data); }
1677 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned short &data)
1678 { readAtomicAttribute(datasetName,attributeName,data); }
1679 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned int &data)
1680 { readAtomicAttribute(datasetName,attributeName,data); }
1681 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned long &data)
1682 { readAtomicAttribute(datasetName,attributeName,data); }
1683 inline void readAttribute(std::string datasetName, std::string attributeName,
unsigned long long &data)
1684 { readAtomicAttribute(datasetName,attributeName,data); }
1685 inline void readAttribute(std::string datasetName, std::string attributeName,
float &data)
1686 { readAtomicAttribute(datasetName,attributeName,data); }
1687 inline void readAttribute(std::string datasetName, std::string attributeName,
double &data)
1688 { readAtomicAttribute(datasetName,attributeName,data); }
1689 inline void readAttribute(std::string datasetName, std::string attributeName,
long double &data)
1690 { readAtomicAttribute(datasetName,attributeName,data); }
1691 inline void readAttribute(std::string datasetName, std::string attributeName, std::string &data)
1692 { readAtomicAttribute(datasetName,attributeName,data); }
1720 template<
unsigned int N,
class T,
class Str
ide>
1721 inline void write(std::string datasetName,
1723 int iChunkSize = 0,
int compression = 0)
1729 for(
unsigned int i = 0; i < N; i++){
1730 chunkSize[i] = iChunkSize;
1732 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
1752 template<
unsigned int N,
class T,
class Str
ide>
1753 inline void write(std::string datasetName,
1760 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
1774 template<
unsigned int N,
class T,
class Str
ide>
1781 typedef detail::HDF5TypeTraits<T> TypeTraits;
1782 writeBlock_(datasetName, blockOffset, array,
1783 TypeTraits::getH5DataType(), TypeTraits::numberOfBands());
1786 template<
unsigned int N,
class T,
class Str
ide>
1791 typedef detail::HDF5TypeTraits<T> TypeTraits;
1792 return writeBlock_(dataset, blockOffset, array,
1793 TypeTraits::getH5DataType(), TypeTraits::numberOfBands());
1797 template<
unsigned int N,
class T,
int SIZE,
class Str
ide>
1798 inline void write(std::string datasetName,
1799 const MultiArrayView<N, TinyVector<T, SIZE>, Stride> & array,
1800 int iChunkSize = 0,
int compression = 0)
1805 typename MultiArrayShape<N>::type chunkSize;
1806 for(
int i = 0; i < N; i++){
1807 chunkSize[i] = iChunkSize;
1809 write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
1812 template<
unsigned int N,
class T,
int SIZE,
class Str
ide>
1813 inline void write(std::string datasetName,
1814 const MultiArrayView<N, TinyVector<T, SIZE>, Stride> & array,
1815 typename MultiArrayShape<N>::type chunkSize,
int compression = 0)
1820 write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
1834 void write(
const std::string & datasetName,
1836 int compression = 0)
1841 write(datasetName, m_array, compression);
1845 template<
unsigned int N,
class T,
class Str
ide>
1846 inline void write(std::string datasetName,
1848 int iChunkSize = 0,
int compression = 0)
1854 for(
int i = 0; i < N; i++){
1855 chunkSize[i] = iChunkSize;
1857 write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
1860 template<
unsigned int N,
class T,
class Str
ide>
1861 inline void write(std::string datasetName,
1862 const MultiArrayView<N, RGBValue<T>, Stride> & array,
1863 typename MultiArrayShape<N>::type chunkSize,
int compression = 0)
1868 write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
1874 inline void write(std::string datasetName,
char data) { writeAtomic(datasetName,data); }
1875 inline void write(std::string datasetName,
signed char data) { writeAtomic(datasetName,data); }
1876 inline void write(std::string datasetName,
signed short data) { writeAtomic(datasetName,data); }
1877 inline void write(std::string datasetName,
signed int data) { writeAtomic(datasetName,data); }
1878 inline void write(std::string datasetName,
signed long data) { writeAtomic(datasetName,data); }
1879 inline void write(std::string datasetName,
signed long long data) { writeAtomic(datasetName,data); }
1880 inline void write(std::string datasetName,
unsigned char data) { writeAtomic(datasetName,data); }
1881 inline void write(std::string datasetName,
unsigned short data) { writeAtomic(datasetName,data); }
1882 inline void write(std::string datasetName,
unsigned int data) { writeAtomic(datasetName,data); }
1883 inline void write(std::string datasetName,
unsigned long data) { writeAtomic(datasetName,data); }
1884 inline void write(std::string datasetName,
unsigned long long data) { writeAtomic(datasetName,data); }
1885 inline void write(std::string datasetName,
float data) { writeAtomic(datasetName,data); }
1886 inline void write(std::string datasetName,
double data) { writeAtomic(datasetName,data); }
1887 inline void write(std::string datasetName,
long double data) { writeAtomic(datasetName,data); }
1888 inline void write(std::string datasetName,
const char* data) { writeAtomic(datasetName,data); }
1889 inline void write(std::string datasetName, std::string
const & data) { writeAtomic(datasetName,data.c_str()); }
1902 template<
unsigned int N,
class T,
class Str
ide>
1908 read_(datasetName, array, detail::getH5DataType<T>(), 1);
1920 template<
unsigned int N,
class T,
class Alloc>
1931 "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
1935 for(
int k=0; k < static_cast<int>(dimshape.
size()); ++k)
1936 shape[k] = static_cast<MultiArrayIndex>(dimshape[k]);
1939 read_(datasetName, array, detail::getH5DataType<T>(), 1);
1952 read(datasetName, m_array);
1971 "HDF5File::readAndResize(): Array dimension disagrees with Dataset dimension must equal one for vigra::ArrayVector.");
1979 read_(datasetName, m_array, detail::getH5DataType<T>(), 1);
1997 template<
unsigned int N,
class T,
class Str
ide>
2005 typedef detail::HDF5TypeTraits<T> TypeTraits;
2006 readBlock_(datasetName, blockOffset, blockShape, array,
2007 TypeTraits::getH5DataType(), TypeTraits::numberOfBands());
2010 template<
unsigned int N,
class T,
class Str
ide>
2016 typedef detail::HDF5TypeTraits<T> TypeTraits;
2017 return readBlock_(dataset, blockOffset, blockShape, array,
2018 TypeTraits::getH5DataType(), TypeTraits::numberOfBands());
2022 template<
unsigned int N,
class T,
int SIZE,
class Str
ide>
2023 inline void read(std::string datasetName, MultiArrayView<N, TinyVector<T, SIZE>, Stride> array)
2028 read_(datasetName, array, detail::getH5DataType<T>(), SIZE);
2032 template<
unsigned int N,
class T,
int SIZE,
class Alloc>
2033 inline void readAndResize(std::string datasetName, MultiArray<N, TinyVector<T, SIZE>, Alloc> & array)
2043 SIZE == dimshape[0],
2044 "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
2047 typename MultiArrayShape<N>::type shape;
2048 for(
int k=1; k < static_cast<int>(dimshape.size()); ++k)
2049 shape[k-1] = static_cast<MultiArrayIndex>(dimshape[k]);
2050 array.reshape(shape);
2052 read_(datasetName, array, detail::getH5DataType<T>(), SIZE);
2056 template<
unsigned int N,
class T,
class Str
ide>
2057 inline void read(std::string datasetName, MultiArrayView<N, RGBValue<T>, Stride> array)
2062 read_(datasetName, array, detail::getH5DataType<T>(), 3);
2066 template<
unsigned int N,
class T,
class Alloc>
2067 inline void readAndResize(std::string datasetName, MultiArray<N, RGBValue<T>, Alloc> & array)
2078 "HDF5File::readAndResize(): Array dimension disagrees with dataset dimension.");
2081 typename MultiArrayShape<N>::type shape;
2082 for(
int k=1; k < static_cast<int>(dimshape.size()); ++k)
2083 shape[k-1] = static_cast<MultiArrayIndex>(dimshape[k]);
2084 array.reshape(shape);
2086 read_(datasetName, array, detail::getH5DataType<T>(), 3);
2092 inline void read(std::string datasetName,
char &data) { readAtomic(datasetName,data); }
2093 inline void read(std::string datasetName,
signed char &data) { readAtomic(datasetName,data); }
2094 inline void read(std::string datasetName,
signed short &data) { readAtomic(datasetName,data); }
2095 inline void read(std::string datasetName,
signed int &data) { readAtomic(datasetName,data); }
2096 inline void read(std::string datasetName,
signed long &data) { readAtomic(datasetName,data); }
2097 inline void read(std::string datasetName,
signed long long &data) { readAtomic(datasetName,data); }
2098 inline void read(std::string datasetName,
unsigned char &data) { readAtomic(datasetName,data); }
2099 inline void read(std::string datasetName,
unsigned short &data) { readAtomic(datasetName,data); }
2100 inline void read(std::string datasetName,
unsigned int &data) { readAtomic(datasetName,data); }
2101 inline void read(std::string datasetName,
unsigned long &data) { readAtomic(datasetName,data); }
2102 inline void read(std::string datasetName,
unsigned long long &data) { readAtomic(datasetName,data); }
2103 inline void read(std::string datasetName,
float &data) { readAtomic(datasetName,data); }
2104 inline void read(std::string datasetName,
double &data) { readAtomic(datasetName,data); }
2105 inline void read(std::string datasetName,
long double &data) { readAtomic(datasetName,data); }
2106 inline void read(std::string datasetName, std::string &data) { readAtomic(datasetName,data); }
2132 template<
int N,
class T>
2135 TinyVector<MultiArrayIndex, N>
const & shape,
2136 typename detail::HDF5TypeTraits<T>::value_type init =
2137 typename detail::HDF5TypeTraits<T>::value_type(),
2139 TinyVector<MultiArrayIndex, N>
const & chunkSize = TinyVector<MultiArrayIndex, N>(),
2141 TinyVector<MultiArrayIndex, N>
const & chunkSize = (TinyVector<MultiArrayIndex, N>()),
2143 int compressionParameter = 0);
2146 template<
int N,
class T>
2149 TinyVector<MultiArrayIndex, N>
const & shape,
2152 int compressionParameter = 0)
2154 typename MultiArrayShape<N>::type chunkSize;
2155 for(
int i = 0; i < N; i++){
2156 chunkSize[i] = iChunkSize;
2158 return this->
template createDataset<N, T>(datasetName, shape, init,
2159 chunkSize, compressionParameter);
2166 H5Fflush(fileHandle_, H5F_SCOPE_GLOBAL);
2179 class SplitString:
public std::string {
2181 SplitString(std::string &sstring): std::string(sstring) {};
2184 std::string first(
char delimiter =
'/')
2186 size_t lastPos = find_last_of(delimiter);
2187 if(lastPos == std::string::npos)
2190 return std::string(begin(), begin()+lastPos+1);
2194 std::string last(
char delimiter =
'/')
2196 size_t lastPos = find_last_of(delimiter);
2197 if(lastPos == std::string::npos)
2198 return std::string(*
this);
2199 return std::string(begin()+lastPos+1, end());
2203 template <
class Shape>
2204 ArrayVector<hsize_t>
2205 defineChunks(Shape chunks, Shape
const & shape,
int numBands,
int compression = 0)
2207 if(
prod(chunks) > 0)
2209 ArrayVector<hsize_t> res(chunks.begin(), chunks.end());
2211 res.insert(res.begin(),
static_cast<hsize_t
>(numBands));
2214 else if(compression > 0)
2217 chunks = min(detail::ChunkShape<Shape::static_size>::defaultShape(), shape);
2218 ArrayVector<hsize_t> res(chunks.begin(), chunks.end());
2220 res.insert(res.begin(),
static_cast<hsize_t
>(numBands));
2225 return ArrayVector<hsize_t>();
2239 if(path.length() == 0 || path ==
"."){
2240 return currentGroupName_();
2245 if(relativePath_(path)){
2246 std::string cname = currentGroupName_();
2248 str = currentGroupName_()+path;
2250 str = currentGroupName_()+
"/"+path;
2256 std::string::size_type startpos = 0;
2257 while(str.find(std::string(
"./"), startpos) != std::string::npos){
2258 std::string::size_type pos = str.find(std::string(
"./"), startpos);
2261 if(str.substr(pos-1,3) !=
"../"){
2263 str = str.substr(0,pos) + str.substr(pos+2,str.length()-pos-2);
2269 while(str.find(std::string(
"..")) != std::string::npos){
2270 std::string::size_type pos = str.find(std::string(
".."));
2273 std::string::size_type end = str.find(
"/",pos);
2274 if(end != std::string::npos){
2284 std::string::size_type prev_slash = str.rfind(
"/",pos);
2286 vigra_invariant(prev_slash != 0 && prev_slash != std::string::npos,
2287 "Error parsing path: "+str);
2289 std::string::size_type begin = str.rfind(
"/",prev_slash-1);
2292 str = str.substr(0,begin+1) + str.substr(end,str.length()-end);
2302 inline bool relativePath_(std::string & path)
const
2304 std::string::size_type pos = path.find(
'/') ;
2313 inline std::string currentGroupName_()
const
2315 int len = H5Iget_name(cGroupHandle_,NULL,1000);
2316 ArrayVector<char> name (len+1,0);
2317 H5Iget_name(cGroupHandle_,name.begin(),len+1);
2319 return std::string(name.begin());
2324 inline std::string fileName_()
const
2326 int len = H5Fget_name(fileHandle_,NULL,1000);
2327 ArrayVector<char> name (len+1,0);
2328 H5Fget_name(fileHandle_,name.begin(),len+1);
2330 return std::string(name.begin());
2335 inline hid_t createFile_(std::string filePath,
OpenMode mode = Open)
2339 pFile = fopen ( filePath.c_str(),
"r" );
2343 if ( pFile == NULL )
2345 vigra_precondition(mode != OpenReadOnly,
2346 "HDF5File::open(): cannot open non-existing file in read-only mode.");
2347 fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
2352 if(mode == OpenReadOnly)
2354 fileId = H5Fopen(filePath.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
2356 else if(mode == New)
2358 std::remove(filePath.c_str());
2359 fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
2363 fileId = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
2374 hid_t openGroup_(std::string groupName)
const
2376 return const_cast<HDF5File *
>(
this)->openCreateGroup_(groupName,
false);
2387 hid_t openCreateGroup_(std::string groupName,
bool create =
true)
2393 hid_t parent = H5Gopen(fileHandle_,
"/", H5P_DEFAULT);
2394 if(groupName ==
"/")
2400 groupName = std::string(groupName.begin()+1, groupName.end());
2403 if( groupName.size() != 0 && *groupName.rbegin() !=
'/')
2405 groupName = groupName +
'/';
2409 std::string::size_type begin = 0, end = groupName.find(
'/');
2410 while (end != std::string::npos)
2412 std::string group(groupName.begin()+begin, groupName.begin()+end);
2413 hid_t prevParent = parent;
2415 if(H5LTfind_dataset(parent, group.c_str()) == 0)
2418 parent = H5Gcreate(prevParent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
2424 parent = H5Gopen(prevParent, group.c_str(), H5P_DEFAULT);
2426 H5Gclose(prevParent);
2433 end = groupName.find(
'/', begin);
2442 inline void deleteDataset_(hid_t parent, std::string datasetName)
2445 if(H5LTfind_dataset(parent, datasetName.c_str()))
2448 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
2449 if(H5Gunlink(parent, datasetName.c_str()) < 0)
2451 vigra_postcondition(
false,
"HDF5File::deleteDataset_(): Unable to delete existing data.");
2454 if(H5Ldelete(parent, datasetName.c_str(), H5P_DEFAULT ) < 0)
2456 vigra_postcondition(
false,
"HDF5File::deleteDataset_(): Unable to delete existing data.");
2464 hid_t getDatasetHandle_(std::string datasetName)
const
2469 std::string groupname = SplitString(datasetName).first();
2470 std::string setname = SplitString(datasetName).last();
2472 if(H5Lexists(fileHandle_, datasetName.c_str(), H5P_DEFAULT) <= 0)
2474 std::cerr <<
"HDF5File::getDatasetHandle_(): Dataset '" << datasetName <<
"' does not exist.\n";
2479 HDF5Handle groupHandle(openGroup_(groupname), &H5Gclose,
"HDF5File::getDatasetHandle_(): Internal error");
2481 return H5Dopen(groupHandle, setname.c_str(), H5P_DEFAULT);
2486 H5O_type_t get_object_type_(std::string name)
const
2489 std::string group_name = SplitString(name).first();
2490 std::string object_name = SplitString(name).last();
2491 if (!object_name.size())
2492 return H5O_TYPE_GROUP;
2494 htri_t exists = H5Lexists(fileHandle_, name.c_str(), H5P_DEFAULT);
2495 vigra_precondition(exists > 0,
"HDF5File::get_object_type_(): "
2496 "object \"" + name +
"\" "
2499 HDF5Handle group_handle(openGroup_(group_name), &H5Gclose,
"Internal error");
2500 return HDF5_get_type(group_handle, name.c_str());
2505 template<
unsigned int N,
class T,
class Str
ide>
2506 void write_attribute_(std::string name,
2507 const std::string & attribute_name,
2508 const MultiArrayView<N, T, Stride> & array,
2509 const hid_t datatype,
2510 const int numBandsOfType);
2518 inline void writeAtomicAttribute(std::string datasetName, std::string attributeName,
const T data)
2523 typename MultiArrayShape<1>::type chunkSize;
2525 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
2527 write_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 1);
2532 template<
unsigned int N,
class T,
class Str
ide>
2533 void read_attribute_(std::string datasetName,
2534 std::string attributeName,
2535 MultiArrayView<N, T, Stride> array,
2536 const hid_t datatype,
const int numBandsOfType);
2544 inline void readAtomicAttribute(std::string datasetName, std::string attributeName, T & data)
2549 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
2550 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<T>(), 1);
2554 inline void readAtomicAttribute(std::string datasetName, std::string attributeName, std::string & data)
2559 MultiArray<1,const char *> array(MultiArrayShape<1>::type(1));
2560 read_attribute_(datasetName, attributeName, array, detail::getH5DataType<const char *>(), 1);
2561 data = std::string(array[0]);
2566 template<
unsigned int N,
class T,
class Str
ide>
2567 void write_(std::string &datasetName,
2568 const MultiArrayView<N, T, Stride> & array,
2569 const hid_t datatype,
2570 const int numBandsOfType,
2571 typename MultiArrayShape<N>::type &chunkSize,
2572 int compressionParameter = 0);
2583 inline void writeAtomic(std::string datasetName,
const T data)
2588 typename MultiArrayShape<1>::type chunkSize;
2590 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
2592 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize,0);
2597 template<
unsigned int N,
class T,
class Str
ide>
2598 void read_(std::string datasetName,
2599 MultiArrayView<N, T, Stride> array,
2600 const hid_t datatype,
const int numBandsOfType);
2611 inline void readAtomic(std::string datasetName, T & data)
2616 MultiArray<1,T> array(MultiArrayShape<1>::type(1));
2617 read_(datasetName, array, detail::getH5DataType<T>(), 1);
2621 inline void readAtomic(std::string datasetName, std::string & data)
2626 MultiArray<1,const char *> array(MultiArrayShape<1>::type(1));
2627 read_(datasetName, array, detail::getH5DataType<const char *>(), 1);
2628 data = std::string(array[0]);
2633 template<
unsigned int N,
class T,
class Str
ide>
2634 void writeBlock_(std::string datasetName,
2635 typename MultiArrayShape<N>::type &blockOffset,
2636 const MultiArrayView<N, T, Stride> & array,
2637 const hid_t datatype,
2638 const int numBandsOfType)
2641 std::string errorMessage =
"HDF5File::writeBlock(): Error opening dataset '" + datasetName +
"'.";
2642 HDF5HandleShared dataset(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
2643 herr_t status = writeBlock_(dataset, blockOffset, array, datatype, numBandsOfType);
2644 vigra_postcondition(status >= 0,
2645 "HDF5File::writeBlock(): write to dataset '" + datasetName +
"' via H5Dwrite() failed.");
2652 template<
unsigned int N,
class T,
class Str
ide>
2653 herr_t writeBlock_(HDF5HandleShared dataset,
2654 typename MultiArrayShape<N>::type &blockOffset,
2655 const MultiArrayView<N, T, Stride> & array,
2656 const hid_t datatype,
2657 const int numBandsOfType);
2663 template<
unsigned int N,
class T,
class Str
ide>
2664 void readBlock_(std::string datasetName,
2665 typename MultiArrayShape<N>::type &blockOffset,
2666 typename MultiArrayShape<N>::type &blockShape,
2667 MultiArrayView<N, T, Stride> array,
2668 const hid_t datatype,
const int numBandsOfType)
2670 std::string errorMessage (
"HDF5File::readBlock(): Unable to open dataset '" + datasetName +
"'.");
2671 HDF5HandleShared dataset(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
2672 herr_t status = readBlock_(dataset, blockOffset, blockShape, array, datatype, numBandsOfType);
2673 vigra_postcondition(status >= 0,
2674 "HDF5File::readBlock(): read from dataset '" + datasetName +
"' via H5Dread() failed.");
2682 template<
unsigned int N,
class T,
class Str
ide>
2683 herr_t readBlock_(HDF5HandleShared dataset,
2684 typename MultiArrayShape<N>::type &blockOffset,
2685 typename MultiArrayShape<N>::type &blockShape,
2686 MultiArrayView<N, T, Stride> array,
2687 const hid_t datatype,
const int numBandsOfType);
2692 template<
int N,
class T>
2696 typename detail::HDF5TypeTraits<T>::value_type init,
2698 int compressionParameter)
2700 vigra_precondition(!isReadOnly(),
2701 "HDF5File::createDataset(): file is read-only.");
2706 std::string groupname = SplitString(datasetName).first();
2707 std::string setname = SplitString(datasetName).last();
2709 hid_t parent = openCreateGroup_(groupname);
2712 deleteDataset_(parent, setname);
2716 typedef detail::HDF5TypeTraits<T> TypeTraits;
2718 if(TypeTraits::numberOfBands() > 1)
2720 shape_inv.resize(N+1);
2721 shape_inv[N] = TypeTraits::numberOfBands();
2725 shape_inv.resize(N);
2727 for(
int k=0; k<N; ++k)
2728 shape_inv[N-1-k] = shape[k];
2732 dataspaceHandle =
HDF5Handle(H5Screate_simple(shape_inv.
size(), shape_inv.
data(), NULL),
2733 &H5Sclose,
"HDF5File::createDataset(): unable to create dataspace for scalar data.");
2736 HDF5Handle plist ( H5Pcreate(H5P_DATASET_CREATE), &H5Pclose,
"HDF5File::createDataset(): unable to create property list." );
2737 H5Pset_fill_value(plist, TypeTraits::getH5DataType(), &init);
2740 H5Pset_obj_track_times(plist, track_time);
2743 ArrayVector<hsize_t> chunks(defineChunks(chunkSize, shape, TypeTraits::numberOfBands(), compressionParameter));
2744 if(chunks.
size() > 0)
2746 std::reverse(chunks.
begin(), chunks.
end());
2747 H5Pset_chunk (plist, chunks.
size(), chunks.
begin());
2751 if(compressionParameter > 0)
2753 H5Pset_deflate(plist, compressionParameter);
2758 TypeTraits::getH5DataType(),
2759 dataspaceHandle, H5P_DEFAULT, plist, H5P_DEFAULT),
2761 "HDF5File::createDataset(): unable to create dataset.");
2762 if(parent != cGroupHandle_)
2765 return datasetHandle;
2770 template<
unsigned int N,
class T,
class Str
ide>
2771 void HDF5File::write_(std::string &datasetName,
2773 const hid_t datatype,
2774 const int numBandsOfType,
2776 int compressionParameter)
2778 vigra_precondition(!isReadOnly(),
2779 "HDF5File::write(): file is read-only.");
2781 std::string groupname = SplitString(datasetName).first();
2782 std::string setname = SplitString(datasetName).last();
2786 std::reverse(shape.begin(), shape.end());
2788 if(numBandsOfType > 1)
2789 shape.push_back(numBandsOfType);
2791 HDF5Handle dataspace(H5Screate_simple(shape.size(), shape.begin(), NULL), &H5Sclose,
2792 "HDF5File::write(): Can not create dataspace.");
2795 std::string errorMessage (
"HDF5File::write(): can not create group '" + groupname +
"'.");
2796 HDF5Handle groupHandle(openCreateGroup_(groupname), &H5Gclose, errorMessage.c_str());
2799 deleteDataset_(groupHandle, setname.c_str());
2802 HDF5Handle plist(H5Pcreate(H5P_DATASET_CREATE), &H5Pclose,
2803 "HDF5File::write(): unable to create property list." );
2806 H5Pset_obj_track_times(plist, track_time);
2810 if(chunks.size() > 0)
2812 std::reverse(chunks.begin(), chunks.end());
2813 H5Pset_chunk (plist, chunks.size(), chunks.begin());
2817 if(compressionParameter > 0)
2819 H5Pset_deflate(plist, compressionParameter);
2823 HDF5Handle datasetHandle(H5Dcreate(groupHandle, setname.c_str(), datatype, dataspace,H5P_DEFAULT, plist, H5P_DEFAULT),
2824 &H5Dclose,
"HDF5File::write(): Can not create dataset.");
2830 status = H5Dwrite(datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.
data());
2840 int offset = numBandsOfType > 1 ? 1 : 0;
2841 std::reverse(shape.begin(), shape.end());
2842 if(chunks.size() > 0)
2845 std::reverse(chunks.begin(), chunks.end());
2850 ArrayVector<hsize_t>(shape.size(), 1).swap(chunks);
2851 chunks[0] = numBandsOfType;
2853 for(
unsigned int k=0; k<N; ++k)
2855 chunks[k+offset] = array.
shape(k);
2856 prod *= array.
shape(k);
2862 ArrayVector<hsize_t> null(shape.size(), 0),
2863 start(shape.size(), 0),
2864 count(shape.size(), 1);
2866 count[N-1-offset] = numBandsOfType;
2868 typedef typename MultiArrayShape<N>::type Shape;
2869 Shape chunkCount, chunkMaxShape;
2870 for(
unsigned int k=offset; k<chunks.size(); ++k)
2872 chunkMaxShape[k-offset] = chunks[k];
2876 typename CoupledIteratorType<N>::type chunkIter = createCoupledIterator(chunkCount),
2877 chunkEnd = chunkIter.getEndIterator();
2878 for(; chunkIter != chunkEnd; ++chunkIter)
2880 Shape chunkStart(chunkIter.point() * chunkMaxShape),
2881 chunkStop(min(chunkStart + chunkMaxShape, array.
shape()));
2882 MultiArray<N, T> buffer(array.
subarray(chunkStart, chunkStop));
2884 for(
unsigned int k=0; k<N; ++k)
2886 start[N-1-k] = chunkStart[k];
2887 count[N-1-k] = buffer.shape(k);
2892 count[N] = numBandsOfType;
2894 HDF5Handle filespace(H5Dget_space(datasetHandle),
2895 &H5Sclose,
"HDF5File::write(): unable to create hyperslabs.");
2896 status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start.data(), NULL, count.data(), NULL);
2900 HDF5Handle dataspace2(H5Screate_simple(count.size(), count.data(), NULL),
2901 &H5Sclose,
"HDF5File::write(): unable to create hyperslabs.");
2902 status = H5Sselect_hyperslab(dataspace2, H5S_SELECT_SET, null.data(), NULL, count.data(), NULL);
2906 status = H5Dwrite(datasetHandle, datatype, dataspace2, filespace, H5P_DEFAULT, buffer.data());
2911 vigra_postcondition(status >= 0,
2912 "HDF5File::write(): write to dataset '" + datasetName +
"' via H5Dwrite() failed.");
2917 template<
unsigned int N,
class T,
class Str
ide>
2918 herr_t HDF5File::writeBlock_(HDF5HandleShared datasetHandle,
2919 typename MultiArrayShape<N>::type &blockOffset,
2920 const MultiArrayView<N, T, Stride> & array,
2921 const hid_t datatype,
2922 const int numBandsOfType)
2924 vigra_precondition(!isReadOnly(),
2925 "HDF5File::writeBlock(): file is read-only.");
2927 ArrayVector<hsize_t> boffset, bshape, bones(N+1, 1);
2928 hssize_t dimensions = getDatasetDimensions_(datasetHandle);
2929 if(numBandsOfType > 1)
2931 vigra_precondition(N+1 == dimensions,
2932 "HDF5File::readBlock(): Array dimension disagrees with data dimension.");
2934 boffset.resize(N+1);
2935 bshape[N] = numBandsOfType;
2940 vigra_precondition(N == dimensions,
2941 "HDF5File::readBlock(): Array dimension disagrees with data dimension.");
2946 for(
int i = 0; i < N; ++i)
2949 bshape[N-1-i] = array.shape(i);
2950 boffset[N-1-i] = blockOffset[i];
2954 HDF5Handle memspace_handle (H5Screate_simple(bshape.size(), bshape.data(), NULL),
2956 "Unable to get origin dataspace");
2959 HDF5Handle dataspaceHandle (H5Dget_space(datasetHandle),&H5Sclose,
"Unable to create target dataspace");
2960 H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET,
2961 boffset.data(), bones.data(), bones.data(), bshape.data());
2964 if(array.isUnstrided())
2967 status = H5Dwrite( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data());
2972 MultiArray<N, T> buffer(array);
2973 status = H5Dwrite( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, buffer.data());
2980 template<
unsigned int N,
class T,
class Str
ide>
2981 void HDF5File::write_attribute_(std::string name,
2982 const std::string & attribute_name,
2983 const MultiArrayView<N, T, Stride> & array,
2984 const hid_t datatype,
2985 const int numBandsOfType)
2987 vigra_precondition(!isReadOnly(),
2988 "HDF5File::writeAttribute(): file is read-only.");
2991 ArrayVector<hsize_t> shape(array.shape().begin(), array.shape().end());
2992 std::reverse(shape.begin(), shape.end());
2993 if(numBandsOfType > 1)
2994 shape.push_back(numBandsOfType);
2996 HDF5Handle dataspace(H5Screate_simple(shape.size(),
2997 shape.begin(), NULL),
2998 &H5Sclose,
"HDF5File::writeAttribute(): Can not"
2999 " create dataspace.");
3001 std::string errorMessage (
"HDF5File::writeAttribute(): can not find "
3002 "object '" + name +
"'.");
3004 H5O_type_t h5_type = get_object_type_(name);
3005 bool is_group = h5_type == H5O_TYPE_GROUP;
3006 if (!is_group && h5_type != H5O_TYPE_DATASET)
3007 vigra_precondition(0,
"HDF5File::writeAttribute(): object \""
3008 + name +
"\" is neither a group nor a "
3011 HDF5Handle object_handle(is_group
3012 ? openCreateGroup_(name)
3013 : getDatasetHandle_(name),
3017 errorMessage.c_str());
3020 HDF5Handle attributeHandle(exists
3021 ? H5Aopen(object_handle,
3022 attribute_name.c_str(),
3024 : H5Acreate(object_handle,
3025 attribute_name.c_str(), datatype,
3026 dataspace, H5P_DEFAULT,
3029 "HDF5File::writeAttribute(): Can not create"
3032 if(array.isUnstrided())
3035 status = H5Awrite(attributeHandle, datatype, array.data());
3041 MultiArray<N, T> buffer(array);
3042 status = H5Awrite(attributeHandle, datatype, buffer.data());
3044 vigra_postcondition(status >= 0,
3045 "HDF5File::writeAttribute(): write to attribute '" + attribute_name +
"' via H5Awrite() failed.");
3050 template<
unsigned int N,
class T,
class Str
ide>
3051 void HDF5File::read_(std::string datasetName,
3052 MultiArrayView<N, T, Stride> array,
3053 const hid_t datatype,
const int numBandsOfType)
3058 std::string errorMessage (
"HDF5File::read(): Unable to open dataset '" + datasetName +
"'.");
3059 HDF5Handle datasetHandle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
3063 int offset = (numBandsOfType > 1)
3068 "HDF5File::read(): Array dimension disagrees with dataset dimension.");
3070 typename MultiArrayShape<N>::type shape;
3071 for(
int k=offset; k < (int)dimshape.size(); ++k)
3074 vigra_precondition(shape == array.shape(),
3075 "HDF5File::read(): Array shape disagrees with dataset shape.");
3077 vigra_precondition(dimshape[0] == static_cast<hsize_t>(numBandsOfType),
3078 "HDF5File::read(): Band count doesn't match destination array compound type.");
3081 if(array.isUnstrided())
3084 status = H5Dread(datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data() );
3090 ArrayVector<hsize_t> null(dimshape.size(), 0),
3091 chunks(dimshape.size(), 1),
3092 start(dimshape.size(), 0),
3093 count(dimshape.size(), 1);
3095 HDF5Handle properties(H5Dget_create_plist(datasetHandle),
3096 &H5Pclose,
"HDF5File::read(): failed to get property list");
3097 if(H5D_CHUNKED == H5Pget_layout(properties))
3100 H5Pget_chunk(properties, static_cast<int>(chunks.size()), chunks.data());
3101 std::reverse(chunks.begin(), chunks.end());
3106 chunks[0] = numBandsOfType;
3108 for(
unsigned int k=0; k<N; ++k)
3110 chunks[k+offset] = array.shape(k);
3111 prod *= array.shape(k);
3117 count[N-1-offset] =
static_cast<hsize_t
>(numBandsOfType);
3119 typedef typename MultiArrayShape<N>::type Shape;
3120 Shape chunkCount, chunkMaxShape;
3121 for(
unsigned int k=offset; k<chunks.size(); ++k)
3123 chunkMaxShape[k-offset] = chunks[k];
3127 typename CoupledIteratorType<N>::type chunkIter = createCoupledIterator(chunkCount),
3128 chunkEnd = chunkIter.getEndIterator();
3129 for(; chunkIter != chunkEnd; ++chunkIter)
3131 Shape chunkStart(chunkIter.point() * chunkMaxShape),
3132 chunkStop(min(chunkStart + chunkMaxShape, array.shape()));
3133 MultiArray<N, T> buffer(chunkStop - chunkStart);
3135 for(
unsigned int k=0; k<N; ++k)
3137 start[N-1-k] = chunkStart[k];
3138 count[N-1-k] = buffer.shape(k);
3143 count[N] = numBandsOfType;
3145 HDF5Handle filespace(H5Dget_space(datasetHandle),
3146 &H5Sclose,
"HDF5File::read(): unable to create hyperslabs.");
3147 status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start.data(), NULL, count.data(), NULL);
3151 HDF5Handle dataspace(H5Screate_simple(count.size(), count.data(), NULL),
3152 &H5Sclose,
"HDF5File::read(): unable to create hyperslabs.");
3153 status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, null.data(), NULL, count.data(), NULL);
3157 status = H5Dread(datasetHandle, datatype, dataspace, filespace, H5P_DEFAULT, buffer.data());
3161 array.subarray(chunkStart, chunkStop) = buffer;
3164 vigra_postcondition(status >= 0,
3165 "HDF5File::read(): read from dataset '" + datasetName +
"' via H5Dread() failed.");
3170 template<
unsigned int N,
class T,
class Str
ide>
3171 herr_t HDF5File::readBlock_(HDF5HandleShared datasetHandle,
3172 typename MultiArrayShape<N>::type &blockOffset,
3173 typename MultiArrayShape<N>::type &blockShape,
3174 MultiArrayView<N, T, Stride> array,
3175 const hid_t datatype,
const int numBandsOfType)
3177 vigra_precondition(blockShape == array.shape(),
3178 "HDF5File::readBlock(): Array shape disagrees with block size.");
3180 ArrayVector<hsize_t> boffset, bshape, bones(N+1, 1);
3181 hssize_t dimensions = getDatasetDimensions_(datasetHandle);
3182 if(numBandsOfType > 1)
3184 vigra_precondition(N+1 == dimensions,
3185 "HDF5File::readBlock(): Array dimension disagrees with data dimension.");
3187 boffset.resize(N+1);
3188 bshape[N] = numBandsOfType;
3193 vigra_precondition(N == dimensions,
3194 "HDF5File::readBlock(): Array dimension disagrees with data dimension.");
3199 for(
int i = 0; i < N; ++i)
3202 bshape[N-1-i] = blockShape[i];
3203 boffset[N-1-i] = blockOffset[i];
3207 HDF5Handle memspace_handle(H5Screate_simple(bshape.size(), bshape.data(), NULL),
3209 "Unable to create target dataspace");
3212 HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose,
3213 "Unable to get dataspace");
3214 H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET,
3215 boffset.data(), bones.data(), bones.data(), bshape.data());
3218 if(array.isUnstrided())
3221 status = H5Dread( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data());
3226 MultiArray<N, T> buffer(array.shape());
3227 status = H5Dread( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, buffer.data());
3237 template<
unsigned int N,
class T,
class Str
ide>
3238 void HDF5File::read_attribute_(std::string datasetName,
3239 std::string attributeName,
3240 MultiArrayView<N, T, Stride> array,
3241 const hid_t datatype,
const int numBandsOfType)
3245 std::string message =
"HDF5File::readAttribute(): could not get handle for attribute '"+attributeName+
"'' of object '"+dataset_path+
"'.";
3246 HDF5Handle attr_handle (H5Aopen_by_name(fileHandle_,dataset_path.c_str(),attributeName.c_str(),H5P_DEFAULT,H5P_DEFAULT),&H5Aclose, message.c_str());
3249 message =
"HDF5File::readAttribute(): could not get dataspace for attribute '"+attributeName+
"'' of object '"+dataset_path+
"'.";
3250 HDF5Handle attr_dataspace_handle (H5Aget_space(attr_handle),&H5Sclose,message.c_str());
3253 int raw_dims = H5Sget_simple_extent_ndims(attr_dataspace_handle);
3254 int dims = std::max(raw_dims, 1);
3255 ArrayVector<hsize_t> dimshape(dims);
3257 H5Sget_simple_extent_dims(attr_dataspace_handle, dimshape.data(), NULL);
3262 std::reverse(dimshape.begin(), dimshape.end());
3264 int offset = (numBandsOfType > 1)
3267 message =
"HDF5File::readAttribute(): Array dimension disagrees with dataset dimension.";
3271 for(
int k=offset; k < (int)dimshape.size(); ++k)
3272 vigra_precondition(array.shape()[k-offset] == (
MultiArrayIndex)dimshape[k],
3273 "HDF5File::readAttribute(): Array shape disagrees with dataset shape");
3276 if(array.isUnstrided())
3279 status = H5Aread( attr_handle, datatype, array.data());
3285 MultiArray<N, T> buffer(array.shape());
3286 status = H5Aread( attr_handle, datatype, buffer.data() );
3291 vigra_postcondition(status >= 0,
3292 "HDF5File::readAttribute(): read from attribute '" + attributeName +
"' via H5Aread() failed.");
3334 template<
unsigned int N,
class T,
class Str
ideTag>
3335 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, StrideTag> array)
3340 template<
unsigned int N,
class T,
class Str
ideTag>
3341 void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, StrideTag> array,
const hid_t datatype,
const int numBandsOfType)
3343 HDF5File file(info.getFilePath(), HDF5File::OpenReadOnly);
3344 file.read(info.getPathInFile(), array);
3348 inline hid_t openGroup(hid_t parent, std::string group_name)
3351 size_t last_slash = group_name.find_last_of(
'/');
3352 if (last_slash == std::string::npos || last_slash != group_name.size() - 1)
3353 group_name = group_name +
'/';
3354 std::string::size_type begin = 0, end = group_name.find(
'/');
3356 while (end != std::string::npos)
3358 std::string group(group_name.begin()+begin, group_name.begin()+end);
3359 hid_t prev_parent = parent;
3360 parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
3362 if(ii != 0) H5Gclose(prev_parent);
3363 if(parent < 0)
return parent;
3366 end = group_name.find(
'/', begin);
3371 inline hid_t createGroup(hid_t parent, std::string group_name)
3373 if(group_name.size() == 0 ||*group_name.rbegin() !=
'/')
3374 group_name = group_name +
'/';
3375 if(group_name ==
"/")
3376 return H5Gopen(parent, group_name.c_str(), H5P_DEFAULT);
3378 std::string::size_type begin = 0, end = group_name.find(
'/');
3380 while (end != std::string::npos)
3382 std::string group(group_name.begin()+begin, group_name.begin()+end);
3383 hid_t prev_parent = parent;
3385 if(H5LTfind_dataset(parent, group.c_str()) == 0)
3387 parent = H5Gcreate(prev_parent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
3389 parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
3392 if(ii != 0) H5Gclose(prev_parent);
3393 if(parent < 0)
return parent;
3396 end = group_name.find(
'/', begin);
3401 inline void deleteDataset(hid_t parent, std::string dataset_name)
3404 if(H5LTfind_dataset(parent, dataset_name.c_str()))
3407 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
3408 if(H5Gunlink(parent, dataset_name.c_str()) < 0)
3410 vigra_postcondition(
false,
"writeToHDF5File(): Unable to delete existing data.");
3413 if(H5Ldelete(parent, dataset_name.c_str(), H5P_DEFAULT ) < 0)
3415 vigra_postcondition(
false,
"createDataset(): Unable to delete existing data.");
3421 inline hid_t createFile(std::string filePath,
bool append_ =
true)
3424 pFile = fopen ( filePath.c_str(),
"r" );
3426 if ( pFile == NULL )
3428 file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
3433 file_id = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
3438 std::remove(filePath.c_str());
3439 file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
3444 template<
unsigned int N,
class T,
class Tag>
3445 void createDataset(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, Tag> & array,
const hid_t datatype,
const int numBandsOfType, HDF5Handle & file_handle, HDF5Handle & dataset_handle)
3447 std::string path_name(pathInFile), group_name, data_set_name, message;
3448 std::string::size_type delimiter = path_name.rfind(
'/');
3451 file_handle = HDF5Handle(createFile(filePath), &H5Fclose,
3452 "createDataset(): unable to open output file.");
3455 if(delimiter == std::string::npos)
3458 data_set_name = path_name;
3462 group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
3463 data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
3467 HDF5Handle group(createGroup(file_handle, group_name), &H5Gclose,
3468 "createDataset(): Unable to create and open group. generic v");
3471 deleteDataset(group, data_set_name);
3475 HDF5Handle dataspace_handle;
3476 if(numBandsOfType > 1) {
3478 hsize_t shape_inv[N+1];
3479 for(
unsigned int k=0; k<N; ++k) {
3480 shape_inv[N-1-k] = array.shape(k);
3483 shape_inv[N] = numBandsOfType;
3486 dataspace_handle = HDF5Handle(H5Screate_simple(N+1, shape_inv, NULL),
3487 &H5Sclose,
"createDataset(): unable to create dataspace for non-scalar data.");
3490 hsize_t shape_inv[N];
3491 for(
unsigned int k=0; k<N; ++k)
3492 shape_inv[N-1-k] = array.shape(k);
3495 dataspace_handle = HDF5Handle(H5Screate_simple(N, shape_inv, NULL),
3496 &H5Sclose,
"createDataset(): unable to create dataspace for scalar data.");
3500 dataset_handle = HDF5Handle(H5Dcreate(group,
3501 data_set_name.c_str(),
3504 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT),
3505 &H5Dclose,
"createDataset(): unable to create dataset.");
3548 template<
unsigned int N,
class T,
class Str
ideTag>
3549 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, StrideTag> & array)
3552 writeHDF5(filePath, pathInFile, array, 0, 0);
3555 template<
unsigned int N,
class T,
class Str
ideTag>
3556 void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, StrideTag> & array,
const hid_t datatype,
const int numBandsOfType)
3558 HDF5File file(filePath, HDF5File::Open);
3559 file.write(pathInFile, array);
3574 void operator()(std::string
const & in)
3576 size = in.size() > size ?
3584 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8) || DOXYGEN
3591 template<
size_t N,
class T,
class C>
3596 if(H5Aexists(loc, name) > 0)
3597 H5Adelete(loc, name);
3600 array.
shape().end());
3602 dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
3604 "writeToHDF5File(): unable to create dataspace.");
3608 detail::getH5DataType<T>(),
3610 H5P_DEFAULT ,H5P_DEFAULT ),
3612 "writeHDF5Attr: unable to create Attribute");
3616 for(
int ii = 0; ii < array.
size(); ++ii)
3617 buffer.push_back(array[ii]);
3618 H5Awrite(attr, detail::getH5DataType<T>(), buffer.
data());
3627 template<
size_t N,
class C>
3632 if(H5Aexists(loc, name) > 0)
3633 H5Adelete(loc, name);
3636 array.
shape().end());
3638 dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
3640 "writeToHDF5File(): unable to create dataspace.");
3644 "writeToHDF5File(): unable to create type.");
3646 detail::MaxSizeFnc max_size;
3647 max_size = std::for_each(array.
data(),array.
data()+ array.
size(), max_size);
3648 H5Tset_size (atype, max_size.size);
3654 H5P_DEFAULT ,H5P_DEFAULT ),
3656 "writeHDF5Attr: unable to create Attribute");
3658 std::string buf =
"";
3659 for(
int ii = 0; ii < array.
size(); ++ii)
3661 buf = buf + array[ii]
3662 + std::string(max_size.size - array[ii].
size(),
' ');
3664 H5Awrite(attr, atype, buf.c_str());
3692 std::string pathInFile,
3695 std::string path_name(pathInFile), group_name, data_set_name, message, attr_name;
3696 std::string::size_type delimiter = path_name.rfind(
'/');
3699 HDF5Handle file_id(createFile(filePath), &H5Fclose,
3700 "writeToHDF5File(): unable to open output file.");
3703 if(delimiter == std::string::npos)
3706 data_set_name = path_name;
3711 group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
3712 data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
3714 delimiter = data_set_name.rfind(
'.');
3715 if(delimiter == std::string::npos)
3717 attr_name = path_name;
3718 data_set_name =
"/";
3722 attr_name = std::string(data_set_name.begin()+delimiter+1, data_set_name.end());
3723 data_set_name = std::string(data_set_name.begin(), data_set_name.begin()+delimiter);
3726 HDF5Handle group(openGroup(file_id, group_name), &H5Gclose,
3727 "writeToHDF5File(): Unable to create and open group. attr ver");
3729 if(data_set_name !=
"/")
3731 HDF5Handle dset(H5Dopen(group, data_set_name.c_str(), H5P_DEFAULT), &H5Dclose,
3732 "writeHDF5Attr():unable to open dataset");
3747 #endif // VIGRA_HDF5IMPEX_HXX