Coverage Report

Created: 2026-04-01 06:20

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, 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 = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1;
437
438
    /* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
439
        nRows, nBands, nValidPixels, blobSize,
440
        and starting with liblerc 3.0 nRequestedMasks } */
441
0
    if (infoArray[0] != (unsigned)sp->lerc_version)
442
0
    {
443
0
        TIFFWarningExtR(tif, module,
444
0
                        "Unexpected version number: %u. Expected: %d",
445
0
                        infoArray[0], sp->lerc_version);
446
0
    }
447
0
    if (infoArray[1] != (unsigned)lerc_data_type)
448
0
    {
449
0
        TIFFErrorExtR(tif, module, "Unexpected dataType: %u. Expected: %d",
450
0
                      infoArray[1], lerc_data_type);
451
0
        return 0;
452
0
    }
453
454
0
    const unsigned nFoundDims = infoArray[2];
455
#if LERC_AT_LEAST_VERSION(3, 0, 0)
456
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
457
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
458
        td->td_samplesperpixel > 1)
459
    {
460
        if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
461
        {
462
            TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: 1 or %d",
463
                          nFoundDims, ndims);
464
            return 0;
465
        }
466
    }
467
    else
468
#endif
469
0
        if (nFoundDims != (unsigned)ndims)
470
0
    {
471
0
        TIFFErrorExtR(tif, module, "Unexpected nDim: %u. Expected: %d",
472
0
                      nFoundDims, ndims);
473
0
        return 0;
474
0
    }
475
476
0
    if (infoArray[3] != sp->segment_width)
477
0
    {
478
0
        TIFFErrorExtR(tif, module, "Unexpected nCols: %u. Expected: %u",
479
0
                      infoArray[3], sp->segment_width);
480
0
        return 0;
481
0
    }
482
0
    if (infoArray[4] != sp->segment_height)
483
0
    {
484
0
        TIFFErrorExtR(tif, module, "Unexpected nRows: %u. Expected: %u",
485
0
                      infoArray[4], sp->segment_height);
486
0
        return 0;
487
0
    }
488
489
0
    const unsigned nFoundBands = infoArray[5];
490
0
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
491
0
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
492
0
        td->td_samplesperpixel > 1 && nFoundDims == 1)
493
0
    {
494
0
#if !LERC_AT_LEAST_VERSION(3, 0, 0)
495
0
        if (nFoundBands == td->td_samplesperpixel)
496
0
        {
497
0
            TIFFErrorExtR(
498
0
                tif, module,
499
0
                "Unexpected nBands: %d. This file may have been generated with "
500
0
                "a liblerc version >= 3.0, with one mask per band, and is not "
501
0
                "supported by this older version of liblerc",
502
0
                nFoundBands);
503
0
            return 0;
504
0
        }
505
0
#endif
506
0
        if (nFoundBands != td->td_samplesperpixel)
507
0
        {
508
0
            TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
509
0
                          nFoundBands, td->td_samplesperpixel);
510
0
            return 0;
511
0
        }
512
0
    }
513
0
    else if (nFoundBands != 1)
514
0
    {
515
0
        TIFFErrorExtR(tif, module, "Unexpected nBands: %u. Expected: %d",
516
0
                      nFoundBands, 1);
517
0
        return 0;
518
0
    }
519
520
0
    if (infoArray[7] != lerc_data_size)
521
0
    {
522
0
        TIFFErrorExtR(tif, module, "Unexpected blobSize: %u. Expected: %u",
523
0
                      infoArray[7], lerc_data_size);
524
0
        return 0;
525
0
    }
526
527
0
    int nRequestedMasks = use_mask ? 1 : 0;
528
#if LERC_AT_LEAST_VERSION(3, 0, 0)
529
    const int nFoundMasks = infoArray[8];
530
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
531
        td->td_planarconfig == PLANARCONFIG_CONTIG &&
532
        td->td_samplesperpixel > 1 && nFoundDims == 1)
533
    {
534
        if (nFoundMasks != 0 && nFoundMasks != td->td_samplesperpixel)
535
        {
536
            TIFFErrorExtR(tif, module,
537
                          "Unexpected nFoundMasks: %d. Expected: 0 or %d",
538
                          nFoundMasks, td->td_samplesperpixel);
539
            return 0;
540
        }
541
        nRequestedMasks = nFoundMasks;
542
    }
543
    else
544
    {
545
        if (nFoundMasks != 0 && nFoundMasks != 1)
546
        {
547
            TIFFErrorExtR(tif, module,
548
                          "Unexpected nFoundMasks: %d. Expected: 0 or 1",
549
                          nFoundMasks);
550
            return 0;
551
        }
552
    }
553
    if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && nFoundMasks == 0)
554
    {
555
        nRequestedMasks = 0;
556
        use_mask = 0;
557
    }
558
#endif
559
560
0
    const unsigned nb_pixels = sp->segment_width * sp->segment_height;
561
562
#if LERC_AT_LEAST_VERSION(3, 0, 0)
563
    if (nRequestedMasks > 1)
