Coverage Report

Created: 2026-11-12 08:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}