Coverage Report

Created: 2026-04-10 07:04

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