Coverage Report

Created: 2026-11-12 08:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/gtiff/libtiff/tif_lerc.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2018, Even Rouault
3
 * Author: <even.rouault at spatialys.com>
4
 *
5
 * Permission to use, copy, modify, distribute, and sell this software and
6
 * its documentation for any purpose is hereby granted without fee, provided
7
 * that (i) the above copyright notices and this permission notice appear in
8
 * all copies of the software and related documentation, and (ii) the names of
9
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10
 * publicity relating to the software without the specific, prior written
11
 * permission of Sam Leffler and Silicon Graphics.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
 *
17
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22
 * OF THIS SOFTWARE.
23
 */
24
25
#include "tiffiop.h"
26
#ifdef LERC_SUPPORT
27
/*
28
 * TIFF Library.
29
 *
30
 * LERC Compression Support
31
 *
32
 */
33
34
#include "Lerc_c_api.h"
35
#include "zlib.h"
36
#include <math.h>
37
#ifdef ZSTD_SUPPORT
38
#include "zstd.h"
39
#endif
40
41
#if LIBDEFLATE_SUPPORT
42
#include "libdeflate.h"
43
#endif
44
0
#define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
45
46
#include <assert.h>
47
48
26.2k
#define LSTATE_INIT_DECODE 0x01
49
5.08k
#define LSTATE_INIT_ENCODE 0x02
50
51
#ifndef LERC_AT_LEAST_VERSION
52
#define LERC_AT_LEAST_VERSION(maj, min, patch) 0
53
#endif
54
55
/*
56
 * State block for each open TIFF file using LERC compression/decompression.
57
 */
58
typedef struct
59
{
60
    double maxzerror; /* max z error */
61
    int lerc_version;
62
    int additional_compression;
63
    int zstd_compress_level; /* zstd */
64
    int zipquality;          /* deflate */
65
    int state;               /* state flags */
66
67
    uint32_t segment_width;
68
    uint32_t segment_height;
69
70
    unsigned int uncompressed_size;
71
    unsigned int uncompressed_alloc;
72
    uint8_t *uncompressed_buffer;
73
    unsigned int uncompressed_offset;
74
75
    uint8_t *uncompressed_buffer_multiband;
76
    unsigned int uncompressed_buffer_multiband_alloc;
77
78
    unsigned int mask_size;
79
    uint8_t *mask_buffer;
80
81
    unsigned int compressed_size;
82
    void *compressed_buffer;
83
84
#if LIBDEFLATE_SUPPORT
85
    struct libdeflate_decompressor *libdeflate_dec;
86
    struct libdeflate_compressor *libdeflate_enc;
87
#endif
88
89
    TIFFVGetMethod vgetparent; /* super-class method */
90
    TIFFVSetMethod vsetparent; /* super-class method */
91
} LERCState;
92
93
1.50M
#define GetLERCState(tif) ((LERCState *)(tif)->tif_data)
94
36.9k
#define LERCDecoderState(tif) GetLERCState(tif)
95
0
#define LERCEncoderState(tif) GetLERCState(tif)
96
97
static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
98
99
static int LERCFixupTags(TIFF *tif)
100
23.2k
{
101
23.2k
    (void)tif;
102
23.2k
    return 1;
103
23.2k
}
tif_lerc.c:gdal_LERCFixupTags
Line
Count
Source
100
23.2k
{
101
23.2k
    (void)tif;
102
23.2k
    return 1;
103
23.2k
}
Unexecuted instantiation: libertiffdataset.cpp:LERCFixupTags(tiff*)
104
105
static int LERCSetupDecode(TIFF *tif)
106
5.08k
{
107
5.08k
    LERCState *sp = LERCDecoderState(tif);
108
109
5.08k
    assert(sp != NULL);
110
111
    /* if we were last encoding, terminate this mode */
112
5.08k
    if (sp->state & LSTATE_INIT_ENCODE)
113
0
    {
114
0
        sp->state = 0;
115
0
    }
116
117
5.08k
    sp->state |= LSTATE_INIT_DECODE;
118
5.08k
    return 1;
119
5.08k
}
tif_lerc.c:gdal_LERCSetupDecode
Line
Count
Source
106
2.23k
{
107
2.23k
    LERCState *sp = LERCDecoderState(tif);
108
109
2.23k
    assert(sp != NULL);
110
111
    /* if we were last encoding, terminate this mode */
112
2.23k
    if (sp->state & LSTATE_INIT_ENCODE)
113
0
    {
114
0
        sp->state = 0;
115
0
    }
116
117
2.23k
    sp->state |= LSTATE_INIT_DECODE;
118
2.23k
    return 1;
119
2.23k
}
libertiffdataset.cpp:LERCSetupDecode(tiff*)
Line
Count
Source
106
2.85k
{
107
2.85k
    LERCState *sp = LERCDecoderState(tif);
108
109
2.85k
    assert(sp != NULL);
110
111
    /* if we were last encoding, terminate this mode */
112
2.85k
    if (sp->state & LSTATE_INIT_ENCODE)
113
0
    {
114
0
        sp->state = 0;
115
0
    }
116
117
2.85k
    sp->state |= LSTATE_INIT_DECODE;
118
2.85k
    return 1;
119
2.85k
}
120
121
static int GetLercDataType(TIFF *tif)
122
27.8k
{
123
27.8k
    TIFFDirectory *td = &tif->tif_dir;
124
27.8k
    static const char module[] = "GetLercDataType";
125
126
27.8k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8)
127
4.18k
    {
128
4.18k
        return 0;
129
4.18k
    }
130
131
23.7k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8)
132
18.3k
    {
133
18.3k
        return 1;
134
18.3k
    }
135
136
5.38k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16)
137
757
    {
138
757
        return 2;
139
757
    }
140
141
4.62k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16)
142
1.26k
    {
143
1.26k
        return 3;
144
1.26k
    }
145
146
3.35k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32)
147
1.19k
    {
148
1.19k
        return 4;
149
1.19k
    }
150
151
2.16k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32)
152
1.45k
    {
153
1.45k
        return 5;
154
1.45k
    }
155
156
714
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
157
526
        td->td_bitspersample == 32)
158
276
    {
159
276
        return 6;
160
276
    }
161
162
438
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
163
250
        td->td_bitspersample == 64)
164
187
    {
165
187
        return 7;
166
187
    }
167
168
251
    TIFFErrorExtR(
169
251
        tif, module,
170
251
        "Unsupported combination of SampleFormat and td_bitspersample");
171
251
    return -1;
172
438
}
tif_lerc.c:gdal_GetLercDataType
Line
Count
Source
122
9.85k
{
123
9.85k
    TIFFDirectory *td = &tif->tif_dir;
124
9.85k
    static const char module[] = "GetLercDataType";
125
126
9.85k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8)
127
2.78k
    {
128
2.78k
        return 0;
129
2.78k
    }
130
131
7.07k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8)
132
5.85k
    {
133
5.85k
        return 1;
134
5.85k
    }
135
136
1.22k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16)
137
101
    {
138
101
        return 2;
139
101
    }
140
141
1.12k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16)
142
191
    {
143
191
        return 3;
144
191
    }
145
146
934
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32)
147
139
    {
148
139
        return 4;
149
139
    }
150
151
795
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32)
152
412
    {
153
412
        return 5;
154
412
    }
155
156
383
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
157
241
        td->td_bitspersample == 32)
158
108
    {
159
108
        return 6;
160
108
    }
161
162
275
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
163
133
        td->td_bitspersample == 64)
164
70
    {
165
70
        return 7;
166
70
    }
167
168
205
    TIFFErrorExtR(
169
205
        tif, module,
170
205
        "Unsupported combination of SampleFormat and td_bitspersample");
171
205
    return -1;
172
275
}
libertiffdataset.cpp:GetLercDataType(tiff*)
Line
Count
Source
122
18.0k
{
123
18.0k
    TIFFDirectory *td = &tif->tif_dir;
124
18.0k
    static const char module[] = "GetLercDataType";
125
126
18.0k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8)
127
1.40k
    {
128
1.40k
        return 0;
129
1.40k
    }
130
131
16.6k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8)
132
12.4k
    {
133
12.4k
        return 1;
134
12.4k
    }
135
136
4.15k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16)
137
656
    {
138
656
        return 2;
139
656
    }
140
141
3.49k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16)
142
1.07k
    {
143
1.07k
        return 3;
144
1.07k
    }
145
146
2.42k
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32)
147
1.05k
    {
148
1.05k
        return 4;
149
1.05k
    }
150
151
1.37k
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32)
152
1.03k
    {
153
1.03k
        return 5;
154
1.03k
    }
155
156
331
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
157
285
        td->td_bitspersample == 32)
158
168
    {
159
168
        return 6;
160
168
    }
161
162
163
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
163
117
        td->td_bitspersample == 64)
164
117
    {
165
117
        return 7;
166
117
    }
167
168
46
    TIFFErrorExtR(
169
46
        tif, module,
170
46
        "Unsupported combination of SampleFormat and td_bitspersample");
171
46
    return -1;
172
163
}
173
174
static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
175
20.8k
{
176
20.8k
    TIFFDirectory *td = &tif->tif_dir;
177
20.8k
    uint64_t new_size_64;
178
20.8k
    uint64_t new_alloc_64;
179
20.8k
    unsigned int new_size;
180
20.8k
    unsigned int new_alloc;
181
182
20.8k
    sp->uncompressed_offset = 0;
183
184
20.8k
    if (isTiled(tif))
185
1.15k
    {
186
1.15k
        sp->segment_width = td->td_tilewidth;
187
1.15k
        sp->segment_height = td->td_tilelength;
188
1.15k
    }
189
19.7k
    else
190
19.7k
    {
191
19.7k
        sp->segment_width = td->td_imagewidth;
192
19.7k
        sp->segment_height = td->td_imagelength - tif->tif_dir.td_row;
193
19.7k
        if (sp->segment_height > td->td_rowsperstrip)
194
11.2k
            sp->segment_height = td->td_rowsperstrip;
195
19.7k
    }
196
197
20.8k
    new_size_64 = (uint64_t)sp->segment_width * sp->segment_height *
198
20.8k
                  (td->td_bitspersample / 8);
199
20.8k
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
200
17.5k
    {
201
17.5k
        new_size_64 *= td->td_samplesperpixel;
202
17.5k
    }
203
204
20.8k
    new_size = (unsigned int)new_size_64;
205
20.8k
    sp->uncompressed_size = new_size;
206
207
    /* add some margin as we are going to use it also to store deflate/zstd
208
     * compressed data. We also need extra margin when writing very small
209
     * rasters with one mask per band. */
210
20.8k
    new_alloc_64 = 256 + new_size_64 + new_size_64 / 3;
211
20.8k
#ifdef ZSTD_SUPPORT
212
20.8k
    {
213
20.8k
        size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
214
20.8k
        if (new_alloc_64 < zstd_max)
215
0
        {
216
0
            new_alloc_64 = zstd_max;
217
0
        }
218
20.8k
    }
219
20.8k
#endif
220
20.8k
    new_alloc = (unsigned int)new_alloc_64;
221
20.8k
    if (new_alloc != new_alloc_64)
222
0
    {
223
0
        TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile");
224
0
        _TIFFfreeExt(tif, sp->uncompressed_buffer);
225
0
        sp->uncompressed_buffer = NULL;
226
0
        sp->uncompressed_alloc = 0;
227
0
        return 0;
228
0
    }
229
230
20.8k
    if (sp->uncompressed_alloc < new_alloc)
231
5.03k
    {
232
5.03k
        _TIFFfreeExt(tif, sp->uncompressed_buffer);
233
5.03k
        sp->uncompressed_buffer = (uint8_t *)_TIFFmallocExt(tif, new_alloc);
234
5.03k
        if (!sp->uncompressed_buffer)
235
0
        {
236
0
            TIFFErrorExtR(tif, module, "Cannot allocate buffer");
237
0
            _TIFFfreeExt(tif, sp->uncompressed_buffer);
238
0
            sp->uncompressed_buffer = NULL;
239
0
            sp->uncompressed_alloc = 0;
240
0
            return 0;
241
0
        }
242
5.03k
        sp->uncompressed_alloc = new_alloc;
243
5.03k
    }
244
245
20.8k
    if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
246
17.5k
         td->td_extrasamples > 0 && td->td_sampleinfo &&
247
8.26k
         td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
248
3.00k
         GetLercDataType(tif) == 1) ||
249
18.3k
        (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
250
368
         (td->td_bitspersample == 32 || td->td_bitspersample == 64)))
251
2.95k
    {
252
2.95k
        unsigned int mask_size = sp->segment_width * sp->segment_height;
253
#if LERC_AT_LEAST_VERSION(3, 0, 0)
254
        if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
255
            td->td_planarconfig == PLANARCONFIG_CONTIG)
256
        {
257
            /* We may need one mask per band */
258
            mask_size *= td->td_samplesperpixel;
259
        }
260
#endif
261
2.95k
        if (sp->mask_size < mask_size)
262
486
        {
263
486
            void *mask_buffer =
264
486
                _TIFFreallocExt(tif, sp->mask_buffer, mask_size);
265
486
            if (mask_buffer == NULL)
266
0
            {
267
0
                TIFFErrorExtR(tif, module, "Cannot allocate buffer");
268
0
                sp->mask_size = 0;
269
0
                _TIFFfreeExt(tif, sp->uncompressed_buffer);
270
0
                sp->uncompressed_buffer = NULL;
271
0
                sp->uncompressed_alloc = 0;
272
0
                return 0;
273
0
            }
274
486
            sp->mask_buffer = (uint8_t *)mask_buffer;
275
486
            sp->mask_size = mask_size;
276
486
        }
277
2.95k
    }
278
279
20.8k
    return 1;
