Coverage Report

Created: 2026-09-14 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libtiff/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
28
#define LSTATE_INIT_DECODE 0x01
49
14
#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
2.21k
#define GetLERCState(tif) ((LERCState *)(tif)->tif_data)
94
28
#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
32
{
101
32
    (void)tif;
102
32
    return 1;
103
32
}
104
105
static int LERCSetupDecode(TIFF *tif)
106
14
{
107
14
    LERCState *sp = LERCDecoderState(tif);
108
109
14
    assert(sp != NULL);
110
111
    /* if we were last encoding, terminate this mode */
112
14
    if (sp->state & LSTATE_INIT_ENCODE)
113
0
    {
114
0
        sp->state = 0;
115
0
    }
116
117
14
    sp->state |= LSTATE_INIT_DECODE;
118
14
    return 1;
119
14
}
120
121
static int GetLercDataType(TIFF *tif)
122
14
{
123
14
    TIFFDirectory *td = &tif->tif_dir;
124
14
    static const char module[] = "GetLercDataType";
125
126
14
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8)
127
1
    {
128
1
        return 0;
129
1
    }
130
131
13
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8)
132
7
    {
133
7
        return 1;
134
7
    }
135
136
6
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16)
137
0
    {
138
0
        return 2;
139
0
    }
140
141
6
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16)
142
2
    {
143
2
        return 3;
144
2
    }
145
146
4
    if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32)
147
0
    {
148
0
        return 4;
149
0
    }
150
151
4
    if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32)
152
1
    {
153
1
        return 5;
154
1
    }
155
156
3
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
157
1
        td->td_bitspersample == 32)
158
0
    {
159
0
        return 6;
160
0
    }
161
162
3
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
163
1
        td->td_bitspersample == 64)
164
0
    {
165
0
        return 7;
166
0
    }
167
168
3
    TIFFErrorExtR(
169
3
        tif, module,
170
3
        "Unsupported combination of SampleFormat and td_bitspersample");
171
3
    return -1;
172
3
}
173
174
static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
175
11
{
176
11
    TIFFDirectory *td = &tif->tif_dir;
177
11
    uint64_t new_size_64;
178
11
    uint64_t new_alloc_64;
179
11
    unsigned int new_size;
180
11
    unsigned int new_alloc;
181
182
11
    sp->uncompressed_offset = 0;
183
184
11
    if (isTiled(tif))
185
0
    {
186
0
        sp->segment_width = td->td_tilewidth;
187
0
        sp->segment_height = td->td_tilelength;
188
0
    }
189
11
    else
190
11
    {
191
11
        sp->segment_width = td->td_imagewidth;
192
11
        sp->segment_height = td->td_imagelength - tif->tif_dir.td_row;
193
11
        if (sp->segment_height > td->td_rowsperstrip)
194
2
            sp->segment_height = td->td_rowsperstrip;
195
11
    }
196
197
11
    new_size_64 = (uint64_t)sp->segment_width * sp->segment_height *
198
11
                  (td->td_bitspersample / 8);
199
11
    if (td->td_planarconfig == PLANARCONFIG_CONTIG)
200
9
    {
201
9
        new_size_64 *= td->td_samplesperpixel;
202
9
    }
203
204
11
    new_size = (unsigned int)new_size_64;
205
11
    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
11
    new_alloc_64 = 256 + new_size_64 + new_size_64 / 3;
211
11
#ifdef ZSTD_SUPPORT
212
11
    {
213
11
        size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
214
11
        if (new_alloc_64 < zstd_max)
215
0
        {
216
0
            new_alloc_64 = zstd_max;
217
0
        }
218
11
    }
219
11
#endif
220
11
    new_alloc = (unsigned int)new_alloc_64;
221
11
    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
11
    if (sp->uncompressed_alloc < new_alloc)
231
11
    {
232
11
        _TIFFfreeExt(tif, sp->uncompressed_buffer);
233
11
        sp->uncompressed_buffer = (uint8_t *)_TIFFmallocExt(tif, new_alloc);
234
11
        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
11
        sp->uncompressed_alloc = new_alloc;
243
11
    }
244
245
11
    if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
246
9
         td->td_extrasamples > 0 && td->td_sampleinfo &&
247
6
         td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
248
0
         GetLercDataType(tif) == 1) ||