564
    {
565
        unsigned int num_bytes_needed =
566
            nb_pixels * td->td_samplesperpixel * (td->td_bitspersample / 8);
567
        if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
568
        {
569
            _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
570
            sp->uncompressed_buffer_multiband =
571
                (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
572
            if (!sp->uncompressed_buffer_multiband)
573
            {
574
                sp->uncompressed_buffer_multiband_alloc = 0;
575
                return 0;
576
            }
577
            sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
578
        }
579
        lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
580
                               sp->mask_buffer, nFoundDims, sp->segment_width,
581
                               sp->segment_height, nFoundBands, lerc_data_type,
582
                               sp->uncompressed_buffer_multiband);
583
    }
584
    else
585
#endif
586
0
    {
587
0
        lerc_ret =
588
0
            lerc_decode(lerc_data, lerc_data_size,
589
#if LERC_AT_LEAST_VERSION(3, 0, 0)
590
                        nRequestedMasks,
591
#endif
592
0
                        use_mask ? sp->mask_buffer : NULL, nFoundDims,
593
0
                        sp->segment_width, sp->segment_height, nFoundBands,
594
0
                        lerc_data_type, sp->uncompressed_buffer);
595
0
    }
596
0
    if (lerc_ret != 0)
597
0
    {
598
0
        TIFFErrorExtR(tif, module, "lerc_decode() failed");
599
0
        return 0;
600
0
    }
601
602
    /* Interleave alpha mask with other samples. */
603
0
    if (use_mask && GetLercDataType(tif) == 1)
604
0
    {
605
0
        unsigned src_stride =
606
0
            (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
607
0
        unsigned dst_stride =
608
0
            td->td_samplesperpixel * (td->td_bitspersample / 8);
609
0
        unsigned i = sp->segment_width * sp->segment_height;
610
        /* Operate from end to begin to be able to move in place */
611
0
        while (i > 0 && i > nomask_bands)
612
0
        {
613
0
            i--;
614
0
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
615
0
                                    1] = 255 * sp->mask_buffer[i];
616
0
            memcpy(sp->uncompressed_buffer + i * dst_stride,
617
0
                   sp->uncompressed_buffer + i * src_stride, src_stride);
618
0
        }
619
        /* First pixels must use memmove due to overlapping areas */
620
0
        while (i > 0)
621
0
        {
622
0
            i--;
623
0
            sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
624
0
                                    1] = 255 * sp->mask_buffer[i];
625
0
            memmove(sp->uncompressed_buffer + i * dst_stride,
626
0
                    sp->uncompressed_buffer + i * src_stride, src_stride);
627
0
        }
628
0
    }
629
0
    else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
630
0
    {
631
0
        unsigned i;
632
#if WORDS_BIGENDIAN
633
        const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0};
634
#else
635
0
        const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f};
636
0
#endif
637
0
        float nan_float32;
638
0
        memcpy(&nan_float32, nan_bytes, 4);
639
640
0
        if (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
641
0
            td->td_samplesperpixel == 1)
642
0
        {
643
0
            if (td->td_bitspersample == 32)
644
0
            {
645
0
                for (i = 0; i < nb_pixels; i++)
646
0
                {
647
0
                    if (sp->mask_buffer[i] == 0)
648
0
                        ((float *)sp->uncompressed_buffer)[i] = nan_float32;
649
0
                }
650
0
            }
651
0
            else
652
0
            {
653
0
                const double nan_float64 = nan_float32;
654
0
                for (i = 0; i < nb_pixels; i++)
655
0
                {
656
0
                    if (sp->mask_buffer[i] == 0)
657
0
                        ((double *)sp->uncompressed_buffer)[i] = nan_float64;
658
0
                }
659
0
            }
660
0
        }
661
0
        else if (nRequestedMasks == 1)
662
0
        {
663
0
            assert(nFoundDims == td->td_samplesperpixel);
664
0
            assert(nFoundBands == 1);
665
666
0
            unsigned k = 0;
667
0
            if (td->td_bitspersample == 32)
668
0
            {
669
0
                for (i = 0; i < nb_pixels; i++)
670
0
                {
671
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
672
0
                    {
673
0
                        if (sp->mask_buffer[i] == 0)
674
0
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
675
0
                        ++k;
676
0
                    }
677
0
                }
678
0
            }
679
0
            else
680
0
            {
681
0
                const double nan_float64 = nan_float32;
682
0
                for (i = 0; i < nb_pixels; i++)
683
0
                {
684
0
                    for (int j = 0; j < td->td_samplesperpixel; j++)
685
0
                    {
686
0
                        if (sp->mask_buffer[i] == 0)
687
0
                            ((double *)sp->uncompressed_buffer)[k] =
688
0
                                nan_float64;
689
0
                        ++k;
690
0
                    }
691
0
                }
692
0
            }
693
0
        }
694
#if LERC_AT_LEAST_VERSION(3, 0, 0)
695
        else