280
20.8k
}
tif_lerc.c:gdal_SetupBuffers
Line
Count
Source
175
7.85k
{
176
7.85k
    TIFFDirectory *td = &tif->tif_dir;
177
7.85k
    uint64_t new_size_64;
178
7.85k
    uint64_t new_alloc_64;
179
7.85k
    unsigned int new_size;
180
7.85k
    unsigned int new_alloc;
181
182
7.85k
    sp->uncompressed_offset = 0;
183
184
7.85k
    if (isTiled(tif))
185
551
    {
186
551
        sp->segment_width = td->td_tilewidth;
187
551
        sp->segment_height = td->td_tilelength;
188
551
    }
189
7.30k
    else
190
7.30k
    {
191
7.30k
        sp->segment_width = td->td_imagewidth;
192
7.30k
        sp->segment_height = td->td_imagelength - tif->tif_dir.td_row;
193
7.30k
        if (sp->segment_height > td->td_rowsperstrip)
194
1.72k
            sp->segment_height = td->td_rowsperstrip;
195
7.30k
    }
196
197
7.85k
    new_size_64 = (uint64_t)sp->segment_width * sp->segment_height *
198
7.85k
                  (td->td_bitspersample / 8);
199
7.85k
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
200
7.35k
    {
201
7.35k
        new_size_64 *= td->td_samplesperpixel;
202
7.35k
    }
203
204
7.85k
    new_size = (unsigned int)new_size_64;
205
7.85k
    sp->uncompressed_size = new_size;
206
207
    /* add some margin as we are going to use it also to store deflate/zstd
208
     * compressed data. We also need extra margin when writing very small
209
     * rasters with one mask per band. */
210
7.85k
    new_alloc_64 = 256 + new_size_64 + new_size_64 / 3;
211
7.85k
#ifdef ZSTD_SUPPORT
212
7.85k
    {
213
7.85k
        size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
214
7.85k
        if (new_alloc_64 < zstd_max)
215
0
        {
216
0
            new_alloc_64 = zstd_max;
217
0
        }
218
7.85k
    }
219
7.85k
#endif
220
7.85k
    new_alloc = (unsigned int)new_alloc_64;
221
7.85k
    if (new_alloc != new_alloc_64)
222
0
    {
223
0
        TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile");
224
0
        _TIFFfreeExt(tif, sp->uncompressed_buffer);
225
0
        sp->uncompressed_buffer = NULL;
226
0
        sp->uncompressed_alloc = 0;
227
0
        return 0;
228
0
    }
229
230
7.85k
    if (sp->uncompressed_alloc < new_alloc)
231
2.17k
    {
232
2.17k
        _TIFFfreeExt(tif, sp->uncompressed_buffer);
233
2.17k
        sp->uncompressed_buffer = (uint8_t *)_TIFFmallocExt(tif, new_alloc);
234
2.17k
        if (!sp->uncompressed_buffer)
235
0
        {
236
0
            TIFFErrorExtR(tif, module, "Cannot allocate buffer");
237
0
            _TIFFfreeExt(tif, sp->uncompressed_buffer);
238
0
            sp->uncompressed_buffer = NULL;
239
0
            sp->uncompressed_alloc = 0;
240
0
            return 0;
241
0
        }
242
2.17k
        sp->uncompressed_alloc = new_alloc;
243
2.17k
    }
244
245
7.85k
    if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
246
7.35k
         td->td_extrasamples > 0 && td->td_sampleinfo &&
247
6.36k
         td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
248
1.15k
         GetLercDataType(tif) == 1) ||
249
6.93k
        (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
250
154
         (td->td_bitspersample == 32 || td->td_bitspersample == 64)))
251
1.08k
    {
252
1.08k
        unsigned int mask_size = sp->segment_width * sp->segment_height;
253
#if LERC_AT_LEAST_VERSION(3, 0, 0)
254
        if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
255
            td->td_planarconfig == PLANARCONFIG_CONTIG)
256
        {
257
            /* We may need one mask per band */
258
            mask_size *= td->td_samplesperpixel;
259
        }
260
#endif
261
1.08k
        if (sp->mask_size < mask_size)
262
322
        {
263
322
            void *mask_buffer =
264
322
                _TIFFreallocExt(tif, sp->mask_buffer, mask_size);
265
322
            if (mask_buffer == NULL)
266
0
            {
267
0
                TIFFErrorExtR(tif, module, "Cannot allocate buffer");
268
0
                sp->mask_size = 0;
269
0
                _TIFFfreeExt(tif, sp->uncompressed_buffer);
270
0
                sp->uncompressed_buffer = NULL;
271
0
                sp->uncompressed_alloc = 0;
272
0
                return 0;
273
0
            }
274
322
            sp->mask_buffer = (uint8_t *)mask_buffer;
275
322
            sp->mask_size = mask_size;
276
322
        }
277
1.08k
    }
278
279
7.85k
    return 1;
280
7.85k
}
libertiffdataset.cpp:SetupBuffers(tiff*, LERCState*, char const*)
Line
Count
Source
175
13.0k
{
176
13.0k
    TIFFDirectory *td = &tif->tif_dir;
177
13.0k
    uint64_t new_size_64;
178
13.0k
    uint64_t new_alloc_64;
179
13.0k
    unsigned int new_size;
180
13.0k
    unsigned int new_alloc;
181
182
13.0k
    sp->uncompressed_offset = 0;
183
184
13.0k
    if (isTiled(tif))
185
608
    {
186
608
        sp->segment_width = td->td_tilewidth;
187
608
        sp->segment_height = td->td_tilelength;
188
608
    }
189
12.4k
    else
190
12.4k
    {
191
12.4k
        sp->segment_width = td->td_imagewidth;
192
12.4k
        sp->segment_height = td->td_imagelength - tif->tif_dir.td_row;
193
12.4k
        if (sp->segment_height > td->td_rowsperstrip)
194
9.52k
            sp->segment_height = td->td_rowsperstrip;
195
12.4k
    }
196
197
13.0k
    new_size_64 = (uint64_t)sp->segment_width * sp->segment_height *
198
13.0k
                  (td->td_bitspersample / 8);
199
13.0k
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
200
10.1k
    {
201
10.1k
        new_size_64 *= td->td_samplesperpixel;
202
10.1k
    }
203
204
13.0k
    new_size = (unsigned int)new_size_64;
205
13.0k
    sp->uncompressed_size = new_size;
206
207
    /* add some margin as we are going to use it also to store deflate/zstd
208
     * compressed data. We also need extra margin when writing very small
209
     * rasters with one mask per band. */
210
13.0k
    new_alloc_64 = 256 + new_size_64 + new_size_64 / 3;
211
13.0k
#ifdef ZSTD_SUPPORT
212
13.0k
    {
213
13.0k
        size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
214
13.0k
        if (new_alloc_64 < zstd_max)
215
0
        {
216
0
            new_alloc_64 = zstd_max;
217
0
        }
218
13.0k
    }
219
13.0k
#endif
220
13.0k
    new_alloc = (unsigned int)new_alloc_64;
221
13.0k
    if (new_alloc != new_alloc_64)
222
0
    {
223
0
        TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile");
224
0
        _TIFFfreeExt(tif, sp->uncompressed_buffer);
225
0
        sp->uncompressed_buffer = NULL;
226
0
        sp->uncompressed_alloc = 0;
227
0
        return 0;
228
0
    }
229
230
13.0k
    if (sp->uncompressed_alloc < new_alloc)
231
2.85k
    {
232
2.85k
        _TIFFfreeExt(tif, sp->uncompressed_buffer);
233
2.85k
        sp->uncompressed_buffer = (uint8_t *)_TIFFmallocExt(tif, new_alloc);
234
2.85k
        if (!sp->uncompressed_buffer)
235
0
        {
236
0
            TIFFErrorExtR(tif, module, "Cannot allocate buffer");
237
0
            _TIFFfreeExt(tif, sp->uncompressed_buffer);
238
0
            sp->uncompressed_buffer = NULL;
239
0
            sp->uncompressed_alloc = 0;
240
0
            return 0;
241
0
        }
242
2.85k
        sp->uncompressed_alloc = new_alloc;
243
2.85k
    }
244
245
13.0k
    if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
246
10.1k
         td->td_extrasamples > 0 && td->td_sampleinfo &&
247
1.89k
         td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
248
1.85k
         GetLercDataType(tif) == 1) ||
249
11.3k
        (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
250
214
         (td->td_bitspersample == 32 || td->td_bitspersample == 64)))
251
1.87k
    {
252
1.87k
        unsigned int mask_size = sp->segment_width * sp->segment_height;
253
#if LERC_AT_LEAST_VERSION(3, 0, 0)
254
        if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
255
            td->td_planarconfig == PLANARCONFIG_CONTIG)
256
        {
257
            /* We may need one mask per band */
258
            mask_size *= td->td_samplesperpixel;
259
        }
260
#endif
261
1.87k
        if (sp->mask_size < mask_size)
262
164
        {
263
164
            void *mask_buffer =
264
164
                _TIFFreallocExt(tif, sp->mask_buffer, mask_size);
265
164
            if (mask_buffer == NULL)
266
0
            {
267
0
                TIFFErrorExtR(tif, module, "Cannot allocate buffer");
268
0
                sp->mask_size = 0;
269
0
                _TIFFfreeExt(tif, sp->uncompressed_buffer);
270
0
                sp->uncompressed_buffer = NULL;
271
0
                sp->uncompressed_alloc = 0;
272
0
                return 0;
273
0
            }
274
164
            sp->mask_buffer = (uint8_t *)mask_buffer;
275
164
            sp->mask_size = mask_size;
276
164
        }
277
1.87k
    }
278
279
13.0k
    return 1;
280
13.0k
}
281
282
/*
283
 * Setup state for decoding a strip.
284
 */
285
static int LERCPreDecode(TIFF *tif, uint16_t s)
286
21.1k
{
287
21.1k
    static const char module[] = "LERCPreDecode";
288
21.1k
    lerc_status lerc_ret;
289
21.1k
    TIFFDirectory *td = &tif->tif_dir;
290
21.1k
    LERCState *sp = LERCDecoderState(tif);
291
21.1k
    int lerc_data_type;
292
21.1k
    unsigned int infoArray[9];
293
21.1k
    unsigned nomask_bands = td->td_samplesperpixel;
294
21.1k
    int ndims;
295
21.1k
    int use_mask = 0;
296
21.1k
    uint8_t *lerc_data = tif->tif_rawcp;
297
21.1k
    unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc;
298
299
21.1k
    (void)s;
300
21.1k
    assert(sp != NULL);
301
21.1k
    if (sp->state != LSTATE_INIT_DECODE)
302
2.85k
        tif->tif_setupdecode(tif);
303
304
21.1k
    lerc_data_type = GetLercDataType(tif);
305
21.1k
    if (lerc_data_type < 0)
306
251
        return 0;
307
308
20.8k
    if (!SetupBuffers(tif, sp, module))
309
0
        return 0;
310
311
20.8k
    if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
312
1.48k
    {
313
1.48k
        if (sp->compressed_size < sp->uncompressed_alloc)
314
264
        {
315
264
            _TIFFfreeExt(tif, sp->compressed_buffer);
316
264
            sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc);
317
264
            if (!sp->compressed_buffer)
318
0
            {
319
0
                sp->compressed_size = 0;
320
0
                return 0;
321
0
            }
322
264
            sp->compressed_size = sp->uncompressed_alloc;
323
264
        }
324
1.48k
    }
325
326
20.8k
    if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
327
496
    {
328
496
#if LIBDEFLATE_SUPPORT
329
496
        enum libdeflate_result res;
330
496
        size_t lerc_data_sizet = 0;
331
496
        if (sp->libdeflate_dec == NULL)
332
71
        {
333
71
            sp->libdeflate_dec = libdeflate_alloc_decompressor();
334
71
            if (sp->libdeflate_dec == NULL)
335
0
            {
336
0
                TIFFErrorExtR(tif, module, "Cannot allocate decompressor");
337
0
                return 0;
338
0
            }
339
71
        }
340
341
496
        res = libdeflate_zlib_decompress(
342
496
            sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc,
343
496
            sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet);
344
496
        if (res != LIBDEFLATE_SUCCESS)
345
98
        {
346
98
            TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
347
98
                          (unsigned long)tif->tif_dir.td_row);
348
98
            return 0;
349
98
        }
350
496
        assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
351
398
        lerc_data = (uint8_t *)sp->compressed_buffer;
352
398
        lerc_data_size = (unsigned int)lerc_data_sizet;
353
#else
354
        z_stream strm;
355
        int zlib_ret;
356
357
        memset(&strm, 0, sizeof(strm));
358
        strm.zalloc = NULL;
359
        strm.zfree = NULL;
360
        strm.opaque = NULL;
361
        zlib_ret = inflateInit(&strm);
362
        if (zlib_ret != Z_OK)
363
        {
364
            TIFFErrorExtR(tif, module, "inflateInit() failed");
365
            inflateEnd(&strm);
366
            return 0;
367
        }
368
369
        strm.avail_in = (uInt)tif->tif_rawcc;
370
        strm.next_in = tif->tif_rawcp;
371
        strm.avail_out = sp->compressed_size;
372
        strm.next_out = (Bytef *)sp->compressed_buffer;
373
        zlib_ret = inflate(&strm, Z_FINISH);
374
        if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK)
375
        {
376
            TIFFErrorExtR(tif, module, "inflate() failed");
377
            inflateEnd(&strm);
378
            return 0;
379
        }
380
        lerc_data = (uint8_t *)sp->compressed_buffer;
381
        lerc_data_size = sp->compressed_size - strm.avail_out;
382
        inflateEnd(&strm);
383
#endif
384
398
    }
385
20.3k
    else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
386
164
    {
387
164
#ifdef ZSTD_SUPPORT
388
164
        size_t zstd_ret;
389
390
164
        zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
391
164
                                   tif->tif_rawcp, (size_t)tif->tif_rawcc);
392
164
        if (ZSTD_isError(zstd_ret))
393
57
        {
394
57
            TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
395
57
                          ZSTD_getErrorName(zstd_ret));
396
57
            return 0;
397
57
        }
398
399
107
        lerc_data = (uint8_t *)sp->compressed_buffer;
400
107
        lerc_data_size = (unsigned int)zstd_ret;
401
#else
402
        TIFFErrorExtR(tif, module, "ZSTD support missing");
403
        return 0;
404
#endif
405
107
    }
406
20.2k
    else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
407
823
    {
408
823
        TIFFErrorExtR(tif, module, "Unhandled additional compression");
409
823
        return 0;
410
823
    }
411
412
19.9k
    lerc_ret =
413
19.9k
        lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 9, 0);
414
19.9k
    if (lerc_ret != 0)
415
6.24k
    {
416
6.24k
        TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed");
417
6.24k
        return 0;
418
6.24k
    }
419
420
    /* If the configuration is compatible of a LERC mask, and that the */
421
    /* LERC info has dim == samplesperpixel - 1, then there is a LERC */
422
    /* mask. */
423
13.6k
    if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
424
6.15k
        td->td_sampleinfo &&
425
6.15k
        td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
426
2.28k
        GetLercDataType(tif) == 1 &&
427
2.20k
        infoArray[2] == td->td_samplesperpixel - 1U)
428
2.02k
    {
429
2.02k
        use_mask = 1;
430
2.02k
        nomask_bands--;
431
2.02k
    }
432
11.6k
    else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
433
42
    {
434
42
        use_mask = 1;
435
42
    }
436
437
13.6k
    ndims =
438
13.6k
        (int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1);
439
440
    /* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
441
        nRows, nBands, nValidPixels, blobSize,
442
        and starting with liblerc 3.0 nRequestedMasks } */
443
13.6k
    if (infoArray[0] != (unsigned)sp->lerc_version)
444
3.35k
    {
445
3.35k
        TIFFWarningExtR(tif, module,
446
3.35k
                        "Unexpected version number: %u. Expected: %d",
447
3.35k
                        infoArray[0], sp->lerc_version);
448
3.35k
    }
449
13.6k
    if (infoArray[1] != (unsigned)lerc_data_type)
450
421
    {
451
421
        TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d",
452
421
                      infoArray[1], lerc_data_type);
453
421
        return 0;
454
421
    }
455
456
13.2k
    const unsigned nFoundDims = infoArray[2];
457
#if LERC_AT_LEAST_VERSION(3, 0, 0)
458
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
459
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
460
        td->td_samplesperpixel > 1)
461
    {
462
        if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
463
        {
464
            TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d",
465
                          nFoundDims, ndims);
466
            return 0;
467
        }
468
    }
469
    else
470
#endif
471
13.2k
        if (nFoundDims != (unsigned)ndims)
472
332
    {
473
332
        TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d",
474
332
                      nFoundDims, ndims);
475
332
        return 0;
476
332
    }
477
478
12.9k
    if (infoArray[3] != sp->segment_width)
