Line data Source code
1 : /****************************************************************************** 2 : * $Id$ 3 : * 4 : * Project: Hierarchical Data Format Release 5 (HDF5) 5 : * Purpose: Header file for HDF5 datasets reader. 6 : * Author: Denis Nadeau (denis.nadeau@gmail.com) 7 : * 8 : ****************************************************************************** 9 : * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com> 10 : * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com> 11 : * 12 : * SPDX-License-Identifier: MIT 13 : ****************************************************************************/ 14 : 15 : #ifndef HDF5DATASET_H_INCLUDED_ 16 : #define HDF5DATASET_H_INCLUDED_ 17 : 18 : #include "hdf5_api.h" 19 : #include "hdf5eosparser.h" 20 : 21 : #include "cpl_list.h" 22 : #include "gdal_pam.h" 23 : 24 : #include <map> 25 : 26 : #ifdef ENABLE_HDF5_GLOBAL_LOCK 27 : #include <mutex> 28 : std::recursive_mutex &GetHDF5GlobalMutex(); 29 : #define HDF5_GLOBAL_LOCK() \ 30 : std::lock_guard<std::recursive_mutex> oLock(GetHDF5GlobalMutex()) 31 : #else 32 : #define HDF5_GLOBAL_LOCK() \ 33 : do \ 34 : { \ 35 : } while (0) 36 : #endif 37 : 38 : typedef struct HDF5GroupObjects 39 : { 40 : char *pszName; 41 : char *pszPath; 42 : char *pszUnderscorePath; 43 : char *pszTemp; 44 : int nType; 45 : int nIndex; 46 : hsize_t nbObjs; 47 : int nbAttrs; 48 : int nRank; 49 : hsize_t *paDims; 50 : hid_t native; 51 : hid_t HDatatype; 52 : unsigned long objno[2]; 53 : struct HDF5GroupObjects *poHparent; 54 : struct HDF5GroupObjects *poHchild; 55 : } HDF5GroupObjects; 56 : 57 : herr_t HDF5CreateGroupObjs(hid_t, const char *, void *); 58 : 59 : hid_t HDF5GetFileDriver(); 60 : void HDF5UnloadFileDriver(); 61 : 62 : hid_t GDAL_HDF5Open(const std::string &osFilename); 63 : 64 : #if defined(H5_VERSION_GE) // added in 1.8.7 65 : #if !H5_VERSION_GE(1, 8, 13) 66 : #ifndef _WIN32 67 : #define H5free_memory(x) free(x) 68 : #else 69 : #define H5free_memory(x) CPL_IGNORE_RET_VAL(x) 70 : #endif 71 : #endif 72 : #else 73 : #ifndef _WIN32 74 : #define H5free_memory(x) free(x) 75 : #else 76 : #define H5free_memory(x) CPL_IGNORE_RET_VAL(x) 77 : #endif 78 : #endif 79 : 80 : // Release 1.6.3 or 1.6.4 changed the type of count in some API functions. 81 : 82 : #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6 && \ 83 : (H5_VERS_MINOR < 6 || H5_VERS_RELEASE < 3) 84 : #define H5OFFSET_TYPE hssize_t 85 : #else 86 : #define H5OFFSET_TYPE hsize_t 87 : #endif 88 : 89 : class HDF5Dataset; 90 : class HDF5EOSParser; 91 : class BAGDataset; 92 : class S100BaseDataset; 93 : 94 : namespace GDAL 95 : { 96 : class HDF5Group; 97 : 98 : /************************************************************************/ 99 : /* HDF5SharedResources */ 100 : /************************************************************************/ 101 : 102 : class HDF5SharedResources 103 : { 104 : friend class ::HDF5Dataset; 105 : friend class ::BAGDataset; 106 : friend class ::S100BaseDataset; 107 : 108 : std::weak_ptr<HDF5SharedResources> m_poSelf{}; 109 : bool m_bReadOnly = true; 110 : hid_t m_hHDF5 = 0; 111 : CPLString m_osFilename{}; 112 : std::shared_ptr<GDALPamMultiDim> m_poPAM{}; 113 : std::unique_ptr<HDF5EOSParser> m_poHDF5EOSParser{}; 114 : std::map<std::string, std::vector<std::shared_ptr<GDALDimension>>> 115 : m_oMapEOSGridNameToDimensions{}; 116 : std::map<std::string, std::vector<std::shared_ptr<GDALDimension>>> 117 : m_oMapEOSSwathNameToDimensions{}; 118 : std::map<std::string, std::shared_ptr<GDALMDArray>> m_oRefKeeper; 119 : 120 : explicit HDF5SharedResources(const std::string &osFilename); 121 : 122 : public: 123 : static std::shared_ptr<HDF5SharedResources> 124 : Create(const std::string &osFilename); 125 : ~HDF5SharedResources(); 126 : 127 : std::shared_ptr<HDF5Group> GetRootGroup(); 128 : 129 344 : const std::string &GetFilename() const 130 : { 131 344 : return m_osFilename; 132 : } 133 : 134 1033 : inline hid_t GetHDF5() const 135 : { 136 1033 : return m_hHDF5; 137 : } 138 : 139 42 : inline bool IsReadOnly() const 140 : { 141 42 : return m_bReadOnly; 142 : } 143 : 144 : const std::shared_ptr<GDALPamMultiDim> &GetPAM() 145 : { 146 : return m_poPAM; 147 : } 148 : 149 190 : const HDF5EOSParser *GetHDF5EOSParser() const 150 : { 151 190 : return m_poHDF5EOSParser.get(); 152 : } 153 : 154 2 : void RegisterEOSGridDimensions( 155 : const std::string &osGridName, 156 : const std::vector<std::shared_ptr<GDALDimension>> &apoDims) 157 : { 158 2 : m_oMapEOSGridNameToDimensions[osGridName] = apoDims; 159 2 : } 160 : 161 : std::vector<std::shared_ptr<GDALDimension>> 162 2 : GetEOSGridDimensions(const std::string &osGridName) const 163 : { 164 2 : auto oIter = m_oMapEOSGridNameToDimensions.find(osGridName); 165 2 : if (oIter == m_oMapEOSGridNameToDimensions.end()) 166 0 : return {}; 167 2 : return oIter->second; 168 : } 169 : 170 3 : void RegisterEOSSwathDimensions( 171 : const std::string &osSwathName, 172 : const std::vector<std::shared_ptr<GDALDimension>> &apoDims) 173 : { 174 3 : m_oMapEOSSwathNameToDimensions[osSwathName] = apoDims; 175 3 : } 176 : 177 : std::vector<std::shared_ptr<GDALDimension>> 178 3 : GetEOSSwathDimensions(const std::string &osSwathName) const 179 : { 180 3 : auto oIter = m_oMapEOSSwathNameToDimensions.find(osSwathName); 181 3 : if (oIter == m_oMapEOSSwathNameToDimensions.end()) 182 0 : return {}; 183 3 : return oIter->second; 184 : } 185 : 186 56 : void KeepRef(const std::shared_ptr<GDALMDArray> &poArray) 187 : { 188 56 : m_oRefKeeper[poArray->GetFullName()] = poArray; 189 56 : } 190 : }; 191 : 192 : } // namespace GDAL 193 : 194 : /************************************************************************/ 195 : /* ==================================================================== */ 196 : /* HDF5Dataset */ 197 : /* ==================================================================== */ 198 : /************************************************************************/ 199 : class HDF5Dataset CPL_NON_FINAL : public GDALPamDataset 200 : { 201 : protected: 202 : hid_t m_hHDF5 = -1; 203 : hid_t hGroupID; // H handler interface. 204 : char **papszSubDatasets; 205 : int nDatasetType; 206 : int nSubDataCount; 207 : 208 : HDF5GroupObjects *poH5RootGroup; /* Contain hdf5 Groups information */ 209 : std::shared_ptr<GDALGroup> m_poRootGroup{}; 210 : 211 : CPLStringList m_aosMetadata{}; 212 : 213 : HDF5EOSParser m_oHDFEOSParser{}; 214 : 215 : CPLErr ReadGlobalAttributes(int); 216 : CPLErr HDF5ListGroupObjects(HDF5GroupObjects *, int); 217 : static CPLErr CreateMetadata(hid_t hHDF5, HDF5GroupObjects *, int, 218 : bool bPrefixWithDatasetName, 219 : CPLStringList &aosMetadata); 220 : 221 : HDF5GroupObjects *HDF5FindDatasetObjects(HDF5GroupObjects *, const char *); 222 : HDF5GroupObjects *HDF5FindDatasetObjectsbyPath(HDF5GroupObjects *, 223 : const char *); 224 : char *CreatePath(HDF5GroupObjects *); 225 : static void DestroyH5Objects(HDF5GroupObjects *); 226 : 227 : /** 228 : * Reads an array of double attributes from the HDF5 metadata. 229 : * It reads the attributes directly on its binary form directly, 230 : * thus avoiding string conversions. 231 : * 232 : * Important: It allocates the memory for the attributes internally, 233 : * so the caller must free the returned array after using it. 234 : * @param pszAttrName Name of the attribute to be read. 235 : * the attribute name must be the form: 236 : * root attribute name 237 : * SUBDATASET/subdataset attribute name 238 : * @param pdfValues pointer which will store the array of doubles read. 239 : * @param nLen it stores the length of the array read. If NULL it doesn't 240 : * inform the length of the array. 241 : * @return CPLErr CE_None in case of success, CE_Failure in case of failure 242 : */ 243 : CPLErr HDF5ReadDoubleAttr(const char *pszAttrName, double **pdfValues, 244 : int *nLen = nullptr); 245 : 246 : public: 247 : HDF5Dataset(); 248 : ~HDF5Dataset(); 249 : 250 27 : std::shared_ptr<GDALGroup> GetRootGroup() const override 251 : { 252 27 : return m_poRootGroup; 253 : } 254 : 255 : static GDALDataset *Open(GDALOpenInfo *); 256 : static GDALDataset *OpenMultiDim(GDALOpenInfo *); 257 : static std::shared_ptr<GDALGroup> OpenGroup( 258 : const std::shared_ptr<GDAL::HDF5SharedResources> &poSharedResources); 259 : 260 : static bool IsNativeCFloat16(hid_t hDataType); 261 : static const char *GetDataTypeName(hid_t); 262 : static GDALDataType GetDataType(hid_t); 263 : }; 264 : 265 : #endif /* HDF5DATASET_H_INCLUDED_ */