696
        {
697
            assert(nRequestedMasks == td->td_samplesperpixel);
698
            assert(nFoundDims == 1);
699
            assert(nFoundBands == td->td_samplesperpixel);
700
701
            unsigned k = 0;
702
            if (td->td_bitspersample == 32)
703
            {
704
                for (i = 0; i < nb_pixels; i++)
705
                {
706
                    for (int j = 0; j < td->td_samplesperpixel; j++)
707
                    {
708
                        if (sp->mask_buffer[i + j * nb_pixels] == 0)
709
                            ((float *)sp->uncompressed_buffer)[k] = nan_float32;
710
                        else
711
                            ((float *)sp->uncompressed_buffer)[k] =
712
                                ((float *)sp->uncompressed_buffer_multiband)
713
                                    [i + j * nb_pixels];
714
                        ++k;
715
                    }
716
                }
717
            }
718
            else
719
            {
720
                const double nan_float64 = nan_float32;
721
                for (i = 0; i < nb_pixels; i++)
722
                {
723
                    for (int j = 0; j < td->td_samplesperpixel; j++)
724
                    {
725
                        if (sp->mask_buffer[i + j * nb_pixels] == 0)
726
                            ((double *)sp->uncompressed_buffer)[k] =
727
                                nan_float64;
728
                        else
729
                            ((double *)sp->uncompressed_buffer)[k] =
730
                                ((double *)sp->uncompressed_buffer_multiband)
731
                                    [i + j * nb_pixels];
732
                        ++k;
733
                    }
734
                }
735
            }
736
        }
737
#endif
738
0
    }
739
740
0
    return 1;
741
0
}
742
743
/*
744
 * Decode a strip, tile or scanline.
745
 */
746
static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
747
0
{
748
0
    static const char module[] = "LERCDecode";
749
0
    LERCState *sp = LERCDecoderState(tif);
750
751
0
    (void)s;
752
0
    assert(sp != NULL);
753
0
    assert(sp->state == LSTATE_INIT_DECODE);
754
755
0
    if (sp->uncompressed_buffer == NULL)
756
0
    {
757
0
        memset(op, 0, (size_t)occ);
758
0
        TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
759
0
        return 0;
760
0
    }
761
762
0
    if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
763
0
        sp->uncompressed_size)
764
0
    {
765
0
        memset(op, 0, (size_t)occ);
766
0
        TIFFErrorExtR(tif, module, "Too many bytes read");
767
0
        return 0;
768
0
    }
769
770
0
    memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ);
771
0
    sp->uncompressed_offset += (unsigned)occ;
772
773
0
    return 1;
774
0
}
775
776
#ifndef LERC_READ_ONLY
777
778
static int LERCSetupEncode(TIFF *tif)
779
0
{
780
0
    LERCState *sp = LERCEncoderState(tif);
781
782
0
    assert(sp != NULL);
783
0
    if (sp->state & LSTATE_INIT_DECODE)
784
0
    {
785
0
        sp->state = 0;
786
0
    }
787
788
0
    sp->state |= LSTATE_INIT_ENCODE;
789
790
0
    return 1;
791
0
}
792
793
/*
794
 * Reset encoding state at the start of a strip.
795
 */
796
static int LERCPreEncode(TIFF *tif, uint16_t s)
797
0
{
798
0
    static const char module[] = "LERCPreEncode";
799
0
    LERCState *sp = LERCEncoderState(tif);
800
0
    int lerc_data_type;
801
802
0
    (void)s;
803
0
    assert(sp != NULL);
804
0
    if (sp->state != LSTATE_INIT_ENCODE)
805
0
        tif->tif_setupencode(tif);
806
807
0
    lerc_data_type = GetLercDataType(tif);
808
0
    if (lerc_data_type < 0)
809
0
        return 0;
810
811
0
    if (!SetupBuffers(tif, sp, module))
812
0
        return 0;
813
814
0
    return 1;
815
0
}
816
817
/*
818
 * Encode a chunk of pixels.
819
 */
820
static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
821
0
{
822
0
    static const char module[] = "LERCEncode";
823
0
    LERCState *sp = LERCEncoderState(tif);
824
825
0
    (void)s;
826
0
    assert(sp != NULL);
827
0
    assert(sp->state == LSTATE_INIT_ENCODE);
828
829
0
    if ((uint64_t)sp->uncompressed_offset + (uint64_t)cc >
830
0
        sp->uncompressed_size)
831
0
    {
832
0
        TIFFErrorExtR(tif, module, "Too many bytes written");
833
0
        return 0;
834
0
    }
835
836
0
    memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc);
837
0
    sp->uncompressed_offset += (unsigned)cc;
838
839
0
    return 1;
840
0
}
841
842
/*
843
 * Finish off an encoded strip by flushing it.
844
 */
845
static int LERCPostEncode(TIFF *tif)
846
0
{
847
0
    lerc_status lerc_ret;
848
0
    static const char module[] = "LERCPostEncode";
849
0
    LERCState *sp = LERCEncoderState(tif);
850
0
    unsigned int numBytesWritten = 0;
851
0
    TIFFDirectory *td = &tif->tif_dir;
852
0
    int use_mask = 0;
853
0
    unsigned dst_nbands = td->td_samplesperpixel;
854
855
0
    if (sp->uncompressed_offset != sp->uncompressed_size)
856
0
    {
857
0
        TIFFErrorExtR(tif, module, "Unexpected number of bytes in the buffer");
858
0
        return 0;
859
0
    }
860
861
0
    int mask_count = 1;
862
0
    const unsigned nb_pixels = sp->segment_width * sp->segment_height;
863
864
    /* Extract alpha mask (if containing only 0 and 255 values, */
865
    /* and compact array of regular bands */
866
0
    if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
867
0
        td->td_sampleinfo &&
868
0
        td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
869
0
        GetLercDataType(tif) == 1)
