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