LCOV - code coverage report
Current view: top level - frmts/zarr - zarrdrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 54 54 100.0 %
Date: 2025-06-19 12:30:01 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Zarr driver
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2021, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "zarrdrivercore.h"
      14             : 
      15             : #include "vsikerchunk.h"
      16             : #include "vsikerchunk_inline.hpp"
      17             : 
      18             : /************************************************************************/
      19             : /*                    CheckExistenceOfOneZarrFile()                     */
      20             : /************************************************************************/
      21             : 
      22        1642 : static bool CheckExistenceOfOneZarrFile(const char *pszFilename)
      23             : {
      24             : 
      25             :     CPLString osMDFilename =
      26        3284 :         CPLFormFilenameSafe(pszFilename, ".zarray", nullptr);
      27             : 
      28             :     VSIStatBufL sStat;
      29        1642 :     if (VSIStatL(osMDFilename, &sStat) == 0)
      30         488 :         return true;
      31             : 
      32        1154 :     osMDFilename = CPLFormFilenameSafe(pszFilename, ".zgroup", nullptr);
      33        1154 :     if (VSIStatL(osMDFilename, &sStat) == 0)
      34         452 :         return true;
      35             : 
      36             :     // Zarr V3
      37         702 :     osMDFilename = CPLFormFilenameSafe(pszFilename, "zarr.json", nullptr);
      38         702 :     if (VSIStatL(osMDFilename, &sStat) == 0)
      39         424 :         return true;
      40             : 
      41         278 :     return false;
      42             : }
      43             : 
      44             : /************************************************************************/
      45             : /*                   ZARRIsLikelyKerchunkJSONRef()                      */
      46             : /************************************************************************/
      47             : 
      48       55981 : bool ZARRIsLikelyKerchunkJSONRef(const GDALOpenInfo *poOpenInfo)
      49             : {
      50       57401 :     if (poOpenInfo->nHeaderBytes > 0 && poOpenInfo->eAccess == GA_ReadOnly &&
      51        1420 :         poOpenInfo->IsExtensionEqualToCI("json"))
      52             :     {
      53          59 :         const char *pszHeader =
      54             :             reinterpret_cast<const char *>(poOpenInfo->pabyHeader);
      55          59 :         if (ZARRIsLikelyStreamableKerchunkJSONRefContent(
      56         118 :                 std::string_view(pszHeader, poOpenInfo->nHeaderBytes)))
      57             :         {
      58          54 :             return true;
      59             :         }
      60             :     }
      61       55927 :     return false;
      62             : }
      63             : 
      64             : /************************************************************************/
      65             : /*                     ZARRDriverIdentify()                             */
      66             : /************************************************************************/
      67             : 
      68       55320 : int ZARRDriverIdentify(GDALOpenInfo *poOpenInfo)
      69             : 
      70             : {
      71       55320 :     if (STARTS_WITH(poOpenInfo->pszFilename, "ZARR:") ||
      72       55223 :         STARTS_WITH(poOpenInfo->pszFilename, "ZARR_DUMMY:"))
      73             :     {
      74          99 :         return TRUE;
      75             :     }
      76             : 
      77       55221 :     if (ZARRIsLikelyKerchunkJSONRef(poOpenInfo))
      78             :     {
      79          36 :         return TRUE;
      80             :     }
      81       55184 :     if (STARTS_WITH(poOpenInfo->pszFilename, JSON_REF_FS_PREFIX))
      82             :     {
      83           4 :         return -1;
      84             :     }
      85             : 
      86       55180 :     if (!poOpenInfo->bIsDirectory)
      87             :     {
      88       53539 :         return FALSE;
      89             :     }
      90             : 
      91        1641 :     return CheckExistenceOfOneZarrFile(poOpenInfo->pszFilename);
      92             : }
      93             : 
      94             : /************************************************************************/
      95             : /*                     ZARRDriverSetCommonMetadata()                    */
      96             : /************************************************************************/
      97             : 
      98        1629 : void ZARRDriverSetCommonMetadata(GDALDriver *poDriver)
      99             : {
     100        1629 :     poDriver->SetDescription(DRIVER_NAME);
     101        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     102        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_MULTIDIM_RASTER, "YES");
     103        1629 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Zarr");
     104        1629 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "zarr");
     105        1629 :     poDriver->SetMetadataItem(
     106             :         GDAL_DMD_CREATIONDATATYPES,
     107             :         "Int8 Byte Int16 UInt16 Int32 UInt32 Int64 UInt64 "
     108        1629 :         "Float16 Float32 Float64 CFLoat16 CFloat32 CFloat64");
     109        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     110        1629 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     111        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_SUBDATASETS, "YES");
     112             : 
     113        1629 :     poDriver->SetMetadataItem(
     114             :         GDAL_DMD_OPENOPTIONLIST,
     115             :         "<OpenOptionList>"
     116             :         "   <Option name='LIST_ALL_ARRAYS' type='boolean' "
     117             :         "description='Whether to list all arrays, and not only those whose "
     118             :         "dimension count is 2 or more' default='NO'/>"
     119             :         "   <Option name='USE_ZMETADATA' type='boolean' description='Whether "
     120             :         "to use consolidated metadata from .zmetadata' default='YES'/>"
     121             :         "   <Option name='CACHE_TILE_PRESENCE' type='boolean' "
     122             :         "description='Whether to establish an initial listing of present "
     123             :         "tiles' default='NO'/>"
     124             :         "   <Option name='CACHE_KERCHUNK_JSON' type='boolean' "
     125             :         "description='Whether to transform Kerchunk JSON reference files into "
     126             :         "Kerchunk Parquet reference files in a local cache' default='NO'/>"
     127             :         "   <Option name='MULTIBAND' type='boolean' default='YES' "
     128             :         "description='Whether to expose >= 3D arrays as GDAL multiband "
     129             :         "datasets "
     130             :         "(when using the classic 2D API)'/>"
     131             :         "   <Option name='DIM_X' type='string' description="
     132             :         "'Name or index of the X dimension (only used when MULTIBAND=YES)'/>"
     133             :         "   <Option name='DIM_Y' type='string' description="
     134             :         "'Name or index of the Y dimension (only used when MULTIBAND=YES)'/>"
     135             :         "   <Option name='LOAD_EXTRA_DIM_METADATA_DELAY' type='string' "
     136             :         "description="
     137             :         "'Maximum delay in seconds allowed to set the DIM_{dimname}_VALUE band "
     138             :         "metadata items'/>"
     139        1629 :         "</OpenOptionList>");
     140             : 
     141        1629 :     poDriver->SetMetadataItem(
     142             :         GDAL_DMD_MULTIDIM_DATASET_CREATIONOPTIONLIST,
     143             :         "<MultiDimDatasetCreationOptionList>"
     144             :         "   <Option name='FORMAT' type='string-select' default='ZARR_V2'>"
     145             :         "     <Value>ZARR_V2</Value>"
     146             :         "     <Value>ZARR_V3</Value>"
     147             :         "   </Option>"
     148             :         "   <Option name='CREATE_ZMETADATA' type='boolean' "
     149             :         "description='Whether to create consolidated metadata into .zmetadata "
     150             :         "(Zarr V2 only)' default='YES'/>"
     151        1629 :         "</MultiDimDatasetCreationOptionList>");
     152             : 
     153        1629 :     poDriver->pfnIdentify = ZARRDriverIdentify;
     154        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     155        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
     156        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
     157        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE_MULTIDIMENSIONAL, "YES");
     158             : 
     159        1629 :     poDriver->SetMetadataItem(GDAL_DCAP_UPDATE, "YES");
     160        1629 :     poDriver->SetMetadataItem(GDAL_DMD_UPDATE_ITEMS,
     161             :                               "GeoTransform SRS NoData "
     162             :                               "RasterValues "
     163        1629 :                               "DatasetMetadata BandMetadata");
     164        1629 : }
     165             : 
     166             : /************************************************************************/
     167             : /*                    DeclareDeferredZarrPlugin()                       */
     168             : /************************************************************************/
     169             : 
     170             : #ifdef PLUGIN_FILENAME
     171             : void DeclareDeferredZarrPlugin()
     172             : {
     173             :     if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
     174             :     {
     175             :         return;
     176             :     }
     177             :     auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     178             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     179             :     poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     180             :                               PLUGIN_INSTALLATION_MESSAGE);
     181             : #endif
     182             :     ZARRDriverSetCommonMetadata(poDriver);
     183             :     GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     184             : }
     185             : #endif

Generated by: LCOV version 1.14