LCOV - code coverage report
Current view: top level - frmts/zarr - zarr_v3_codec_bytes.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 48 67 71.6 %
Date: 2026-02-11 08:43:47 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Zarr driver, "bytes" codec
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "zarr_v3_codec.h"
      14             : 
      15             : // Implements https://zarr-specs.readthedocs.io/en/latest/v3/codecs/bytes/index.html
      16             : 
      17             : /************************************************************************/
      18             : /*                          ZarrV3CodecBytes()                          */
      19             : /************************************************************************/
      20             : 
      21        1800 : ZarrV3CodecBytes::ZarrV3CodecBytes() : ZarrV3Codec(NAME)
      22             : {
      23        1800 : }
      24             : 
      25             : /************************************************************************/
      26             : /*                          GetConfiguration()                          */
      27             : /************************************************************************/
      28             : 
      29         131 : /* static */ CPLJSONObject ZarrV3CodecBytes::GetConfiguration(bool bLittle)
      30             : {
      31         131 :     CPLJSONObject oConfig;
      32         131 :     oConfig.Add("endian", bLittle ? "little" : "big");
      33         131 :     return oConfig;
      34             : }
      35             : 
      36             : /************************************************************************/
      37             : /*              ZarrV3CodecBytes::InitFromConfiguration()               */
      38             : /************************************************************************/
      39             : 
      40        1800 : bool ZarrV3CodecBytes::InitFromConfiguration(
      41             :     const CPLJSONObject &configuration,
      42             :     const ZarrArrayMetadata &oInputArrayMetadata,
      43             :     ZarrArrayMetadata &oOutputArrayMetadata, bool /* bEmitWarnings */)
      44             : {
      45        1800 :     m_oConfiguration = configuration.Clone();
      46        1800 :     m_bLittle = true;
      47        1800 :     m_oInputArrayMetadata = oInputArrayMetadata;
      48        1800 :     oOutputArrayMetadata = oInputArrayMetadata;
      49             : 
      50        1800 :     if (configuration.IsValid())
      51             :     {
      52        1779 :         if (configuration.GetType() != CPLJSONObject::Type::Object)
      53             :         {
      54           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      55             :                      "Codec endian: configuration is not an object");
      56           0 :             return false;
      57             :         }
      58             : 
      59        3558 :         for (const auto &oChild : configuration.GetChildren())
      60             :         {
      61        1779 :             if (oChild.GetName() != "endian")
      62             :             {
      63           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
      64             :                          "Codec endian: configuration contains a unhandled "
      65             :                          "member: %s",
      66           0 :                          oChild.GetName().c_str());
      67           0 :                 return false;
      68             :             }
      69             :         }
      70             : 
      71        3558 :         const auto oEndian = configuration.GetObj("endian");
      72        1779 :         if (oEndian.IsValid())
      73             :         {
      74        1779 :             if (oEndian.GetType() != CPLJSONObject::Type::String)
      75             :             {
      76           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
      77             :                          "Codec gzip: endian is not a string");
      78           0 :                 return false;
      79             :             }
      80        1779 :             if (oEndian.ToString() == "little")
      81        1714 :                 m_bLittle = true;
      82          65 :             else if (oEndian.ToString() == "big")
      83          65 :                 m_bLittle = false;
      84             :             else
      85             :             {
      86           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
      87             :                          "Codec gzip: invalid value for endian");
      88           0 :                 return false;
      89             :             }
      90             :         }
      91             :     }
      92             : 
      93        1800 :     return true;
      94             : }
      95             : 
      96             : /************************************************************************/
      97             : /*                      ZarrV3CodecBytes::Clone()                       */
      98             : /************************************************************************/
      99             : 
     100           0 : std::unique_ptr<ZarrV3Codec> ZarrV3CodecBytes::Clone() const
     101             : {
     102           0 :     auto psClone = std::make_unique<ZarrV3CodecBytes>();
     103           0 :     ZarrArrayMetadata oOutputArrayMetadata;
     104           0 :     psClone->InitFromConfiguration(m_oConfiguration, m_oInputArrayMetadata,
     105             :                                    oOutputArrayMetadata,
     106             :                                    /* bEmitWarnings = */ false);
     107           0 :     return psClone;
     108             : }
     109             : 
     110             : /************************************************************************/
     111             : /*                      ZarrV3CodecBytes::Encode()                      */
     112             : /************************************************************************/
     113             : 
     114          53 : bool ZarrV3CodecBytes::Encode(const ZarrByteVectorQuickResize &abySrc,
     115             :                               ZarrByteVectorQuickResize &abyDst) const
     116             : {
     117          53 :     CPLAssert(!IsNoOp());
     118             : 
     119          53 :     size_t nEltCount = MultiplyElements(m_oInputArrayMetadata.anBlockSizes);
     120          53 :     size_t nNativeSize = m_oInputArrayMetadata.oElt.nativeSize;
     121          53 :     if (abySrc.size() < nEltCount * nNativeSize)
     122             :     {
     123           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     124             :                  "ZarrV3CodecBytes::Encode(): input buffer too small");
     125           0 :         return false;
     126             :     }
     127          53 :     CPLAssert(abySrc.size() >= nEltCount * nNativeSize);
     128          53 :     abyDst.resize(nEltCount * nNativeSize);
     129             : 
     130          53 :     const GByte *pabySrc = abySrc.data();
     131          53 :     GByte *pabyDst = abyDst.data();
     132             : 
     133          53 :     if (m_oInputArrayMetadata.oElt.nativeType ==
     134             :         DtypeElt::NativeType::COMPLEX_IEEEFP)
     135             :     {
     136           0 :         nEltCount *= 2;
     137           0 :         nNativeSize /= 2;
     138             :     }
     139          53 :     if (nNativeSize == 2)
     140             :     {
     141          36 :         for (size_t i = 0; i < nEltCount; ++i)
     142             :         {
     143          24 :             const uint16_t val = CPL_SWAP16(*reinterpret_cast<const uint16_t *>(
     144             :                 pabySrc + sizeof(uint16_t) * i));
     145          24 :             memcpy(pabyDst + sizeof(uint16_t) * i, &val, sizeof(val));
     146             :         }
     147             :     }
     148          41 :     else if (nNativeSize == 4)
     149             :     {
     150          54 :         for (size_t i = 0; i < nEltCount; ++i)
     151             :         {
     152          36 :             const uint32_t val = CPL_SWAP32(*reinterpret_cast<const uint32_t *>(
     153             :                 pabySrc + sizeof(uint32_t) * i));
     154          36 :             memcpy(pabyDst + sizeof(uint32_t) * i, &val, sizeof(val));
     155             :         }
     156             :     }
     157          23 :     else if (nNativeSize == 8)
     158             :     {
     159          75 :         for (size_t i = 0; i < nEltCount; ++i)
     160             :         {
     161          52 :             const uint64_t val = CPL_SWAP64(*reinterpret_cast<const uint64_t *>(
     162             :                 pabySrc + sizeof(uint64_t) * i));
     163          52 :             memcpy(pabyDst + sizeof(uint64_t) * i, &val, sizeof(val));
     164             :         }
     165             :     }
     166             :     else
     167             :     {
     168           0 :         CPLAssert(false);
     169             :     }
     170          53 :     return true;
     171             : }
     172             : 
     173             : /************************************************************************/
     174             : /*                      ZarrV3CodecBytes::Decode()                      */
     175             : /************************************************************************/
     176             : 
     177          29 : bool ZarrV3CodecBytes::Decode(const ZarrByteVectorQuickResize &abySrc,
     178             :                               ZarrByteVectorQuickResize &abyDst) const
     179             : {
     180          29 :     return Encode(abySrc, abyDst);
     181             : }

Generated by: LCOV version 1.14