249
11
        (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
250
0
         (td->td_bitspersample == 32 || td->td_bitspersample == 64)))
251
0
    {
252
0
        unsigned int mask_size = sp->segment_width * sp->segment_height;
253
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
254
0
        if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
255
0
            td->td_planarconfig == PLANARCONFIG_CONTIG)
256
0
        {
257
            /* We may need one mask per band */
258
0
            mask_size *= td->td_samplesperpixel;
259
0
        }
260
0
#endif
261
0
        if (sp->mask_size < mask_size)
262
0
        {
263
0
            void *mask_buffer =
264
0
                _TIFFreallocExt(tif, sp->mask_buffer, mask_size);
265
0
            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
0
            sp->mask_buffer = (uint8_t *)mask_buffer;
275
0
            sp->mask_size = mask_size;
276
0
        }
277
0
    }
278
279
11
    return 1;
280
11
}
281
282
/*
283
 * Setup state for decoding a strip.
284
 */
285
static int LERCPreDecode(TIFF *tif, uint16_t s)
286
14
{
287
14
    static const char module[] = "LERCPreDecode";
288
14
    lerc_status lerc_ret;
289
14
    TIFFDirectory *td = &tif->tif_dir;
290
14
    LERCState *sp = LERCDecoderState(tif);
291
14
    int lerc_data_type;
292
14
    unsigned int infoArray[9];
293
14
    unsigned nomask_bands = td->td_samplesperpixel;
294
14
    int ndims;
295
14
    int use_mask = 0;
296
14
    uint8_t *lerc_data = tif->tif_rawcp;
297
14
    unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc;
298
299
14
    (void)s;
300
14
    assert(sp != NULL);
301
14
    if (sp->state != LSTATE_INIT_DECODE)
302
0
        tif->tif_setupdecode(tif);
303
304
14
    lerc_data_type = GetLercDataType(tif);
305
14
    if (lerc_data_type < 0)
306
3
        return 0;
307
308
11
    if (!SetupBuffers(tif, sp, module))
309
0
        return 0;
310
311
11
    if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
312
0
    {
313
0
        if (sp->compressed_size < sp->uncompressed_alloc)
314
0
        {
315
0
            _TIFFfreeExt(tif, sp->compressed_buffer);
316
0
            sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc);
317
0
            if (!sp->compressed_buffer)
318
0
            {
319
0
                sp->compressed_size = 0;
320
0
                return 0;
321
0
            }
322
0
            sp->compressed_size = sp->uncompressed_alloc;
323
0
        }
324
0
    }
325
326
11
    if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
327
0
    {
328
0
#if LIBDEFLATE_SUPPORT
329
0
        enum libdeflate_result res;
330
0
        size_t lerc_data_sizet = 0;
331
0
        if (sp->libdeflate_dec == NULL)
332
0
        {
333
0
            sp->libdeflate_dec = libdeflate_alloc_decompressor();
334
0
            if (sp->libdeflate_dec == NULL)
335
0
            {
336
0
                TIFFErrorExtR(tif, module, "Cannot allocate decompressor");
337
0
                return 0;
338
0
            }
339
0
        }
340
341
0
        res = libdeflate_zlib_decompress(
342
0
            sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc,
343
0
            sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet);
344
0
        if (res != LIBDEFLATE_SUCCESS)
345
0
        {
346
0
            TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
347
0
                          (unsigned long)tif->tif_dir.td_row);
348
0
            return 0;
349
0
        }
350
0
        assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
351
0
        lerc_data = (uint8_t *)sp->compressed_buffer;
352
0
        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
0
    }
385
11
    else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