479
131
    {
480
131
        TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u",
481
131
                      infoArray[3], sp->segment_width);
482
131
        return 0;
483
131
    }
484
12.7k
    if (infoArray[4] != sp->segment_height)
485
124
    {
486
124
        TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u",
487
124
                      infoArray[4], sp->segment_height);
488
124
        return 0;
489
124
    }
490
491
12.6k
    const unsigned nFoundBands = infoArray[5];
492
12.6k
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
493
2
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
494
2
        td->td_samplesperpixel > 1 && nFoundDims == 1)
495
0
    {
496
0
#if !LERC_AT_LEAST_VERSION(3, 0, 0)
497
0
        if (nFoundBands == td->td_samplesperpixel)
498
0
        {
499
0
            TIFFErrorExtR(
500
0
                tif, module,
501
0
                "Unexpected nBands: %d. This file may have been generated with "
502
0
                "a liblerc version >= 3.0, with one mask per band, and is not "
503
0
                "supported by this older version of liblerc",
504
0
                nFoundBands);
505
0
            return 0;
506
0
        }
507
0
#endif
508
0
        if (nFoundBands != td->td_samplesperpixel)
509
0
        {
510
0
            TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
511
0
                          nFoundBands, td->td_samplesperpixel);
512
0
            return 0;
513
0
        }
514
0
    }
515
12.6k
    else if (nFoundBands != 1)
516
19
    {
517
19
        TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
518
19
                      nFoundBands, 1);
519
19
        return 0;
520
19
    }
521
522
12.6k
    if (infoArray[7] != lerc_data_size)
523
102
    {
524
102
        TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u",
525
102
                      infoArray[7], lerc_data_size);
526
102
        return 0;
527
102
    }
528
529
12.5k
    int nRequestedMasks = use_mask ? 1 : 0;
530
#if LERC_AT_LEAST_VERSION(3, 0, 0)
531
    const int nFoundMasks = (int)infoArray[8];
532
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
533
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
534
        td->td_samplesperpixel > 1 && nFoundDims == 1)
535
    {
536
        if (nFoundMasks != 0 && nFoundMasks != td->td_samplesperpixel)
537
        {
538
            TIFFErrorExtR(tif, module,
539
                          "Unexpected nFoundMasks: %d. Expected: 0 or %d",
540
                          nFoundMasks, td->td_samplesperpixel);
541
            return 0;
542
        }
543
        nRequestedMasks = nFoundMasks;
544
    }
545
    else
546
    {
547
        if (nFoundMasks != 0 && nFoundMasks != 1)
548
        {
549
            TIFFErrorExtR(tif, module,
550
                          "Unexpected nFoundMasks: %d. Expected: 0 or 1",
551
                          nFoundMasks);
552
            return 0;
553
        }
554
    }
555
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && nFoundMasks == 0)
556
    {
557
        nRequestedMasks = 0;
558
        use_mask = 0;
559
    }
560
#endif
561
562
12.5k
    const unsigned nb_pixels = sp->segment_width * sp->segment_height;
563
564
#if LERC_AT_LEAST_VERSION(3, 0, 0)
565
    if (nRequestedMasks > 1)
566
    {
567
        unsigned int num_bytes_needed =
568
            nb_pixels * td->td_samplesperpixel * (td->td_bitspersample / 8);
569
        if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
570
        {
571
            _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
572
            sp->uncompressed_buffer_multiband =
573
                (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
574
            if (!sp->uncompressed_buffer_multiband)
575
            {
576
                sp->uncompressed_buffer_multiband_alloc = 0;
577
                return 0;
578
            }
579
            sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
580
        }
581
        lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
582
                               sp->mask_buffer, (int)nFoundDims,
583
                               (int)sp->segment_width, (int)sp->segment_height,
584
                               (int)nFoundBands, (unsigned int)lerc_data_type,
585
                               sp->uncompressed_buffer_multiband);
586
    }
587
    else
588
#endif
589
12.5k
    {
590
12.5k
        lerc_ret = lerc_decode(
591
12.5k
            lerc_data, lerc_data_size,
592
#if LERC_AT_LEAST_VERSION(3, 0, 0)
593
            nRequestedMasks,
594
#endif
595
12.5k
            use_mask ? sp->mask_buffer : NULL, (int)nFoundDims,
596
12.5k
            (int)sp->segment_width, (int)sp->segment_height, (int)nFoundBands,
597
12.5k
            (unsigned int)lerc_data_type, sp->uncompressed_buffer);
598
12.5k
    }
599
12.5k
    if (lerc_ret != 0)
600
9.46k
    {
601
9.46k
        TIFFErrorExtR(tif, module, "lerc_decode() failed");
602
9.46k
        return 0;
603
9.46k
    }
604
605
    /* Interleave alpha mask with other samples. */
606
3.06k
    if (use_mask && GetLercDataType(tif) == 1)
607
1.45k
    {
608
1.45k
        unsigned src_stride = (unsigned int)((td->td_samplesperpixel - 1) *
609
1.45k
                                             (td->td_bitspersample / 8));
610
1.45k
        unsigned dst_stride =
611
1.45k
            (unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
612
1.45k
        unsigned i = sp->segment_width * sp->segment_height;
613
        /* Operate from end to begin to be able to move in place */
614
182k
        while (i > 0 && i > nomask_bands)
615
181k
        {
616
181k
            i--;
617
181k
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
618
181k
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
619
181k
            memcpy(sp->uncompressed_buffer + i * dst_stride,
620
181k
                   sp->uncompressed_buffer + i * src_stride, src_stride);
621
181k
        }
622
        /* First pixels must use memmove due to overlapping areas */
623
2.92k
        while (i > 0)
624
1.46k
        {
625
1.46k
            i--;
626
1.46k
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
627
1.46k
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
628
1.46k
            memmove(sp->uncompressed_buffer + i * dst_stride,
629
1.46k
                    sp->uncompressed_buffer + i * src_stride, src_stride);
630
1.46k
        }
631
1.45k
    }
632
1.61k
    else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
633
2
    {
634
2
        unsigned i;
635
#if WORDS_BIGENDIAN
636
        const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0};
637
#else
638
2
        const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f};
639
2
#endif
640
2
        float nan_float32;
641
2
        memcpy(&nan_float32, nan_bytes, 4);
642
643
2
        if (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
644
2
            td->td_samplesperpixel == 1)
645
2
        {
646
2
            if (td->td_bitspersample == 32)
647
1
            {
648
529
                for (i = 0; i < nb_pixels; i++)
649
528
                {
650
528
                    if (sp->mask_buffer[i] == 0)
651
128
                        ((float *)sp->uncompressed_buffer)[i] = nan_float32;
652
528
                }
653
1
            }
654
1
            else
655
1
            {
656
1
                const double nan_float64 = (double)nan_float32;
657
529
                for (i = 0; i < nb_pixels; i++)
658
528
                {
659
528
                    if (sp->mask_buffer[i] == 0)
660
128
                        ((double *)sp->uncompressed_buffer)[i] = nan_float64;
661
528
                }
662
1
            }
663
2
        }
664
0
        else if (nRequestedMasks == 1)
665
0
        {
666
0
            assert(nFoundDims == td->td_samplesperpixel);
667
0
            assert(nFoundBands == 1);
668
669
0
            unsigned k = 0;
670
0
            if (td->td_bitspersample == 32)
671
0
            {
672
0
                for (i = 0; i < nb_pixels; i++)
673
0
                {
674
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
675
0
                    {
676
0
                        if (sp->mask_buffer[i] == 0)
677
0
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
678
0
                        ++k;
679
0
                    }
680
0
                }
681
0
            }
682
0
            else
683
0
            {
684
0
                const double nan_float64 = (double)nan_float32;
685
0
                for (i = 0; i < nb_pixels; i++)
686
0
                {
687
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
688
0
                    {
689
0
                        if (sp->mask_buffer[i] == 0)
690
0
                            ((double *)sp->uncompressed_buffer)[k] =
691
0
                                nan_float64;
692
0
                        ++k;
693
0
                    }
694
0
                }
695
0
            }
696
0
        }
697
#if LERC_AT_LEAST_VERSION(3, 0, 0)
698
        else
699
        {
700
            assert(nRequestedMasks == td->td_samplesperpixel);
701
            assert(nFoundDims == 1);
702
            assert(nFoundBands == td->td_samplesperpixel);
703
704
            unsigned k = 0;
705
            if (td->td_bitspersample == 32)
706
            {
707
                for (i = 0; i < nb_pixels; i++)
708
                {
709
                    for (int j = 0; j < td->td_samplesperpixel; j++)
710
                    {
711
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
712
                            0)
713
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
714
                        else
715
                            ((float *)sp->uncompressed_buffer)[k] =
716
                                ((float *)sp->uncompressed_buffer_multiband)
717
                                    [i + (unsigned int)j * nb_pixels];
718
                        ++k;
719
                    }
720
                }
721
            }
722
            else
723
            {
724
                const double nan_float64 = (double)nan_float32;
725
                for (i = 0; i < nb_pixels; i++)
726
                {
727
                    for (int j = 0; j < td->td_samplesperpixel; j++)
728
                    {
729
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
730
                            0)
731
                            ((double *)sp->uncompressed_buffer)[k] =
732
                                nan_float64;
733
                        else
734
                            ((double *)sp->uncompressed_buffer)[k] =
735
                                ((double *)sp->uncompressed_buffer_multiband)
736
                                    [i + (unsigned int)j * nb_pixels];
737
                        ++k;
738
                    }
739
                }
740
            }
741
        }
742
#endif
743
2
    }
744
745
3.06k
    return 1;
746
3.06k
}
tif_lerc.c:gdal_LERCPreDecode
Line
Count
Source
286
8.06k
{
287
8.06k
    static const char module[] = "LERCPreDecode";
288
8.06k
    lerc_status lerc_ret;
289
8.06k
    TIFFDirectory *td = &tif->tif_dir;
290
8.06k
    LERCState *sp = LERCDecoderState(tif);
291
8.06k
    int lerc_data_type;
292
8.06k
    unsigned int infoArray[9];
293
8.06k
    unsigned nomask_bands = td->td_samplesperpixel;
294
8.06k
    int ndims;
295
8.06k
    int use_mask = 0;
296
8.06k
    uint8_t *lerc_data = tif->tif_rawcp;
297
8.06k
    unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc;
298
299
8.06k
    (void)s;
300
8.06k
    assert(sp != NULL);
301
8.06k
    if (sp->state != LSTATE_INIT_DECODE)
302
0
        tif->tif_setupdecode(tif);
303
304
8.06k
    lerc_data_type = GetLercDataType(tif);
305
8.06k
    if (lerc_data_type < 0)
306
205
        return 0;
307
308
7.85k
    if (!SetupBuffers(tif, sp, module))
309
0
        return 0;
310
311
7.85k
    if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
312
631
    {
313
631
        if (sp->compressed_size < sp->uncompressed_alloc)
314
135
        {
315
135
            _TIFFfreeExt(tif, sp->compressed_buffer);
316
135
            sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc);
317
135
            if (!sp->compressed_buffer)
318
0
            {
319
0
                sp->compressed_size = 0;
320
0
                return 0;
321
0
            }
322
135
            sp->compressed_size = sp->uncompressed_alloc;
323
135
        }
324
631
    }
325
326
7.85k
    if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
327
192
    {
328
192
#if LIBDEFLATE_SUPPORT
329
192
        enum libdeflate_result res;
330
192
        size_t lerc_data_sizet = 0;
331
192
        if (sp->libdeflate_dec == NULL)
332
23
        {
333
23
            sp->libdeflate_dec = libdeflate_alloc_decompressor();
334
23
            if (sp->libdeflate_dec == NULL)
335
0
            {
336
0
                TIFFErrorExtR(tif, module, "Cannot allocate decompressor");
337
0
                return 0;
338
0
            }
339
23
        }
340
341
192
        res = libdeflate_zlib_decompress(
342
192
            sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc,
343
192
            sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet);
344
192
        if (res != LIBDEFLATE_SUCCESS)
345
51
        {
346
51
            TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
347
51
                          (unsigned long)tif->tif_dir.td_row);
348
51
            return 0;
349
51
        }
350
192
        assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
351
141
        lerc_data = (uint8_t *)sp->compressed_buffer;
352
141
        lerc_data_size = (unsigned int)lerc_data_sizet;
353
#else
354
        z_stream strm;
355
        int zlib_ret;
356
357
        memset(&strm, 0, sizeof(strm));
358
        strm.zalloc = NULL;
359
        strm.zfree = NULL;
360
        strm.opaque = NULL;
361
        zlib_ret = inflateInit(&strm);
362
        if (zlib_ret != Z_OK)
363
        {
364
            TIFFErrorExtR(tif, module, "inflateInit() failed");
365
            inflateEnd(&strm);
366
            return 0;
367
        }
368
369
        strm.avail_in = (uInt)tif->tif_rawcc;
370
        strm.next_in = tif->tif_rawcp;
371
        strm.avail_out = sp->compressed_size;
372
        strm.next_out = (Bytef *)sp->compressed_buffer;
373
        zlib_ret = inflate(&strm, Z_FINISH);
374
        if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK)
375
        {
376
            TIFFErrorExtR(tif, module, "inflate() failed");
377
            inflateEnd(&strm);
378
            return 0;
379
        }
380
        lerc_data = (uint8_t *)sp->compressed_buffer;
381
        lerc_data_size = sp->compressed_size - strm.avail_out;
382
        inflateEnd(&strm);
383
#endif
384
141
    }
385
7.66k
    else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
386
105
    {
387
105
#ifdef ZSTD_SUPPORT
388
105
        size_t zstd_ret;
389
390
105
        zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
391
105
                                   tif->tif_rawcp, (size_t)tif->tif_rawcc);
392
105
        if (ZSTD_isError(zstd_ret))
393
34
        {
394
34
            TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
395
34
                          ZSTD_getErrorName(zstd_ret));
396
34
            return 0;
397
34
        }
398
399
71
        lerc_data = (uint8_t *)sp->compressed_buffer;
400
71
        lerc_data_size = (unsigned int)zstd_ret;
401
#else
402
        TIFFErrorExtR(tif, module, "ZSTD support missing");
403
        return 0;
404
#endif
405
71
    }
406
7.56k
    else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
407
334
    {
408
334
        TIFFErrorExtR(tif, module, "Unhandled additional compression");
409
334
        return 0;
410
334
    }
411
412
7.43k
    lerc_ret =
413
7.43k
        lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 9, 0);
414
7.43k
    if (lerc_ret != 0)
415
1.92k
    {
416
1.92k
        TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed");
417
1.92k
        return 0;
418
1.92k
    }
419
420
    /* If the configuration is compatible of a LERC mask, and that the */
421
    /* LERC info has dim == samplesperpixel - 1, then there is a LERC */
422
    /* mask. */
423
5.51k
    if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
424
4.48k
        td->td_sampleinfo &&
425
4.48k
        td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
426
634
        GetLercDataType(tif) == 1 &&
427
609
        infoArray[2] == td->td_samplesperpixel - 1U)
428
492
    {
429
492
        use_mask = 1;
430
492
        nomask_bands--;
431
492
    }
432
5.02k
    else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
433
2
    {
434
2
        use_mask = 1;
435
2
    }
436
437
5.51k
    ndims =
438
5.51k
        (int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1);
