/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 */ |