/src/gdal/frmts/zarr/zarr_compressors.cpp
Line | Count | Source |
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 | | 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 | 0 | { |
29 | 0 | if (output_data != nullptr && *output_data != nullptr && |
30 | 0 | output_size != nullptr && *output_size != 0) |
31 | 0 | { |
32 | 0 | const std::string osTmpFilename = |
33 | 0 | VSIMemGenerateHiddenFilename("tmp.tif"); |
34 | 0 | VSIFCloseL(VSIFileFromMemBuffer( |
35 | 0 | osTmpFilename.c_str(), |
36 | 0 | const_cast<GByte *>(static_cast<const GByte *>(input_data)), |
37 | 0 | input_size, /* bTakeOwnership = */ false)); |
38 | 0 | const char *const apszDrivers[] = {"GTIFF", "LIBERTIFF", nullptr}; |
39 | 0 | auto poDS = std::unique_ptr<GDALDataset>(GDALDataset::Open( |
40 | 0 | osTmpFilename.c_str(), GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR, |
41 | 0 | apszDrivers, nullptr, nullptr)); |
42 | 0 | if (!poDS) |
43 | 0 | { |
44 | 0 | *output_size = 0; |
45 | 0 | return false; |
46 | 0 | } |
47 | | |
48 | 0 | const int nBands = poDS->GetRasterCount(); |
49 | 0 | if (nBands != 1) |
50 | 0 | { |
51 | | // This might be supported but I'm not sure which interleaving |
52 | | // should be returned ! |
53 | 0 | CPLError(CE_Failure, CPLE_NotSupported, |
54 | 0 | "ZarrTIFFDecompressor(): more than 1 band not supported"); |
55 | 0 | *output_size = 0; |
56 | 0 | return false; |
57 | 0 | } |
58 | 0 | const int nXSize = poDS->GetRasterXSize(); |
59 | 0 | const int nYSize = poDS->GetRasterYSize(); |
60 | 0 | const GDALDataType eDT = poDS->GetRasterBand(1)->GetRasterDataType(); |
61 | 0 | const int nDTSize = GDALGetDataTypeSizeBytes(eDT); |
62 | 0 | if (static_cast<uint64_t>(nXSize) * nYSize * nDTSize != *output_size) |
63 | 0 | { |
64 | 0 | CPLError(CE_Failure, CPLE_AppDefined, |
65 | 0 | "ZarrTIFFDecompressor(): %" PRIu64 |
66 | 0 | " bytes expected, but %" PRIu64 " would be returned", |
67 | 0 | static_cast<uint64_t>(*output_size), |
68 | 0 | static_cast<uint64_t>(nXSize) * nYSize * nDTSize); |
69 | 0 | *output_size = 0; |
70 | 0 | return false; |
71 | 0 | } |
72 | | |
73 | 0 | const bool bOK = poDS->GetRasterBand(1)->RasterIO( |
74 | 0 | GF_Read, 0, 0, nXSize, nYSize, *output_data, |
75 | 0 | 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 | 0 | return bOK; |
85 | 0 | } |
86 | | |
87 | 0 | CPLError(CE_Failure, CPLE_AppDefined, "Invalid use of API"); |
88 | 0 | return false; |
89 | 0 | } |
90 | | |
91 | | /************************************************************************/ |
92 | | /* ZarrGetTIFFDecompressor() */ |
93 | | /************************************************************************/ |
94 | | |
95 | | const CPLCompressor *ZarrGetTIFFDecompressor() |
96 | 0 | { |
97 | 0 | static const CPLCompressor gTIFFDecompressor = { |
98 | 0 | /* nStructVersion = */ 1, |
99 | 0 | /* pszId = */ "imagecodecs_tiff", |
100 | 0 | CCT_COMPRESSOR, |
101 | 0 | /* papszMetadata = */ nullptr, |
102 | 0 | ZarrTIFFDecompressor, |
103 | 0 | /* user_data = */ nullptr}; |
104 | |
|
105 | 0 | return &gTIFFDecompressor; |
106 | 0 | } |