439
440
    /* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
441
        nRows, nBands, nValidPixels, blobSize,
442
        and starting with liblerc 3.0 nRequestedMasks } */
443
5.51k
    if (infoArray[0] != (unsigned)sp->lerc_version)
444
36
    {
445
36
        TIFFWarningExtR(tif, module,
446
36
                        "Unexpected version number: %u. Expected: %d",
447
36
                        infoArray[0], sp->lerc_version);
448
36
    }
449
5.51k
    if (infoArray[1] != (unsigned)lerc_data_type)
450
63
    {
451
63
        TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d",
452
63
                      infoArray[1], lerc_data_type);
453
63
        return 0;
454
63
    }
455
456
5.45k
    const unsigned nFoundDims = infoArray[2];
457
#if LERC_AT_LEAST_VERSION(3, 0, 0)
458
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
459
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
460
        td->td_samplesperpixel > 1)
461
    {
462
        if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
463
        {
464
            TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d",
465
                          nFoundDims, ndims);
466
            return 0;
467
        }
468
    }
469
    else
470
#endif
471
5.45k
        if (nFoundDims != (unsigned)ndims)
472
178
    {
473
178
        TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d",
474
178
                      nFoundDims, ndims);
475
178
        return 0;
476
178
    }
477
478
5.27k
    if (infoArray[3] != sp->segment_width)
479
62
    {
480
62
        TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u",
481
62
                      infoArray[3], sp->segment_width);
482
62
        return 0;
483
62
    }
484
5.21k
    if (infoArray[4] != sp->segment_height)
485
44
    {
486
44
        TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u",
487
44
                      infoArray[4], sp->segment_height);
488
44
        return 0;
489
44
    }
490
491
5.16k
    const unsigned nFoundBands = infoArray[5];
492
5.16k
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
493
2
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
494
2
        td->td_samplesperpixel > 1 && nFoundDims == 1)
495
0
    {
496
0
#if !LERC_AT_LEAST_VERSION(3, 0, 0)
497
0
        if (nFoundBands == td->td_samplesperpixel)
498
0
        {
499
0
            TIFFErrorExtR(
500
0
                tif, module,
501
0
                "Unexpected nBands: %d. This file may have been generated with "
502
0
                "a liblerc version >= 3.0, with one mask per band, and is not "
503
0
                "supported by this older version of liblerc",
504
0
                nFoundBands);
505
0
            return 0;
506
0
        }
507
0
#endif
508
0
        if (nFoundBands != td->td_samplesperpixel)
509
0
        {
510
0
            TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
511
0
                          nFoundBands, td->td_samplesperpixel);
512
0
            return 0;
513
0
        }
514
0
    }
515
5.16k
    else if (nFoundBands != 1)
516
0
    {
517
0
        TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
518
0
                      nFoundBands, 1);
519
0
        return 0;
520
0
    }
521
522
5.16k
    if (infoArray[7] != lerc_data_size)
523
42
    {
524
42
        TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u",
525
42
                      infoArray[7], lerc_data_size);
526
42
        return 0;
527
42
    }
528
529
5.12k
    int nRequestedMasks = use_mask ? 1 : 0;
530
#if LERC_AT_LEAST_VERSION(3, 0, 0)
531
    const int nFoundMasks = (int)infoArray[8];
532
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
533
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
534
        td->td_samplesperpixel > 1 && nFoundDims == 1)
535
    {
536
        if (nFoundMasks != 0 && nFoundMasks != td->td_samplesperpixel)
537
        {
538
            TIFFErrorExtR(tif, module,
539
                          "Unexpected nFoundMasks: %d. Expected: 0 or %d",
540
                          nFoundMasks, td->td_samplesperpixel);
541
            return 0;
542
        }
543
        nRequestedMasks = nFoundMasks;
544
    }
545
    else
546
    {
547
        if (nFoundMasks != 0 && nFoundMasks != 1)
548
        {
549
            TIFFErrorExtR(tif, module,
550
                          "Unexpected nFoundMasks: %d. Expected: 0 or 1",
551
                          nFoundMasks);
552
            return 0;
553
        }
554
    }
555
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && nFoundMasks == 0)
556
    {
557
        nRequestedMasks = 0;
558
        use_mask = 0;
559
    }
560
#endif
561
562
5.12k
    const unsigned nb_pixels = sp->segment_width * sp->segment_height;
563
564
#if LERC_AT_LEAST_VERSION(3, 0, 0)
565
    if (nRequestedMasks > 1)
566
    {
567
        unsigned int num_bytes_needed =
568
            nb_pixels * td->td_samplesperpixel * (td->td_bitspersample / 8);
569
        if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
570
        {
571
            _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
572
            sp->uncompressed_buffer_multiband =
573
                (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
574
            if (!sp->uncompressed_buffer_multiband)
575
            {
576
                sp->uncompressed_buffer_multiband_alloc = 0;
577
                return 0;
578
            }
579
            sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
580
        }
581
        lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
582
                               sp->mask_buffer, (int)nFoundDims,
583
                               (int)sp->segment_width, (int)sp->segment_height,
584
                               (int)nFoundBands, (unsigned int)lerc_data_type,
585
                               sp->uncompressed_buffer_multiband);
586
    }
587
    else
588
#endif
589
5.12k
    {
590
5.12k
        lerc_ret = lerc_decode(
591
5.12k
            lerc_data, lerc_data_size,
592
#if LERC_AT_LEAST_VERSION(3, 0, 0)
593
            nRequestedMasks,
594
#endif
595
5.12k
            use_mask ? sp->mask_buffer : NULL, (int)nFoundDims,
596
5.12k
            (int)sp->segment_width, (int)sp->segment_height, (int)nFoundBands,
597
5.12k
            (unsigned int)lerc_data_type, sp->uncompressed_buffer);
598
5.12k
    }
599
5.12k
    if (lerc_ret != 0)
600
4.72k
    {
601
4.72k
        TIFFErrorExtR(tif, module, "lerc_decode() failed");
602
4.72k
        return 0;
603
4.72k
    }
604
605
    /* Interleave alpha mask with other samples. */
606
407
    if (use_mask && GetLercDataType(tif) == 1)
607
8
    {
608
8
        unsigned src_stride = (unsigned int)((td->td_samplesperpixel - 1) *
609
8
                                             (td->td_bitspersample / 8));
610
8
        unsigned dst_stride =
611
8
            (unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
612
8
        unsigned i = sp->segment_width * sp->segment_height;
613
        /* Operate from end to begin to be able to move in place */
614
3.18k
        while (i > 0 && i > nomask_bands)
615
3.17k
        {
616
3.17k
            i--;
617
3.17k
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
618
3.17k
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
619
3.17k
            memcpy(sp->uncompressed_buffer + i * dst_stride,
620
3.17k
                   sp->uncompressed_buffer + i * src_stride, src_stride);
621
3.17k
        }
622
        /* First pixels must use memmove due to overlapping areas */
623
32
        while (i > 0)
624
24
        {
625
24
            i--;
626
24
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
627
24
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
628
24
            memmove(sp->uncompressed_buffer + i * dst_stride,
629
24
                    sp->uncompressed_buffer + i * src_stride, src_stride);
630
24
        }
631
8
    }
632
399
    else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
633
2
    {
634
2
        unsigned i;
635
#if WORDS_BIGENDIAN
636
        const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0};
637
#else
638
2
        const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f};
639
2
#endif
640
2
        float nan_float32;
641
2
        memcpy(&nan_float32, nan_bytes, 4);
642
643
2
        if (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
644
2
            td->td_samplesperpixel == 1)
645
2
        {
646
2
            if (td->td_bitspersample == 32)
647
1
            {
648
529
                for (i = 0; i < nb_pixels; i++)
649
528
                {
650
528
                    if (sp->mask_buffer[i] == 0)
651
128
                        ((float *)sp->uncompressed_buffer)[i] = nan_float32;
652
528
                }
653
1
            }
654
1
            else
655
1
            {
656
1
                const double nan_float64 = (double)nan_float32;
657
529
                for (i = 0; i < nb_pixels; i++)
658
528
                {
659
528
                    if (sp->mask_buffer[i] == 0)
660
128
                        ((double *)sp->uncompressed_buffer)[i] = nan_float64;
661
528
                }
662
1
            }
663
2
        }
664
0
        else if (nRequestedMasks == 1)
665
0
        {
666
0
            assert(nFoundDims == td->td_samplesperpixel);
667
0
            assert(nFoundBands == 1);
668
669
0
            unsigned k = 0;
670
0
            if (td->td_bitspersample == 32)
671
0
            {
672
0
                for (i = 0; i < nb_pixels; i++)
673
0
                {
674
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
675
0
                    {
676
0
                        if (sp->mask_buffer[i] == 0)
677
0
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
678
0
                        ++k;
679
0
                    }
680
0
                }
681
0
            }
682
0
            else
683
0
            {
684
0
                const double nan_float64 = (double)nan_float32;
685
0
                for (i = 0; i < nb_pixels; i++)
686
0
                {
687
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
688
0
                    {
689
0
                        if (sp->mask_buffer[i] == 0)
690
0
                            ((double *)sp->uncompressed_buffer)[k] =
691
0
                                nan_float64;
692
0
                        ++k;
693
0
                    }
694
0
                }
695
0
            }
696
0
        }
697
#if LERC_AT_LEAST_VERSION(3, 0, 0)
698
        else
699
        {
700
            assert(nRequestedMasks == td->td_samplesperpixel);
701
            assert(nFoundDims == 1);
702
            assert(nFoundBands == td->td_samplesperpixel);
703
704
            unsigned k = 0;
705
            if (td->td_bitspersample == 32)
706
            {
707
                for (i = 0; i < nb_pixels; i++)
708
                {
709
                    for (int j = 0; j < td->td_samplesperpixel; j++)
710
                    {
711
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
712
                            0)
713
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
714
                        else
715
                            ((float *)sp->uncompressed_buffer)[k] =
716
                                ((float *)sp->uncompressed_buffer_multiband)
717
                                    [i + (unsigned int)j * nb_pixels];
718
                        ++k;
719
                    }
720
                }
721
            }
722
            else
723
            {
724
                const double nan_float64 = (double)nan_float32;
725
                for (i = 0; i < nb_pixels; i++)
726
                {
727
                    for (int j = 0; j < td->td_samplesperpixel; j++)
728
                    {
729
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
730
                            0)
731
                            ((double *)sp->uncompressed_buffer)[k] =
732
                                nan_float64;
733
                        else
734
                            ((double *)sp->uncompressed_buffer)[k] =
735
                                ((double *)sp->uncompressed_buffer_multiband)
736
                                    [i + (unsigned int)j * nb_pixels];
737
                        ++k;
738
                    }
739
                }
740
            }
741
        }
742
#endif
743
2
    }
744
745
407
    return 1;
746
407
}
libertiffdataset.cpp:LERCPreDecode(tiff*, unsigned short)
Line
Count
Source
286
13.0k
{
287
13.0k
    static const char module[] = "LERCPreDecode";
288
13.0k
    lerc_status lerc_ret;
289
13.0k
    TIFFDirectory *td = &tif->tif_dir;
290
13.0k
    LERCState *sp = LERCDecoderState(tif);
291
13.0k
    int lerc_data_type;
292
13.0k
    unsigned int infoArray[9];
293
13.0k
    unsigned nomask_bands = td->td_samplesperpixel;
294
13.0k
    int ndims;
295
13.0k
    int use_mask = 0;
296
13.0k
    uint8_t *lerc_data = tif->tif_rawcp;
297
13.0k
    unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc;
298
299
13.0k
    (void)s;
300
13.0k
    assert(sp != NULL);
301
13.0k
    if (sp->state != LSTATE_INIT_DECODE)
302
2.85k
        tif->tif_setupdecode(tif);
303
304
13.0k
    lerc_data_type = GetLercDataType(tif);
305
13.0k
    if (lerc_data_type < 0)
306
46
        return 0;
307
308
13.0k
    if (!SetupBuffers(tif, sp, module))
309
0
        return 0;
310
311
13.0k
    if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
312
852
    {
313
852
        if (sp->compressed_size < sp->uncompressed_alloc)
314
129
        {
315
129
            _TIFFfreeExt(tif, sp->compressed_buffer);
316
129
            sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc);
317
129
            if (!sp->compressed_buffer)
318
0
            {
319
0
                sp->compressed_size = 0;
320
0
                return 0;
321
0
            }
322
129
            sp->compressed_size = sp->uncompressed_alloc;
323
129
        }
324
852
    }
325
326
13.0k
    if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
327
304
    {
328
304
#if LIBDEFLATE_SUPPORT
329
304
        enum libdeflate_result res;
330
304
        size_t lerc_data_sizet = 0;
331
304
        if (sp->libdeflate_dec == NULL)
332
48
        {
333
48
            sp->libdeflate_dec = libdeflate_alloc_decompressor();
334
48
            if (sp->libdeflate_dec == NULL)
335
0
            {
336
0
                TIFFErrorExtR(tif, module, "Cannot allocate decompressor");
337
0
                return 0;
338
0
            }
339
48
        }
340
341
304
        res = libdeflate_zlib_decompress(
342
304
            sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc,
343
304
            sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet);
344
304
        if (res != LIBDEFLATE_SUCCESS)
345
47
        {
346
47
            TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
347
47
                          (unsigned long)tif->tif_dir.td_row);
348
47
            return 0;
349
47
        }
350
304
        assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
351
257
        lerc_data = (uint8_t *)sp->compressed_buffer;
352
257
        lerc_data_size = (unsigned int)lerc_data_sizet;
353
#else
354
        z_stream strm;
355
        int zlib_ret;
356
357
        memset(&strm, 0, sizeof(strm));
358
        strm.zalloc = NULL;
359
        strm.zfree = NULL;
360
        strm.opaque = NULL;
361
        zlib_ret = inflateInit(&strm);
362
        if (zlib_ret != Z_OK)
363
        {
364
            TIFFErrorExtR(tif, module, "inflateInit() failed");
365
            inflateEnd(&strm);
366
            return 0;
367
        }
368
369
        strm.avail_in = (uInt)tif->tif_rawcc;
370
        strm.next_in = tif->tif_rawcp;
371
        strm.avail_out = sp->compressed_size;
372
        strm.next_out = (Bytef *)sp->compressed_buffer;
373
        zlib_ret = inflate(&strm, Z_FINISH);
374
        if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK)
375
        {
376
            TIFFErrorExtR(tif, module, "inflate() failed");
377
            inflateEnd(&strm);
378
            return 0;
379
        }
380
        lerc_data = (uint8_t *)sp->compressed_buffer;
381
        lerc_data_size = sp->compressed_size - strm.avail_out;
382
        inflateEnd(&strm);
383
#endif
384
257
    }
385
12.7k
    else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
386
59
    {
387
59
#ifdef ZSTD_SUPPORT
388
59
        size_t zstd_ret;
389
390
59
        zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
391
59
                                   tif->tif_rawcp, (size_t)tif->tif_rawcc);
392
59
        if (ZSTD_isError(zstd_ret))
393
23
        {
394
23
            TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
395
23
                          ZSTD_getErrorName(zstd_ret));
396
23
            return 0;
397
23
        }
398
399
36
        lerc_data = (uint8_t *)sp->compressed_buffer;
400
36
        lerc_data_size = (unsigned int)zstd_ret;