870
0
    {
871
0
        const unsigned dst_stride =
872
0
            (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
873
0
        const unsigned src_stride =
874
0
            td->td_samplesperpixel * (td->td_bitspersample / 8);
875
0
        unsigned i = 0;
876
877
0
        use_mask = 1;
878
0
        for (i = 0; i < nb_pixels; i++)
879
0
        {
880
0
            int v = sp->uncompressed_buffer[i * src_stride +
881
0
                                            td->td_samplesperpixel - 1];
882
0
            if (v != 0 && v != 255)
883
0
            {
884
0
                use_mask = 0;
885
0
                break;
886
0
            }
887
0
        }
888
889
0
        if (use_mask)
890
0
        {
891
0
            dst_nbands--;
892
            /* First pixels must use memmove due to overlapping areas */
893
0
            for (i = 0; i < dst_nbands && i < nb_pixels; i++)
894
0
            {
895
0
                memmove(sp->uncompressed_buffer + i * dst_stride,
896
0
                        sp->uncompressed_buffer + i * src_stride, dst_stride);
897
0
                sp->mask_buffer[i] =
898
0
                    sp->uncompressed_buffer[i * src_stride +
899
0
                                            td->td_samplesperpixel - 1];
900
0
            }
901
0
            for (; i < nb_pixels; i++)
902
0
            {
903
0
                memcpy(sp->uncompressed_buffer + i * dst_stride,
904
0
                       sp->uncompressed_buffer + i * src_stride, dst_stride);
905
0
                sp->mask_buffer[i] =
906
0
                    sp->uncompressed_buffer[i * src_stride +
907
0
                                            td->td_samplesperpixel - 1];
908
0
            }
909
0
        }
910
0
    }
911
0
    else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
912
0
             (td->td_bitspersample == 32 || td->td_bitspersample == 64))
913
0
    {
914
        /* Check for NaN values */
915
0
        unsigned i;
916
0
        if (td->td_bitspersample == 32)
917
0
        {
918
0
            if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
919
0
            {
920
0
                unsigned k = 0;
921
0
                for (i = 0; i < nb_pixels; i++)
922
0
                {
923
0
                    int count_nan = 0;
924
0
                    for (int j = 0; j < td->td_samplesperpixel; ++j)
925
0
                    {
926
0
                        const float val = ((float *)sp->uncompressed_buffer)[k];
927
0
                        ++k;
928
0
                        if (val != val)
929
0
                        {
930
0
                            ++count_nan;
931
0
                        }
932
0
                    }
933
0
                    if (count_nan > 0)
934
0
                    {
935
0
                        use_mask = 1;
936
0
                        if (count_nan < td->td_samplesperpixel)
937
0
                        {
938
0
                            mask_count = td->td_samplesperpixel;
939
0
                            break;
940
0
                        }
941
0
                    }
942
0
                }
943
0
            }
944
0
            else
945
0
            {
946
0
                for (i = 0; i < nb_pixels; i++)
947
0
                {
948
0
                    const float val = ((float *)sp->uncompressed_buffer)[i];
949
0
                    if (val != val)
950
0
                    {
951
0
                        use_mask = 1;
952
0
                        break;
953
0
                    }
954
0
                }
955
0
            }
956
0
        }
957
0
        else
958
0
        {
959
0
            if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
960
0
            {
961
0
                unsigned k = 0;
962
0
                for (i = 0; i < nb_pixels; i++)
963
0
                {
964
0
                    int count_nan = 0;
965
0
                    for (int j = 0; j < td->td_samplesperpixel; ++j)
966
0
                    {
967
0
                        const double val =
968
0
                            ((double *)sp->uncompressed_buffer)[k];
969
0
                        ++k;
970
0
                        if (val != val)
971
0
                        {
972
0
                            ++count_nan;
973
0
                        }
974
0
                    }
975
0
                    if (count_nan > 0)
976
0
                    {
977
0
                        use_mask = 1;
978
0
                        if (count_nan < td->td_samplesperpixel)
979
0
                        {
980
0
                            mask_count = td->td_samplesperpixel;
981
0
                            break;
982
0
                        }
983
0
                    }
984
0
                }
985
0
            }
986
0
            else
987
0
            {
988
0
                for (i = 0; i < nb_pixels; i++)
989
0
                {
990
0
                    const double val = ((double *)sp->uncompressed_buffer)[i];
991
0
                    if (val != val)
992
0
                    {
993
0
                        use_mask = 1;
994
0
                        break;
995
0
                    }
996
0
                }
997
0
            }
998
0
        }
999
1000
0
        if (use_mask)
1001
0
        {
1002
0
            if (mask_count > 1)
1003
0
            {
1004
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1005
                unsigned int num_bytes_needed =
1006
                    nb_pixels * dst_nbands * (td->td_bitspersample / 8);
1007
                if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
1008
                {
1009
                    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1010
                    sp->uncompressed_buffer_multiband =
1011
                        (uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
1012
                    if (!sp->uncompressed_buffer_multiband)
1013
                    {
1014
                        sp->uncompressed_buffer_multiband_alloc = 0;
1015
                        return 0;
1016
                    }
1017
                    sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
1018
                }
1019
1020
                unsigned k = 0;
1021
                if (td->td_bitspersample == 32)
1022
                {
1023
                    for (i = 0; i < nb_pixels; i++)
1024
                    {
1025
                        for (int j = 0; j < td->td_samplesperpixel; ++j)
1026
                        {
1027
                            const float val =
1028
                                ((float *)sp->uncompressed_buffer)[k];
1029
                            ((float *)sp->uncompressed_buffer_multiband)
1030
                                [i + j * nb_pixels] = val;
1031
                            ++k;
1032
                            sp->mask_buffer[i + j * nb_pixels] =
1033
                                (val == val) ? 255 : 0;
1034
                        }
1035
                    }
1036
                }
1037
                else
1038
                {
1039
                    for (i = 0; i < nb_pixels; i++)
1040
                    {
1041
                        for (int j = 0; j < td->td_samplesperpixel; ++j)
1042
                        {
1043
                            const double val =
1044
                                ((double *)sp->uncompressed_buffer)[k];
1045
                            ((double *)sp->uncompressed_buffer_multiband)
1046
                                [i + j * nb_pixels] = val;
1047
                            ++k;
1048
                            sp->mask_buffer[i + j * nb_pixels] =
1049
                                (val == val) ? 255 : 0;
1050
                        }
1051
                    }
1052
                }
1053
#else
1054
0
                TIFFErrorExtR(tif, module,
1055
0
                              "lerc_encode() would need to create one mask per "
1056
0
                              "sample, but this requires liblerc >= 3.0");
1057
0
                return 0;
1058
0
#endif
1059
0
            }
1060
0
            else if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
1061
0
                     dst_nbands > 1)
1062
0
            {
1063
0
                if (td->td_bitspersample == 32)
1064
0
                {
1065
0
                    for (i = 0; i < nb_pixels; i++)
1066
0
                    {
1067
0
                        const float val =
1068
0
                            ((float *)sp->uncompressed_buffer)[i * dst_nbands];
1069
0
                        sp->mask_buffer[i] = (val == val) ? 255 : 0;
1070
0
                    }
1071
0
                }
1072
0
                else
1073
0
                {
1074
0
                    for (i = 0; i < nb_pixels; i++)
1075
0
                    {
1076
0
                        const double val =
1077
0
                            ((double *)sp->uncompressed_buffer)[i * dst_nbands];
1078
0
                        sp->mask_buffer[i] = (val == val) ? 255 : 0;
1079
0
                    }
1080
0
                }
1081
0
            }
1082
0
            else
1083
0
            {
1084
0
                if (td->td_bitspersample == 32)
1085
0
                {
1086
0
                    for (i = 0; i < nb_pixels; i++)
1087
0
                    {
1088
0
                        const float val = ((float *)sp->uncompressed_buffer)[i];
1089
0
                        sp->mask_buffer[i] = (val == val) ? 255 : 0;
1090
0
                    }
1091
0
                }
1092
0
                else
1093
0
                {
1094
0
                    for (i = 0; i < nb_pixels; i++)
1095
0
                    {
1096
0
                        const double val =
1097
0
                            ((double *)sp->uncompressed_buffer)[i];
1098
0
                        sp->mask_buffer[i] = (val == val) ? 255 : 0;
1099
0
                    }
1100
0
                }
1101
0
            }
1102
0
        }
1103
0
    }
