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) 2025, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "zarr.h"
14 :
15 : #include "cpl_vsi.h"
16 : #include "gdal_priv.h"
17 :
18 : #include <cinttypes>
19 :
20 : /************************************************************************/
21 : /* ZarrTIFFDecompressor() */
22 : /************************************************************************/
23 :
24 4 : static bool ZarrTIFFDecompressor(const void *input_data, size_t input_size,
25 : void **output_data, size_t *output_size,
26 : CSLConstList /* options */,
27 : void * /* compressor_user_data */)
28 : {
29 4 : if (output_data != nullptr && *output_data != nullptr &&
30 4 : output_size != nullptr && *output_size != 0)
31 : {
32 : const std::string osTmpFilename =
33 8 : VSIMemGenerateHiddenFilename("tmp.tif");
34 4 : VSIFCloseL(VSIFileFromMemBuffer(
35 : osTmpFilename.c_str(),
36 : const_cast<GByte *>(static_cast<const GByte *>(input_data)),
37 : input_size, /* bTakeOwnership = */ false));
38 4 : const char *const apszDrivers[] = {"GTIFF", "LIBERTIFF", nullptr};
39 : auto poDS = std::unique_ptr<GDALDataset>(GDALDataset::Open(
40 : osTmpFilename.c_str(), GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR,
41 8 : apszDrivers, nullptr, nullptr));
42 4 : if (!poDS)
43 : {
44 1 : *output_size = 0;
45 1 : return false;
46 : }
47 :
48 3 : const int nBands = poDS->GetRasterCount();
49 3 : if (nBands != 1)
50 : {
51 : // This might be supported but I'm not sure which interleaving
52 : // should be returned !
53 1 : CPLError(CE_Failure, CPLE_NotSupported,
54 : "ZarrTIFFDecompressor(): more than 1 band not supported");
55 1 : *output_size = 0;
56 1 : return false;
57 : }
58 2 : const int nXSize = poDS->GetRasterXSize();
59 2 : const int nYSize = poDS->GetRasterYSize();
60 2 : const GDALDataType eDT = poDS->GetRasterBand(1)->GetRasterDataType();
61 2 : const int nDTSize = GDALGetDataTypeSizeBytes(eDT);
62 2 : if (static_cast<uint64_t>(nXSize) * nYSize * nDTSize != *output_size)
63 : {
64 1 : CPLError(CE_Failure, CPLE_AppDefined,
65 : "ZarrTIFFDecompressor(): %" PRIu64
66 : " bytes expected, but %" PRIu64 " would be returned",
67 : static_cast<uint64_t>(*output_size),
68 1 : static_cast<uint64_t>(nXSize) * nYSize * nDTSize);
69 1 : *output_size = 0;
70 1 : return false;
71 : }
72 :
73 1 : const bool bOK = poDS->GetRasterBand(1)->RasterIO(
74 : GF_Read, 0, 0, nXSize, nYSize, *output_data,
75 1 : nXSize, nYSize, eDT, 0, 0, nullptr) == CE_None;
76 : #ifdef CPL_MSB
77 : if (bOK && nDTSize > 1)
78 : {
79 : // Very likely we are expected to return in LSB order
80 : GDALSwapWordsEx(*output_data, nDTSize,
81 : static_cast<size_t>(nXSize) * nYSize, nDTSize);
82 : }
83 : #endif
84 1 : return bOK;
85 : }
86 :
87 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid use of API");
88 0 : return false;
89 : }
90 :
91 : /************************************************************************/
92 : /* ZarrGetTIFFDecompressor() */
93 : /************************************************************************/
94 :
95 5 : const CPLCompressor *ZarrGetTIFFDecompressor()
96 : {
97 : static const CPLCompressor gTIFFDecompressor = {
98 : /* nStructVersion = */ 1,
99 : /* pszId = */ "imagecodecs_tiff",
100 : CCT_COMPRESSOR,
101 : /* papszMetadata = */ nullptr,
102 : ZarrTIFFDecompressor,
103 : /* user_data = */ nullptr};
104 :
105 5 : return &gTIFFDecompressor;
106 : }
|