Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: Zarr driver, "zstd" (extension) 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 : #include "cpl_compressor.h" 16 : 17 : // Implements https://github.com/zarr-developers/zarr-extensions/tree/main/codecs/zstd 18 : 19 : /************************************************************************/ 20 : /* ZarrV3CodecZstd() */ 21 : /************************************************************************/ 22 : 23 503 : ZarrV3CodecZstd::ZarrV3CodecZstd() : ZarrV3CodecAbstractCompressor(NAME) 24 : { 25 503 : } 26 : 27 : /************************************************************************/ 28 : /* GetConfiguration() */ 29 : /************************************************************************/ 30 : 31 2 : /* static */ CPLJSONObject ZarrV3CodecZstd::GetConfiguration(int nLevel, 32 : bool checksum) 33 : { 34 2 : CPLJSONObject oConfig; 35 2 : oConfig.Add("level", nLevel); 36 2 : oConfig.Add("checksum", checksum); 37 2 : return oConfig; 38 : } 39 : 40 : /************************************************************************/ 41 : /* ZarrV3CodecZstd::InitFromConfiguration() */ 42 : /************************************************************************/ 43 : 44 503 : bool ZarrV3CodecZstd::InitFromConfiguration( 45 : const CPLJSONObject &configuration, 46 : const ZarrArrayMetadata &oInputArrayMetadata, 47 : ZarrArrayMetadata &oOutputArrayMetadata, bool /* bEmitWarnings */) 48 : { 49 503 : m_pCompressor = CPLGetCompressor("zstd"); 50 503 : m_pDecompressor = CPLGetDecompressor("zstd"); 51 503 : if (!m_pCompressor || !m_pDecompressor) 52 : { 53 0 : CPLError(CE_Failure, CPLE_AppDefined, "zstd compressor not available"); 54 0 : return false; 55 : } 56 : 57 503 : m_oConfiguration = configuration.Clone(); 58 503 : m_oInputArrayMetadata = oInputArrayMetadata; 59 : // byte->byte codec 60 503 : oOutputArrayMetadata = oInputArrayMetadata; 61 : 62 503 : int nLevel = 13; 63 503 : bool bChecksum = false; 64 : 65 503 : if (configuration.IsValid()) 66 : { 67 503 : if (configuration.GetType() != CPLJSONObject::Type::Object) 68 : { 69 0 : CPLError(CE_Failure, CPLE_AppDefined, 70 : "Codec zstd: configuration is not an object"); 71 0 : return false; 72 : } 73 : 74 1509 : for (const auto &oChild : configuration.GetChildren()) 75 : { 76 1006 : if (oChild.GetName() != "level" && oChild.GetName() != "checksum") 77 : { 78 0 : CPLError( 79 : CE_Failure, CPLE_AppDefined, 80 : "Codec zstd: configuration contains a unhandled member: %s", 81 0 : oChild.GetName().c_str()); 82 0 : return false; 83 : } 84 : } 85 : 86 1006 : const auto oLevel = configuration.GetObj("level"); 87 503 : if (oLevel.IsValid()) 88 : { 89 503 : if (oLevel.GetType() != CPLJSONObject::Type::Integer) 90 : { 91 0 : CPLError(CE_Failure, CPLE_AppDefined, 92 : "Codec zstd: level is not an integer"); 93 0 : return false; 94 : } 95 503 : nLevel = oLevel.ToInteger(); 96 503 : if (nLevel < 0 || nLevel > 22) 97 : { 98 0 : CPLError(CE_Failure, CPLE_AppDefined, 99 : "Codec zstd: invalid value for level: %d", nLevel); 100 0 : return false; 101 : } 102 : } 103 : 104 1006 : const auto oChecksum = configuration.GetObj("checksum"); 105 503 : if (oChecksum.IsValid()) 106 : { 107 503 : if (oChecksum.GetType() != CPLJSONObject::Type::Boolean) 108 : { 109 0 : CPLError(CE_Failure, CPLE_AppDefined, 110 : "Codec zstd: checksum is not a boolean"); 111 0 : return false; 112 : } 113 503 : bChecksum = oChecksum.ToBool(); 114 : } 115 : } 116 : 117 503 : m_aosCompressorOptions.SetNameValue("LEVEL", CPLSPrintf("%d", nLevel)); 118 503 : if (bChecksum) 119 2 : m_aosCompressorOptions.SetNameValue("CHECKSUM", "YES"); 120 : 121 503 : return true; 122 : } 123 : 124 : /************************************************************************/ 125 : /* ZarrV3CodecZstd::Clone() */ 126 : /************************************************************************/ 127 : 128 0 : std::unique_ptr<ZarrV3Codec> ZarrV3CodecZstd::Clone() const 129 : { 130 0 : auto psClone = std::make_unique<ZarrV3CodecZstd>(); 131 0 : ZarrArrayMetadata oOutputArrayMetadata; 132 0 : psClone->InitFromConfiguration(m_oConfiguration, m_oInputArrayMetadata, 133 : oOutputArrayMetadata, 134 : /* bEmitWarnings = */ false); 135 0 : return psClone; 136 : }