1104
1105
0
    unsigned int estimated_compressed_size = sp->uncompressed_alloc;
1106
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1107
    if (mask_count > 1)
1108
    {
1109
        estimated_compressed_size += nb_pixels * mask_count / 8;
1110
    }
1111
#endif
1112
1113
0
    if (sp->compressed_size < estimated_compressed_size)
1114
0
    {
1115
0
        _TIFFfreeExt(tif, sp->compressed_buffer);
1116
0
        sp->compressed_buffer = _TIFFmallocExt(tif, estimated_compressed_size);
1117
0
        if (!sp->compressed_buffer)
1118
0
        {
1119
0
            sp->compressed_size = 0;
1120
0
            return 0;
1121
0
        }
1122
0
        sp->compressed_size = estimated_compressed_size;
1123
0
    }
1124
1125
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1126
    if (mask_count > 1)
1127
    {
1128
        lerc_ret = lerc_encodeForVersion(
1129
            sp->uncompressed_buffer_multiband, sp->lerc_version,
1130
            GetLercDataType(tif), 1, sp->segment_width, sp->segment_height,
1131
            dst_nbands, dst_nbands, sp->mask_buffer, sp->maxzerror,
1132
            (unsigned char *)sp->compressed_buffer, sp->compressed_size,
1133
            &numBytesWritten);
1134
    }
1135
    else
1136
#endif
1137
0
    {
1138
0
        lerc_ret = lerc_encodeForVersion(
1139
0
            sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif),
1140
0
            td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1,
1141
0
            sp->segment_width, sp->segment_height, 1,
1142
#if LERC_AT_LEAST_VERSION(3, 0, 0)
1143
            use_mask ? 1 : 0,
1144
#endif
1145
0
            use_mask ? sp->mask_buffer : NULL, sp->maxzerror,
1146
0
            (unsigned char *)sp->compressed_buffer, sp->compressed_size,
1147
0
            &numBytesWritten);
1148
0
    }
1149
0
    if (lerc_ret != 0)
1150
0
    {
1151
0
        TIFFErrorExtR(tif, module, "lerc_encode() failed");
1152
0
        return 0;
1153
0
    }
1154
0
    assert(numBytesWritten < estimated_compressed_size);
1155
1156
0
    if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
