LCOV - code coverage report
Current view: top level - frmts/hdf5 - hdf5drivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 246 256 96.1 %
Date: 2025-08-01 10:10:57 Functions: 31 31 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  HDF5 driver
       5             :  * Author:   Even Rouault, <even.rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, Even Rouault, <even.rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "hdf5drivercore.h"
      14             : 
      15             : #include <algorithm>
      16             : #include <cctype>
      17             : 
      18             : /************************************************************************/
      19             : /*                          HDF5DatasetIdentify()                       */
      20             : /************************************************************************/
      21             : 
      22       58444 : int HDF5DatasetIdentify(GDALOpenInfo *poOpenInfo)
      23             : 
      24             : {
      25       58444 :     if ((poOpenInfo->nOpenFlags & GDAL_OF_MULTIDIM_RASTER) &&
      26         680 :         STARTS_WITH(poOpenInfo->pszFilename, "HDF5:"))
      27             :     {
      28          14 :         return TRUE;
      29             :     }
      30             : 
      31             :     // Is it an HDF5 file?
      32       58430 :     constexpr char achSignature[] = "\211HDF\r\n\032\n";
      33             : 
      34       58430 :     if (!poOpenInfo->pabyHeader)
      35       54778 :         return FALSE;
      36             : 
      37        7303 :     const CPLString osExt(poOpenInfo->osExtension);
      38             : 
      39         550 :     const auto IsRecognizedByNetCDFDriver = [&osExt, poOpenInfo]()
      40             :     {
      41         275 :         if ((EQUAL(osExt, "NC") || EQUAL(osExt, "CDF") || EQUAL(osExt, "NC4") ||
      42         280 :              EQUAL(osExt, "gmac")) &&
      43           5 :             GDALGetDriverByName("netCDF") != nullptr)
      44             :         {
      45           5 :             const char *const apszAllowedDriver[] = {"netCDF", nullptr};
      46           5 :             CPLErrorStateBackuper oErrorStateBackuper(CPLQuietErrorHandler);
      47          10 :             return std::unique_ptr<GDALDataset>(GDALDataset::Open(
      48           5 :                        poOpenInfo->pszFilename,
      49             :                        GDAL_OF_RASTER | GDAL_OF_MULTIDIM_RASTER |
      50             :                            GDAL_OF_VECTOR,
      51           5 :                        apszAllowedDriver, nullptr, nullptr)) != nullptr;
      52             :         }
      53         135 :         return false;
      54        3651 :     };
      55             : 
      56        3651 :     if (memcmp(poOpenInfo->pabyHeader, achSignature, 8) == 0 ||
      57        3508 :         (poOpenInfo->nHeaderBytes > 512 + 8 &&
      58        2209 :          memcmp(poOpenInfo->pabyHeader + 512, achSignature, 8) == 0))
      59             :     {
      60         143 :         if (poOpenInfo->IsSingleAllowedDriver("HDF5"))
      61             :         {
      62           4 :             return TRUE;
      63             :         }
      64             : 
      65             :         // The tests to avoid opening KEA and BAG drivers are not
      66             :         // necessary when drivers are built in the core lib, as they
      67             :         // are registered after HDF5, but in the case of plugins, we
      68             :         // cannot do assumptions about the registration order.
      69             : 
      70             :         // Avoid opening kea files if the kea driver is available.
      71         139 :         if (EQUAL(osExt, "KEA") && GDALGetDriverByName("KEA") != nullptr)
      72             :         {
      73           0 :             return FALSE;
      74             :         }
      75             : 
      76             :         // Avoid opening BAG files if the bag driver is available.
      77         139 :         if (EQUAL(osExt, "BAG") && GDALGetDriverByName("BAG") != nullptr)
      78             :         {
      79           1 :             return FALSE;
      80             :         }
      81             : 
      82             :         // Avoid opening NC files if the netCDF driver is available and
      83             :         // they are recognized by it.
      84         138 :         if (IsRecognizedByNetCDFDriver())
      85             :         {
      86           3 :             return FALSE;
      87             :         }
      88             : 
      89         135 :         return TRUE;
      90             :     }
      91             : 
      92        3508 :     if (memcmp(poOpenInfo->pabyHeader, "<HDF_UserBlock>", 15) == 0)
      93             :     {
      94           0 :         return TRUE;
      95             :     }
      96             : 
      97             :     // The HDF5 signature can be at offsets 512, 1024, 2048, etc.
      98        6962 :     if (poOpenInfo->fpL != nullptr &&
      99        3454 :         (EQUAL(osExt, "h5") || EQUAL(osExt, "hdf5") || EQUAL(osExt, "nc") ||
     100        3442 :          EQUAL(osExt, "cdf") || EQUAL(osExt, "nc4") ||
     101        3442 :          poOpenInfo->IsSingleAllowedDriver("HDF5")))
     102             :     {
     103          14 :         vsi_l_offset nOffset = 512;
     104          38 :         for (int i = 0; i < 64; i++)
     105             :         {
     106             :             GByte abyBuf[8];
     107          76 :             if (VSIFSeekL(poOpenInfo->fpL, nOffset, SEEK_SET) != 0 ||
     108          38 :                 VSIFReadL(abyBuf, 1, 8, poOpenInfo->fpL) != 8)
     109             :             {
     110           8 :                 break;
     111             :             }
     112          30 :             if (memcmp(abyBuf, achSignature, 8) == 0)
     113             :             {
     114           6 :                 if (poOpenInfo->IsSingleAllowedDriver("HDF5"))
     115             :                 {
     116           6 :                     return TRUE;
     117             :                 }
     118             :                 // Avoid opening NC files if the netCDF driver is available and
     119             :                 // they are recognized by it.
     120           2 :                 if (IsRecognizedByNetCDFDriver())
     121             :                 {
     122           0 :                     return FALSE;
     123             :                 }
     124             : 
     125           2 :                 return TRUE;
     126             :             }
     127          24 :             nOffset *= 2;
     128             :         }
     129             :     }
     130             : 
     131        3502 :     return FALSE;
     132             : }
     133             : 
     134             : /************************************************************************/
     135             : /*                     HDF5ImageDatasetIdentify()                       */
     136             : /************************************************************************/
     137             : 
     138       57660 : int HDF5ImageDatasetIdentify(GDALOpenInfo *poOpenInfo)
     139             : 
     140             : {
     141       57660 :     if (!STARTS_WITH_CI(poOpenInfo->pszFilename, "HDF5:"))
     142       57601 :         return FALSE;
     143             : 
     144          59 :     return TRUE;
     145             : }
     146             : 
     147             : /************************************************************************/
     148             : /*                    HDF5DriverGetSubdatasetInfo()                     */
     149             : /************************************************************************/
     150             : 
     151             : struct HDF5DriverSubdatasetInfo : public GDALSubdatasetInfo
     152             : {
     153             :   public:
     154          12 :     explicit HDF5DriverSubdatasetInfo(const std::string &fileName)
     155          12 :         : GDALSubdatasetInfo(fileName)
     156             :     {
     157          12 :     }
     158             : 
     159             :     // GDALSubdatasetInfo interface
     160             :   private:
     161             :     void parseFileName() override;
     162             : };
     163             : 
     164          12 : void HDF5DriverSubdatasetInfo::parseFileName()
     165             : {
     166             : 
     167          12 :     if (!STARTS_WITH_CI(m_fileName.c_str(), "HDF5:"))
     168             :     {
     169           0 :         return;
     170             :     }
     171             : 
     172          24 :     CPLStringList aosParts{CSLTokenizeString2(m_fileName.c_str(), ":", 0)};
     173          12 :     const int iPartsCount{CSLCount(aosParts)};
     174             : 
     175          12 :     if (iPartsCount >= 3)
     176             :     {
     177             : 
     178          10 :         m_driverPrefixComponent = aosParts[0];
     179             : 
     180          20 :         std::string part1{aosParts[1]};
     181          10 :         if (!part1.empty() && part1[0] == '"')
     182             :         {
     183           6 :             part1 = part1.substr(1);
     184             :         }
     185             : 
     186          10 :         int subdatasetIndex{2};
     187             :         const bool hasDriveLetter{
     188          10 :             part1.length() == 1 &&
     189          16 :             std::isalpha(static_cast<unsigned char>(part1.at(0))) &&
     190           6 :             (strlen(aosParts[2]) > 1 &&
     191           5 :              (aosParts[2][0] == '\\' ||
     192           3 :               (aosParts[2][0] == '/' && aosParts[2][1] != '/')))};
     193             : 
     194          19 :         const bool hasProtocol{part1 == "/vsicurl/http" ||
     195          18 :                                part1 == "/vsicurl/https" ||
     196          28 :                                part1 == "/vsicurl_streaming/http" ||
     197           9 :                                part1 == "/vsicurl_streaming/https"};
     198             : 
     199          10 :         m_pathComponent = aosParts[1];
     200             : 
     201          10 :         if (hasDriveLetter || hasProtocol)
     202             :         {
     203           5 :             m_pathComponent.append(":");
     204           5 :             m_pathComponent.append(aosParts[2]);
     205           5 :             subdatasetIndex++;
     206             :         }
     207             : 
     208          10 :         if (iPartsCount > subdatasetIndex)
     209             :         {
     210          10 :             m_subdatasetComponent = aosParts[subdatasetIndex];
     211             : 
     212             :             // Append any remaining part
     213          10 :             for (int i = subdatasetIndex + 1; i < iPartsCount; ++i)
     214             :             {
     215           0 :                 m_subdatasetComponent.append(":");
     216           0 :                 m_subdatasetComponent.append(aosParts[i]);
     217             :             }
     218             :         }
     219             :     }
     220             : }
     221             : 
     222        2697 : static GDALSubdatasetInfo *HDF5DriverGetSubdatasetInfo(const char *pszFileName)
     223             : {
     224        2697 :     if (STARTS_WITH_CI(pszFileName, "HDF5:"))
     225             :     {
     226             :         std::unique_ptr<GDALSubdatasetInfo> info =
     227          12 :             std::make_unique<HDF5DriverSubdatasetInfo>(pszFileName);
     228          34 :         if (!info->GetSubdatasetComponent().empty() &&
     229          22 :             !info->GetPathComponent().empty())
     230             :         {
     231          10 :             return info.release();
     232             :         }
     233             :     }
     234        2687 :     return nullptr;
     235             : }
     236             : 
     237             : /************************************************************************/
     238             : /*                         IdentifySxx()                                */
     239             : /************************************************************************/
     240             : 
     241      175168 : static bool IdentifySxx(GDALOpenInfo *poOpenInfo, const char *pszDriverName,
     242             :                         const char *pszConfigOption,
     243             :                         const char *pszMainGroupName)
     244             : {
     245      175168 :     if (STARTS_WITH(poOpenInfo->pszFilename, pszDriverName) &&
     246          34 :         poOpenInfo->pszFilename[strlen(pszDriverName)] == ':')
     247          34 :         return TRUE;
     248             : 
     249             :     // Is it an HDF5 file?
     250             :     static const char achSignature[] = "\211HDF\r\n\032\n";
     251             : 
     252      175134 :     if (poOpenInfo->pabyHeader == nullptr ||
     253       10766 :         memcmp(poOpenInfo->pabyHeader, achSignature, 8) != 0)
     254      174873 :         return FALSE;
     255             : 
     256         261 :     if (poOpenInfo->IsSingleAllowedDriver(pszDriverName))
     257             :     {
     258           1 :         return TRUE;
     259             :     }
     260             : 
     261             :     // GDAL_Sxxx_IDENTIFY can be set to NO only for tests, to test that
     262             :     // HDF5Dataset::Open() can redirect to Sxxx if the below logic fails
     263         260 :     if (CPLTestBool(CPLGetConfigOption(pszConfigOption, "YES")))
     264             :     {
     265             :         // The below identification logic may be a bit fragile...
     266             :         // Works at least on:
     267             :         // - /vsis3/noaa-s102-pds/ed2.1.0/national_bathymetric_source/boston/dcf2/tiles/102US00_US4MA1GC.h5
     268             :         // - https://datahub.admiralty.co.uk/portal/sharing/rest/content/items/6fd07bde26124d48820b6dee60695389/data (S-102_Liverpool_Trial_Cells.zip)
     269         259 :         const int nLenMainGroup = static_cast<int>(strlen(pszMainGroupName));
     270         259 :         const int nLenGroupF = static_cast<int>(strlen("Group_F"));
     271         259 :         const int nLenProductSpecification =
     272             :             static_cast<int>(strlen("productSpecification"));
     273         259 :         bool bFoundMainGroup = false;
     274         259 :         bool bFoundGroupF = false;
     275         259 :         bool bFoundProductSpecification = false;
     276         259 :         for (int iTry = 0; iTry < 2; ++iTry)
     277             :         {
     278      253301 :             for (int i = 0; i <= poOpenInfo->nHeaderBytes - nLenGroupF; ++i)
     279             :             {
     280      253080 :                 if (i <= poOpenInfo->nHeaderBytes - nLenMainGroup &&
     281      251529 :                     poOpenInfo->pabyHeader[i] == pszMainGroupName[0] &&
     282         152 :                     memcmp(poOpenInfo->pabyHeader + i, pszMainGroupName,
     283             :                            nLenMainGroup) == 0)
     284             :                 {
     285          38 :                     bFoundMainGroup = true;
     286          38 :                     if (bFoundGroupF)
     287           0 :                         return true;
     288             :                 }
     289      253080 :                 if (poOpenInfo->pabyHeader[i] == 'G' &&
     290         225 :                     memcmp(poOpenInfo->pabyHeader + i, "Group_F", nLenGroupF) ==
     291             :                         0)
     292             :                 {
     293          46 :                     bFoundGroupF = true;
     294          46 :                     if (bFoundMainGroup)
     295          38 :                         return true;
     296             :                 }
     297      253042 :                 if (i <= poOpenInfo->nHeaderBytes - nLenProductSpecification &&
     298      250169 :                     poOpenInfo->pabyHeader[i] == 'p' &&
     299         221 :                     memcmp(poOpenInfo->pabyHeader + i, "productSpecification",
     300             :                            nLenProductSpecification) == 0)
     301             :                 {
     302             :                     // For 102DE00OS08J.H5
     303           0 :                     bFoundProductSpecification = true;
     304             :                 }
     305             :             }
     306         221 :             if (!(iTry == 0 && bFoundProductSpecification &&
     307           0 :                   poOpenInfo->nHeaderBytes == 1024 &&
     308           0 :                   poOpenInfo->TryToIngest(4096)))
     309             :             {
     310         221 :                 break;
     311             :             }
     312             :         }
     313             :     }
     314             : 
     315         222 :     return false;
     316             : }
     317             : 
     318             : /************************************************************************/
     319             : /*                        S102DatasetIdentify()                         */
     320             : /************************************************************************/
     321             : 
     322       58425 : int S102DatasetIdentify(GDALOpenInfo *poOpenInfo)
     323             : 
     324             : {
     325       58425 :     return IdentifySxx(poOpenInfo, "S102", "GDAL_S102_IDENTIFY",
     326       58423 :                        "BathymetryCoverage");
     327             : }
     328             : 
     329             : /************************************************************************/
     330             : /*                        S104DatasetIdentify()                         */
     331             : /************************************************************************/
     332             : 
     333       58376 : int S104DatasetIdentify(GDALOpenInfo *poOpenInfo)
     334             : 
     335             : {
     336       58376 :     return IdentifySxx(poOpenInfo, "S104", "GDAL_S104_IDENTIFY", "WaterLevel");
     337             : }
     338             : 
     339             : /************************************************************************/
     340             : /*                        S111DatasetIdentify()                         */
     341             : /************************************************************************/
     342             : 
     343       58369 : int S111DatasetIdentify(GDALOpenInfo *poOpenInfo)
     344             : 
     345             : {
     346       58369 :     return IdentifySxx(poOpenInfo, "S111", "GDAL_S111_IDENTIFY",
     347       58370 :                        "SurfaceCurrent");
     348             : }
     349             : 
     350             : /************************************************************************/
     351             : /*                        BAGDatasetIdentify()                          */
     352             : /************************************************************************/
     353             : 
     354       68903 : int BAGDatasetIdentify(GDALOpenInfo *poOpenInfo)
     355             : 
     356             : {
     357       68903 :     if (STARTS_WITH(poOpenInfo->pszFilename, "BAG:"))
     358          30 :         return TRUE;
     359             : 
     360             :     // Is it an HDF5 file?
     361             :     static const char achSignature[] = "\211HDF\r\n\032\n";
     362             : 
     363       68873 :     if (poOpenInfo->pabyHeader == nullptr ||
     364       11599 :         memcmp(poOpenInfo->pabyHeader, achSignature, 8) != 0)
     365       68634 :         return FALSE;
     366             : 
     367             :     // Does it have the extension .bag?
     368         239 :     if (!poOpenInfo->IsExtensionEqualToCI("bag"))
     369             :     {
     370         103 :         if (poOpenInfo->IsSingleAllowedDriver("BAG"))
     371             :         {
     372           1 :             return TRUE;
     373             :         }
     374         102 :         return FALSE;
     375             :     }
     376             : 
     377         136 :     return TRUE;
     378             : }
     379             : 
     380             : /************************************************************************/
     381             : /*                   HDF5DriverSetCommonMetadata()                      */
     382             : /************************************************************************/
     383             : 
     384        1689 : void HDF5DriverSetCommonMetadata(GDALDriver *poDriver)
     385             : {
     386        1689 :     poDriver->SetDescription(HDF5_DRIVER_NAME);
     387        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     388        1689 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
     389        1689 :                               "Hierarchical Data Format Release 5");
     390        1689 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/hdf5.html");
     391        1689 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSIONS, "h5 hdf5");
     392        1689 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     393        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     394             : 
     395        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIDIM_RASTER, "YES");
     396             : 
     397        1689 :     poDriver->pfnIdentify = HDF5DatasetIdentify;
     398        1689 :     poDriver->pfnGetSubdatasetInfoFunc = HDF5DriverGetSubdatasetInfo;
     399        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     400        1689 : }
     401             : 
     402             : /************************************************************************/
     403             : /*                 HDF5ImageDriverSetCommonMetadata()                   */
     404             : /************************************************************************/
     405             : 
     406        1689 : void HDF5ImageDriverSetCommonMetadata(GDALDriver *poDriver)
     407             : {
     408        1689 :     poDriver->SetDescription(HDF5_IMAGE_DRIVER_NAME);
     409        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     410        1689 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "HDF5 Dataset");
     411        1689 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/hdf5.html");
     412        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     413             : 
     414        1689 :     poDriver->pfnIdentify = HDF5ImageDatasetIdentify;
     415        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     416        1689 : }
     417             : 
     418             : /************************************************************************/
     419             : /*                     BAGDriverSetCommonMetadata()                     */
     420             : /************************************************************************/
     421             : 
     422        1689 : void BAGDriverSetCommonMetadata(GDALDriver *poDriver)
     423             : {
     424        1689 :     poDriver->SetDescription(BAG_DRIVER_NAME);
     425        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     426        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES");
     427        1689 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Bathymetry Attributed Grid");
     428        1689 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/bag.html");
     429        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     430        1689 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "bag");
     431             : 
     432        1689 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES, "Float32");
     433             : 
     434        1689 :     poDriver->SetMetadataItem(
     435             :         GDAL_DMD_OPENOPTIONLIST,
     436             :         "<OpenOptionList>"
     437             :         "   <Option name='MODE' type='string-select' default='AUTO'>"
     438             :         "       <Value>AUTO</Value>"
     439             :         "       <Value>LOW_RES_GRID</Value>"
     440             :         "       <Value>LIST_SUPERGRIDS</Value>"
     441             :         "       <Value>RESAMPLED_GRID</Value>"
     442             :         "       <Value>INTERPOLATED</Value>"
     443             :         "   </Option>"
     444             :         "   <Option name='SUPERGRIDS_INDICES' type='string' description="
     445             :         "'Tuple(s) (y1,x1),(y2,x2),...  of supergrids, by indices, to expose "
     446             :         "as subdatasets'/>"
     447             :         "   <Option name='MINX' type='float' description='Minimum X value of "
     448             :         "area of interest'/>"
     449             :         "   <Option name='MINY' type='float' description='Minimum Y value of "
     450             :         "area of interest'/>"
     451             :         "   <Option name='MAXX' type='float' description='Maximum X value of "
     452             :         "area of interest'/>"
     453             :         "   <Option name='MAXY' type='float' description='Maximum Y value of "
     454             :         "area of interest'/>"
     455             :         "   <Option name='RESX' type='float' description="
     456             :         "'Horizontal resolution. Only used for "
     457             :         "MODE=RESAMPLED_GRID/INTERPOLATED'/>"
     458             :         "   <Option name='RESY' type='float' description="
     459             :         "'Vertical resolution (positive value). Only used for "
     460             :         "MODE=RESAMPLED_GRID/INTERPOLATED'/>"
     461             :         "   <Option name='RES_STRATEGY' type='string-select' description="
     462             :         "'Which strategy to apply to select the resampled grid resolution. "
     463             :         "Only used for MODE=RESAMPLED_GRID/INTERPOLATED' default='AUTO'>"
     464             :         "       <Value>AUTO</Value>"
     465             :         "       <Value>MIN</Value>"
     466             :         "       <Value>MAX</Value>"
     467             :         "       <Value>MEAN</Value>"
     468             :         "   </Option>"
     469             :         "   <Option name='RES_FILTER_MIN' type='float' description="
     470             :         "'Minimum resolution of supergrids to take into account (excluded "
     471             :         "bound). "
     472             :         "Only used for MODE=RESAMPLED_GRID, INTERPOLATED or LIST_SUPERGRIDS' "
     473             :         "default='0'/>"
     474             :         "   <Option name='RES_FILTER_MAX' type='float' description="
     475             :         "'Maximum resolution of supergrids to take into account (included "
     476             :         "bound). "
     477             :         "Only used for MODE=RESAMPLED_GRID, INTERPOLATED or LIST_SUPERGRIDS' "
     478             :         "default='inf'/>"
     479             :         "   <Option name='VALUE_POPULATION' type='string-select' description="
     480             :         "'Which value population strategy to apply to compute the resampled "
     481             :         "cell "
     482             :         "values. Only used for MODE=RESAMPLED_GRID' default='MAX'>"
     483             :         "       <Value>MIN</Value>"
     484             :         "       <Value>MAX</Value>"
     485             :         "       <Value>MEAN</Value>"
     486             :         "       <Value>COUNT</Value>"
     487             :         "   </Option>"
     488             :         "   <Option name='SUPERGRIDS_MASK' type='boolean' description="
     489             :         "'Whether the dataset should consist of a mask band indicating if a "
     490             :         "supergrid node matches each target pixel. Only used for "
     491             :         "MODE=RESAMPLED_GRID' default='NO'/>"
     492             :         "   <Option name='NODATA_VALUE' type='float' default='1000000'/>"
     493             :         "   <Option name='REPORT_VERTCRS' type='boolean' default='YES'/>"
     494        1689 :         "</OpenOptionList>");
     495             : 
     496        1689 :     poDriver->SetMetadataItem(
     497             :         GDAL_DMD_CREATIONOPTIONLIST,
     498             :         "<CreationOptionList>"
     499             :         "  <Option name='VAR_*' type='string' description="
     500             :         "'Value to substitute to a variable in the template'/>"
     501             :         "  <Option name='TEMPLATE' type='string' description="
     502             :         "'.xml template to use'/>"
     503             :         "  <Option name='BAG_VERSION' type='string' description="
     504             :         "'Version to write in the Bag Version attribute' default='1.6.2'/>"
     505             :         "  <Option name='COMPRESS' type='string-select' default='DEFLATE'>"
     506             :         "    <Value>NONE</Value>"
     507             :         "    <Value>DEFLATE</Value>"
     508             :         "  </Option>"
     509             :         "  <Option name='ZLEVEL' type='int' "
     510             :         "description='DEFLATE compression level 1-9' default='6' />"
     511             :         "  <Option name='BLOCK_SIZE' type='int' description='Chunk size' />"
     512        1689 :         "</CreationOptionList>");
     513             : 
     514        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIDIM_RASTER, "YES");
     515             : 
     516        1689 :     poDriver->pfnIdentify = BAGDatasetIdentify;
     517        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     518        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
     519        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
     520        1689 : }
     521             : 
     522             : /************************************************************************/
     523             : /*                    S102DriverSetCommonMetadata()                     */
     524             : /************************************************************************/
     525             : 
     526        1689 : void S102DriverSetCommonMetadata(GDALDriver *poDriver)
     527             : {
     528        1689 :     poDriver->SetDescription(S102_DRIVER_NAME);
     529        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     530        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIDIM_RASTER, "YES");
     531        1689 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
     532        1689 :                               "S-102 Bathymetric Surface Product");
     533        1689 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/s102.html");
     534        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     535        1689 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "h5");
     536        1689 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     537             : 
     538        1689 :     poDriver->SetMetadataItem(
     539             :         GDAL_DMD_OPENOPTIONLIST,
     540             :         "<OpenOptionList>"
     541             :         "   <Option name='DEPTH_OR_ELEVATION' type='string-select' "
     542             :         "default='DEPTH'>"
     543             :         "       <Value>DEPTH</Value>"
     544             :         "       <Value>ELEVATION</Value>"
     545             :         "   </Option>"
     546             :         "   <Option name='NORTH_UP' type='boolean' default='YES' "
     547             :         "description='Whether the top line of the dataset should be the "
     548             :         "northern-most one'/>"
     549        1689 :         "</OpenOptionList>");
     550        1689 :     poDriver->pfnIdentify = S102DatasetIdentify;
     551        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     552        1689 : }
     553             : 
     554             : /************************************************************************/
     555             : /*                    S104DriverSetCommonMetadata()                     */
     556             : /************************************************************************/
     557             : 
     558        1689 : void S104DriverSetCommonMetadata(GDALDriver *poDriver)
     559             : {
     560        1689 :     poDriver->SetDescription(S104_DRIVER_NAME);
     561        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     562        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIDIM_RASTER, "YES");
     563        1689 :     poDriver->SetMetadataItem(
     564             :         GDAL_DMD_LONGNAME,
     565        1689 :         "S-104 Water Level Information for Surface Navigation Product");
     566        1689 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/s104.html");
     567        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     568        1689 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "h5");
     569             : 
     570        1689 :     poDriver->SetMetadataItem(
     571             :         GDAL_DMD_OPENOPTIONLIST,
     572             :         "<OpenOptionList>"
     573             :         "   <Option name='NORTH_UP' type='boolean' default='YES' "
     574             :         "description='Whether the top line of the dataset should be the "
     575             :         "northern-most one'/>"
     576        1689 :         "</OpenOptionList>");
     577        1689 :     poDriver->pfnIdentify = S104DatasetIdentify;
     578        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     579        1689 : }
     580             : 
     581             : /************************************************************************/
     582             : /*                    S111DriverSetCommonMetadata()                     */
     583             : /************************************************************************/
     584             : 
     585        1689 : void S111DriverSetCommonMetadata(GDALDriver *poDriver)
     586             : {
     587        1689 :     poDriver->SetDescription(S111_DRIVER_NAME);
     588        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     589        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIDIM_RASTER, "YES");
     590        1689 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Surface Currents Product");
     591        1689 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/s111.html");
     592        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     593        1689 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "h5");
     594             : 
     595        1689 :     poDriver->SetMetadataItem(
     596             :         GDAL_DMD_OPENOPTIONLIST,
     597             :         "<OpenOptionList>"
     598             :         "   <Option name='NORTH_UP' type='boolean' default='YES' "
     599             :         "description='Whether the top line of the dataset should be the "
     600             :         "northern-most one'/>"
     601        1689 :         "</OpenOptionList>");
     602        1689 :     poDriver->pfnIdentify = S111DatasetIdentify;
     603        1689 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     604        1689 : }
     605             : 
     606             : /************************************************************************/
     607             : /*                    DeclareDeferredHDF5Plugin()                       */
     608             : /************************************************************************/
     609             : 
     610             : #ifdef PLUGIN_FILENAME
     611        1961 : void DeclareDeferredHDF5Plugin()
     612             : {
     613        1961 :     if (GDALGetDriverByName(HDF5_DRIVER_NAME) != nullptr)
     614             :     {
     615         283 :         return;
     616             :     }
     617             :     {
     618        1678 :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     619             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     620             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     621             :                                   PLUGIN_INSTALLATION_MESSAGE);
     622             : #endif
     623        1678 :         HDF5DriverSetCommonMetadata(poDriver);
     624        1678 :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     625             :     }
     626             :     {
     627        1678 :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     628             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     629             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     630             :                                   PLUGIN_INSTALLATION_MESSAGE);
     631             : #endif
     632        1678 :         HDF5ImageDriverSetCommonMetadata(poDriver);
     633        1678 :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     634             :     }
     635             :     {
     636        1678 :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     637             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     638             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     639             :                                   PLUGIN_INSTALLATION_MESSAGE);
     640             : #endif
     641        1678 :         BAGDriverSetCommonMetadata(poDriver);
     642        1678 :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     643             :     }
     644             :     {
     645        1678 :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     646             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     647             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     648             :                                   PLUGIN_INSTALLATION_MESSAGE);
     649             : #endif
     650        1678 :         S102DriverSetCommonMetadata(poDriver);
     651        1678 :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     652             :     }
     653             :     {
     654        1678 :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     655             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     656             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     657             :                                   PLUGIN_INSTALLATION_MESSAGE);
     658             : #endif
     659        1678 :         S104DriverSetCommonMetadata(poDriver);
     660        1678 :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     661             :     }
     662             :     {
     663        1678 :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     664             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     665             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     666             :                                   PLUGIN_INSTALLATION_MESSAGE);
     667             : #endif
     668        1678 :         S111DriverSetCommonMetadata(poDriver);
     669        1678 :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     670             :     }
     671             : }
     672             : #endif

Generated by: LCOV version 1.14