401
#else
402
        TIFFErrorExtR(tif, module, "ZSTD support missing");
403
        return 0;
404
#endif
405
36
    }
406
12.6k
    else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
407
489
    {
408
489
        TIFFErrorExtR(tif, module, "Unhandled additional compression");
409
489
        return 0;
410
489
    }
411
412
12.4k
    lerc_ret =
413
12.4k
        lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 9, 0);
414
12.4k
    if (lerc_ret != 0)
415
4.32k
    {
416
4.32k
        TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed");
417
4.32k
        return 0;
418
4.32k
    }
419
420
    /* If the configuration is compatible of a LERC mask, and that the */
421
    /* LERC info has dim == samplesperpixel - 1, then there is a LERC */
422
    /* mask. */
423
8.14k
    if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
424
1.67k
        td->td_sampleinfo &&
425
1.67k
        td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
426
1.65k
        GetLercDataType(tif) == 1 &&
427
1.59k
        infoArray[2] == td->td_samplesperpixel - 1U)
428
1.53k
    {
429
1.53k
        use_mask = 1;
430
1.53k
        nomask_bands--;
431
1.53k
    }
432
6.61k
    else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
433
40
    {
434
40
        use_mask = 1;
435
40
    }
436
437
8.14k
    ndims =
438
8.14k
        (int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1);
439
440
    /* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
441
        nRows, nBands, nValidPixels, blobSize,
442
        and starting with liblerc 3.0 nRequestedMasks } */
443
8.14k
    if (infoArray[0] != (unsigned)sp->lerc_version)
444
3.32k
    {
445
3.32k
        TIFFWarningExtR(tif, module,
446
3.32k
                        "Unexpected version number: %u. Expected: %d",
447
3.32k
                        infoArray[0], sp->lerc_version);
448
3.32k
    }
449
8.14k
    if (infoArray[1] != (unsigned)lerc_data_type)
450
358
    {
451
358
        TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d",
452
358
                      infoArray[1], lerc_data_type);
453
358
        return 0;
454
358
    }
455
456
7.78k
    const unsigned nFoundDims = infoArray[2];
457
#if LERC_AT_LEAST_VERSION(3, 0, 0)
458
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
459
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
460
        td->td_samplesperpixel > 1)
461
    {
462
        if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
463
        {
464
            TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d",
465
                          nFoundDims, ndims);
466
            return 0;
467
        }
468
    }
469
    else
470
#endif
471
7.78k
        if (nFoundDims != (unsigned)ndims)
472
154
    {
473
154
        TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d",
474
154
                      nFoundDims, ndims);
475
154
        return 0;
476
154
    }
477
478
7.63k
    if (infoArray[3] != sp->segment_width)
479
69
    {
480
69
        TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u",
481
69
                      infoArray[3], sp->segment_width);
482
69
        return 0;
483
69
    }
484
7.56k
    if (infoArray[4] != sp->segment_height)
485
80
    {
486
80
        TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u",
487
80
                      infoArray[4], sp->segment_height);
488
80
        return 0;
489
80
    }
490
491
7.48k
    const unsigned nFoundBands = infoArray[5];
492
7.48k
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
493
0
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
494
0
        td->td_samplesperpixel > 1 && nFoundDims == 1)
495
0
    {
496
0
#if !LERC_AT_LEAST_VERSION(3, 0, 0)
497
0
        if (nFoundBands == td->td_samplesperpixel)
498
0
        {
499
0
            TIFFErrorExtR(
500
0
                tif, module,
501
0
                "Unexpected nBands: %d. This file may have been generated with "
502
0
                "a liblerc version >= 3.0, with one mask per band, and is not "
503
0
                "supported by this older version of liblerc",
504
0
                nFoundBands);
505
0
            return 0;
506
0
        }
507
0
#endif
508
0
        if (nFoundBands != td->td_samplesperpixel)
509
0
        {
510
0
            TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
511
0
                          nFoundBands, td->td_samplesperpixel);
512
0
            return 0;
513
0
        }
514
0
    }
515
7.48k
    else if (nFoundBands != 1)
516
19
    {
517
19
        TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
518
19
                      nFoundBands, 1);
519
19
        return 0;
520
19
    }
521
522
7.46k
    if (infoArray[7] != lerc_data_size)
523
60
    {
524
60
        TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u",
525
60
                      infoArray[7], lerc_data_size);
526
60
        return 0;
527
60
    }
528
529
7.40k
    int nRequestedMasks = use_mask ? 1 : 0;
530
#if LERC_AT_LEAST_VERSION(3, 0, 0)
531
    const int nFoundMasks = (int)infoArray[8];
532
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
533
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
534
        td->td_samplesperpixel > 1 && nFoundDims == 1)
535
    {
536
        if (nFoundMasks != 0 && nFoundMasks != td->td_samplesperpixel)
537
        {
538
            TIFFErrorExtR(tif, module,
539
                          "Unexpected nFoundMasks: %d. Expected: 0 or %d",
540
                          nFoundMasks, td->td_samplesperpixel);
541
            return 0;
542
        }
543
        nRequestedMasks = nFoundMasks;
544
    }
545
    else
546
    {
547
        if (nFoundMasks != 0 && nFoundMasks != 1)
548
        {
549
            TIFFErrorExtR(tif, module,
550
                          "Unexpected nFoundMasks: %d. Expected: 0 or 1",
551
                          nFoundMasks);
552
            return 0;
553
        }
554
    }
555
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && nFoundMasks == 0)
556
    {
557
        nRequestedMasks = 0;
558
        use_mask = 0;
559
    }
560
#endif
561
562
7.40k
    const unsigned nb_pixels = sp->segment_width * sp->segment_height;
563
564
#if LERC_AT_LEAST_VERSION(3, 0, 0)
565
    if (nRequestedMasks > 1)
566
    {
567
        unsigned int num_bytes_needed =
568
            nb_pixels * td->td_samplesperpixel * (td->td_bitspersample / 8);
569
        if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
570
        {
571
            _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
572
            sp->uncompressed_buffer_multiband =
573
                (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
574
            if (!sp->uncompressed_buffer_multiband)
575
            {
576
                sp->uncompressed_buffer_multiband_alloc = 0;
577
                return 0;
578
            }
579
            sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
580
        }
581
        lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
582
                               sp->mask_buffer, (int)nFoundDims,
583
                               (int)sp->segment_width, (int)sp->segment_height,
584
                               (int)nFoundBands, (unsigned int)lerc_data_type,
585
                               sp->uncompressed_buffer_multiband);
586
    }
587
    else
588
#endif
589
7.40k
    {
590
7.40k
        lerc_ret = lerc_decode(
591
7.40k
            lerc_data, lerc_data_size,
592
#if LERC_AT_LEAST_VERSION(3, 0, 0)
593
            nRequestedMasks,
594
#endif
595
7.40k
            use_mask ? sp->mask_buffer : NULL, (int)nFoundDims,
596
7.40k
            (int)sp->segment_width, (int)sp->segment_height, (int)nFoundBands,
597
7.40k
            (unsigned int)lerc_data_type, sp->uncompressed_buffer);
598
7.40k
    }
599
7.40k
    if (lerc_ret != 0)
600
4.74k
    {
601
4.74k
        TIFFErrorExtR(tif, module, "lerc_decode() failed");
602
4.74k
        return 0;
603
4.74k
    }
604
605
    /* Interleave alpha mask with other samples. */
606
2.65k
    if (use_mask && GetLercDataType(tif) == 1)
607
1.44k
    {
608
1.44k
        unsigned src_stride = (unsigned int)((td->td_samplesperpixel - 1) *
609
1.44k
                                             (td->td_bitspersample / 8));
610
1.44k
        unsigned dst_stride =
611
1.44k
            (unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
612
1.44k
        unsigned i = sp->segment_width * sp->segment_height;
613
        /* Operate from end to begin to be able to move in place */
614
179k
        while (i > 0 && i > nomask_bands)
615
177k
        {
616
177k
            i--;
617
177k
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
618
177k
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
619
177k
            memcpy(sp->uncompressed_buffer + i * dst_stride,
620
177k
                   sp->uncompressed_buffer + i * src_stride, src_stride);
621
177k
        }
622
        /* First pixels must use memmove due to overlapping areas */
623
2.88k
        while (i > 0)
624
1.44k
        {
625
1.44k
            i--;
626
1.44k
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
627
1.44k
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
628
1.44k
            memmove(sp->uncompressed_buffer + i * dst_stride,
629
1.44k
                    sp->uncompressed_buffer + i * src_stride, src_stride);
630
1.44k
        }
631
1.44k
    }
632
1.21k
    else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
633
0
    {
634
0
        unsigned i;
635
#if WORDS_BIGENDIAN
636
        const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0};
637
#else
638
0
        const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f};
639
0
#endif
640
0
        float nan_float32;
641
0
        memcpy(&nan_float32, nan_bytes, 4);
642
643
0
        if (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
644
0
            td->td_samplesperpixel == 1)
645
0
        {
646
0
            if (td->td_bitspersample == 32)
647
0
            {
648
0
                for (i = 0; i < nb_pixels; i++)
649
0
                {
650
0
                    if (sp->mask_buffer[i] == 0)
651
0
                        ((float *)sp->uncompressed_buffer)[i] = nan_float32;
652
0
                }
653
0
            }
654
0
            else
655
0
            {
656
0
                const double nan_float64 = (double)nan_float32;
657
0
                for (i = 0; i < nb_pixels; i++)
658
0
                {
659
0
                    if (sp->mask_buffer[i] == 0)
660
0
                        ((double *)sp->uncompressed_buffer)[i] = nan_float64;
661
0
                }
662
0
            }
663
0
        }
664
0
        else if (nRequestedMasks == 1)
665
0
        {
666
0
            assert(nFoundDims == td->td_samplesperpixel);
667
0
            assert(nFoundBands == 1);
668
669
0
            unsigned k = 0;
670
0
            if (td->td_bitspersample == 32)
671
0
            {
672
0
                for (i = 0; i < nb_pixels; i++)
673
0
                {
674
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
675
0
                    {
676
0
                        if (sp->mask_buffer[i] == 0)
677
0
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
678
0
                        ++k;
679
0
                    }
680
0
                }
681
0
            }
682
0
            else
683
0
            {
684
0
                const double nan_float64 = (double)nan_float32;
685
0
                for (i = 0; i < nb_pixels; i++)
686
0
                {
687
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
688
0
                    {
689
0
                        if (sp->mask_buffer[i] == 0)
690
0
                            ((double *)sp->uncompressed_buffer)[k] =
691
0
                                nan_float64;
692
0
                        ++k;
693
0
                    }
694
0
                }
695
0
            }
696
0
        }
697
#if LERC_AT_LEAST_VERSION(3, 0, 0)
698
        else
699
        {
700
            assert(nRequestedMasks == td->td_samplesperpixel);
701
            assert(nFoundDims == 1);
702
            assert(nFoundBands == td->td_samplesperpixel);
703
704
            unsigned k = 0;
705
            if (td->td_bitspersample == 32)
706
            {
707
                for (i = 0; i < nb_pixels; i++)
708
                {
709
                    for (int j = 0; j < td->td_samplesperpixel; j++)
710
                    {
711
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
712
                            0)
713
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
714
                        else
715
                            ((float *)sp->uncompressed_buffer)[k] =
716
                                ((float *)sp->uncompressed_buffer_multiband)
717
                                    [i + (unsigned int)j * nb_pixels];
718
                        ++k;
719
                    }
720
                }
721
            }
722
            else
723
            {
724
                const double nan_float64 = (double)nan_float32;
725
                for (i = 0; i < nb_pixels; i++)
726
                {
727
                    for (int j = 0; j < td->td_samplesperpixel; j++)
728
                    {
729
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
730
                            0)
731
                            ((double *)sp->uncompressed_buffer)[k] =
732
                                nan_float64;
733
                        else
734
                            ((double *)sp->uncompressed_buffer)[k] =
735
                                ((double *)sp->uncompressed_buffer_multiband)
736
                                    [i + (unsigned int)j * nb_pixels];
737
                        ++k;
738
                    }
739
                }
740
            }
741
        }
742
#endif
743
0
    }
744
745
2.65k
    return 1;
746
2.65k
}
747
748
/*
749
 * Decode a strip, tile or scanline.
750
 */
751
static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
752
10.7k
{
753
10.7k
    static const char module[] = "LERCDecode";
754
10.7k
    LERCState *sp = LERCDecoderState(tif);
755
756
10.7k
    (void)s;
757
10.7k
    assert(sp != NULL);
758
10.7k
    assert(sp->state == LSTATE_INIT_DECODE);
759
760
10.7k
    if (sp->uncompressed_buffer == NULL)
761
0
    {
762
0
        memset(op, 0, (size_t)occ);
763
0
        TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
764
0
        return 0;
765
0
    }
766
767
10.7k
    if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
768
10.7k
        sp->uncompressed_size)
769
0
    {
770
0
        memset(op, 0, (size_t)occ);
771
0
        TIFFErrorExtR(tif, module, "Too many bytes read");
772
0
        return 0;
773
0
    }
774
775
10.7k
    memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, (size_t)occ);
776
10.7k
    sp->uncompressed_offset += (unsigned int)occ;
777
778
10.7k
    return 1;
779
10.7k
}
tif_lerc.c:gdal_LERCDecode
Line
Count
Source
752
8.07k
{
753
8.07k
    static const char module[] = "LERCDecode";
754
8.07k
    LERCState *sp = LERCDecoderState(tif);
755
756
8.07k
    (void)s;
757
8.07k
    assert(sp != NULL);
758
8.07k
    assert(sp->state == LSTATE_INIT_DECODE);
759
760
8.07k
    if (sp->uncompressed_buffer == NULL)
761
0
    {
762
0
        memset(op, 0, (size_t)occ);
763
0
        TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
764
0
        return 0;
765
0
    }
766
767
8.07k
    if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
768
8.07k
        sp->uncompressed_size)
769
0
    {
770
0
        memset(op, 0, (size_t)occ);
771
0
        TIFFErrorExtR(tif, module, "Too many bytes read");
772
0
        return 0;
773
0
    }
774
775
8.07k
    memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, (size_t)occ);
776
8.07k
    sp->uncompressed_offset += (unsigned int)occ;
777
778
8.07k
    return 1;
779
8.07k
}
libertiffdataset.cpp:LERCDecode(tiff*, unsigned char*, long, unsigned short)
Line
Count
Source
752
2.65k
{
753
2.65k
    static const char module[] = "LERCDecode";
754
2.65k
    LERCState *sp = LERCDecoderState(tif);
755
756
2.65k
    (void)s;
757
2.65k
    assert(sp != NULL);
758
2.65k
    assert(sp->state == LSTATE_INIT_DECODE);
759
760
2.65k
    if (sp->uncompressed_buffer == NULL)
761
0
    {
762
0
        memset(op, 0, (size_t)occ);
763
0
        TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
764
0
        return 0;
765
0
    }
766
767
2.65k
    if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
768
2.65k
        sp->uncompressed_size)
769
0
    {
770
0
        memset(op, 0, (size_t)occ);
771
0
        TIFFErrorExtR(tif, module, "Too many bytes read");
772
0
        return 0;
773
0
    }
774
775
2.65k
    memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, (size_t)occ);
776
2.65k
    sp->uncompressed_offset += (unsigned int)occ;