1157
0
    {
1158
#if LIBDEFLATE_SUPPORT
1159
        if (sp->libdeflate_enc == NULL)
1160
        {
1161
            /* To get results as good as zlib, we ask for an extra */
1162
            /* level of compression */
1163
            sp->libdeflate_enc = libdeflate_alloc_compressor(
1164
                sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
1165
                : sp->zipquality >= 6 && sp->zipquality <= 9
1166
                    ? sp->zipquality + 1
1167
                    : sp->zipquality);
1168
            if (sp->libdeflate_enc == NULL)
1169
            {
1170
                TIFFErrorExtR(tif, module, "Cannot allocate compressor");
1171
                return 0;
1172
            }
1173
        }
1174
1175
        /* Should not happen normally */
1176
        if (libdeflate_zlib_compress_bound(
1177
                sp->libdeflate_enc, numBytesWritten) > sp->uncompressed_alloc)
1178
        {
1179
            TIFFErrorExtR(tif, module,
1180
                          "Output buffer for libdeflate too small");
1181
            return 0;
1182
        }
1183
1184
        tif->tif_rawcc = libdeflate_zlib_compress(
1185
            sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten,
1186
            sp->uncompressed_buffer, sp->uncompressed_alloc);
1187
1188
        if (tif->tif_rawcc == 0)
1189
        {
1190
            TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
1191
                          (unsigned long)tif->tif_row);
1192
            return 0;
1193
        }
1194
#else
1195
0
        z_stream strm;
1196
0
        int zlib_ret;
1197
0
        int cappedQuality = sp->zipquality;
1198
0
        if (cappedQuality > Z_BEST_COMPRESSION)
1199
0
            cappedQuality = Z_BEST_COMPRESSION;
1200
1201
0
        memset(&strm, 0, sizeof(strm));
1202
0
        strm.zalloc = NULL;
1203
0
        strm.zfree = NULL;
1204
0
        strm.opaque = NULL;
1205
0
        zlib_ret = deflateInit(&strm, cappedQuality);
1206
0
        if (zlib_ret != Z_OK)
1207
0
        {
1208
0
            TIFFErrorExtR(tif, module, "deflateInit() failed");
1209
0
            return 0;
1210
0
        }
1211
1212
0
        strm.avail_in = numBytesWritten;
1213
0
        strm.next_in = sp->compressed_buffer;
1214
0
        strm.avail_out = sp->uncompressed_alloc;
1215
0
        strm.next_out = sp->uncompressed_buffer;
1216
0
        zlib_ret = deflate(&strm, Z_FINISH);
1217
0
        if (zlib_ret == Z_STREAM_END)
1218
0
        {
1219
0
            tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out;
1220
0
        }
1221
0
        deflateEnd(&strm);
1222
0
        if (zlib_ret != Z_STREAM_END)
1223
0
        {
1224
0
            TIFFErrorExtR(tif, module, "deflate() failed");
1225
0
            return 0;
1226
0
        }
1227
0
#endif
1228
0
        {
1229
0
            int ret;
1230
0
            uint8_t *tif_rawdata_backup = tif->tif_rawdata;
1231
0
            tif->tif_rawdata = sp->uncompressed_buffer;
1232
0
            ret = TIFFFlushData1(tif);
1233
0
            tif->tif_rawdata = tif_rawdata_backup;
1234
0
            if (!ret)
1235
0
            {
1236
0
                return 0;
1237
0
            }
1238
0
        }
1239
0
    }
1240
0
    else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
1241
0
    {
1242
#ifdef ZSTD_SUPPORT
1243
        size_t zstd_ret = ZSTD_compress(
1244
            sp->uncompressed_buffer, sp->uncompressed_alloc,
1245
            sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level);
1246
        if (ZSTD_isError(zstd_ret))
1247
        {
1248
            TIFFErrorExtR(tif, module, "Error in ZSTD_compress(): %s",
1249
                          ZSTD_getErrorName(zstd_ret));
1250
            return 0;
1251
        }
1252
1253
        {
1254
            int ret;
1255
            uint8_t *tif_rawdata_backup = tif->tif_rawdata;
1256
            tif->tif_rawdata = sp->uncompressed_buffer;
1257
            tif->tif_rawcc = zstd_ret;
1258
            ret = TIFFFlushData1(tif);
1259
            tif->tif_rawdata = tif_rawdata_backup;
1260
            if (!ret)
1261
            {
1262
                return 0;
1263
            }
1264
        }
1265
#else
1266
0
        TIFFErrorExtR(tif, module, "ZSTD support missing");
1267
0
        return 0;
1268
0
#endif
1269
0
    }
1270
0
    else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
1271
0
    {
1272
0
        TIFFErrorExtR(tif, module, "Unhandled additional compression");
1273
0
        return 0;
1274
0
    }
1275
0
    else
1276
0
    {
1277
0
        int ret;
1278
0
        uint8_t *tif_rawdata_backup = tif->tif_rawdata;
1279
0
        tif->tif_rawdata = (uint8_t *)sp->compressed_buffer;
1280
0
        tif->tif_rawcc = numBytesWritten;
1281
0
        ret = TIFFFlushData1(tif);
1282
0
        tif->tif_rawdata = tif_rawdata_backup;
1283
0
        if (!ret)
1284
0
            return 0;
1285
0
    }
1286
1287
0
    return 1;
