Coverage Report

Created: 2025-06-13 06:18

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