777
778
2.65k
    return 1;
779
2.65k
}
780
781
#ifndef LERC_READ_ONLY
782
783
static int LERCSetupEncode(TIFF *tif)
784
0
{
785
0
    LERCState *sp = LERCEncoderState(tif);
786
787
0
    assert(sp != NULL);
788
0
    if (sp->state & LSTATE_INIT_DECODE)
789
0
    {
790
0
        sp->state = 0;
791
0
    }
792
793
0
    sp->state |= LSTATE_INIT_ENCODE;
794
795
0
    return 1;
796
0
}
797
798
/*
799
 * Reset encoding state at the start of a strip.
800
 */
801
static int LERCPreEncode(TIFF *tif, uint16_t s)
802
0
{
803
0
    static const char module[] = "LERCPreEncode";
804
0
    LERCState *sp = LERCEncoderState(tif);
805
0
    int lerc_data_type;
806
807
0
    (void)s;
808
0
    assert(sp != NULL);
809
0
    if (sp->state != LSTATE_INIT_ENCODE)
810
0
        tif->tif_setupencode(tif);
811
812
0
    lerc_data_type = GetLercDataType(tif);
813
0
    if (lerc_data_type < 0)
814
0
        return 0;
815
816
0
    if (!SetupBuffers(tif, sp, module))
817
0
        return 0;
818
819
0
    return 1;
820
0
}
821
822
/*
823
 * Encode a chunk of pixels.
824
 */
825
static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
826
0
{
827
0
    static const char module[] = "LERCEncode";
828
0
    LERCState *sp = LERCEncoderState(tif);
829
830
0
    (void)s;
831
0
    assert(sp != NULL);
832
0
    assert(sp->state == LSTATE_INIT_ENCODE);
833
834
0
    if ((uint64_t)sp->uncompressed_offset + (uint64_t)cc >
835
0
        sp->uncompressed_size)
836
0
    {
837
0
        TIFFErrorExtR(tif, module, "Too many bytes written");
838
0
        return 0;
839
0
    }
840
841
0
    memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, (size_t)cc);
842
0
    sp->uncompressed_offset += (unsigned int)cc;
843
844
0
    return 1;
845
0
}
846
847
/*
848
 * Finish off an encoded strip by flushing it.
849
 */
850
static int LERCPostEncode(TIFF *tif)
851
0
{
852
0
    lerc_status lerc_ret;
853
0
    static const char module[] = "LERCPostEncode";
854
0
    LERCState *sp = LERCEncoderState(tif);
855
0
    unsigned int numBytesWritten = 0;
856
0
    TIFFDirectory *td = &tif->tif_dir;
857
0
    int use_mask = 0;
858
0
    unsigned dst_nbands = td->td_samplesperpixel;
859
860
0
    if (sp->uncompressed_offset != sp->uncompressed_size)
861
0
    {
862
0
        TIFFErrorExtR(tif, module, "Unexpected number of bytes in the buffer");
863
0
        return 0;
864
0
    }
865
866
0
    int mask_count = 1;
867
0
    const unsigned nb_pixels = sp->segment_width * sp->segment_height;
868
869
    /* Extract alpha mask (if containing only 0 and 255 values, */
870
    /* and compact array of regular bands */
871
0
    if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
872
0
        td->td_sampleinfo &&
873
0
        td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
874
0
        GetLercDataType(tif) == 1)
875
0
    {
876
0
        const unsigned dst_stride =
877
0
            (unsigned int)((td->td_samplesperpixel - 1) *
878
0
                           (td->td_bitspersample / 8));
879
0
        const unsigned src_stride =
880
0
            (unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
881
0
        unsigned i = 0;
882
883
0
        use_mask = 1;
884
0
        for (i = 0; i < nb_pixels; i++)
885
0
        {
886
0
            int v = sp->uncompressed_buffer[i * src_stride +
887
0
                                            td->td_samplesperpixel - 1];
888
0
            if (v != 0 && v != 255)
889
0
            {
890
0
                use_mask = 0;
891
0
                break;
892
0
            }
893
0
        }
894
895
0
        if (use_mask)
896
0
        {
897
0
            dst_nbands--;
898
            /* First pixels must use memmove due to overlapping areas */
899
0
            for (i = 0; i < dst_nbands && i < nb_pixels; i++)
900
0
            {
901
0
                memmove(sp->uncompressed_buffer + i * dst_stride,
902
0
                        sp->uncompressed_buffer + i * src_stride, dst_stride);
903
0
                sp->mask_buffer[i] =
904
0
                    sp->uncompressed_buffer[i * src_stride +
905
0
                                            td->td_samplesperpixel - 1];
906
0
            }
907
0
            for (; i < nb_pixels; i++)
908
0
            {
909
0
                memcpy(sp->uncompressed_buffer + i * dst_stride,
910
0
                       sp->uncompressed_buffer + i * src_stride, dst_stride);
911
0
                sp->mask_buffer[i] =
912
0
                    sp->uncompressed_buffer[i * src_stride +
913
0
                                            td->td_samplesperpixel - 1];
914
0
            }
915
0
        }
916
0
    }
917
0
    else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
918
0
             (td->td_bitspersample == 32 || td->td_bitspersample == 64))
919
0
    {
920
        /* Check for NaN values */
921
0
        unsigned i;
922
0
        if (td->td_bitspersample == 32)
923
0
        {
924
0
            if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
925
0
            {
926
0
                unsigned k = 0;
927
0
                for (i = 0; i < nb_pixels; i++)
928
0
                {
929
0
                    int count_nan = 0;
930
0
                    for (int j = 0; j < td->td_samplesperpixel; ++j)
931
0
                    {
932
0
                        const float val = ((float *)sp->uncompressed_buffer)[k];
933
0
                        ++k;
934
0
                        if (isnan(val))
935
0
                        {
936
0
                            ++count_nan;
937
0
                        }
938
0
                    }
939
0
                    if (count_nan > 0)
940
0
                    {
941
0
                        use_mask = 1;
942
0
                        if (count_nan < td->td_samplesperpixel)
943
0
                        {
944
0
                            mask_count = td->td_samplesperpixel;
945
0
                            break;
946
0
                        }
947
0
                    }
948
0
                }
949
0
            }
950
0
            else
951
0
            {
952
0
                for (i = 0; i < nb_pixels; i++)
953
0
                {
954
0
                    const float val = ((float *)sp->uncompressed_buffer)[i];
955
0
                    if (isnan(val))
956
0
                    {
957
0
                        use_mask = 1;
958
0
                        break;
959
0
                    }
960
0
                }
961
0
            }
962
0
        }
963
0
        else
964
0
        {
965
0
            if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
966
0
            {
967
0
                unsigned k = 0;
968
0
                for (i = 0; i < nb_pixels; i++)
969
0
                {
970
0
                    int count_nan = 0;
971
0
                    for (int j = 0; j < td->td_samplesperpixel; ++j)
972
0
                    {
973
0
                        const double val =
974
0
                            ((double *)sp->uncompressed_buffer)[k];
975
0
                        ++k;
976
0
                        if (isnan(val))
977
0
                        {
978
0
                            ++count_nan;
979
0
                        }
980
0
                    }
981
0
                    if (count_nan > 0)
982
0
                    {
983
0
                        use_mask = 1;
984
0
                        if (count_nan < td->td_samplesperpixel)
985
0
                        {
986
0
                            mask_count = td->td_samplesperpixel;
987
0
                            break;
988
0
                        }
989
0
                    }
990
0
                }
991
0
            }
992
0
            else
993
0
            {
994
0
                for (i = 0; i < nb_pixels; i++)
995
0
                {
996
0
                    const double val = ((double *)sp->uncompressed_buffer)[i];
997
0
                    if (isnan(val))
998
0
                    {
999
0
                        use_mask = 1;
1000
0
                        break;
1001
0
                    }
1002
0
                }
1003
0
            }
1004
0
        }
1005
1006
0
        if (use_mask)
1007
0
        {
1008
0
            if (mask_count > 1)
1009
0
            {
1010
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1011
                unsigned int num_bytes_needed =
1012
                    nb_pixels * dst_nbands * (td->td_bitspersample / 8);
1013
                if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
1014
                {
1015
                    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1016
                    sp->uncompressed_buffer_multiband =
1017
                        (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
1018
                    if (!sp->uncompressed_buffer_multiband)
1019
                    {
1020
                        sp->uncompressed_buffer_multiband_alloc = 0;
1021
                        return 0;
1022
                    }
1023
                    sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
1024
                }
1025
1026
                unsigned k = 0;
1027
                if (td->td_bitspersample == 32)
1028
                {
1029
                    for (i = 0; i < nb_pixels; i++)
1030
                    {
1031
                        for (int j = 0; j < td->td_samplesperpixel; ++j)
1032
                        {
1033
                            const float val =
1034
                                ((float *)sp->uncompressed_buffer)[k];
1035
                            ((float *)sp->uncompressed_buffer_multiband)
1036
                                [i + (unsigned int)j * nb_pixels] = val;
1037
                            ++k;
1038
                            sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
1039
                                !isnan(val) ? 255 : 0;
1040
                        }
1041
                    }
1042
                }
1043
                else
1044
                {
1045
                    for (i = 0; i < nb_pixels; i++)
1046
                    {
1047
                        for (int j = 0; j < td->td_samplesperpixel; ++j)
1048
                        {
1049
                            const double val =
1050
                                ((double *)sp->uncompressed_buffer)[k];
1051
                            ((double *)sp->uncompressed_buffer_multiband)
1052
                                [i + (unsigned int)j * nb_pixels] = val;
1053
                            ++k;
1054
                            sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
1055
                                !isnan(val) ? 255 : 0;
1056
                        }
1057
                    }
1058
                }
1059
#else
1060
0
                TIFFErrorExtR(tif, module,
1061
0
                              "lerc_encode() would need to create one mask per "
1062
0
                              "sample, but this requires liblerc >= 3.0");
1063
0
                return 0;
1064
0
#endif
1065
0
            }
1066
0
            else if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
1067
0
                     dst_nbands > 1)
1068
0
            {
1069
0
                if (td->td_bitspersample == 32)
1070
0
                {
1071
0
                    for (i = 0; i < nb_pixels; i++)
1072
0
                    {
1073
0
                        const float val =
1074
0
                            ((float *)sp->uncompressed_buffer)[i * dst_nbands];
1075
0
                        sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
1076
0
                    }
1077
0
                }
1078
0
                else
1079
0
                {
1080
0
                    for (i = 0; i < nb_pixels; i++)
1081
0
                    {
1082
0
                        const double val =
1083
0
                            ((double *)sp->uncompressed_buffer)[i * dst_nbands];
1084
0
                        sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
1085
0
                    }
1086
0
                }
1087
0
            }
1088
0
            else
1089
0
            {
1090
0
                if (td->td_bitspersample == 32)
1091
0
                {
1092
0
                    for (i = 0; i < nb_pixels; i++)
1093
0
                    {
1094
0
                        const float val = ((float *)sp->uncompressed_buffer)[i];
1095
0
                        sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
1096
0
                    }
1097
0
                }
1098
0
                else
1099
0
                {
1100
0
                    for (i = 0; i < nb_pixels; i++)
1101
0
                    {
1102
0
                        const double val =
1103
0
                            ((double *)sp->uncompressed_buffer)[i];
1104
0
                        sp->mask_buffer[i] = !isnan(val) ? 255 : 0;
1105
0
                    }
1106
0
                }
1107
0
            }
1108
0
        }
1109
0
    }
1110
1111
0
    unsigned int estimated_compressed_size = sp->uncompressed_alloc;
1112
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1113
    if (mask_count > 1)
1114
    {
1115
        estimated_compressed_size +=
1116
            (unsigned int)(nb_pixels * (unsigned int)mask_count / 8);
1117
    }
1118
#endif
1119
1120
0
    if (sp->compressed_size < estimated_compressed_size)
1121
0
    {
1122
0
        _TIFFfreeExt(tif, sp->compressed_buffer);
1123
0
        sp->compressed_buffer = _TIFFmallocExt(tif, estimated_compressed_size);
1124
0
        if (!sp->compressed_buffer)
1125
0
        {
1126
0
            sp->compressed_size = 0;
1127
0
            return 0;
1128
0
        }
1129
0
        sp->compressed_size = estimated_compressed_size;
1130
0
    }
1131
1132
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1133
    if (mask_count > 1)
1134
    {
1135
        lerc_ret = lerc_encodeForVersion(
1136
            sp->uncompressed_buffer_multiband, sp->lerc_version,
1137
            (unsigned int)GetLercDataType(tif), 1, (int)sp->segment_width,
1138
            (int)sp->segment_height, (int)dst_nbands, (int)dst_nbands,
1139
            sp->mask_buffer, sp->maxzerror,
1140
            (unsigned char *)sp->compressed_buffer, sp->compressed_size,
1141
            &numBytesWritten);
1142
    }
1143
    else
1144
#endif
1145
0
    {
1146
0
        lerc_ret = lerc_encodeForVersion(
1147
0
            sp->uncompressed_buffer, sp->lerc_version,
1148
0
            (unsigned int)GetLercDataType(tif),
1149
0
            (int)(td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1),
1150
0
            (int)sp->segment_width, (int)sp->segment_height, 1,
1151
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1152
            use_mask ? 1 : 0,
1153
#endif
1154
0
            use_mask ? sp->mask_buffer : NULL, sp->maxzerror,
1155
0
            (unsigned char *)sp->compressed_buffer, sp->compressed_size,
1156
0
            &numBytesWritten);
1157
0
    }
1158
0
    if (lerc_ret != 0)
1159
0
    {
1160
0
        TIFFErrorExtR(tif, module, "lerc_encode() failed");
1161
0
        return 0;
1162
0
    }
1163
0
    assert(numBytesWritten < estimated_compressed_size);
1164
1165
0
    if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
1166
0
    {
1167
0
#if LIBDEFLATE_SUPPORT
1168
0
        if (sp->libdeflate_enc == NULL)
1169
0
        {
1170
            /* To get results as good as zlib, we ask for an extra */
1171
            /* level of compression */
1172
0
            sp->libdeflate_enc = libdeflate_alloc_compressor(
1173
0
                sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
1174
0
                : sp->zipquality >= 6 && sp->zipquality <= 9
1175
0
                    ? sp->zipquality + 1
1176
0
                    : sp->zipquality);
1177
0
            if (sp->libdeflate_enc == NULL)
1178
0
            {
1179
0
                TIFFErrorExtR(tif, module, "Cannot allocate compressor");
1180
0
                return 0;
1181
0
            }
1182
0
        }
1183
1184
        /* Should not happen normally */
1185
0
        if (libdeflate_zlib_compress_bound(
1186
0
                sp->libdeflate_enc, numBytesWritten) > sp->uncompressed_alloc)
1187
0
        {
1188
0
            TIFFErrorExtR(tif, module,
1189
0
                          "Output buffer for libdeflate too small");
1190
0
            return 0;
1191
0
        }
1192
1193
0
        tif->tif_rawcc = (tmsize_t)libdeflate_zlib_compress(
1194
0
            sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten,
1195
0
            sp->uncompressed_buffer, sp->uncompressed_alloc);
1196
1197
0
        if (tif->tif_rawcc == 0)
1198
0
        {
1199
0
            TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
1200
0
                          (unsigned long)tif->tif_dir.td_row);
1201
0
            return 0;
1202
0
        }
