36 #ifndef VIGRA_HDF5IMPEX_HXX
37 #define VIGRA_HDF5IMPEX_HXX
41 #define H5Gcreate_vers 2
42 #define H5Gopen_vers 2
43 #define H5Dopen_vers 2
44 #define H5Dcreate_vers 2
45 #define H5Acreate_vers 2
49 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
51 # define H5Gopen(a, b, c) H5Gopen(a, b)
54 # define H5Gcreate(a, b, c, d, e) H5Gcreate(a, b, 1)
57 # define H5Dopen(a, b, c) H5Dopen(a, b)
60 # define H5Dcreate(a, b, c, d, e, f, g) H5Dcreate(a, b, c, d, f)
63 # define H5Acreate(a, b, c, d, e, f) H5Acreate(a, b, c, d, e)
71 #include "multi_array.hxx"
72 #include "multi_impex.hxx"
112 typedef herr_t (*Destructor)(hid_t);
116 Destructor destructor_;
147 HDF5Handle(hid_t h, Destructor destructor,
const char * error_message)
149 destructor_(destructor)
152 vigra_fail(error_message);
159 : handle_( h.handle_ ),
160 destructor_(h.destructor_)
171 if(h.handle_ != handle_)
175 destructor_ = h.destructor_;
195 if(handle_ && destructor_)
196 res = (*destructor_)(handle_);
216 operator hid_t()
const
225 return handle_ == h.handle_;
239 return handle_ != h.handle_;
269 enum PixelType { UINT8, UINT16, UINT32, UINT64,
270 INT8, INT16, INT32, INT64,
283 VIGRA_EXPORT
HDF5ImportInfo(
const char* filePath,
const char* pathInFile );
285 VIGRA_EXPORT ~HDF5ImportInfo();
289 VIGRA_EXPORT
const std::string&
getFilePath()
const;
350 VIGRA_EXPORT PixelType
pixelType()
const;
354 std::string m_filename, m_path, m_pixeltype;
355 hssize_t m_dimensions;
363 inline hid_t getH5DataType()
365 std::runtime_error(
"getH5DataType(): invalid type");
369 #define VIGRA_H5_DATATYPE(type, h5type) \
371 inline hid_t getH5DataType<type>() \
373 VIGRA_H5_DATATYPE(
char, H5T_NATIVE_CHAR)
374 VIGRA_H5_DATATYPE(
Int8, H5T_NATIVE_INT8)
375 VIGRA_H5_DATATYPE(
Int16, H5T_NATIVE_INT16)
376 VIGRA_H5_DATATYPE(
Int32, H5T_NATIVE_INT32)
377 VIGRA_H5_DATATYPE(
Int64, H5T_NATIVE_INT64)
378 VIGRA_H5_DATATYPE(
UInt8, H5T_NATIVE_UINT8)
379 VIGRA_H5_DATATYPE(
UInt16, H5T_NATIVE_UINT16)
380 VIGRA_H5_DATATYPE(
UInt32, H5T_NATIVE_UINT32)
381 VIGRA_H5_DATATYPE(
UInt64, H5T_NATIVE_UINT64)
382 VIGRA_H5_DATATYPE(
float, H5T_NATIVE_FLOAT)
383 VIGRA_H5_DATATYPE(
double, H5T_NATIVE_DOUBLE)
384 VIGRA_H5_DATATYPE(
long double, H5T_NATIVE_LDOUBLE)
386 #undef VIGRA_H5_DATATYPE
438 std::vector<std::string> objects;
442 static herr_t opFunc (hid_t loc_id,
const char *name,
const H5L_info_t *info,
void *operator_data)
446 H5Oget_info_by_name (loc_id, name, &infobuf, H5P_DEFAULT);
449 if(infobuf.type == H5O_TYPE_GROUP)
451 (*(
struct lsOpData *) operator_data).objects.push_back(std::string(name)+
"/");
453 if(infobuf.type == H5O_TYPE_DATASET)
455 (*(
struct lsOpData *) operator_data).objects.push_back(std::string(name));
481 std::string errorMessage =
"HDF5File: Could not create file '" + filename +
"'.";
482 fileHandle_ =
HDF5Handle(createFile_(filename, mode), &H5Fclose, errorMessage.c_str());
483 cGroupHandle_ =
HDF5Handle(openCreateGroup_(
"/"), &H5Gclose,
"HDF5File(): Failed to open root group.");
492 H5Fflush(fileHandle_, H5F_SCOPE_GLOBAL);
500 std::string message =
"HDF5File::root(): Could not open group '/'.";
501 cGroupHandle_ =
HDF5Handle(H5Gopen(fileHandle_,
"/", H5P_DEFAULT),&H5Gclose,message.c_str());
509 void cd(std::string groupName)
511 std::string message =
"HDF5File::cd(): Could not open group '" + groupName +
"'.\n";
514 cGroupHandle_ =
HDF5Handle(openCreateGroup_(
"/"),&H5Gclose,message.c_str());
517 else if(groupName ==
"..")
522 if(relativePath_(groupName))
524 if (H5Lexists(cGroupHandle_, groupName.c_str(), H5P_DEFAULT) == 0)
526 std::cerr << message;
529 cGroupHandle_ =
HDF5Handle(openCreateGroup_(groupName),&H5Gclose,message.c_str());
533 if (H5Lexists(fileHandle_, groupName.c_str(), H5P_DEFAULT) == 0)
535 std::cerr << message;
538 cGroupHandle_ =
HDF5Handle(openCreateGroup_(groupName),&H5Gclose,message.c_str());
548 std::string groupName = currentGroupName_();
551 if(groupName ==
"/"){
555 size_t lastSlash = groupName.find_last_of(
'/');
557 std::string parentGroup (groupName.begin(), groupName.begin()+lastSlash+1);
563 void cd_up(
int levels)
565 for(
int i = 0; i<levels; i++)
576 hid_t handle = openCreateGroup_(groupName.c_str());
577 if (handle != cGroupHandle_){
588 std::string message =
"HDF5File::cd_mk(): Could not create group '" + groupName +
"'.";
589 cGroupHandle_ =
HDF5Handle(openCreateGroup_(groupName.c_str()),&H5Gclose,message.c_str());
599 std::vector<std::string>
ls()
602 H5Literate(cGroupHandle_,H5_INDEX_NAME,H5_ITER_NATIVE,NULL, &opFunc, (
void *) &data);
612 return currentGroupName_();
629 std::string errorMessage =
"HDF5File::getDatasetDimensions(): Unable to open dataset '" + datasetName +
"'.";
630 HDF5Handle datasetHandle =
HDF5Handle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
632 errorMessage =
"HDF5File::getDatasetDimensions(): Unable to access dataspace.";
633 HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose, errorMessage.c_str());
636 return H5Sget_simple_extent_ndims(dataspaceHandle);
648 std::string errorMessage =
"HDF5File::getDatasetShape(): Unable to open dataset '" + datasetName +
"'.";
649 HDF5Handle datasetHandle =
HDF5Handle(getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
651 errorMessage =
"HDF5File::getDatasetShape(): Unable to access dataspace.";
652 HDF5Handle dataspaceHandle(H5Dget_space(datasetHandle), &H5Sclose, errorMessage.c_str());
659 H5Sget_simple_extent_dims(dataspaceHandle, shape.
data(), maxdims.
data());
665 shape_inv[i] = shape[dimensions-1-i];
674 void setAttribute(std::string datasetName, std::string attributeName, std::string text)
676 std::string groupname = SplitString(datasetName).first();
677 std::string setname = SplitString(datasetName).last();
679 std::string errorMessage (
"HDF5File::setAttribute(): Unable to open group '" + groupname +
"'.");
680 HDF5Handle groupHandle (openCreateGroup_(groupname), &H5Gclose, errorMessage.c_str());
682 H5LTset_attribute_string(groupHandle,setname.c_str(), attributeName.c_str(),text.c_str());
688 std::string
getAttribute(std::string datasetName, std::string attributeName)
690 typedef ArrayVector<char>::size_type SizeType;
691 if (H5Lexists(fileHandle_, datasetName.c_str(), H5P_DEFAULT) == 0)
693 std::cerr <<
"HDF5File::getAttribute(): Dataset '" << datasetName <<
"' does not exist.\n";
694 return "error - dataset not found";
697 std::string groupname = SplitString(datasetName).first();
698 std::string setname = SplitString(datasetName).last();
700 std::string errorMessage (
"HDF5File::setAttribute(): Unable to open group '" + groupname +
"'.");
701 HDF5Handle groupHandle (openCreateGroup_(groupname), &H5Gclose, errorMessage.c_str());
704 HDF5Handle AttrHandle (H5Aopen_by_name(groupHandle,setname.c_str(),attributeName.c_str(),H5P_DEFAULT, H5P_DEFAULT),&H5Aclose,
"HDF5File::getAttribute(): Unable to open attribute.");
705 SizeType len = (SizeType)H5Aget_storage_size(AttrHandle);
709 H5LTget_attribute_string(groupHandle, setname.c_str(), attributeName.c_str(), text.
begin());
711 return std::string(text.
begin());
727 template<
unsigned int N,
class T>
731 for(
int i = 0; i < N; i++){
732 chunkSize[i] = iChunkSize;
734 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
747 template<
unsigned int N,
class T>
750 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize, compression);
765 template<
unsigned int N,
class T>
768 writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), 1);
772 template<
unsigned int N,
class T,
int SIZE>
776 for(
int i = 0; i < N; i++){
777 chunkSize[i] = iChunkSize;
779 write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
782 template<
unsigned int N,
class T,
int SIZE>
783 inline void write(std::string datasetName,
const MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> & array,
typename MultiArrayShape<N>::type chunkSize,
int compression = 0)
785 write_(datasetName, array, detail::getH5DataType<T>(), SIZE, chunkSize, compression);
788 template<
unsigned int N,
class T,
int SIZE>
789 inline void writeBlock(std::string datasetName,
typename MultiArrayShape<N>::type blockOffset,
const MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> & array)
791 writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), SIZE);
795 template<
unsigned int N,
class T>
796 inline void write(std::string datasetName,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array,
int iChunkSize = 0,
int compression = 0)
798 typename MultiArrayShape<N>::type chunkSize;
799 for(
int i = 0; i < N; i++){
800 chunkSize[i] = iChunkSize;
802 write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
805 template<
unsigned int N,
class T>
806 inline void write(std::string datasetName,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array,
typename MultiArrayShape<N>::type chunkSize,
int compression = 0)
808 write_(datasetName, array, detail::getH5DataType<T>(), 3, chunkSize, compression);
811 template<
unsigned int N,
class T>
812 inline void writeBlock(std::string datasetName,
typename MultiArrayShape<N>::type blockOffset,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
814 writeBlock_(datasetName, blockOffset, array, detail::getH5DataType<T>(), 3);
832 write_(datasetName, array, detail::getH5DataType<T>(), 1, chunkSize,0);
842 template<
unsigned int N,
class T>
845 read_(datasetName, array, detail::getH5DataType<T>(), 1);
858 template<
unsigned int N,
class T>
861 readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), 1);
865 template<
unsigned int N,
class T,
int SIZE>
868 read_(datasetName, array, detail::getH5DataType<T>(), SIZE);
871 template<
unsigned int N,
class T,
int SIZE>
872 inline void readBlock(std::string datasetName,
typename MultiArrayShape<N>::type blockOffset,
typename MultiArrayShape<N>::type blockShape, MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> array)
874 readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), SIZE);
878 template<
unsigned int N,
class T>
879 inline void read(std::string datasetName, MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> array)
881 read_(datasetName, array, detail::getH5DataType<T>(), 3);
884 template<
unsigned int N,
class T>
885 inline void readBlock(std::string datasetName,
typename MultiArrayShape<N>::type blockOffset,
typename MultiArrayShape<N>::type blockShape, MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> array)
887 readBlock_(datasetName, blockOffset, blockShape, array, detail::getH5DataType<T>(), 3);
902 read_(datasetName, array, detail::getH5DataType<T>(), 1);
924 template<
unsigned int N,
class T>
928 for(
int i = 0; i < N; i++){
929 chunkSize[i] = iChunkSize;
931 createDataset<N,T>(datasetName, shape, init, chunkSize, compressionParameter);
934 template<
unsigned int N,
class T>
937 std::string groupname = SplitString(datasetName).first();
938 std::string setname = SplitString(datasetName).last();
940 hid_t parent = openCreateGroup_(groupname);
943 deleteDataset_(parent, setname);
950 hsize_t shape_inv[N];
951 for(
unsigned int k=0; k<N; ++k)
952 shape_inv[N-1-k] = shape[k];
955 dataspaceHandle =
HDF5Handle(H5Screate_simple(N, shape_inv, NULL),
956 &H5Sclose,
"HDF5File::createDataset(): unable to create dataspace for scalar data.");
959 HDF5Handle plist ( H5Pcreate(H5P_DATASET_CREATE), &H5Pclose,
"HDF5File::createDataset(): unable to create property list." );
960 H5Pset_fill_value(plist,detail::getH5DataType<T>(), &init);
966 for(
int i = 0; i<N; i++)
968 cSize[i] = chunkSize[N-1-i];
970 H5Pset_chunk (plist, N, cSize);
974 if(compressionParameter > 0)
976 H5Pset_deflate(plist, compressionParameter);
980 HDF5Handle datasetHandle ( H5Dcreate(parent, setname.c_str(), detail::getH5DataType<T>(), dataspaceHandle, H5P_DEFAULT, plist, H5P_DEFAULT),
981 &H5Dclose,
"HDF5File::createDataset(): unable to create dataset.");
982 if(parent != cGroupHandle_)
990 H5Fflush(fileHandle_, H5F_SCOPE_GLOBAL);
1004 class SplitString:
public std::string {
1006 SplitString(std::string &sstring): std::string(sstring) {};
1009 std::string first(
char delimiter =
'/')
1011 size_t last = find_last_of(delimiter);
1012 if(last == std::string::npos)
1015 return std::string(begin(), begin()+last+1);
1019 std::string last(
char delimiter =
'/')
1021 size_t last = find_last_of(delimiter);
1022 if(last == std::string::npos)
1023 return std::string(*
this);
1024 return std::string(begin()+last+1, end());
1028 inline bool relativePath_(std::string & path)
1030 std::string::size_type pos = path.find(
'/') ;
1038 std::string currentGroupName_()
1040 int len = H5Iget_name(cGroupHandle_,NULL,1000);
1041 ArrayVector<char> name (len+1,0);
1042 H5Iget_name(cGroupHandle_,name.begin(),len+1);
1044 return std::string(name.begin());
1047 std::string fileName_()
1049 int len = H5Fget_name(fileHandle_,NULL,1000);
1050 ArrayVector<char> name (len+1,0);
1051 H5Fget_name(fileHandle_,name.begin(),len+1);
1053 return std::string(name.begin());
1057 inline hid_t createFile_(std::string filePath,
OpenMode mode = Open)
1061 pFile = fopen ( filePath.c_str(),
"r" );
1065 if ( pFile == NULL )
1067 fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1069 else if(mode == Open)
1072 fileId = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
1077 std::remove(filePath.c_str());
1078 fileId = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1085 inline hid_t openCreateGroup_(std::string groupName)
1089 if(relativePath_(groupName))
1091 parent = cGroupHandle_;
1096 parent = H5Gopen(fileHandle_,
"/", H5P_DEFAULT);
1097 if(groupName ==
"/")
1103 groupName = std::string(groupName.begin()+1, groupName.end());
1108 if( groupName.size() != 0 && *groupName.rbegin() !=
'/')
1110 groupName = groupName +
'/';
1115 std::string::size_type begin = 0, end = groupName.find(
'/');
1117 while (end != std::string::npos)
1119 std::string group(groupName.begin()+begin, groupName.begin()+end);
1120 hid_t prevParent = parent;
1122 if(H5LTfind_dataset(parent, group.c_str()) == 0)
1124 parent = H5Gcreate(prevParent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1126 parent = H5Gopen(prevParent, group.c_str(), H5P_DEFAULT);
1131 H5Gclose(prevParent);
1139 end = groupName.find(
'/', begin);
1147 inline void deleteDataset_(hid_t parent, std::string datasetName)
1150 if(H5LTfind_dataset(parent, datasetName.c_str()))
1153 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
1154 if(H5Gunlink(parent, datasetName.c_str()) < 0)
1156 vigra_postcondition(
false,
"HDF5File::deleteDataset_(): Unable to delete existing data.");
1159 if(H5Ldelete(parent, datasetName.c_str(), H5P_DEFAULT ) < 0)
1161 vigra_postcondition(
false,
"HDF5File::deleteDataset_(): Unable to delete existing data.");
1167 hid_t getDatasetHandle_(std::string datasetName)
1169 std::string groupname = SplitString(datasetName).first();
1170 std::string setname = SplitString(datasetName).last();
1172 if(relativePath_(datasetName))
1174 if (H5Lexists(cGroupHandle_, datasetName.c_str(), H5P_DEFAULT) != 1)
1176 std::cerr <<
"HDF5File::getDatasetHandle_(): Dataset '" << datasetName <<
"' does not exist.\n";
1180 hid_t groupHandle = openCreateGroup_(groupname);
1182 hid_t datasetHandle = H5Dopen(groupHandle, setname.c_str(), H5P_DEFAULT);
1184 if(groupHandle != cGroupHandle_){
1185 H5Gclose(groupHandle);
1189 return datasetHandle;
1193 if (H5Lexists(fileHandle_, datasetName.c_str(), H5P_DEFAULT) != 1)
1195 std::cerr <<
"HDF5File::getDatasetHandle_(): Dataset '" << datasetName <<
"' does not exist.\n";
1200 hid_t groupHandle = openCreateGroup_(groupname);
1202 hid_t datasetHandle = H5Dopen(groupHandle, setname.c_str(), H5P_DEFAULT);
1204 if(groupHandle != cGroupHandle_){
1205 H5Gclose(groupHandle);
1209 return datasetHandle;
1215 template<
unsigned int N,
class T>
1216 void write_(std::string &datasetName,
const MultiArrayView<N, T, UnstridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType,
typename MultiArrayShape<N>::type &chunkSize,
int compressionParameter = 0)
1218 std::string groupname = SplitString(datasetName).first();
1219 std::string setname = SplitString(datasetName).last();
1222 ArrayVector<hsize_t> shape(N + (numBandsOfType > 1),0);
1223 for(
int i = 0; i < N; i++){
1224 shape[N-1-i] = array.shape(i);
1227 if(numBandsOfType > 1)
1228 shape[N] = numBandsOfType;
1230 HDF5Handle dataspace ( H5Screate_simple(N + (numBandsOfType > 1), shape.
begin(), NULL), &H5Sclose,
"HDF5File::write(): Can not create dataspace.");
1233 std::string errorMessage (
"HDF5File::write(): can not create group '" + groupname +
"'.");
1234 hid_t groupHandle = openCreateGroup_(groupname);
1235 if(groupHandle <= 0)
1237 std::cerr << errorMessage <<
"\n";
1241 deleteDataset_(groupHandle, setname.c_str());
1244 HDF5Handle plist ( H5Pcreate(H5P_DATASET_CREATE), &H5Pclose,
"HDF5File::write(): unable to create property list." );
1247 if(chunkSize[0] > 0)
1249 ArrayVector<hsize_t> cSize(N + (numBandsOfType > 1),0);
1250 for(
int i = 0; i<N; i++)
1252 cSize[i] = chunkSize[N-1-i];
1254 if(numBandsOfType > 1)
1255 cSize[N] = numBandsOfType;
1257 H5Pset_chunk (plist, N + (numBandsOfType > 1), cSize.begin());
1261 if(compressionParameter > 0)
1263 H5Pset_deflate(plist, compressionParameter);
1267 HDF5Handle datasetHandle (H5Dcreate(groupHandle, setname.c_str(), datatype, dataspace,H5P_DEFAULT, plist, H5P_DEFAULT), &H5Dclose,
"HDF5File::write(): Can not create dataset.");
1270 H5Dwrite( datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data());
1272 if(groupHandle != cGroupHandle_)
1274 H5Gclose(groupHandle);
1279 template<
unsigned int N,
class T>
1280 void read_(std::string datasetName, MultiArrayView<N, T, UnstridedArrayTag> array,
const hid_t datatype,
const int numBandsOfType)
1286 std::string errorMessage (
"HDF5File::read(): Unable to open dataset '" + datasetName +
"'.");
1287 HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
1289 int offset = (numBandsOfType > 1);
1292 "HDF5File::read(): Array dimension disagrees with dataset dimension.");
1294 typename MultiArrayShape<N>::type shape;
1299 vigra_precondition(shape == array.shape(),
1300 "HDF5File::read(): Array shape disagrees with dataset shape.");
1303 H5Dread( datasetHandle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data() );
1306 template<
unsigned int N,
class T>
1307 void writeBlock_(std::string datasetName,
typename MultiArrayShape<N>::type &blockOffset,
const MultiArrayView<N, T, UnstridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType)
1310 std::string errorMessage =
"HDF5File::writeBlock(): Error opening dataset '" + datasetName +
"'.";
1311 HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
1315 hsize_t boffset [N];
1319 for(
int i = 0; i < N; i++){
1320 boffset[i] = blockOffset[N-1-i];
1321 bshape[i] = array.size(N-1-i);
1326 HDF5Handle memspace_handle (H5Screate_simple(N,bshape,NULL),&H5Sclose,
"Unable to get origin dataspace");
1329 HDF5Handle dataspaceHandle (H5Dget_space(datasetHandle),&H5Sclose,
"Unable to create target dataspace");
1330 H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET, boffset, bones, bones, bshape);
1333 H5Dwrite( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data());
1340 template<
unsigned int N,
class T>
1341 void readBlock_(std::string datasetName,
typename MultiArrayShape<N>::type &blockOffset,
typename MultiArrayShape<N>::type &blockShape, MultiArrayView<N, T, UnstridedArrayTag> &array,
const hid_t datatype,
const int numBandsOfType)
1347 std::string errorMessage (
"HDF5File::readBlock(): Unable to open dataset '" + datasetName +
"'.");
1348 HDF5Handle datasetHandle (getDatasetHandle_(datasetName), &H5Dclose, errorMessage.c_str());
1351 int offset = (numBandsOfType > 1);
1354 "readHDF5_block(): Array dimension disagrees with data dimension.");
1356 vigra_precondition(blockShape == array.shape(),
1357 "readHDF5_block(): Array shape disagrees with block size.");
1360 hsize_t boffset [N];
1364 for(
int i = 0; i < N; i++){
1366 boffset[i] = blockOffset[N-1-i];
1368 bshape[i] = blockShape[N-1-i];
1374 HDF5Handle memspace_handle (H5Screate_simple(N,bshape,NULL),&H5Sclose,
"Unable to create target dataspace");
1377 HDF5Handle dataspaceHandle (H5Dget_space(datasetHandle),&H5Sclose,
"Unable to get dataspace");
1378 H5Sselect_hyperslab(dataspaceHandle, H5S_SELECT_SET, boffset, bones, bones, bshape);
1381 H5Dread( datasetHandle, datatype, memspace_handle, dataspaceHandle, H5P_DEFAULT, array.data() );
1394 template <
class Shape>
1396 selectHyperslabs(HDF5Handle & mid1, HDF5Handle & mid2, Shape
const & shape,
int & counter,
const int elements,
const int numBandsOfType)
1399 hsize_t shapeHDF5[2];
1401 shapeHDF5[1] = elements;
1402 hsize_t startHDF5[2];
1404 startHDF5[1] = counter * numBandsOfType * shape[0];
1405 hsize_t strideHDF5[2];
1408 hsize_t countHDF5[2];
1410 countHDF5[1] = numBandsOfType * shape[0];
1411 hsize_t blockHDF5[2];
1414 mid1 = HDF5Handle(H5Screate_simple(2, shapeHDF5, NULL),
1415 &H5Sclose,
"unable to create hyperslabs.");
1416 H5Sselect_hyperslab(mid1, H5S_SELECT_SET, startHDF5, strideHDF5, countHDF5, blockHDF5);
1418 hsize_t shapeData[2];
1420 shapeData[1] = numBandsOfType * shape[0];
1421 hsize_t startData[2];
1424 hsize_t strideData[2];
1427 hsize_t countData[2];
1429 countData[1] = numBandsOfType * shape[0];
1430 hsize_t blockData[2];
1433 mid2 = HDF5Handle(H5Screate_simple(2, shapeData, NULL),
1434 &H5Sclose,
"unable to create hyperslabs.");
1435 H5Sselect_hyperslab(mid2, H5S_SELECT_SET, startData, strideData, countData, blockData);
1438 template <
class DestIterator,
class Shape,
class T>
1440 readHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<0>)
1442 HDF5Handle mid1, mid2;
1445 selectHyperslabs(mid1, mid2, shape, counter, elements, numBandsOfType);
1448 H5Dread(dataset_id, datatype, mid2, mid1, H5P_DEFAULT, buffer.data());
1455 DestIterator dend = d + shape[0];
1457 for(; d < dend; ++d, k++)
1465 template <
class DestIterator,
class Shape,
class T,
int N>
1467 readHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<N>)
1469 DestIterator dend = d + shape[N];
1470 for(; d < dend; ++d)
1472 readHDF5Impl(d.begin(), shape, dataset_id, datatype, buffer, counter, elements, numBandsOfType, MetaInt<N-1>());
1516 template<
unsigned int N,
class T>
1517 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, UnstridedArrayTag> array)
1519 readHDF5(info, array, detail::getH5DataType<T>(), 1);
1523 template<
unsigned int N,
class T,
int SIZE>
1524 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> array)
1526 readHDF5(info, array, detail::getH5DataType<T>(), SIZE);
1530 template<
unsigned int N,
class T>
1531 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> array)
1533 readHDF5(info, array, detail::getH5DataType<T>(), 3);
1537 template<
unsigned int N,
class T>
1538 void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, UnstridedArrayTag> array,
const hid_t datatype,
const int numBandsOfType)
1540 int offset = (numBandsOfType > 1);
1543 vigra_precondition(( (N + offset ) == info.numDimensions()),
1544 "readHDF5(): Array dimension disagrees with HDF5ImportInfo.numDimensions().");
1546 typename MultiArrayShape<N>::type shape;
1547 for(
int k=offset; k<info.numDimensions(); ++k) {
1548 shape[k-offset] = info.shapeOfDimension(k);
1551 vigra_precondition(shape == array.shape(),
1552 "readHDF5(): Array shape disagrees with HDF5ImportInfo.");
1555 H5Dread( info.getDatasetHandle(), datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data() );
1559 template<
unsigned int N,
class T>
1560 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, StridedArrayTag> array)
1562 readHDF5(info, array, detail::getH5DataType<T>(), 1);
1566 template<
unsigned int N,
class T,
int SIZE>
1567 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, TinyVector<T, SIZE>, StridedArrayTag> array)
1569 readHDF5(info, array, detail::getH5DataType<T>(), SIZE);
1573 template<
unsigned int N,
class T>
1574 inline void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, RGBValue<T>, StridedArrayTag> array)
1576 readHDF5(info, array, detail::getH5DataType<T>(), 3);
1580 template<
unsigned int N,
class T>
1581 void readHDF5(
const HDF5ImportInfo &info, MultiArrayView<N, T, StridedArrayTag> array,
const hid_t datatype,
const int numBandsOfType)
1583 int offset = (numBandsOfType > 1);
1586 vigra_precondition(( (N + offset ) == info.numDimensions()),
1587 "readHDF5(): Array dimension disagrees with HDF5ImportInfo.numDimensions().");
1589 typename MultiArrayShape<N>::type shape;
1590 for(
int k=offset; k<info.numDimensions(); ++k) {
1591 shape[k-offset] = info.shapeOfDimension(k);
1594 vigra_precondition(shape == array.shape(),
1595 "readHDF5(): Array shape disagrees with HDF5ImportInfo.");
1599 int elements = numBandsOfType;
1600 for(
unsigned int i=0;i<N;++i)
1601 elements *= shape[i];
1602 ArrayVector<T> buffer(shape[0]);
1603 detail::readHDF5Impl(array.traverser_begin(), shape, info.getDatasetHandle(), datatype, buffer, counter, elements, numBandsOfType, vigra::MetaInt<N-1>());
1606 inline hid_t openGroup(hid_t parent, std::string group_name)
1609 size_t last_slash = group_name.find_last_of(
'/');
1610 if (last_slash == std::string::npos || last_slash != group_name.size() - 1)
1611 group_name = group_name +
'/';
1612 std::string::size_type begin = 0, end = group_name.find(
'/');
1614 while (end != std::string::npos)
1616 std::string group(group_name.begin()+begin, group_name.begin()+end);
1617 hid_t prev_parent = parent;
1618 parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
1620 if(ii != 0) H5Gclose(prev_parent);
1621 if(parent < 0)
return parent;
1624 end = group_name.find(
'/', begin);
1629 inline hid_t createGroup(hid_t parent, std::string group_name)
1631 if(group_name.size() == 0 ||*group_name.rbegin() !=
'/')
1632 group_name = group_name +
'/';
1633 if(group_name ==
"/")
1634 return H5Gopen(parent, group_name.c_str(), H5P_DEFAULT);
1636 std::string::size_type begin = 0, end = group_name.find(
'/');
1638 while (end != std::string::npos)
1640 std::string group(group_name.begin()+begin, group_name.begin()+end);
1641 hid_t prev_parent = parent;
1643 if(H5LTfind_dataset(parent, group.c_str()) == 0)
1645 parent = H5Gcreate(prev_parent, group.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1647 parent = H5Gopen(prev_parent, group.c_str(), H5P_DEFAULT);
1650 if(ii != 0) H5Gclose(prev_parent);
1651 if(parent < 0)
return parent;
1654 end = group_name.find(
'/', begin);
1659 inline void deleteDataset(hid_t parent, std::string dataset_name)
1662 if(H5LTfind_dataset(parent, dataset_name.c_str()))
1665 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6)
1666 if(H5Gunlink(parent, dataset_name.c_str()) < 0)
1668 vigra_postcondition(
false,
"writeToHDF5File(): Unable to delete existing data.");
1671 if(H5Ldelete(parent, dataset_name.c_str(), H5P_DEFAULT ) < 0)
1673 vigra_postcondition(
false,
"createDataset(): Unable to delete existing data.");
1679 inline hid_t createFile(std::string filePath,
bool append_ =
true)
1682 pFile = fopen ( filePath.c_str(),
"r" );
1684 if ( pFile == NULL )
1686 file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1691 file_id = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
1696 std::remove(filePath.c_str());
1697 file_id = H5Fcreate(filePath.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1702 template<
unsigned int N,
class T,
class Tag>
1703 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)
1705 std::string path_name(pathInFile), group_name, data_set_name, message;
1706 std::string::size_type delimiter = path_name.rfind(
'/');
1709 file_handle = HDF5Handle(createFile(filePath), &H5Fclose,
1710 "createDataset(): unable to open output file.");
1713 if(delimiter == std::string::npos)
1716 data_set_name = path_name;
1720 group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
1721 data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
1725 HDF5Handle group(createGroup(file_handle, group_name), &H5Gclose,
1726 "createDataset(): Unable to create and open group. generic v");
1729 deleteDataset(group, data_set_name);
1733 HDF5Handle dataspace_handle;
1734 if(numBandsOfType > 1) {
1736 hsize_t shape_inv[N+1];
1737 for(
unsigned int k=0; k<N; ++k) {
1738 shape_inv[N-1-k] = array.shape(k);
1741 shape_inv[N] = numBandsOfType;
1744 dataspace_handle = HDF5Handle(H5Screate_simple(N+1, shape_inv, NULL),
1745 &H5Sclose,
"createDataset(): unable to create dataspace for non-scalar data.");
1748 hsize_t shape_inv[N];
1749 for(
unsigned int k=0; k<N; ++k)
1750 shape_inv[N-1-k] = array.shape(k);
1753 dataspace_handle = HDF5Handle(H5Screate_simple(N, shape_inv, NULL),
1754 &H5Sclose,
"createDataset(): unable to create dataspace for scalar data.");
1758 dataset_handle = HDF5Handle(H5Dcreate(group,
1759 data_set_name.c_str(),
1762 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT),
1763 &H5Dclose,
"createDataset(): unable to create dataset.");
1770 template <
class DestIterator,
class Shape,
class T>
1772 writeHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<0>)
1774 DestIterator dend = d + (
typename DestIterator::difference_type)shape[0];
1777 for(; d < dend; ++d, k++)
1783 HDF5Handle mid1, mid2;
1786 selectHyperslabs(mid1, mid2, shape, counter, elements, numBandsOfType);
1789 H5Dwrite(dataset_id, datatype, mid2, mid1, H5P_DEFAULT, buffer.data());
1794 template <
class DestIterator,
class Shape,
class T,
int N>
1796 writeHDF5Impl(DestIterator d, Shape
const & shape,
const hid_t dataset_id,
const hid_t datatype, ArrayVector<T> & buffer,
int & counter,
const int elements,
const int numBandsOfType, MetaInt<N>)
1798 DestIterator dend = d + (
typename DestIterator::difference_type)shape[N];
1799 for(; d < dend; ++d)
1801 writeHDF5Impl(d.begin(), shape, dataset_id, datatype, buffer, counter, elements, numBandsOfType, MetaInt<N-1>());
1844 template<
unsigned int N,
class T>
1845 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, UnstridedArrayTag> & array)
1847 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 1);
1851 template<
unsigned int N,
class T,
int SIZE>
1852 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, TinyVector<T, SIZE>, UnstridedArrayTag> & array)
1854 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), SIZE);
1858 template<
unsigned int N,
class T>
1859 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, RGBValue<T>, UnstridedArrayTag> & array)
1861 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 3);
1865 template<
unsigned int N,
class T>
1866 void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, UnstridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType)
1868 HDF5Handle file_handle;
1869 HDF5Handle dataset_handle;
1870 createDataset(filePath, pathInFile, array, datatype, numBandsOfType, file_handle, dataset_handle);
1873 H5Dwrite( dataset_handle, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.data());
1875 H5Fflush(file_handle, H5F_SCOPE_GLOBAL);
1880 template<
unsigned int N,
class T>
1881 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, StridedArrayTag> & array)
1883 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 1);
1887 template<
unsigned int N,
class T,
int SIZE>
1888 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, TinyVector<T, SIZE>, StridedArrayTag> & array)
1890 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), SIZE);
1894 template<
unsigned int N,
class T>
1895 inline void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, RGBValue<T>, StridedArrayTag> & array)
1897 writeHDF5(filePath, pathInFile, array, detail::getH5DataType<T>(), 3);
1901 template<
unsigned int N,
class T>
1902 void writeHDF5(
const char* filePath,
const char* pathInFile,
const MultiArrayView<N, T, StridedArrayTag> & array,
const hid_t datatype,
const int numBandsOfType)
1904 HDF5Handle file_handle;
1905 HDF5Handle dataset_handle;
1906 createDataset(filePath, pathInFile, array, datatype, numBandsOfType, file_handle, dataset_handle);
1910 int elements = numBandsOfType;
1911 for(
unsigned int k=0; k<N; ++k)
1913 shape[k] = array.shape(k);
1914 stride[k] = array.stride(k);
1915 elements *= (int)shape[k];
1919 ArrayVector<T> buffer((
int)array.shape(0));
1920 detail::writeHDF5Impl(array.traverser_begin(), shape, dataset_handle, datatype, buffer, counter, elements, numBandsOfType, vigra::MetaInt<N-1>());
1922 H5Fflush(file_handle, H5F_SCOPE_GLOBAL);
1936 void operator()(std::string
const & in)
1938 size = in.size() > size ?
1946 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8) || DOXYGEN
1953 template<
size_t N,
class T,
class C>
1958 if(H5Aexists(loc, name) > 0)
1959 H5Adelete(loc, name);
1962 array.
shape().end());
1964 dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
1966 "writeToHDF5File(): unable to create dataspace.");
1970 detail::getH5DataType<T>(),
1972 H5P_DEFAULT ,H5P_DEFAULT ),
1974 "writeHDF5Attr: unable to create Attribute");
1978 for(
int ii = 0; ii < array.
size(); ++ii)
1979 buffer.push_back(array[ii]);
1980 H5Awrite(attr, detail::getH5DataType<T>(), buffer.
data());
1989 template<
size_t N,
class C>
1994 if(H5Aexists(loc, name) > 0)
1995 H5Adelete(loc, name);
1998 array.
shape().end());
2000 dataspace_handle(H5Screate_simple(N, shape.data(), NULL),
2002 "writeToHDF5File(): unable to create dataspace.");
2006 "writeToHDF5File(): unable to create type.");
2008 detail::MaxSizeFnc max_size;
2009 max_size = std::for_each(array.
data(),array.
data()+ array.
size(), max_size);
2010 H5Tset_size (atype, max_size.size);
2016 H5P_DEFAULT ,H5P_DEFAULT ),
2018 "writeHDF5Attr: unable to create Attribute");
2020 std::string buf =
"";
2021 for(
int ii = 0; ii < array.
size(); ++ii)
2023 buf = buf + array[ii]
2024 + std::string(max_size.size - array[ii].
size(),
' ');
2026 H5Awrite(attr, atype, buf.c_str());
2054 std::string pathInFile,
2057 std::string path_name(pathInFile), group_name, data_set_name, message, attr_name;
2058 std::string::size_type delimiter = path_name.rfind(
'/');
2061 HDF5Handle file_id(createFile(filePath), &H5Fclose,
2062 "writeToHDF5File(): unable to open output file.");
2065 if(delimiter == std::string::npos)
2068 data_set_name = path_name;
2073 group_name = std::string(path_name.begin(), path_name.begin()+delimiter);
2074 data_set_name = std::string(path_name.begin()+delimiter+1, path_name.end());
2076 delimiter = data_set_name.rfind(
'.');
2077 if(delimiter == std::string::npos)
2079 attr_name = path_name;
2080 data_set_name =
"/";
2084 attr_name = std::string(data_set_name.begin()+delimiter+1, data_set_name.end());
2085 data_set_name = std::string(data_set_name.begin(), data_set_name.begin()+delimiter);
2088 HDF5Handle group(openGroup(file_id, group_name), &H5Gclose,
2089 "writeToHDF5File(): Unable to create and open group. attr ver");
2091 if(data_set_name !=
"/")
2093 HDF5Handle dset(H5Dopen(group, data_set_name.c_str(), H5P_DEFAULT), &H5Dclose,
2094 "writeHDF5Attr():unable to open dataset");
2109 #endif // VIGRA_HDF5IMPEX_HXX