386
0
    {
387
0
#ifdef ZSTD_SUPPORT
388
0
        size_t zstd_ret;
389
390
0
        zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
391
0
                                   tif->tif_rawcp, (size_t)tif->tif_rawcc);
392
0
        if (ZSTD_isError(zstd_ret))
393
0
        {
394
0
            TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
395
0
                          ZSTD_getErrorName(zstd_ret));
396
0
            return 0;
397
0
        }
398
399
0
        lerc_data = (uint8_t *)sp->compressed_buffer;
400
0
        lerc_data_size = (unsigned int)zstd_ret;
401
#else
402
        TIFFErrorExtR(tif, module, "ZSTD support missing");
403
        return 0;
404
#endif
405
0
    }
406
11
    else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
407
0
    {
408
0
        TIFFErrorExtR(tif, module, "Unhandled additional compression");
409
0
        return 0;
410
0
    }
411
412
11
    lerc_ret =
413
11
        lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 9, 0);
414
11
    if (lerc_ret != 0)
415
11
    {
416
11
        TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed");
417
11
        return 0;
418
11
    }
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
0
    if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
424
0
        td->td_sampleinfo &&
425
0
        td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
426
0
        GetLercDataType(tif) == 1 &&
427
0
        infoArray[2] == td->td_samplesperpixel - 1U)
428
0
    {
429
0
        use_mask = 1;
430
0
        nomask_bands--;
431
0
    }
432
0
    else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
433
0
    {
434
0
        use_mask = 1;
435
0
    }
436
437
0
    ndims =
438
0
        (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
0
    if (infoArray[0] != (unsigned)sp->lerc_version)
444
0
    {
445
0
        TIFFWarningExtR(tif, module,
446
0
                        "Unexpected version number: %u. Expected: %d",
447
0
                        infoArray[0], sp->lerc_version);
448
0
    }
449
0
    if (infoArray[1] != (unsigned)lerc_data_type)
450
0
    {
451
0
        TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d",
452
0
                      infoArray[1], lerc_data_type);
453
0
        return 0;
454
0
    }
455
456
0
    const unsigned nFoundDims = infoArray[2];
457
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
458
0
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
459
0
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
460
0
        td->td_samplesperpixel > 1)
461
0
    {
462
0
        if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
463
0
        {
464
0
            TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d",
465
0
                          nFoundDims, ndims);
466
0
            return 0;
467
0
        }
468
0
    }
469
0
    else
470
0
#endif
471
0
        if (nFoundDims != (unsigned)ndims)
472
0
    {
473
0
        TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d",
474
0
                      nFoundDims, ndims);
475
0
        return 0;
476
0
    }
477
478
0
    if (infoArray[3] != sp->segment_width)
479
0
    {
480
0
        TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u",
481
0
                      infoArray[3], sp->segment_width);
482
0
        return 0;
483
0
    }
484
0
    if (infoArray[4] != sp->segment_height)
485
0
    {
486
0
        TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u",
487
0
                      infoArray[4], sp->segment_height);
488
0
        return 0;
489
0
    }
490
491
0
    const unsigned nFoundBands = infoArray[5];
492
0
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
493
0
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
494
0
        td->td_samplesperpixel > 1 && nFoundDims == 1)
495
0
    {
496
#if !LERC_AT_LEAST_VERSION(3, 0, 0)
497
        if (nFoundBands == td->td_samplesperpixel)
498
        {
499
            TIFFErrorExtR(
500
                tif, module,
501
                "Unexpected nBands: %d. This file may have been generated with "
502
                "a liblerc version >= 3.0, with one mask per band, and is not "
503
                "supported by this older version of liblerc",
504
                nFoundBands);
505
            return 0;
506
        }
507
#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
0
    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
0
    if (infoArray[7] != lerc_data_size)
523
0
    {
524
0
        TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u",
525
0
                      infoArray[7], lerc_data_size);
526
0
        return 0;
527
0
    }
528
529
0
    int nRequestedMasks = use_mask ? 1 : 0;
530
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
531
0
    const int nFoundMasks = (int)infoArray[8];