1203
#else
1204
        z_stream strm;
1205
        int zlib_ret;
1206
        int cappedQuality = sp->zipquality;
1207
        if (cappedQuality > Z_BEST_COMPRESSION)
1208
            cappedQuality = Z_BEST_COMPRESSION;
1209
1210
        memset(&strm, 0, sizeof(strm));
1211
        strm.zalloc = NULL;
1212
        strm.zfree = NULL;
1213
        strm.opaque = NULL;
1214
        zlib_ret = deflateInit(&strm, cappedQuality);
1215
        if (zlib_ret != Z_OK)
1216
        {
1217
            TIFFErrorExtR(tif, module, "deflateInit() failed");
1218
            return 0;
1219
        }
1220
1221
        strm.avail_in = numBytesWritten;
1222
        strm.next_in = sp->compressed_buffer;
1223
        strm.avail_out = sp->uncompressed_alloc;
1224
        strm.next_out = sp->uncompressed_buffer;
1225
        zlib_ret = deflate(&strm, Z_FINISH);
1226
        if (zlib_ret == Z_STREAM_END)
1227
        {
1228
            tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out;
1229
        }
1230
        deflateEnd(&strm);
1231
        if (zlib_ret != Z_STREAM_END)
1232
        {
1233
            TIFFErrorExtR(tif, module, "deflate() failed");
1234
            return 0;
1235
        }
1236
#endif
1237
0
        {
1238
0
            int ret;
1239
0
            uint8_t *tif_rawdata_backup = tif->tif_rawdata;
1240
0
            tif->tif_rawdata = sp->uncompressed_buffer;
1241
0
            ret = TIFFFlushData1(tif);
1242
0
            tif->tif_rawdata = tif_rawdata_backup;
1243
0
            if (!ret)
1244
0
            {
1245
0
                return 0;
1246
0
            }
1247
0
        }
1248
0
    }
1249
0
    else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
1250
0
    {
1251
0
#ifdef ZSTD_SUPPORT
1252
0
        size_t zstd_ret = ZSTD_compress(
1253
0
            sp->uncompressed_buffer, sp->uncompressed_alloc,
1254
0
            sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level);
1255
0
        if (ZSTD_isError(zstd_ret))
1256
0
        {
1257
0
            TIFFErrorExtR(tif, module, "Error in ZSTD_compress(): %s",
1258
0
                          ZSTD_getErrorName(zstd_ret));
1259
0
            return 0;
1260
0
        }
1261
1262
0
        {
1263
0
            int ret;
1264
0
            uint8_t *tif_rawdata_backup = tif->tif_rawdata;
1265
0
            tif->tif_rawdata = sp->uncompressed_buffer;
1266
0
            tif->tif_rawcc = (tmsize_t)zstd_ret;
1267
0
            ret = TIFFFlushData1(tif);
1268
0
            tif->tif_rawdata = tif_rawdata_backup;
1269
0
            if (!ret)
1270
0
            {
1271
0
                return 0;
1272
0
            }
1273
0
        }
1274
#else
1275
        TIFFErrorExtR(tif, module, "ZSTD support missing");
1276
        return 0;
1277
#endif
1278
0
    }
1279
0
    else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
1280
0
    {
1281
0
        TIFFErrorExtR(tif, module, "Unhandled additional compression");
1282
0
        return 0;
1283
0
    }
1284
0
    else
1285
0
    {
1286
0
        int ret;
1287
0
        uint8_t *tif_rawdata_backup = tif->tif_rawdata;
1288
0
        tif->tif_rawdata = (uint8_t *)sp->compressed_buffer;
1289
0
        tif->tif_rawcc = numBytesWritten;
1290
0
        ret = TIFFFlushData1(tif);
1291
0
        tif->tif_rawdata = tif_rawdata_backup;
1292
0
        if (!ret)
1293
0
            return 0;
1294
0
    }
1295
1296
0
    return 1;
1297
0
}
1298
1299
#endif /* LERC_READ_ONLY */
1300
1301
static void LERCCleanup(TIFF *tif)
1302
26.2k
{
1303
26.2k
    LERCState *sp = GetLERCState(tif);
1304
1305
26.2k
    assert(sp != NULL);
1306
1307
26.2k
    tif->tif_tagmethods.vgetfield = sp->vgetparent;
1308
26.2k
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
1309
1310
26.2k
    _TIFFfreeExt(tif, sp->uncompressed_buffer);
1311
26.2k
    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1312
26.2k
    _TIFFfreeExt(tif, sp->compressed_buffer);
1313
26.2k
    _TIFFfreeExt(tif, sp->mask_buffer);
1314
1315
26.2k
#if LIBDEFLATE_SUPPORT
1316
26.2k
    if (sp->libdeflate_dec)
1317
71
        libdeflate_free_decompressor(sp->libdeflate_dec);
1318
26.2k
    if (sp->libdeflate_enc)
1319
0
        libdeflate_free_compressor(sp->libdeflate_enc);
1320
26.2k
#endif
1321
1322
26.2k
    _TIFFfreeExt(tif, sp);
1323
26.2k
    tif->tif_data = NULL;
1324
1325
26.2k
    _TIFFSetDefaultCompressionState(tif);
1326
26.2k
}
tif_lerc.c:gdal_LERCCleanup
Line
Count
Source
1302
23.4k
{
1303
23.4k
    LERCState *sp = GetLERCState(tif);
1304
1305
23.4k
    assert(sp != NULL);
1306
1307
23.4k
    tif->tif_tagmethods.vgetfield = sp->vgetparent;
1308
23.4k
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
1309
1310
23.4k
    _TIFFfreeExt(tif, sp->uncompressed_buffer);
1311
23.4k
    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1312
23.4k
    _TIFFfreeExt(tif, sp->compressed_buffer);
1313
23.4k
    _TIFFfreeExt(tif, sp->mask_buffer);
1314
1315
23.4k
#if LIBDEFLATE_SUPPORT
1316
23.4k
    if (sp->libdeflate_dec)
1317
23
        libdeflate_free_decompressor(sp->libdeflate_dec);
1318
23.4k
    if (sp->libdeflate_enc)
1319
0
        libdeflate_free_compressor(sp->libdeflate_enc);
1320
23.4k
#endif
1321
1322
23.4k
    _TIFFfreeExt(tif, sp);
1323
23.4k
    tif->tif_data = NULL;
1324
1325
23.4k
    _TIFFSetDefaultCompressionState(tif);
1326
23.4k
}
libertiffdataset.cpp:LERCCleanup(tiff*)
Line
Count
Source
1302
2.85k
{
1303
2.85k
    LERCState *sp = GetLERCState(tif);
1304
1305
2.85k
    assert(sp != NULL);
1306
1307
2.85k
    tif->tif_tagmethods.vgetfield = sp->vgetparent;
1308
2.85k
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
1309
1310
2.85k
    _TIFFfreeExt(tif, sp->uncompressed_buffer);
1311
2.85k
    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1312
2.85k
    _TIFFfreeExt(tif, sp->compressed_buffer);
1313
2.85k
    _TIFFfreeExt(tif, sp->mask_buffer);
1314
1315
2.85k
#if LIBDEFLATE_SUPPORT
1316
2.85k
    if (sp->libdeflate_dec)
1317
48
        libdeflate_free_decompressor(sp->libdeflate_dec);
1318
2.85k
    if (sp->libdeflate_enc)
1319
0
        libdeflate_free_compressor(sp->libdeflate_enc);
1320
2.85k
#endif
1321
1322
2.85k
    _TIFFfreeExt(tif, sp);
1323
2.85k
    tif->tif_data = NULL;
1324
1325
2.85k
    _TIFFSetDefaultCompressionState(tif);
1326
2.85k
}
1327
1328
static const TIFFField LERCFields[] = {
1329
    {TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0,
1330
     TIFF_SETGET_C32_UINT32, FIELD_CUSTOM, FALSE, TRUE,
1331
     (char *)"LercParameters", NULL},
1332
    {TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE,
1333
     FIELD_PSEUDO, TRUE, FALSE, (char *)"LercMaximumError", NULL},
1334
    {TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, FIELD_PSEUDO,
1335
     FALSE, FALSE, (char *)"LercVersion", NULL},
1336
    {TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
1337
     FIELD_PSEUDO, FALSE, FALSE, (char *)"LercAdditionalCompression", NULL},
1338
    {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
1339
     FALSE, (char *)"ZSTD zstd_compress_level", NULL},
1340
    {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
1341
     FALSE, (char *)"", NULL},
1342
};
1343
1344
static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...)
1345
48.0k
{
1346
48.0k
    LERCState *sp = GetLERCState(tif);
1347
48.0k
    int ret;
1348
48.0k
    va_list ap;
1349
48.0k
    va_start(ap, tag);
1350
48.0k
    ret = (*sp->vsetparent)(tif, tag, ap);
1351
48.0k
    va_end(ap);
1352
48.0k
    return ret;
1353
48.0k
}
tif_lerc.c:gdal_LERCVSetFieldBase
Line
Count
Source
1345
48.0k
{
1346
48.0k
    LERCState *sp = GetLERCState(tif);
1347
48.0k
    int ret;
1348
48.0k
    va_list ap;
1349
48.0k
    va_start(ap, tag);
1350
48.0k
    ret = (*sp->vsetparent)(tif, tag, ap);
1351
    va_end(ap);
1352
48.0k
    return ret;
1353
48.0k
}
Unexecuted instantiation: libertiffdataset.cpp:LERCVSetFieldBase(tiff*, unsigned int, ...)
1354
1355
static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
1356
247k
{
1357
247k
    static const char module[] = "LERCVSetField";
1358
247k
    LERCState *sp = GetLERCState(tif);
1359
1360
247k
    switch (tag)
1361
247k
    {
1362
1.72k
        case TIFFTAG_LERC_PARAMETERS:
1363
1.72k
        {
1364
1.72k
            uint32_t count = (uint32_t)va_arg(ap, int);
1365
1.72k
            int *params = va_arg(ap, int *);
1366
1.72k
            if (count < 2)
1367
568
            {
1368
568
                TIFFErrorExtR(tif, module,
1369
568
                              "Invalid count for LercParameters: %u", count);
1370
568
                return 0;
1371
568
            }
1372
1.15k
            sp->lerc_version = params[0];
1373
1.15k
            sp->additional_compression = params[1];
1374
1.15k
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count,
1375
1.15k
                                     params);
1376
1.72k
        }
1377
0
        case TIFFTAG_LERC_MAXZERROR:
1378
0
            sp->maxzerror = va_arg(ap, double);
1379
0
            return 1;
1380
23.4k
        case TIFFTAG_LERC_VERSION:
1381
23.4k
        {
1382
23.4k
            int params[2] = {0, 0};
1383
23.4k
            int version = va_arg(ap, int);
1384
23.4k
            if (version != LERC_VERSION_2_4)
1385
0
            {
1386
0
                TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d",
1387
0
                              version);
1388
0
                return 0;
1389
0
            }
1390
23.4k
            sp->lerc_version = version;
1391
23.4k
            params[0] = sp->lerc_version;
1392
23.4k
            params[1] = sp->additional_compression;
1393
23.4k
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1394
23.4k
        }
1395
23.4k
        case TIFFTAG_LERC_ADD_COMPRESSION:
1396
23.4k
        {
1397
23.4k
            int params[2] = {0, 0};
1398
23.4k
            int additional_compression = va_arg(ap, int);
1399
#ifndef ZSTD_SUPPORT
1400
            if (additional_compression == LERC_ADD_COMPRESSION_ZSTD)
1401
            {
1402
                TIFFErrorExtR(tif, module,
1403
                              "LERC_ZSTD requested, but ZSTD not available");
1404
                return 0;
1405
            }
1406
#endif
1407
23.4k
            if (additional_compression != LERC_ADD_COMPRESSION_NONE &&
1408
0
                additional_compression != LERC_ADD_COMPRESSION_DEFLATE &&
1409
0
                additional_compression != LERC_ADD_COMPRESSION_ZSTD)
1410
0
            {
1411
0
                TIFFErrorExtR(tif, module,
1412
0
                              "Invalid value for LercAdditionalCompression: %d",
1413
0
                              additional_compression);
1414
0
                return 0;
1415
0
            }
1416
23.4k
            sp->additional_compression = additional_compression;
1417
23.4k
            params[0] = sp->lerc_version;
1418
23.4k
            params[1] = sp->additional_compression;
1419
23.4k
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1420
23.4k
        }
1421
0
#ifdef ZSTD_SUPPORT
1422
0
        case TIFFTAG_ZSTD_LEVEL:
1423
0
        {
1424
0
            sp->zstd_compress_level = (int)va_arg(ap, int);
1425
0
            if (sp->zstd_compress_level <= 0 ||
1426
0
                sp->zstd_compress_level > ZSTD_maxCLevel())
1427
0
            {
1428
0
                TIFFWarningExtR(tif, module,
1429
0
                                "ZSTD_LEVEL should be between 1 and %d",
1430
0
                                ZSTD_maxCLevel());
1431
0
            }
1432
0
            return 1;
1433
23.4k
        }
1434
0
#endif
1435
0
        case TIFFTAG_ZIPQUALITY:
1436
0
        {
1437
0
            sp->zipquality = (int)va_arg(ap, int);
1438
0
            if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
1439
0
                sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
1440
0
            {
1441
0
                TIFFErrorExtR(
1442
0
                    tif, module,
1443
0
                    "Invalid ZipQuality value. Should be in [-1,%d] range",
1444
0
                    LIBDEFLATE_MAX_COMPRESSION_LEVEL);
1445
0
                return 0;
1446
0
            }
1447
1448
0
#if LIBDEFLATE_SUPPORT
1449
0
            if (sp->libdeflate_enc)
1450
0
            {
1451
0
                libdeflate_free_compressor(sp->libdeflate_enc);
1452
0
                sp->libdeflate_enc = NULL;
1453
0
            }
1454
0
#endif
1455
1456
0
            return (1);
1457
0
        }
1458
198k
        default:
1459
198k
            return (*sp->vsetparent)(tif, tag, ap);
1460
247k
    }
1461
    /*NOTREACHED*/
1462
247k
}
tif_lerc.c:gdal_LERCVSetField
Line
Count
Source
1356
247k
{
1357
247k
    static const char module[] = "LERCVSetField";
1358
247k
    LERCState *sp = GetLERCState(tif);
1359
1360
247k
    switch (tag)
1361
247k
    {
1362
1.72k
        case TIFFTAG_LERC_PARAMETERS:
1363
1.72k
        {
1364
1.72k
            uint32_t count = (uint32_t)va_arg(ap, int);
1365
1.72k
            int *params = va_arg(ap, int *);
1366
1.72k
            if (count < 2)
1367
568
            {
1368
568
                TIFFErrorExtR(tif, module,
1369
568
                              "Invalid count for LercParameters: %u", count);
1370
568
                return 0;
1371
568
            }
1372
1.15k
            sp->lerc_version = params[0];
1373
1.15k
            sp->additional_compression = params[1];
1374
1.15k
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count,
1375
1.15k
                                     params);
1376
1.72k
        }
1377
0
        case TIFFTAG_LERC_MAXZERROR:
1378
0
            sp->maxzerror = va_arg(ap, double);
1379
0
            return 1;
1380
23.4k
        case TIFFTAG_LERC_VERSION:
1381
23.4k
        {
1382
23.4k
            int params[2] = {0, 0};
1383
23.4k
            int version = va_arg(ap, int);
1384
23.4k
            if (version != LERC_VERSION_2_4)
1385
0
            {
1386
0
                TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d",
1387
0
                              version);
1388
0
                return 0;
1389
0
            }
1390
23.4k
            sp->lerc_version = version;
1391
23.4k
            params[0] = sp->lerc_version;
1392
23.4k
            params[1] = sp->additional_compression;
1393
23.4k
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1394
23.4k
        }
