/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ /** * The specification for this file format is taken from the * web site https://analyzedirect.com/support/10.0Documents/Analyze_Resource_01.pdf * \author Hans J. Johnson * The University of Iowa 2002 */ #ifndef itkHDF5ImageIO_h #define itkHDF5ImageIO_h #include "ITKIOHDF5Export.h" #include "itkMetaDataObjectBase.h" #include "itkMetaDataDictionary.h" #include // For unique_ptr. // itk namespace first suppresses // kwstyle error for the H5 namespace below namespace itk {} namespace H5 { class H5File; class DataSpace; class DataSet; } // namespace H5 #include "itkStreamingImageIOBase.h" namespace itk { /** * \class HDF5ImageIO * * \author Kent Williams * \brief Class that defines how to read HDF5 file format. * HDF5 IMAGE FILE FORMAT - As much information as I can determine from sourceforge.net/projects/HDF5lib * * \ingroup ITKIOHDF5 * * HDF5 paths for elements in file * \li N is dimension of image * \li \/ITKVersion ITK Library Version string * \li \/HDFVersion HDF Version String * \li \/ITKImage Root Image Group * \li \/ITKImage\/\ name is arbitrary, but to parallel Transform I/O * keep an image in a subgroup. The idea is to * parallel transform file structure. * \li \/ITKImage\/\\/Origin N-D point double * \li \/ITKImage\/\\/Directions N N-vectors double * \li \/ITKImage\/\\/Spacing N-vector double * \li \/ITKImage\/\\/Dimensions N-vector itk::SizeValueType * \li \/ITKImage\/\\/VoxelType String representing voxel type. * This can be inferred from the VoxelData * type info, but it makes the file more * user friendly with respect to HDF5 viewers. * \li \/ITKImage\/\\/VoxelData multi-dim array of voxel data * in the case of non-scalar voxel type, * keep voxel components together, to make * loading possible without * \li \/ITKImage\/\\/MetaData Group for storing metadata from * MetaDataDictionary * \li \/ITKImage\/\\/MetaData\/\ * Dataset containing data for item-name * in the MetaDataDictionary * re-arrangement. * * */ class ITKIOHDF5_EXPORT HDF5ImageIO : public StreamingImageIOBase { public: ITK_DISALLOW_COPY_AND_MOVE(HDF5ImageIO); /** Standard class type aliases. */ using Self = HDF5ImageIO; using Superclass = StreamingImageIOBase; using Pointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** \see LightObject::GetNameOfClass() */ itkOverrideGetNameOfClassMacro(HDF5ImageIO); /*-------- This part of the interfaces deals with reading data. ----- */ /** Determine if the file can be read with this ImageIO implementation. * \author Hans J Johnson * \param FileNameToRead The name of the file to test for reading. * \post Sets classes ImageIOBase::m_FileName variable to be FileNameToWrite * \return Returns true if this ImageIO can read the file specified. */ bool CanReadFile(const char * FileNameToRead) override; /** Set the spacing and dimension information for the set filename. */ void ReadImageInformation() override; /** Reads the data from disk into the memory buffer provided. */ void Read(void * buffer) override; /*-------- This part of the interfaces deals with writing data. ----- */ /** Determine if the file can be written with this ImageIO implementation. * \param name The name of the file to test for writing. * \author Hans J. Johnson * \post Sets classes ImageIOBase::m_FileName variable to be FileNameToWrite * \return Returns true if this ImageIO can write the file specified. */ bool CanWriteFile(const char * name) override; /** Set the spacing and dimension information for the set filename. */ void WriteImageInformation() override; /** Writes the data to disk from the memory buffer provided. Make sure * that the IORegions has been set properly. */ void Write(const void * buffer) override; protected: HDF5ImageIO(); ~HDF5ImageIO() override; SizeType GetHeaderSize() const override; void PrintSelf(std::ostream & os, Indent indent) const override; private: void WriteString(const std::string & path, const std::string & value); void WriteString(const std::string & path, const char * s); std::string ReadString(const std::string & path); void WriteScalar(const std::string & path, const bool value); void WriteScalar(const std::string & path, const long value); void WriteScalar(const std::string & path, const unsigned long value); void WriteScalar(const std::string & path, const long long value); void WriteScalar(const std::string & path, const unsigned long long value); template void WriteScalar(const std::string & path, const TScalar & value); template TScalar ReadScalar(const std::string & DataSetName); template void WriteVector(const std::string & path, const std::vector & vec); template std::vector ReadVector(const std::string & DataSetName); void WriteDirections(const std::string & path, const std::vector> & dir); std::vector> ReadDirections(const std::string & path); template bool WriteMeta(const std::string & name, MetaDataObjectBase * metaObjBase); template bool WriteMetaArray(const std::string & name, MetaDataObjectBase * metaObjBase); template void StoreMetaData(MetaDataDictionary * metaDict, const std::string & HDFPath, const std::string & name, unsigned long numElements); void SetupStreaming(H5::DataSpace * imageSpace, H5::DataSpace * slabSpace); /* A convenience function to ensure that the * state of the HDF5ImageIO object is returned * to a state similar to constructing a new * object. This is needed to ensure that * an HDF5ImageIO object can be used multiple * times to read/write many images. */ void ResetToInitialState(); std::unique_ptr m_H5File; std::unique_ptr m_VoxelDataSet; bool m_ImageInformationWritten{ false }; }; } // end namespace itk #endif // itkHDF5ImageIO_h