532
0
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
533
0
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
534
0
        td->td_samplesperpixel > 1 && nFoundDims == 1)
535
0
    {
536
0
        if (nFoundMasks != 0 && nFoundMasks != td->td_samplesperpixel)
537
0
        {
538
0
            TIFFErrorExtR(tif, module,
539
0
                          "Unexpected nFoundMasks: %d. Expected: 0 or %d",
540
0
                          nFoundMasks, td->td_samplesperpixel);
541
0
            return 0;
542
0
        }
543
0
        nRequestedMasks = nFoundMasks;
544
0
    }
545
0
    else
546
0
    {
547
0
        if (nFoundMasks != 0 && nFoundMasks != 1)
548
0
        {
549
0
            TIFFErrorExtR(tif, module,
550
0
                          "Unexpected nFoundMasks: %d. Expected: 0 or 1",
551
0
                          nFoundMasks);
552
0
            return 0;
553
0
        }
554
0
    }
555
0
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && nFoundMasks == 0)
556
0
    {
557
0
        nRequestedMasks = 0;
558
0
        use_mask = 0;
559
0
    }
560
0
#endif
561
562
0
    const unsigned nb_pixels = sp->segment_width * sp->segment_height;
563
564
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
565
0
    if (nRequestedMasks > 1)
566
0
    {
567
0
        unsigned int num_bytes_needed =
568
0
            nb_pixels * td->td_samplesperpixel * (td->td_bitspersample / 8);
569
0
        if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
570
0
        {
571
0
            _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
572
0
            sp->uncompressed_buffer_multiband =
573
0
                (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
574
0
            if (!sp->uncompressed_buffer_multiband)
575
0
            {
576
0
                sp->uncompressed_buffer_multiband_alloc = 0;
577
0
                return 0;
578
0
            }
579
0
            sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
580
0
        }
581
0
        lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
582
0
                               sp->mask_buffer, (int)nFoundDims,
583
0
                               (int)sp->segment_width, (int)sp->segment_height,
584
0
                               (int)nFoundBands, (unsigned int)lerc_data_type,
585
0
                               sp->uncompressed_buffer_multiband);
586
0
    }
587
0
    else
588
0
#endif
589
0
    {
590
0
        lerc_ret = lerc_decode(
591
0
            lerc_data, lerc_data_size,
592
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
593
0
            nRequestedMasks,
594
0
#endif
595
0
            use_mask ? sp->mask_buffer : NULL, (int)nFoundDims,
596
0
            (int)sp->segment_width, (int)sp->segment_height, (int)nFoundBands,
597
0
            (unsigned int)lerc_data_type, sp->uncompressed_buffer);
598
0
    }
599
0
    if (lerc_ret != 0)
600
0
    {
601
0
        TIFFErrorExtR(tif, module, "lerc_decode() failed");
602
0
        return 0;
603
0
    }
604
605
    /* Interleave alpha mask with other samples. */
606
0
    if (use_mask && GetLercDataType(tif) == 1)
607
0
    {
608
0
        unsigned src_stride = (unsigned int)((td->td_samplesperpixel - 1) *
609
0
                                             (td->td_bitspersample / 8));
610
0
        unsigned dst_stride =
611
0
            (unsigned int)(td->td_samplesperpixel * (td->td_bitspersample / 8));
612
0
        unsigned i = sp->segment_width * sp->segment_height;
613
        /* Operate from end to begin to be able to move in place */
614
0
        while (i > 0 && i > nomask_bands)
615
0
        {
616
0
            i--;
617
0
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
618
0
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
619
0
            memcpy(sp->uncompressed_buffer + i * dst_stride,
620
0
                   sp->uncompressed_buffer + i * src_stride, src_stride);
621
0
        }
622
        /* First pixels must use memmove due to overlapping areas */
623
0
        while (i > 0)
624
0
        {
625
0
            i--;
626
0
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
627
0
                                    1] = (uint8_t)(255 * sp->mask_buffer[i]);
628
0
            memmove(sp->uncompressed_buffer + i * dst_stride,
629
0
                    sp->uncompressed_buffer + i * src_stride, src_stride);
630
0
        }