1395
23.4k
        case TIFFTAG_LERC_ADD_COMPRESSION:
1396
23.4k
        {
1397
23.4k
            int params[2] = {0, 0};
1398
23.4k
            int additional_compression = va_arg(ap, int);
1399
#ifndef ZSTD_SUPPORT
1400
            if (additional_compression == LERC_ADD_COMPRESSION_ZSTD)
1401
            {
1402
                TIFFErrorExtR(tif, module,
1403
                              "LERC_ZSTD requested, but ZSTD not available");
1404
                return 0;
1405
            }
1406
#endif
1407
23.4k
            if (additional_compression != LERC_ADD_COMPRESSION_NONE &&
1408
0
                additional_compression != LERC_ADD_COMPRESSION_DEFLATE &&
1409
0
                additional_compression != LERC_ADD_COMPRESSION_ZSTD)
1410
0
            {
1411
0
                TIFFErrorExtR(tif, module,
1412
0
                              "Invalid value for LercAdditionalCompression: %d",
1413
0
                              additional_compression);
1414
0
                return 0;
1415
0
            }
1416
23.4k
            sp->additional_compression = additional_compression;
1417
23.4k
            params[0] = sp->lerc_version;
1418
23.4k
            params[1] = sp->additional_compression;
1419
23.4k
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1420
23.4k
        }
1421
0
#ifdef ZSTD_SUPPORT
1422
0
        case TIFFTAG_ZSTD_LEVEL:
1423
0
        {
1424
0
            sp->zstd_compress_level = (int)va_arg(ap, int);
1425
0
            if (sp->zstd_compress_level <= 0 ||
1426
0
                sp->zstd_compress_level > ZSTD_maxCLevel())
1427
0
            {
1428
0
                TIFFWarningExtR(tif, module,
1429
0
                                "ZSTD_LEVEL should be between 1 and %d",
1430
0
                                ZSTD_maxCLevel());
1431
0
            }
1432
0
            return 1;
1433
23.4k
        }
1434
0
#endif
1435
0
        case TIFFTAG_ZIPQUALITY:
1436
0
        {
1437
0
            sp->zipquality = (int)va_arg(ap, int);
1438
0
            if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
1439
0
                sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
1440
0
            {
1441
0
                TIFFErrorExtR(
1442
0
                    tif, module,
1443
0
                    "Invalid ZipQuality value. Should be in [-1,%d] range",
1444
0
                    LIBDEFLATE_MAX_COMPRESSION_LEVEL);
1445
0
                return 0;
1446
0
            }
1447
1448
0
#if LIBDEFLATE_SUPPORT
1449
0
            if (sp->libdeflate_enc)
1450
0
            {
1451
0
                libdeflate_free_compressor(sp->libdeflate_enc);
1452
0
                sp->libdeflate_enc = NULL;
1453
0
            }
1454
0
#endif
1455
1456
0
            return (1);
1457
0
        }
1458
198k
        default:
1459
198k
            return (*sp->vsetparent)(tif, tag, ap);
1460
247k
    }
1461
    /*NOTREACHED*/
1462
247k
}
Unexecuted instantiation: libertiffdataset.cpp:LERCVSetField(tiff*, unsigned int, __va_list_tag*)
1463
1464
static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap)
1465
1.12M
{
1466
1.12M
    LERCState *sp = GetLERCState(tif);
1467
1468
1.12M
    switch (tag)
1469
1.12M
    {
1470
0
        case TIFFTAG_LERC_MAXZERROR:
1471
0
            *va_arg(ap, double *) = sp->maxzerror;
1472
0
            break;
1473
10.9k
        case TIFFTAG_LERC_VERSION:
1474
10.9k
            *va_arg(ap, int *) = sp->lerc_version;
1475
10.9k
            break;
1476
10.9k
        case TIFFTAG_LERC_ADD_COMPRESSION:
1477
10.9k
            *va_arg(ap, int *) = sp->additional_compression;
1478
10.9k
            break;
1479
0
        case TIFFTAG_ZSTD_LEVEL:
1480
0
            *va_arg(ap, int *) = sp->zstd_compress_level;
1481
0
            break;
1482
0
        case TIFFTAG_ZIPQUALITY:
1483
0
            *va_arg(ap, int *) = sp->zipquality;
1484
0
            break;
1485
1.10M
        default:
1486
1.10M
            return (*sp->vgetparent)(tif, tag, ap);
1487
1.12M
    }
1488
21.8k
    return 1;
1489
1.12M
}
tif_lerc.c:gdal_LERCVGetField
Line
Count
Source
1465
1.12M
{
1466
1.12M
    LERCState *sp = GetLERCState(tif);
1467
1468
1.12M
    switch (tag)
1469
1.12M
    {
1470
0
        case TIFFTAG_LERC_MAXZERROR:
1471
0
            *va_arg(ap, double *) = sp->maxzerror;
1472
0
            break;
1473
10.9k
        case TIFFTAG_LERC_VERSION:
1474
10.9k
            *va_arg(ap, int *) = sp->lerc_version;
1475
10.9k
            break;
1476
10.9k
        case TIFFTAG_LERC_ADD_COMPRESSION:
1477
10.9k
            *va_arg(ap, int *) = sp->additional_compression;
1478
10.9k
            break;
1479
0
        case TIFFTAG_ZSTD_LEVEL:
1480
0
            *va_arg(ap, int *) = sp->zstd_compress_level;
1481
0
            break;
1482
0
        case TIFFTAG_ZIPQUALITY:
1483
0
            *va_arg(ap, int *) = sp->zipquality;
1484
0
            break;
1485
1.10M
        default:
1486
1.10M
            return (*sp->vgetparent)(tif, tag, ap);
1487
1.12M
    }
1488
21.8k
    return 1;
1489
1.12M
}
Unexecuted instantiation: libertiffdataset.cpp:LERCVGetField(tiff*, unsigned int, __va_list_tag*)
1490
1491
int TIFFInitLERC(TIFF *tif, int scheme)
1492
26.2k
{
1493
26.2k
    static const char module[] = "TIFFInitLERC";
1494
26.2k
    LERCState *sp;
1495
1496
26.2k
    (void)scheme;
1497
26.2k
    assert(scheme == COMPRESSION_LERC);
1498
1499
    /*
1500
     * Merge codec-specific tag information.
1501
     */
1502
26.2k
    if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields)))
1503
0
    {
1504
0
        TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed");
1505
0
        return 0;
1506
0
    }
1507
1508
    /*
1509
     * Allocate state block so tag methods have storage to record values.
1510
     */
1511
26.2k
    tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
1512
26.2k
    if (tif->tif_data == NULL)
1513
0
        goto bad;
1514
26.2k
    sp = GetLERCState(tif);
1515
1516
    /*
1517
     * Override parent get/set field methods.
1518
     */
1519
26.2k
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
1520
26.2k
    tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */
1521
26.2k
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
1522
26.2k
    tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */
1523
1524
    /*
1525
     * Install codec methods.
1526
     */
1527
26.2k
    tif->tif_fixuptags = LERCFixupTags;
1528
26.2k
    tif->tif_setupdecode = LERCSetupDecode;
1529
26.2k
    tif->tif_predecode = LERCPreDecode;
1530
26.2k
    tif->tif_decoderow = LERCDecode;
1531
26.2k
    tif->tif_decodestrip = LERCDecode;
1532
26.2k
    tif->tif_decodetile = LERCDecode;
1533
#ifndef LERC_READ_ONLY
1534
23.4k
    tif->tif_setupencode = LERCSetupEncode;
1535
23.4k
    tif->tif_preencode = LERCPreEncode;
1536
23.4k
    tif->tif_postencode = LERCPostEncode;
1537
23.4k
    tif->tif_encoderow = LERCEncode;
1538
23.4k
    tif->tif_encodestrip = LERCEncode;
1539
23.4k
    tif->tif_encodetile = LERCEncode;
1540
#endif
1541
26.2k
    tif->tif_cleanup = LERCCleanup;
1542
1543
    /* LERC compression ratio can grow to several millions */
1544
    /* eg. 5703725 for Lerc deflate on 16383x16383 array */
1545
    /* or 3829644 for regular Lerc */
1546
    /* See README_for_libtiff_developpers.md for raw data used to estimate
1547
     * the maximum compression rate. */
1548
    /* so we don't define tif->tif_getmaxcompressionratio */
1549
1550
    /* Default values for codec-specific fields */
1551
26.2k
    TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
1552
26.2k
    TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
1553
26.2k
    sp->maxzerror = 0.0;
1554
26.2k
    sp->zstd_compress_level = 9;            /* default comp. level */
1555
26.2k
    sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
1556
26.2k
    sp->state = 0;
1557
1558
26.2k
    return 1;
1559
0
bad:
1560
0
    TIFFErrorExtR(tif, module, "No space for LERC state block");
1561
0
    return 0;
1562
26.2k
}
gdal_TIFFInitLERC
Line
Count
Source
1492
23.4k
{
1493
23.4k
    static const char module[] = "TIFFInitLERC";
1494
23.4k
    LERCState *sp;
1495
1496
23.4k
    (void)scheme;
1497
23.4k
    assert(scheme == COMPRESSION_LERC);
1498
1499
    /*
1500
     * Merge codec-specific tag information.
1501
     */
1502
23.4k
    if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields)))
1503
0
    {
1504
0
        TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed");
1505
0
        return 0;
1506
0
    }
1507
1508
    /*
1509
     * Allocate state block so tag methods have storage to record values.
1510
     */
1511
23.4k
    tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
1512
23.4k
    if (tif->tif_data == NULL)
1513
0
        goto bad;
1514
23.4k
    sp = GetLERCState(tif);
1515
1516
    /*
1517
     * Override parent get/set field methods.
1518
     */
1519
23.4k
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
1520
23.4k
    tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */
1521
23.4k
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
1522
23.4k
    tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */
1523
1524
    /*
1525
     * Install codec methods.
1526
     */
1527
23.4k
    tif->tif_fixuptags = LERCFixupTags;
1528
23.4k
    tif->tif_setupdecode = LERCSetupDecode;
1529
23.4k
    tif->tif_predecode = LERCPreDecode;
1530
23.4k
    tif->tif_decoderow = LERCDecode;
1531
23.4k
    tif->tif_decodestrip = LERCDecode;
1532
23.4k
    tif->tif_decodetile = LERCDecode;
1533
23.4k
#ifndef LERC_READ_ONLY
1534
23.4k
    tif->tif_setupencode = LERCSetupEncode;
1535
23.4k
    tif->tif_preencode = LERCPreEncode;
1536
23.4k
    tif->tif_postencode = LERCPostEncode;
1537
23.4k
    tif->tif_encoderow = LERCEncode;
1538
23.4k
    tif->tif_encodestrip = LERCEncode;
1539
23.4k
    tif->tif_encodetile = LERCEncode;
1540
23.4k
#endif
1541
23.4k
    tif->tif_cleanup = LERCCleanup;
1542
1543
    /* LERC compression ratio can grow to several millions */
1544
    /* eg. 5703725 for Lerc deflate on 16383x16383 array */
1545
    /* or 3829644 for regular Lerc */
1546
    /* See README_for_libtiff_developpers.md for raw data used to estimate
1547
     * the maximum compression rate. */
1548
    /* so we don't define tif->tif_getmaxcompressionratio */
1549
1550
    /* Default values for codec-specific fields */
1551
23.4k
    TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
1552
23.4k
    TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
1553
23.4k
    sp->maxzerror = 0.0;
1554
23.4k
    sp->zstd_compress_level = 9;            /* default comp. level */
1555
23.4k
    sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
1556
23.4k
    sp->state = 0;
1557
1558
23.4k
    return 1;
1559
0
bad:
1560
0
    TIFFErrorExtR(tif, module, "No space for LERC state block");
1561
0
    return 0;
1562
23.4k
}
LIBERTIFF_TIFFInitLERC
Line
Count
Source
1492
2.85k
{
1493
2.85k
    static const char module[] = "TIFFInitLERC";
1494
2.85k
    LERCState *sp;
1495
1496
2.85k
    (void)scheme;
1497
2.85k
    assert(scheme == COMPRESSION_LERC);
1498
1499
    /*
1500
     * Merge codec-specific tag information.
1501
     */
1502
2.85k
    if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields)))
1503
0
    {
1504
0
        TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed");
1505
0
        return 0;
1506
0
    }
1507
1508
    /*
1509
     * Allocate state block so tag methods have storage to record values.
1510
     */
1511
2.85k
    tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
1512
2.85k
    if (tif->tif_data == NULL)
1513
0
        goto bad;
1514
2.85k
    sp = GetLERCState(tif);
1515
1516
    /*
1517
     * Override parent get/set field methods.
1518
     */
1519
2.85k
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
1520
2.85k
    tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */
1521
2.85k
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
1522
2.85k
    tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */
1523
1524
    /*
1525
     * Install codec methods.
1526
     */
1527
2.85k
    tif->tif_fixuptags = LERCFixupTags;
1528
2.85k
    tif->tif_setupdecode = LERCSetupDecode;
1529
2.85k
    tif->tif_predecode = LERCPreDecode;
1530
2.85k
    tif->tif_decoderow = LERCDecode;
1531
2.85k
    tif->tif_decodestrip = LERCDecode;
1532
2.85k
    tif->tif_decodetile = LERCDecode;
1533
#ifndef LERC_READ_ONLY
1534
    tif->tif_setupencode = LERCSetupEncode;
1535
    tif->tif_preencode = LERCPreEncode;
1536
    tif->tif_postencode = LERCPostEncode;
1537
    tif->tif_encoderow = LERCEncode;
1538
    tif->tif_encodestrip = LERCEncode;
1539
    tif->tif_encodetile = LERCEncode;
1540
#endif
1541
2.85k
    tif->tif_cleanup = LERCCleanup;
1542
1543
    /* LERC compression ratio can grow to several millions */
1544
    /* eg. 5703725 for Lerc deflate on 16383x16383 array */
1545
    /* or 3829644 for regular Lerc */
1546
    /* See README_for_libtiff_developpers.md for raw data used to estimate
1547
     * the maximum compression rate. */
1548
    /* so we don't define tif->tif_getmaxcompressionratio */
1549
1550
    /* Default values for codec-specific fields */
1551
2.85k
    TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
1552
2.85k
    TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
1553
2.85k
    sp->maxzerror = 0.0;
1554
2.85k
    sp->zstd_compress_level = 9;            /* default comp. level */
1555
2.85k
    sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
1556
2.85k
    sp->state = 0;
1557
1558
2.85k
    return 1;
1559
0
bad:
1560
0
    TIFFErrorExtR(tif, module, "No space for LERC state block");
1561
0
    return 0;
1562
2.85k
}
1563
#endif /* LERC_SUPPORT */