LCOV - code coverage report
Current view: top level - frmts/zarr - zarr_v3_codec.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 66 66 100.0 %
Date: 2026-03-26 23:25:44 Functions: 27 28 96.4 %

          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             : #ifndef ZARR_V3_CODEC_H
      14             : #define ZARR_V3_CODEC_H
      15             : 
      16             : #include "zarr.h"
      17             : 
      18             : struct VSIVirtualHandle;
      19             : 
      20             : /************************************************************************/
      21             : /*                          ZarrArrayMetadata                           */
      22             : /************************************************************************/
      23             : 
      24             : /** Array-related metadata needed for the good working of Zarr V3 codecs */
      25             : struct ZarrArrayMetadata
      26             : {
      27             :     /** Data type of the array */
      28             :     DtypeElt oElt{};
      29             : 
      30             :     /** Shape of a block/chunk */
      31             :     std::vector<size_t> anBlockSizes{};
      32             : 
      33             :     /** No data value of the array. Empty or abyNoData.size() == oElt.nNativeSize */
      34             :     std::vector<GByte> abyNoData{};
      35             : };
      36             : 
      37             : /************************************************************************/
      38             : /*                             ZarrV3Codec                              */
      39             : /************************************************************************/
      40             : 
      41             : /** Abstract class for a Zarr V3 codec */
      42        4226 : class ZarrV3Codec CPL_NON_FINAL
      43             : {
      44             :   protected:
      45             :     const std::string m_osName;
      46             :     CPLJSONObject m_oConfiguration{};
      47             :     ZarrArrayMetadata m_oInputArrayMetadata{};
      48             : 
      49             :     ZarrV3Codec(const std::string &osName);
      50             : 
      51             :   public:
      52             :     virtual ~ZarrV3Codec();
      53             : 
      54             :     enum class IOType
      55             :     {
      56             :         BYTES,
      57             :         ARRAY
      58             :     };
      59             : 
      60             :     virtual IOType GetInputType() const = 0;
      61             :     virtual IOType GetOutputType() const = 0;
      62             : 
      63             :     virtual bool
      64             :     InitFromConfiguration(const CPLJSONObject &configuration,
      65             :                           const ZarrArrayMetadata &oInputArrayMetadata,
      66             :                           ZarrArrayMetadata &oOutputArrayMetadata,
      67             :                           bool bEmitWarnings) = 0;
      68             : 
      69             :     virtual std::unique_ptr<ZarrV3Codec> Clone() const = 0;
      70             : 
      71        2083 :     virtual bool IsNoOp() const
      72             :     {
      73        2083 :         return false;
      74             :     }
      75             : 
      76             :     virtual bool Encode(const ZarrByteVectorQuickResize &abySrc,
      77             :                         ZarrByteVectorQuickResize &abyDst) const = 0;
      78             :     virtual bool Decode(const ZarrByteVectorQuickResize &abySrc,
      79             :                         ZarrByteVectorQuickResize &abyDst) const = 0;
      80             : 
      81             :     /** Partial decoding.
      82             :      * anStartIdx[i]: coordinate in pixel, within the array of an outer chunk,
      83             :      * that is < m_oInputArrayMetadata.anBlockSizes[i]
      84             :      * anCount[i]: number of pixels to extract <= m_oInputArrayMetadata.anBlockSizes[i]
      85             :      */
      86             :     virtual bool DecodePartial(VSIVirtualHandle *poFile,
      87             :                                const ZarrByteVectorQuickResize &abySrc,
      88             :                                ZarrByteVectorQuickResize &abyDst,
      89             :                                std::vector<size_t> &anStartIdx,
      90             :                                std::vector<size_t> &anCount);
      91             : 
      92       11971 :     const std::string &GetName() const
      93             :     {
      94       11971 :         return m_osName;
      95             :     }
      96             : 
      97             :     const CPLJSONObject &GetConfiguration() const
      98             :     {
      99             :         return m_oConfiguration;
     100             :     }
     101             : 
     102             :     virtual std::vector<size_t>
     103         271 :     GetInnerMostBlockSize(const std::vector<size_t> &input) const
     104             :     {
     105         271 :         return input;
     106             :     }
     107             : 
     108        1027 :     virtual void ChangeArrayShapeForward(std::vector<size_t> &anStartIdx,
     109             :                                          std::vector<size_t> &anCount)
     110             :     {
     111             :         (void)anStartIdx;
     112             :         (void)anCount;
     113        1027 :     }
     114             : };
     115             : 
     116             : /************************************************************************/
     117             : /*                    ZarrV3CodecAbstractCompressor                     */
     118             : /************************************************************************/
     119             : 
     120             : class ZarrV3CodecAbstractCompressor CPL_NON_FINAL : public ZarrV3Codec
     121             : {
     122             :   protected:
     123             :     CPLStringList m_aosCompressorOptions{};
     124             :     const CPLCompressor *m_pDecompressor = nullptr;
     125             :     const CPLCompressor *m_pCompressor = nullptr;
     126             : 
     127             :     explicit ZarrV3CodecAbstractCompressor(const std::string &osName);
     128             : 
     129             :     ZarrV3CodecAbstractCompressor(const ZarrV3CodecAbstractCompressor &) =
     130             :         delete;
     131             :     ZarrV3CodecAbstractCompressor &
     132             :     operator=(const ZarrV3CodecAbstractCompressor &) = delete;
     133             : 
     134             :   public:
     135         590 :     IOType GetInputType() const override
     136             :     {
     137         590 :         return IOType::BYTES;
     138             :     }
     139             : 
     140         590 :     IOType GetOutputType() const override
     141             :     {
     142         590 :         return IOType::BYTES;
     143             :     }
     144             : 
     145             :     bool Encode(const ZarrByteVectorQuickResize &abySrc,
     146             :                 ZarrByteVectorQuickResize &abyDst) const override;
     147             :     bool Decode(const ZarrByteVectorQuickResize &abySrc,
     148             :                 ZarrByteVectorQuickResize &abyDst) const override;
     149             : };
     150             : 
     151             : /************************************************************************/
     152             : /*                           ZarrV3CodecGZip                            */
     153             : /************************************************************************/
     154             : 
     155             : // Implements https://zarr-specs.readthedocs.io/en/latest/v3/codecs/gzip/v1.0.html
     156             : class ZarrV3CodecGZip final : public ZarrV3CodecAbstractCompressor
     157             : {
     158             :   public:
     159             :     static constexpr const char *NAME = "gzip";
     160             : 
     161             :     ZarrV3CodecGZip();
     162             : 
     163             :     static CPLJSONObject GetConfiguration(int nLevel);
     164             : 
     165             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     166             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     167             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     168             :                                bool bEmitWarnings) override;
     169             : 
     170             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     171             : };
     172             : 
     173             : /************************************************************************/
     174             : /*                           ZarrV3CodecBlosc                           */
     175             : /************************************************************************/
     176             : 
     177             : // Implements https://zarr-specs.readthedocs.io/en/latest/v3/codecs/blosc/v1.0.html
     178             : class ZarrV3CodecBlosc final : public ZarrV3CodecAbstractCompressor
     179             : {
     180             :   public:
     181             :     static constexpr const char *NAME = "blosc";
     182             : 
     183             :     ZarrV3CodecBlosc();
     184             : 
     185             :     static CPLJSONObject GetConfiguration(const char *cname, int clevel,
     186             :                                           const char *shuffle, int typesize,
     187             :                                           int blocksize);
     188             : 
     189             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     190             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     191             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     192             :                                bool bEmitWarnings) override;
     193             : 
     194             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     195             : };
     196             : 
     197             : /************************************************************************/
     198             : /*                           ZarrV3CodecZstd                            */
     199             : /************************************************************************/
     200             : 
     201             : // Implements https://github.com/zarr-developers/zarr-specs/pull/256
     202             : class ZarrV3CodecZstd final : public ZarrV3CodecAbstractCompressor
     203             : {
     204             :   public:
     205             :     static constexpr const char *NAME = "zstd";
     206             : 
     207             :     ZarrV3CodecZstd();
     208             : 
     209             :     static CPLJSONObject GetConfiguration(int level, bool checksum);
     210             : 
     211             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     212             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     213             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     214             :                                bool bEmitWarnings) override;
     215             : 
     216             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     217             : };
     218             : 
     219             : /************************************************************************/
     220             : /*                           ZarrV3CodecBytes                           */
     221             : /************************************************************************/
     222             : 
     223             : // Implements https://zarr-specs.readthedocs.io/en/latest/v3/codecs/bytes/v1.0.html
     224             : class ZarrV3CodecBytes final : public ZarrV3Codec
     225             : {
     226             :     bool m_bLittle = true;
     227             : 
     228             :   public:
     229             :     static constexpr const char *NAME = "bytes";
     230             : 
     231             :     ZarrV3CodecBytes();
     232             : 
     233        1973 :     IOType GetInputType() const override
     234             :     {
     235        1973 :         return IOType::ARRAY;
     236             :     }
     237             : 
     238        1974 :     IOType GetOutputType() const override
     239             :     {
     240        1974 :         return IOType::BYTES;
     241             :     }
     242             : 
     243             :     static CPLJSONObject GetConfiguration(bool bLittle);
     244             : 
     245             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     246             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     247             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     248             :                                bool bEmitWarnings) override;
     249             : 
     250           1 :     bool IsLittle() const
     251             :     {
     252           1 :         return m_bLittle;
     253             :     }
     254             : 
     255        2027 :     bool IsNoOp() const override
     256             :     {
     257             :         // Byte-oriented string types have no endianness concept
     258        2027 :         if (m_oInputArrayMetadata.oElt.nativeType ==
     259             :             DtypeElt::NativeType::STRING_ASCII)
     260           2 :             return true;
     261             :         if constexpr (CPL_IS_LSB)
     262        2025 :             return m_oInputArrayMetadata.oElt.nativeSize == 1 || m_bLittle;
     263             :         else
     264             :             return m_oInputArrayMetadata.oElt.nativeSize == 1 || !m_bLittle;
     265             :     }
     266             : 
     267             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     268             : 
     269             :     bool Encode(const ZarrByteVectorQuickResize &abySrc,
     270             :                 ZarrByteVectorQuickResize &abyDst) const override;
     271             :     bool Decode(const ZarrByteVectorQuickResize &abySrc,
     272             :                 ZarrByteVectorQuickResize &abyDst) const override;
     273             : };
     274             : 
     275             : /************************************************************************/
     276             : /*                         ZarrV3CodecVLenUTF8                          */
     277             : /************************************************************************/
     278             : 
     279             : /** Implements the vlen-utf8 array-to-bytes codec for variable-length
     280             :  *  UTF-8 strings (zarr-extensions).
     281             :  *
     282             :  *  Binary format (little-endian):
     283             :  *    [u32 item_count] [u32 len_0][bytes_0] [u32 len_1][bytes_1] ...
     284             :  *
     285             :  *  Decode produces a flat buffer of nElements * nativeSize bytes where
     286             :  *  each slot is a null-padded string. Read-only for now.
     287             :  */
     288             : class ZarrV3CodecVLenUTF8 final : public ZarrV3Codec
     289             : {
     290             :   public:
     291             :     static constexpr const char *NAME = "vlen-utf8";
     292             : 
     293             :     ZarrV3CodecVLenUTF8();
     294             : 
     295          14 :     IOType GetInputType() const override
     296             :     {
     297          14 :         return IOType::ARRAY;
     298             :     }
     299             : 
     300          14 :     IOType GetOutputType() const override
     301             :     {
     302          14 :         return IOType::BYTES;
     303             :     }
     304             : 
     305             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     306             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     307             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     308             :                                bool bEmitWarnings) override;
     309             : 
     310             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     311             : 
     312             :     bool Encode(const ZarrByteVectorQuickResize &abySrc,
     313             :                 ZarrByteVectorQuickResize &abyDst) const override;
     314             :     bool Decode(const ZarrByteVectorQuickResize &abySrc,
     315             :                 ZarrByteVectorQuickResize &abyDst) const override;
     316             : };
     317             : 
     318             : /************************************************************************/
     319             : /*                         ZarrV3CodecTranspose                         */
     320             : /************************************************************************/
     321             : 
     322             : // Implements https://zarr-specs.readthedocs.io/en/latest/v3/codecs/transpose/v1.0.html
     323             : class ZarrV3CodecTranspose final : public ZarrV3Codec
     324             : {
     325             :     // m_anOrder is such that dest_shape[i] = source_shape[m_anOrder[i]]
     326             :     // where source_shape[] is the size of the array before the Encode() operation
     327             :     // and dest_shape[] its size after.
     328             :     // m_anOrder[] describes a bijection of [0,N-1] to [0,N-1]
     329             :     std::vector<int> m_anOrder{};
     330             : 
     331             :     // m_anReverseOrder is such that m_anReverseOrder[m_anOrder[i]] = i
     332             :     std::vector<int> m_anReverseOrder{};
     333             : 
     334             :     bool Transpose(const ZarrByteVectorQuickResize &abySrc,
     335             :                    ZarrByteVectorQuickResize &abyDst, bool bEncodeDirection,
     336             :                    const std::vector<size_t> &anForwardBlockSizes) const;
     337             : 
     338             :   public:
     339             :     static constexpr const char *NAME = "transpose";
     340             : 
     341             :     ZarrV3CodecTranspose();
     342             : 
     343          83 :     IOType GetInputType() const override
     344             :     {
     345          83 :         return IOType::ARRAY;
     346             :     }
     347             : 
     348          83 :     IOType GetOutputType() const override
     349             :     {
     350          83 :         return IOType::ARRAY;
     351             :     }
     352             : 
     353             :     static CPLJSONObject GetConfiguration(const std::vector<int> &anOrder);
     354             : 
     355             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     356             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     357             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     358             :                                bool bEmitWarnings) override;
     359             : 
     360           1 :     const std::vector<int> &GetOrder() const
     361             :     {
     362           1 :         return m_anOrder;
     363             :     }
     364             : 
     365             :     bool IsNoOp() const override;
     366             : 
     367             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     368             : 
     369             :     bool Encode(const ZarrByteVectorQuickResize &abySrc,
     370             :                 ZarrByteVectorQuickResize &abyDst) const override;
     371             :     bool Decode(const ZarrByteVectorQuickResize &abySrc,
     372             :                 ZarrByteVectorQuickResize &abyDst) const override;
     373             : 
     374             :     bool DecodePartial(VSIVirtualHandle *poFile,
     375             :                        const ZarrByteVectorQuickResize &abySrc,
     376             :                        ZarrByteVectorQuickResize &abyDst,
     377             :                        std::vector<size_t> &anStartIdx,
     378             :                        std::vector<size_t> &anCount) override;
     379             : 
     380             :     std::vector<size_t>
     381             :     GetInnerMostBlockSize(const std::vector<size_t> &input) const override;
     382             : 
     383             :     template <class T>
     384          50 :     inline void Reorder1DForward(std::vector<T> &vector) const
     385             :     {
     386         100 :         std::vector<T> res;
     387         150 :         for (int idx : m_anOrder)
     388         100 :             res.push_back(vector[idx]);
     389          50 :         vector = std::move(res);
     390          50 :     }
     391             : 
     392             :     template <class T>
     393          50 :     inline void Reorder1DInverse(std::vector<T> &vector) const
     394             :     {
     395         100 :         std::vector<T> res;
     396         150 :         for (int idx : m_anReverseOrder)
     397         100 :             res.push_back(vector[idx]);
     398          50 :         vector = std::move(res);
     399          50 :     }
     400             : 
     401          25 :     void ChangeArrayShapeForward(std::vector<size_t> &anStartIdx,
     402             :                                  std::vector<size_t> &anCount) override
     403             :     {
     404          25 :         Reorder1DForward(anStartIdx);
     405          25 :         Reorder1DForward(anCount);
     406          25 :     }
     407             : };
     408             : 
     409             : /************************************************************************/
     410             : /*                          ZarrV3CodecCRC32C                           */
     411             : /************************************************************************/
     412             : 
     413             : // Implements https://zarr-specs.readthedocs.io/en/latest/v3/codecs/crc32c/index.html
     414             : class ZarrV3CodecCRC32C final : public ZarrV3Codec
     415             : {
     416             :     bool m_bCheckCRC = true;
     417             : 
     418             :   public:
     419             :     static constexpr const char *NAME = "crc32c";
     420             : 
     421             :     ZarrV3CodecCRC32C();
     422             : 
     423         809 :     IOType GetInputType() const override
     424             :     {
     425         809 :         return IOType::BYTES;
     426             :     }
     427             : 
     428         809 :     IOType GetOutputType() const override
     429             :     {
     430         809 :         return IOType::BYTES;
     431             :     }
     432             : 
     433             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     434             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     435             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     436             :                                bool bEmitWarnings) override;
     437             : 
     438             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     439             : 
     440             :     bool Encode(const ZarrByteVectorQuickResize &abySrc,
     441             :                 ZarrByteVectorQuickResize &abyDst) const override;
     442             :     bool Decode(const ZarrByteVectorQuickResize &abySrc,
     443             :                 ZarrByteVectorQuickResize &abyDst) const override;
     444             : };
     445             : 
     446             : /************************************************************************/
     447             : /*                      ZarrV3CodecShardingIndexed                      */
     448             : /************************************************************************/
     449             : 
     450             : class ZarrV3CodecSequence;
     451             : 
     452             : // https://zarr-specs.readthedocs.io/en/latest/v3/codecs/sharding-indexed/index.html
     453             : class ZarrV3CodecShardingIndexed final : public ZarrV3Codec
     454             : {
     455             :     std::unique_ptr<ZarrV3CodecSequence> m_poCodecSequence{};
     456             :     std::unique_ptr<ZarrV3CodecSequence> m_poIndexCodecSequence{};
     457             :     bool m_bIndexLocationAtEnd = true;
     458             :     bool m_bIndexHasCRC32 = false;
     459             :     std::vector<size_t> m_anInnerBlockSize{};
     460             : 
     461             :     struct Location
     462             :     {
     463             :         uint64_t nOffset;
     464             :         uint64_t nSize;
     465             :     };
     466             : 
     467             :   public:
     468             :     static constexpr const char *NAME = "sharding_indexed";
     469             : 
     470             :     ZarrV3CodecShardingIndexed();
     471             : 
     472         688 :     IOType GetInputType() const override
     473             :     {
     474         688 :         return IOType::ARRAY;
     475             :     }
     476             : 
     477         670 :     IOType GetOutputType() const override
     478             :     {
     479         670 :         return IOType::BYTES;
     480             :     }
     481             : 
     482             :     bool InitFromConfiguration(const CPLJSONObject &configuration,
     483             :                                const ZarrArrayMetadata &oInputArrayMetadata,
     484             :                                ZarrArrayMetadata &oOutputArrayMetadata,
     485             :                                bool bEmitWarnings) override;
     486             : 
     487             :     std::unique_ptr<ZarrV3Codec> Clone() const override;
     488             : 
     489             :     bool Encode(const ZarrByteVectorQuickResize &abySrc,
     490             :                 ZarrByteVectorQuickResize &abyDst) const override;
     491             :     bool Decode(const ZarrByteVectorQuickResize &abySrc,
     492             :                 ZarrByteVectorQuickResize &abyDst) const override;
     493             : 
     494             :     bool DecodePartial(VSIVirtualHandle *poFile,
     495             :                        const ZarrByteVectorQuickResize &abySrc,
     496             :                        ZarrByteVectorQuickResize &abyDst,
     497             :                        std::vector<size_t> &anStartIdx,
     498             :                        std::vector<size_t> &anCount) override;
     499             : 
     500             :     /** Batch-read multiple inner chunks from the same shard via two
     501             :      *  ReadMultiRange() passes (index entries, then data), then decode.
     502             :      *  pszFilename is used as a cache key for the shard index; pass nullptr
     503             :      *  to bypass the cache.
     504             :      */
     505             :     bool BatchDecodePartial(
     506             :         VSIVirtualHandle *poFile, const char *pszFilename,
     507             :         const std::vector<std::pair<std::vector<size_t>, std::vector<size_t>>>
     508             :             &anRequests,
     509             :         std::vector<ZarrByteVectorQuickResize> &aResults);
     510             : 
     511             :     std::vector<size_t>
     512             :     GetInnerMostBlockSize(const std::vector<size_t> &input) const override;
     513             : };
     514             : 
     515             : /************************************************************************/
     516             : /*                         ZarrV3CodecSequence                          */
     517             : /************************************************************************/
     518             : 
     519             : class ZarrV3CodecSequence
     520             : {
     521             :     const ZarrArrayMetadata m_oInputArrayMetadata;
     522             :     std::vector<std::unique_ptr<ZarrV3Codec>> m_apoCodecs{};
     523             :     CPLJSONObject m_oCodecArray{};
     524             :     ZarrByteVectorQuickResize m_abyTmp{};
     525             :     bool m_bPartialDecodingPossible = false;
     526             : 
     527             :     bool AllocateBuffer(ZarrByteVectorQuickResize &abyBuffer, size_t nEltCount);
     528             : 
     529             :   public:
     530        2774 :     explicit ZarrV3CodecSequence(const ZarrArrayMetadata &oInputArrayMetadata)
     531        2774 :         : m_oInputArrayMetadata(oInputArrayMetadata)
     532             :     {
     533        2774 :     }
     534             : 
     535             :     // This method is not thread safe due to cloning a JSON object
     536             :     std::unique_ptr<ZarrV3CodecSequence> Clone() const;
     537             : 
     538             :     bool InitFromJson(const CPLJSONObject &oCodecs,
     539             :                       ZarrArrayMetadata &oOutputArrayMetadata);
     540             : 
     541         226 :     const CPLJSONObject &GetJSon() const
     542             :     {
     543         226 :         return m_oCodecArray;
     544             :     }
     545             : 
     546       10781 :     const std::vector<std::unique_ptr<ZarrV3Codec>> &GetCodecs() const
     547             :     {
     548       10781 :         return m_apoCodecs;
     549             :     }
     550             : 
     551       62083 :     bool SupportsPartialDecoding() const
     552             :     {
     553       62083 :         return m_bPartialDecodingPossible;
     554             :     }
     555             : 
     556             :     bool Encode(ZarrByteVectorQuickResize &abyBuffer);
     557             :     bool Decode(ZarrByteVectorQuickResize &abyBuffer);
     558             : 
     559             :     /** Partial decoding.
     560             :      * anStartIdx[i]: coordinate in pixel, within the array of an outer chunk,
     561             :      * that is < m_oInputArrayMetadata.anBlockSizes[i]
     562             :      * anCount[i]: number of pixels to extract <= m_oInputArrayMetadata.anBlockSizes[i]
     563             :      */
     564             :     bool DecodePartial(VSIVirtualHandle *poFile,
     565             :                        ZarrByteVectorQuickResize &abyBuffer,
     566             :                        const std::vector<size_t> &anStartIdx,
     567             :                        const std::vector<size_t> &anCount);
     568             : 
     569             :     /** Batch-read multiple inner chunks via ReadMultiRange().
     570             :      *  Delegates to the sharding codec if present, otherwise falls back
     571             :      *  to sequential DecodePartial() calls.
     572             :      *  pszFilename is forwarded to the sharding codec for index caching.
     573             :      */
     574             :     bool BatchDecodePartial(
     575             :         VSIVirtualHandle *poFile, const char *pszFilename,
     576             :         const std::vector<std::pair<std::vector<size_t>, std::vector<size_t>>>
     577             :             &anRequests,
     578             :         std::vector<ZarrByteVectorQuickResize> &aResults);
     579             : 
     580             :     std::vector<size_t>
     581             :     GetInnerMostBlockSize(const std::vector<size_t> &anOuterBlockSize) const;
     582             : };
     583             : 
     584             : #endif

Generated by: LCOV version 1.14