631
0
    }
632
0
    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
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
698
0
        else
699
0
        {
700
0
            assert(nRequestedMasks == td->td_samplesperpixel);
701
0
            assert(nFoundDims == 1);
702
0
            assert(nFoundBands == td->td_samplesperpixel);
703
704
0
            unsigned k = 0;
705
0
            if (td->td_bitspersample == 32)
706
0
            {
707
0
                for (i = 0; i < nb_pixels; i++)
708
0
                {
709
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
710
0
                    {
711
0
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
712
0
                            0)
713
0
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
714
0
                        else
715
0
                            ((float *)sp->uncompressed_buffer)[k] =
716
0
                                ((float *)sp->uncompressed_buffer_multiband)
717
0
                                    [i + (unsigned int)j * nb_pixels];
718
0
                        ++k;
719
0
                    }
720
0
                }
721
0
            }
722
0
            else
723
0
            {
724
0
                const double nan_float64 = (double)nan_float32;
725
0
                for (i = 0; i < nb_pixels; i++)
726
0
                {
727
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
728
0
                    {
729
0
                        if (sp->mask_buffer[i + (unsigned int)j * nb_pixels] ==
730
0
                            0)
731
0
                            ((double *)sp->uncompressed_buffer)[k] =
732
0
                                nan_float64;
733
0
                        else
734
0
                            ((double *)sp->uncompressed_buffer)[k] =
735
0
                                ((double *)sp->uncompressed_buffer_multiband)
736
0
                                    [i + (unsigned int)j * nb_pixels];
737
0
                        ++k;
738
0
                    }
739
0
                }
740
0
            }
741
0
        }
742
0
#endif
743
0
    }
744
745
0
    return 1;
746
0
}
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
0
{
753
0
    static const char module[] = "LERCDecode";
754
0
    LERCState *sp = LERCDecoderState(tif);
755
756
0
    (void)s;
757
0
    assert(sp != NULL);
758
0
    assert(sp->state == LSTATE_INIT_DECODE);
759
760
0
    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
0
    if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
768
0
        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
0
    memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, (size_t)occ);
776
0
    sp->uncompressed_offset += (unsigned int)occ;
777
778
0
    return 1;
779
0
}
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
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1011
0
                unsigned int num_bytes_needed =
1012
0
                    nb_pixels * dst_nbands * (td->td_bitspersample / 8);
1013
0
                if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
