Coverage Report

Created: 2026-07-25 06:50

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