1288
0
}
1289
1290
#endif /* LERC_READ_ONLY */
1291
1292
static void LERCCleanup(TIFF *tif)
1293
0
{
1294
0
    LERCState *sp = GetLERCState(tif);
1295
1296
0
    assert(sp != NULL);
1297
1298
0
    tif->tif_tagmethods.vgetfield = sp->vgetparent;
1299
0
    tif->tif_tagmethods.vsetfield = sp->vsetparent;
1300
1301
0
    _TIFFfreeExt(tif, sp->uncompressed_buffer);
1302
0
    _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
1303
0
    _TIFFfreeExt(tif, sp->compressed_buffer);
1304
0
    _TIFFfreeExt(tif, sp->mask_buffer);
1305
1306
#if LIBDEFLATE_SUPPORT
1307
    if (sp->libdeflate_dec)
1308
        libdeflate_free_decompressor(sp->libdeflate_dec);
1309
    if (sp->libdeflate_enc)
1310
        libdeflate_free_compressor(sp->libdeflate_enc);
1311
#endif
1312
1313
0
    _TIFFfreeExt(tif, sp);
1314
0
    tif->tif_data = NULL;
1315
1316
0
    _TIFFSetDefaultCompressionState(tif);
1317
0
}
1318
1319
static const TIFFField LERCFields[] = {
1320
    {TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0,
1321
     TIFF_SETGET_C32_UINT32, FIELD_CUSTOM, FALSE, TRUE,
1322
     (char *)"LercParameters", NULL},
1323
    {TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE,
1324
     FIELD_PSEUDO, TRUE, FALSE, (char *)"LercMaximumError", NULL},
1325
    {TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, FIELD_PSEUDO,
1326
     FALSE, FALSE, (char *)"LercVersion", NULL},
1327
    {TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
1328
     FIELD_PSEUDO, FALSE, FALSE, (char *)"LercAdditionalCompression", NULL},
1329
    {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
1330
     FALSE, (char *)"ZSTD zstd_compress_level", NULL},
1331
    {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
1332
     FALSE, (char *)"", NULL},
1333
};
1334
1335
static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...)
1336
0
{
1337
0
    LERCState *sp = GetLERCState(tif);
1338
0
    int ret;
1339
0
    va_list ap;
1340
0
    va_start(ap, tag);
1341
0
    ret = (*sp->vsetparent)(tif, tag, ap);
1342
0
    va_end(ap);
1343
0
    return ret;
1344
0
}
1345
1346
static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
1347
0
{
1348
0
    static const char module[] = "LERCVSetField";
1349
0
    LERCState *sp = GetLERCState(tif);
1350
1351
0
    switch (tag)
1352
0
    {
1353
0
        case TIFFTAG_LERC_PARAMETERS:
1354
0
        {
1355
0
            uint32_t count = va_arg(ap, int);
1356
0
            int *params = va_arg(ap, int *);
1357
0
            if (count < 2)
1358
0
            {
1359
0
                TIFFErrorExtR(tif, module,
1360
0
                              "Invalid count for LercParameters: %u", count);
1361
0
                return 0;
1362
0
            }
1363
0
            sp->lerc_version = params[0];
1364
0
            sp->additional_compression = params[1];
1365
0
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count,
1366
0
                                     params);
1367
0
        }
1368
0
        case TIFFTAG_LERC_MAXZERROR:
1369
0
            sp->maxzerror = va_arg(ap, double);
1370
0
            return 1;
1371
0
        case TIFFTAG_LERC_VERSION:
1372
0
        {
1373
0
            int params[2] = {0, 0};
1374
0
            int version = va_arg(ap, int);
1375
0
            if (version != LERC_VERSION_2_4)
1376
0
            {
1377
0
                TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d",
1378
0
                              version);
1379
0
                return 0;
1380
0
            }
1381
0
            sp->lerc_version = version;
1382
0
            params[0] = sp->lerc_version;
1383
0
            params[1] = sp->additional_compression;
1384
0
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1385
0
        }
1386
0
        case TIFFTAG_LERC_ADD_COMPRESSION:
1387
0
        {
1388
0
            int params[2] = {0, 0};
1389
0
            int additional_compression = va_arg(ap, int);
1390
0
#ifndef ZSTD_SUPPORT
1391
0
            if (additional_compression == LERC_ADD_COMPRESSION_ZSTD)
1392
0
            {
1393
0
                TIFFErrorExtR(tif, module,
1394
0
                              "LERC_ZSTD requested, but ZSTD not available");
1395
0
                return 0;
1396
0
            }
1397
0
#endif
1398
0
            if (additional_compression != LERC_ADD_COMPRESSION_NONE &&
1399
0
                additional_compression != LERC_ADD_COMPRESSION_DEFLATE &&
1400
0
                additional_compression != LERC_ADD_COMPRESSION_ZSTD)
1401
0
            {
1402
0
                TIFFErrorExtR(tif, module,
1403
0
                              "Invalid value for LercAdditionalCompression: %d",
1404
0
                              additional_compression);
1405
0
                return 0;
1406
0
            }
1407
0
            sp->additional_compression = additional_compression;
1408
0
            params[0] = sp->lerc_version;
1409
0
            params[1] = sp->additional_compression;
1410
0
            return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
1411
0
        }
1412
#ifdef ZSTD_SUPPORT
1413
        case TIFFTAG_ZSTD_LEVEL:
1414
        {
1415
            sp->zstd_compress_level = (int)va_arg(ap, int);
1416
            if (sp->zstd_compress_level <= 0 ||
1417
                sp->zstd_compress_level > ZSTD_maxCLevel())
1418
            {
1419
                TIFFWarningExtR(tif, module,
1420
                                "ZSTD_LEVEL should be between 1 and %d",
1421
                                ZSTD_maxCLevel());
1422
            }
1423
            return 1;
1424
        }
1425
#endif
1426
0
        case TIFFTAG_ZIPQUALITY:
1427
0
        {
1428
0
            sp->zipquality = (int)va_arg(ap, int);
1429
0
            if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
1430
0
                sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
1431
0
            {
1432
0
                TIFFErrorExtR(
1433
0
                    tif, module,
1434
0
                    "Invalid ZipQuality value. Should be in [-1,%d] range",
1435
0
                    LIBDEFLATE_MAX_COMPRESSION_LEVEL);
1436
0
                return 0;
1437
0
            }
1438
1439
#if LIBDEFLATE_SUPPORT
1440
            if (sp->libdeflate_enc)
1441
            {
1442
                libdeflate_free_compressor(sp->libdeflate_enc);
1443
                sp->libdeflate_enc = NULL;
1444
            }
1445
#endif
1446
1447
0
            return (1);
1448
0
        }
1449
0
        default:
1450
0
            return (*sp->vsetparent)(tif, tag, ap);
1451
0
    }
1452
    /*NOTREACHED*/
1453
0
}
1454
1455
static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap)
1456
0
{
1457
0
    LERCState *sp = GetLERCState(tif);
1458
1459
0
    switch (tag)
1460
0
    {
1461
0
        case TIFFTAG_LERC_MAXZERROR:
1462
0
            *va_arg(ap, double *) = sp->maxzerror;
1463
0
            break;
1464
0
        case TIFFTAG_LERC_VERSION:
1465
0
            *va_arg(ap, int *) = sp->lerc_version;
1466
0
            break;
1467
0
        case TIFFTAG_LERC_ADD_COMPRESSION:
1468
0
            *va_arg(ap, int *) = sp->additional_compression;
1469
0
            break;
1470
0
        case TIFFTAG_ZSTD_LEVEL:
1471
0
            *va_arg(ap, int *) = sp->zstd_compress_level;
1472
0
            break;
1473
0
        case TIFFTAG_ZIPQUALITY:
1474
0
            *va_arg(ap, int *) = sp->zipquality;
1475
0
            break;
1476
0
        default:
1477
0
            return (*sp->vgetparent)(tif, tag, ap);
1478
0
    }
1479
0
    return 1;
1480
0
}
1481
1482
int TIFFInitLERC(TIFF *tif, int scheme)
1483
0
{
1484
0
    static const char module[] = "TIFFInitLERC";
1485
0
    LERCState *sp;
1486
1487
0
    (void)scheme;
1488
0
    assert(scheme == COMPRESSION_LERC);
1489
1490
    /*
1491
     * Merge codec-specific tag information.
1492
     */
1493
0
    if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields)))
1494
0
    {
1495
0
        TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed");
1496
0
        return 0;
1497
0
    }
1498
1499
    /*
1500
     * Allocate state block so tag methods have storage to record values.
1501
     */
1502
0
    tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
1503
0
    if (tif->tif_data == NULL)
1504
0
        goto bad;
1505
0
    sp = GetLERCState(tif);
1506
1507
    /*
1508
     * Override parent get/set field methods.
1509
     */
1510
0
    sp->vgetparent = tif->tif_tagmethods.vgetfield;
1511
0
    tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */
1512
0
    sp->vsetparent = tif->tif_tagmethods.vsetfield;
1513
0
    tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */
1514
1515
    /*
1516
     * Install codec methods.
1517
     */
1518
0
    tif->tif_fixuptags = LERCFixupTags;
1519
0
    tif->tif_setupdecode = LERCSetupDecode;
1520
0
    tif->tif_predecode = LERCPreDecode;
1521
0
    tif->tif_decoderow = LERCDecode;
1522
0
    tif->tif_decodestrip = LERCDecode;
1523
0
    tif->tif_decodetile = LERCDecode;
1524
0
#ifndef LERC_READ_ONLY
1525
0
    tif->tif_setupencode = LERCSetupEncode;
1526
0
    tif->tif_preencode = LERCPreEncode;
1527
0
    tif->tif_postencode = LERCPostEncode;
1528
0
    tif->tif_encoderow = LERCEncode;
1529
0
    tif->tif_encodestrip = LERCEncode;
1530
0
    tif->tif_encodetile = LERCEncode;
1531
0
#endif
1532
0
    tif->tif_cleanup = LERCCleanup;
1533
1534
    /* Default values for codec-specific fields */
1535
0
    TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
1536
0
    TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
1537
0
    sp->maxzerror = 0.0;
1538
0
    sp->zstd_compress_level = 9;            /* default comp. level */
1539
0
    sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
1540
0
    sp->state = 0;
1541
1542
0
    return 1;
1543
0
bad:
1544
0
    TIFFErrorExtR(tif, module, "No space for LERC state block");
1545
0
    return 0;
1546
0
}
1547
#endif /* LERC_SUPPORT */