1014
0
                {
1015
0
                    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1016
0
                    sp->uncompressed_buffer_multiband =
1017
0
                        (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
1018
0
                    if (!sp->uncompressed_buffer_multiband)
1019
0
                    {
1020
0
                        sp->uncompressed_buffer_multiband_alloc = 0;
1021
0
                        return 0;
1022
0
                    }
1023
0
                    sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
1024
0
                }
1025
1026
0
                unsigned k = 0;
1027
0
                if (td->td_bitspersample == 32)
1028
0
                {
1029
0
                    for (i = 0; i < nb_pixels; i++)
1030
0
                    {
1031
0
                        for (int j = 0; j < td->td_samplesperpixel; ++j)
1032
0
                        {
1033
0
                            const float val =
1034
0
                                ((float *)sp->uncompressed_buffer)[k];
1035
0
                            ((float *)sp->uncompressed_buffer_multiband)
1036
0
                                [i + (unsigned int)j * nb_pixels] = val;
1037
0
                            ++k;
1038
0
                            sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
1039
0
                                !isnan(val) ? 255 : 0;
1040
0
                        }
1041
0
                    }
1042
0
                }
1043
0
                else
1044
0
                {
1045
0
                    for (i = 0; i < nb_pixels; i++)
1046
0
                    {
1047
0
                        for (int j = 0; j < td->td_samplesperpixel; ++j)
1048
0
                        {
1049
0
                            const double val =
1050
0
                                ((double *)sp->uncompressed_buffer)[k];
1051
0
                            ((double *)sp->uncompressed_buffer_multiband)
1052
0
                                [i + (unsigned int)j * nb_pixels] = val;
1053
0
                            ++k;
1054
0
                            sp->mask_buffer[i + (unsigned int)j * nb_pixels] =
1055
0
                                !isnan(val) ? 255 : 0;
1056
0
                        }
1057
0
                    }
1058
0
                }
1059
#else
1060
                TIFFErrorExtR(tif, module,
1061
                              "lerc_encode() would need to create one mask per "
1062
                              "sample, but this requires liblerc >= 3.0");
1063
                return 0;
1064
#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
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1113
0
    if (mask_count > 1)
1114
0
    {
1115
0
        estimated_compressed_size +=
1116
0
            (unsigned int)(nb_pixels * (unsigned int)mask_count / 8);
1117
0
    }
1118
0
#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
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1133
0
    if (mask_count > 1)
1134
0
    {
1135
0
        lerc_ret = lerc_encodeForVersion(
1136
0
            sp->uncompressed_buffer_multiband, sp->lerc_version,
1137
0
            (unsigned int)GetLercDataType(tif), 1, (int)sp->segment_width,
1138
0
            (int)sp->segment_height, (int)dst_nbands, (int)dst_nbands,
1139
0
            sp->mask_buffer, sp->maxzerror,
1140
0
            (unsigned char *)sp->compressed_buffer, sp->compressed_size,
1141
0
            &numBytesWritten);
1142
0
    }
1143
0
    else
1144
0
#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
0
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1152
0
            use_mask ? 1 : 0,
1153
0
#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
74
{
1303
74
    LERCState *sp = GetLERCState(tif);
1304
1305
74
    assert(sp != NULL);
1306
1307
74
    tif->tif_tagmethods.vgetfield = sp->vgetparent;
1308
74
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
1309
1310
74
    _TIFFfreeExt(tif, sp->uncompressed_buffer);
1311
74
    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1312
74
    _TIFFfreeExt(tif, sp->compressed_buffer);
1313
74
    _TIFFfreeExt(tif, sp->mask_buffer);
1314
1315
74
#if LIBDEFLATE_SUPPORT
1316
74
    if (sp->libdeflate_dec)
1317
0
        libdeflate_free_decompressor(sp->libdeflate_dec);
1318
74
    if (sp->libdeflate_enc)
1319
0
        libdeflate_free_compressor(sp->libdeflate_enc);
1320
74
#endif
1321
1322
74
    _TIFFfreeExt(tif, sp);
1323
74
    tif->tif_data = NULL;
1324
1325
74
    _TIFFSetDefaultCompressionState(tif);
1326
74
}
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
156
{
1346
156
    LERCState *sp = GetLERCState(tif);
1347
156
    int ret;
1348
156
    va_list ap;
1349
156
    va_start(ap, tag);
1350
156
    ret = (*sp->vsetparent)(tif, tag, ap);
1351
156
    va_end(ap);
1352
156
    return ret;
1353
156
}
1354
1355
static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
1356
1.46k
{
1357
1.46k
    static const char module[] = "LERCVSetField";
1358
1.46k
    LERCState *sp = GetLERCState(tif);
1359
1360
1.46k
    switch (tag)
1361
1.46k
    {
1362
8
        case TIFFTAG_LERC_PARAMETERS:
1363
8
        {
1364
8
            uint32_t count = (uint32_t)va_arg(ap, int);
1365
8
            int *params = va_arg(ap, int *);
1366
8
            if (count < 2)
1367
0
            {
1368
0
                TIFFErrorExtR(tif, module,
1369
0
                              "Invalid count for LercParameters: %u", count);
1370
0
                return 0;
1371
0
            }
1372
8
            sp->lerc_version = params[0];
1373
8
            sp->additional_compression = params[1];
1374
8
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count,
1375
8
                                     params);
1376
8
        }
1377
0
        case TIFFTAG_LERC_MAXZERROR:
1378
0
            sp->maxzerror = va_arg(ap, double);
1379
0
            return 1;
1380
74
        case TIFFTAG_LERC_VERSION:
1381
74
        {
1382
74
            int params[2] = {0, 0};
1383
74
            int version = va_arg(ap, int);
1384
74
            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
74
            sp->lerc_version = version;
1391
74
            params[0] = sp->lerc_version;
1392
74
            params[1] = sp->additional_compression;
1393
74
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1394
74
        }
1395
74
        case TIFFTAG_LERC_ADD_COMPRESSION:
1396
74
        {
1397
74
            int params[2] = {0, 0};
1398
74
            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
74
            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
74
            sp->additional_compression = additional_compression;
1417
74
            params[0] = sp->lerc_version;
1418
74
            params[1] = sp->additional_compression;
1419
74
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1420
74
        }
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
74
        }
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
1.30k
        default:
1459
1.30k
            return (*sp->vsetparent)(tif, tag, ap);
1460
1.46k
    }
1461
    /*NOTREACHED*/
1462
1.46k
}
1463
1464
static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap)
1465
422
{
1466
422
    LERCState *sp = GetLERCState(tif);
1467
1468
422
    switch (tag)
1469
422
    {
1470
0
        case TIFFTAG_LERC_MAXZERROR:
1471
0
            *va_arg(ap, double *) = sp->maxzerror;
1472
0
            break;
1473
0
        case TIFFTAG_LERC_VERSION:
1474
0
            *va_arg(ap, int *) = sp->lerc_version;
1475
0
            break;
1476
0
        case TIFFTAG_LERC_ADD_COMPRESSION:
1477
0
            *va_arg(ap, int *) = sp->additional_compression;
1478
0
            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
422
        default:
1486
422
            return (*sp->vgetparent)(tif, tag, ap);
1487
422
    }
1488
0
    return 1;
1489
422
}
1490
1491
int TIFFInitLERC(TIFF *tif, int scheme)
1492
74
{
1493
74
    static const char module[] = "TIFFInitLERC";
1494
74
    LERCState *sp;
1495
1496
74
    (void)scheme;
1497
74
    assert(scheme == COMPRESSION_LERC);
1498
1499
    /*
1500
     * Merge codec-specific tag information.
1501
     */
1502
74
    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
74
    tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
1512
74
    if (tif->tif_data == NULL)
1513
0
        goto bad;
1514
74
    sp = GetLERCState(tif);
1515
1516
    /*
1517
     * Override parent get/set field methods.
1518
     */
1519
74
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
1520
74
    tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */
1521
74
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
1522
74
    tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */
1523
1524
    /*
1525
     * Install codec methods.
1526
     */
1527
74
    tif->tif_fixuptags = LERCFixupTags;
1528
74
    tif->tif_setupdecode = LERCSetupDecode;
1529
74
    tif->tif_predecode = LERCPreDecode;
1530
74
    tif->tif_decoderow = LERCDecode;
1531
74
    tif->tif_decodestrip = LERCDecode;
1532
74
    tif->tif_decodetile = LERCDecode;
1533
74
#ifndef LERC_READ_ONLY
1534
74
    tif->tif_setupencode = LERCSetupEncode;
1535
74
    tif->tif_preencode = LERCPreEncode;
1536
74
    tif->tif_postencode = LERCPostEncode;
1537
74
    tif->tif_encoderow = LERCEncode;
1538
74
    tif->tif_encodestrip = LERCEncode;
1539
74
    tif->tif_encodetile = LERCEncode;
1540
74
#endif
1541
74
    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
74
    TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
1552
74
    TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
1553
74
    sp->maxzerror = 0.0;
1554
74
    sp->zstd_compress_level = 9;            /* default comp. level */
1555
74
    sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
1556
74
    sp->state = 0;
1557
1558
74
    return 1;
1559
0
bad:
1560
0
    TIFFErrorExtR(tif, module, "No space for LERC state block");
1561
0
    return 0;
1562
74
}
1563
#endif /* LERC_SUPPORT */