Line data Source code
1 : /*
2 : * Copyright (c) 1995-1997 Sam Leffler
3 : * Copyright (c) 1995-1997 Silicon Graphics, Inc.
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 ZIP_SUPPORT
27 : /*
28 : * TIFF Library.
29 : *
30 : * ZIP (aka Deflate) Compression Support
31 : *
32 : * This file is an interface to the zlib library written by
33 : * Jean-loup Gailly and Mark Adler. You must use version 1.0 or later
34 : * of the library.
35 : *
36 : * Optionally, libdeflate (https://github.com/ebiggers/libdeflate) may be used
37 : * to do the compression and decompression, but only for whole strips and tiles.
38 : * For scanline access, zlib will be sued as a fallback.
39 : */
40 : #include "tif_predict.h"
41 : #include "zlib.h"
42 :
43 : #if LIBDEFLATE_SUPPORT
44 : #include "libdeflate.h"
45 : #endif
46 : #define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
47 :
48 : #include <stdio.h>
49 :
50 : /*
51 : * Sigh, ZLIB_VERSION is defined as a string so there's no
52 : * way to do a proper check here. Instead we guess based
53 : * on the presence of #defines that were added between the
54 : * 0.95 and 1.0 distributions.
55 : */
56 : #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
57 : #error "Antiquated ZLIB software; you must use version 1.0 or later"
58 : #endif
59 :
60 : #define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
61 :
62 : /*
63 : * State block for each open TIFF
64 : * file using ZIP compression/decompression.
65 : */
66 : typedef struct
67 : {
68 : TIFFPredictorState predict;
69 : z_stream stream;
70 : int zipquality; /* compression level */
71 : int state; /* state flags */
72 : int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
73 : #if LIBDEFLATE_SUPPORT
74 : int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is
75 : called, 0 = use zlib, 1 = use libdeflate */
76 : struct libdeflate_decompressor *libdeflate_dec;
77 : struct libdeflate_compressor *libdeflate_enc;
78 : #endif
79 : #define ZSTATE_INIT_DECODE 0x01
80 : #define ZSTATE_INIT_ENCODE 0x02
81 :
82 : TIFFVGetMethod vgetparent; /* super-class method */
83 : TIFFVSetMethod vsetparent; /* super-class method */
84 : } ZIPState;
85 :
86 : #define GetZIPState(tif) ((ZIPState *)(tif)->tif_data)
87 : #define ZIPDecoderState(tif) GetZIPState(tif)
88 : #define ZIPEncoderState(tif) GetZIPState(tif)
89 :
90 : static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
91 : static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
92 :
93 1907 : static int ZIPFixupTags(TIFF *tif)
94 : {
95 : (void)tif;
96 1907 : return (1);
97 : }
98 :
99 450 : static int ZIPSetupDecode(TIFF *tif)
100 : {
101 : static const char module[] = "ZIPSetupDecode";
102 450 : ZIPState *sp = ZIPDecoderState(tif);
103 :
104 450 : assert(sp != NULL);
105 :
106 : /* if we were last encoding, terminate this mode */
107 450 : if (sp->state & ZSTATE_INIT_ENCODE)
108 : {
109 15 : deflateEnd(&sp->stream);
110 15 : sp->state = 0;
111 : }
112 :
113 : /* This function can possibly be called several times by */
114 : /* PredictorSetupDecode() if this function succeeds but */
115 : /* PredictorSetup() fails */
116 900 : if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
117 450 : inflateInit(&sp->stream) != Z_OK)
118 : {
119 0 : TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
120 0 : return (0);
121 : }
122 : else
123 : {
124 450 : sp->state |= ZSTATE_INIT_DECODE;
125 450 : return (1);
126 : }
127 : }
128 :
129 : /*
130 : * Setup state for decoding a strip.
131 : */
132 3043 : static int ZIPPreDecode(TIFF *tif, uint16_t s)
133 : {
134 3043 : ZIPState *sp = ZIPDecoderState(tif);
135 :
136 : (void)s;
137 3043 : assert(sp != NULL);
138 :
139 3043 : if ((sp->state & ZSTATE_INIT_DECODE) == 0)
140 15 : tif->tif_setupdecode(tif);
141 :
142 : #if LIBDEFLATE_SUPPORT
143 3043 : sp->libdeflate_state = -1;
144 : #endif
145 3043 : sp->stream.next_in = tif->tif_rawdata;
146 : assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
147 : we need to simplify this code to reflect a ZLib that is likely updated
148 : to deal with 8byte memory sizes, though this code will respond
149 : appropriately even before we simplify it */
150 6086 : sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU
151 3043 : ? (uInt)tif->tif_rawcc
152 3043 : : 0xFFFFFFFFU;
153 3043 : return (inflateReset(&sp->stream) == Z_OK);
154 : }
155 :
156 5043 : static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
157 : {
158 : static const char module[] = "ZIPDecode";
159 5043 : ZIPState *sp = ZIPDecoderState(tif);
160 :
161 : (void)s;
162 5043 : assert(sp != NULL);
163 5043 : assert(sp->state == ZSTATE_INIT_DECODE);
164 :
165 : #if LIBDEFLATE_SUPPORT
166 5043 : if (sp->libdeflate_state == 1)
167 0 : return 0;
168 :
169 : /* If we have libdeflate support and we are asked to read a whole */
170 : /* strip/tile, then go for using it */
171 : do
172 : {
173 5043 : TIFFDirectory *td = &tif->tif_dir;
174 :
175 5043 : if (sp->libdeflate_state == 0)
176 2000 : break;
177 3043 : if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
178 0 : break;
179 :
180 : /* Check if we are in the situation where we can use libdeflate */
181 3043 : if (isTiled(tif))
182 : {
183 926 : if (TIFFTileSize64(tif) != (uint64_t)occ)
184 144 : break;
185 : }
186 : else
187 : {
188 2117 : uint32_t strip_height = td->td_imagelength - tif->tif_row;
189 2117 : if (strip_height > td->td_rowsperstrip)
190 1484 : strip_height = td->td_rowsperstrip;
191 2117 : if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ)
192 2 : break;
193 : }
194 :
195 : /* Check for overflow */
196 : if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc)
197 : break;
198 : if ((size_t)occ != (uint64_t)occ)
199 : break;
200 :
201 : /* Go for decompression using libdeflate */
202 : {
203 : enum libdeflate_result res;
204 2897 : if (sp->libdeflate_dec == NULL)
205 : {
206 390 : sp->libdeflate_dec = libdeflate_alloc_decompressor();
207 390 : if (sp->libdeflate_dec == NULL)
208 : {
209 0 : break;
210 : }
211 : }
212 :
213 2897 : sp->libdeflate_state = 1;
214 :
215 2897 : res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp,
216 2897 : (size_t)tif->tif_rawcc, op,
217 : (size_t)occ, NULL);
218 :
219 2897 : tif->tif_rawcp += tif->tif_rawcc;
220 2897 : tif->tif_rawcc = 0;
221 :
222 : /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */
223 : /* There are odd files in the wild where the last strip, when */
224 : /* it is smaller in height than td_rowsperstrip, actually contains
225 : */
226 : /* data for td_rowsperstrip lines. Just ignore that silently. */
227 2897 : if (res != LIBDEFLATE_SUCCESS &&
228 : res != LIBDEFLATE_INSUFFICIENT_SPACE)
229 : {
230 0 : TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
231 0 : (unsigned long)tif->tif_row);
232 0 : return 0;
233 : }
234 :
235 2897 : return 1;
236 : }
237 : } while (0);
238 2146 : sp->libdeflate_state = 0;
239 : #endif /* LIBDEFLATE_SUPPORT */
240 :
241 2146 : sp->stream.next_in = tif->tif_rawcp;
242 :
243 2146 : sp->stream.next_out = op;
244 : assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
245 : we need to simplify this code to reflect a ZLib that is likely updated
246 : to deal with 8byte memory sizes, though this code will respond
247 : appropriately even before we simplify it */
248 : do
249 : {
250 : int state;
251 4292 : uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU
252 2146 : ? (uInt)tif->tif_rawcc
253 2146 : : 0xFFFFFFFFU;
254 2146 : uInt avail_out_before =
255 2146 : (uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU;
256 2146 : sp->stream.avail_in = avail_in_before;
257 2146 : sp->stream.avail_out = avail_out_before;
258 : /* coverity[overrun-buffer-arg] */
259 2146 : state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
260 2146 : tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
261 2146 : occ -= (avail_out_before - sp->stream.avail_out);
262 2146 : if (state == Z_STREAM_END)
263 1 : break;
264 2145 : if (state == Z_DATA_ERROR)
265 : {
266 1 : TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
267 2 : (unsigned long)tif->tif_row, SAFE_MSG(sp));
268 1 : return (0);
269 : }
270 2144 : if (state != Z_OK)
271 : {
272 0 : TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
273 0 : return (0);
274 : }
275 2144 : } while (occ > 0);
276 2145 : if (occ != 0)
277 : {
278 0 : TIFFErrorExtR(tif, module,
279 : "Not enough data at scanline %lu (short %" PRIu64
280 : " bytes)",
281 0 : (unsigned long)tif->tif_row, (uint64_t)occ);
282 0 : return (0);
283 : }
284 :
285 2145 : tif->tif_rawcp = sp->stream.next_in;
286 :
287 2145 : return (1);
288 : }
289 :
290 5619 : static int ZIPSetupEncode(TIFF *tif)
291 : {
292 : static const char module[] = "ZIPSetupEncode";
293 5619 : ZIPState *sp = ZIPEncoderState(tif);
294 : int cappedQuality;
295 :
296 5619 : assert(sp != NULL);
297 5619 : if (sp->state & ZSTATE_INIT_DECODE)
298 : {
299 8 : inflateEnd(&sp->stream);
300 8 : sp->state = 0;
301 : }
302 :
303 5619 : cappedQuality = sp->zipquality;
304 5619 : if (cappedQuality > Z_BEST_COMPRESSION)
305 0 : cappedQuality = Z_BEST_COMPRESSION;
306 :
307 5619 : if (deflateInit(&sp->stream, cappedQuality) != Z_OK)
308 : {
309 0 : TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
310 0 : return (0);
311 : }
312 : else
313 : {
314 5620 : sp->state |= ZSTATE_INIT_ENCODE;
315 5620 : return (1);
316 : }
317 : }
318 :
319 : /*
320 : * Reset encoding state at the start of a strip.
321 : */
322 13142 : static int ZIPPreEncode(TIFF *tif, uint16_t s)
323 : {
324 13142 : ZIPState *sp = ZIPEncoderState(tif);
325 :
326 : (void)s;
327 13142 : assert(sp != NULL);
328 13142 : if (sp->state != ZSTATE_INIT_ENCODE)
329 8 : tif->tif_setupencode(tif);
330 :
331 : #if LIBDEFLATE_SUPPORT
332 13130 : sp->libdeflate_state = -1;
333 : #endif
334 13130 : sp->stream.next_out = tif->tif_rawdata;
335 : assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
336 : we need to simplify this code to reflect a ZLib that is likely updated
337 : to deal with 8byte memory sizes, though this code will respond
338 : appropriately even before we simplify it */
339 26260 : sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
340 13130 : ? (uInt)tif->tif_rawdatasize
341 13130 : : 0xFFFFFFFFU;
342 13130 : return (deflateReset(&sp->stream) == Z_OK);
343 : }
344 :
345 : /*
346 : * Encode a chunk of pixels.
347 : */
348 15145 : static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
349 : {
350 : static const char module[] = "ZIPEncode";
351 15145 : ZIPState *sp = ZIPEncoderState(tif);
352 :
353 15145 : assert(sp != NULL);
354 15145 : assert(sp->state == ZSTATE_INIT_ENCODE);
355 :
356 : (void)s;
357 :
358 : #if LIBDEFLATE_SUPPORT
359 15145 : if (sp->libdeflate_state == 1)
360 0 : return 0;
361 :
362 : /* If we have libdeflate support and we are asked to write a whole */
363 : /* strip/tile, then go for using it */
364 : do
365 : {
366 15145 : TIFFDirectory *td = &tif->tif_dir;
367 :
368 15145 : if (sp->libdeflate_state == 0)
369 2000 : break;
370 13145 : if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
371 4097 : break;
372 :
373 : /* Libdeflate does not support the 0-compression level */
374 9048 : if (sp->zipquality == Z_NO_COMPRESSION)
375 0 : break;
376 :
377 : /* Check if we are in the situation where we can use libdeflate */
378 9048 : if (isTiled(tif))
379 : {
380 5678 : if (TIFFTileSize64(tif) != (uint64_t)cc)
381 0 : break;
382 : }
383 : else
384 : {
385 3370 : uint32_t strip_height = td->td_imagelength - tif->tif_row;
386 3370 : if (strip_height > td->td_rowsperstrip)
387 2018 : strip_height = td->td_rowsperstrip;
388 3370 : if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc)
389 1 : break;
390 : }
391 :
392 : /* Check for overflow */
393 : if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize)
394 : break;
395 : if ((size_t)cc != (uint64_t)cc)
396 : break;
397 :
398 : /* Go for compression using libdeflate */
399 : {
400 : size_t nCompressedBytes;
401 9048 : if (sp->libdeflate_enc == NULL)
402 : {
403 : /* To get results as good as zlib, we asked for an extra */
404 : /* level of compression */
405 1517 : sp->libdeflate_enc = libdeflate_alloc_compressor(
406 1517 : sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
407 11 : : sp->zipquality >= 6 && sp->zipquality <= 9
408 11 : ? sp->zipquality + 1
409 30 : : sp->zipquality);
410 1517 : if (sp->libdeflate_enc == NULL)
411 : {
412 0 : TIFFErrorExtR(tif, module, "Cannot allocate compressor");
413 0 : break;
414 : }
415 : }
416 :
417 : /* Make sure the output buffer is large enough for the worse case.
418 : */
419 : /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */
420 : /* we've taken a 10% margin over the uncompressed size, which should
421 : */
422 : /* be large enough even for the the worse case scenario. */
423 9048 : if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) >
424 9049 : (size_t)tif->tif_rawdatasize)
425 : {
426 0 : break;
427 : }
428 :
429 9049 : sp->libdeflate_state = 1;
430 9049 : nCompressedBytes = libdeflate_zlib_compress(
431 9049 : sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata,
432 9049 : (size_t)tif->tif_rawdatasize);
433 :
434 9047 : if (nCompressedBytes == 0)
435 : {
436 0 : TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
437 0 : (unsigned long)tif->tif_row);
438 0 : return 0;
439 : }
440 :
441 9047 : tif->tif_rawcc = nCompressedBytes;
442 :
443 9047 : if (!TIFFFlushData1(tif))
444 0 : return 0;
445 :
446 9048 : return 1;
447 : }
448 : } while (0);
449 6098 : sp->libdeflate_state = 0;
450 : #endif /* LIBDEFLATE_SUPPORT */
451 :
452 6098 : sp->stream.next_in = bp;
453 : assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
454 : we need to simplify this code to reflect a ZLib that is likely updated
455 : to deal with 8byte memory sizes, though this code will respond
456 : appropriately even before we simplify it */
457 : do
458 : {
459 6098 : uInt avail_in_before =
460 6098 : (uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
461 6098 : sp->stream.avail_in = avail_in_before;
462 : /* coverity[overrun-buffer-arg] */
463 6098 : if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
464 : {
465 0 : TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp));
466 0 : return (0);
467 : }
468 6098 : if (sp->stream.avail_out == 0)
469 : {
470 0 : tif->tif_rawcc = tif->tif_rawdatasize;
471 0 : if (!TIFFFlushData1(tif))
472 0 : return 0;
473 0 : sp->stream.next_out = tif->tif_rawdata;
474 0 : sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
475 0 : ? (uInt)tif->tif_rawdatasize
476 0 : : 0xFFFFFFFFU;
477 : }
478 6098 : cc -= (avail_in_before - sp->stream.avail_in);
479 6098 : } while (cc > 0);
480 6098 : return (1);
481 : }
482 :
483 : /*
484 : * Finish off an encoded strip by flushing the last
485 : * string and tacking on an End Of Information code.
486 : */
487 13144 : static int ZIPPostEncode(TIFF *tif)
488 : {
489 : static const char module[] = "ZIPPostEncode";
490 13144 : ZIPState *sp = ZIPEncoderState(tif);
491 : int state;
492 :
493 : #if LIBDEFLATE_SUPPORT
494 13144 : if (sp->libdeflate_state == 1)
495 9049 : return 1;
496 : #endif
497 :
498 4095 : sp->stream.avail_in = 0;
499 : do
500 : {
501 4095 : state = deflate(&sp->stream, Z_FINISH);
502 4098 : switch (state)
503 : {
504 4098 : case Z_STREAM_END:
505 : case Z_OK:
506 4098 : if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
507 : {
508 4098 : tif->tif_rawcc =
509 4098 : tif->tif_rawdatasize - sp->stream.avail_out;
510 4098 : if (!TIFFFlushData1(tif))
511 0 : return 0;
512 4098 : sp->stream.next_out = tif->tif_rawdata;
513 4098 : sp->stream.avail_out =
514 4098 : (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
515 4098 : ? (uInt)tif->tif_rawdatasize
516 4098 : : 0xFFFFFFFFU;
517 : }
518 4098 : break;
519 0 : default:
520 0 : TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
521 0 : return (0);
522 : }
523 4098 : } while (state != Z_STREAM_END);
524 4098 : return (1);
525 : }
526 :
527 7614 : static void ZIPCleanup(TIFF *tif)
528 : {
529 7614 : ZIPState *sp = GetZIPState(tif);
530 :
531 7614 : assert(sp != 0);
532 :
533 7614 : (void)TIFFPredictorCleanup(tif);
534 :
535 7614 : tif->tif_tagmethods.vgetfield = sp->vgetparent;
536 7614 : tif->tif_tagmethods.vsetfield = sp->vsetparent;
537 :
538 7614 : if (sp->state & ZSTATE_INIT_ENCODE)
539 : {
540 5605 : deflateEnd(&sp->stream);
541 5605 : sp->state = 0;
542 : }
543 2009 : else if (sp->state & ZSTATE_INIT_DECODE)
544 : {
545 442 : inflateEnd(&sp->stream);
546 442 : sp->state = 0;
547 : }
548 :
549 : #if LIBDEFLATE_SUPPORT
550 7614 : if (sp->libdeflate_dec)
551 390 : libdeflate_free_decompressor(sp->libdeflate_dec);
552 7614 : if (sp->libdeflate_enc)
553 1517 : libdeflate_free_compressor(sp->libdeflate_enc);
554 : #endif
555 :
556 7614 : _TIFFfreeExt(tif, sp);
557 7614 : tif->tif_data = NULL;
558 :
559 7614 : _TIFFSetDefaultCompressionState(tif);
560 7614 : }
561 :
562 50640 : static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
563 : {
564 : static const char module[] = "ZIPVSetField";
565 50640 : ZIPState *sp = GetZIPState(tif);
566 :
567 50640 : switch (tag)
568 : {
569 46 : case TIFFTAG_ZIPQUALITY:
570 46 : sp->zipquality = (int)va_arg(ap, int);
571 46 : if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
572 46 : sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
573 : {
574 0 : TIFFErrorExtR(
575 : tif, module,
576 : "Invalid ZipQuality value. Should be in [-1,%d] range",
577 : LIBDEFLATE_MAX_COMPRESSION_LEVEL);
578 0 : return 0;
579 : }
580 :
581 46 : if (sp->state & ZSTATE_INIT_ENCODE)
582 : {
583 0 : int cappedQuality = sp->zipquality;
584 0 : if (cappedQuality > Z_BEST_COMPRESSION)
585 0 : cappedQuality = Z_BEST_COMPRESSION;
586 0 : if (deflateParams(&sp->stream, cappedQuality,
587 : Z_DEFAULT_STRATEGY) != Z_OK)
588 : {
589 0 : TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
590 0 : return (0);
591 : }
592 : }
593 :
594 : #if LIBDEFLATE_SUPPORT
595 46 : if (sp->libdeflate_enc)
596 : {
597 0 : libdeflate_free_compressor(sp->libdeflate_enc);
598 0 : sp->libdeflate_enc = NULL;
599 : }
600 : #endif
601 :
602 46 : return (1);
603 :
604 4097 : case TIFFTAG_DEFLATE_SUBCODEC:
605 4097 : sp->subcodec = (int)va_arg(ap, int);
606 4097 : if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB &&
607 0 : sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE)
608 : {
609 0 : TIFFErrorExtR(tif, module, "Invalid DeflateCodec value.");
610 0 : return 0;
611 : }
612 : #if !LIBDEFLATE_SUPPORT
613 : if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE)
614 : {
615 : TIFFErrorExtR(tif, module,
616 : "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE "
617 : "unsupported in this build");
618 : return 0;
619 : }
620 : #endif
621 4097 : return 1;
622 :
623 46497 : default:
624 46497 : return (*sp->vsetparent)(tif, tag, ap);
625 : }
626 : /*NOTREACHED*/
627 : }
628 :
629 47709 : static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
630 : {
631 47709 : ZIPState *sp = GetZIPState(tif);
632 :
633 47709 : switch (tag)
634 : {
635 0 : case TIFFTAG_ZIPQUALITY:
636 0 : *va_arg(ap, int *) = sp->zipquality;
637 0 : break;
638 :
639 0 : case TIFFTAG_DEFLATE_SUBCODEC:
640 0 : *va_arg(ap, int *) = sp->subcodec;
641 0 : break;
642 :
643 47709 : default:
644 47709 : return (*sp->vgetparent)(tif, tag, ap);
645 : }
646 0 : return (1);
647 : }
648 :
649 : static const TIFFField zipFields[] = {
650 : {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
651 : TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
652 : {TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
653 : TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
654 : };
655 :
656 7615 : int TIFFInitZIP(TIFF *tif, int scheme)
657 : {
658 : static const char module[] = "TIFFInitZIP";
659 : ZIPState *sp;
660 :
661 7615 : assert((scheme == COMPRESSION_DEFLATE) ||
662 : (scheme == COMPRESSION_ADOBE_DEFLATE));
663 : #ifdef NDEBUG
664 : (void)scheme;
665 : #endif
666 :
667 : /*
668 : * Merge codec-specific tag information.
669 : */
670 7615 : if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields)))
671 : {
672 0 : TIFFErrorExtR(tif, module,
673 : "Merging Deflate codec-specific tags failed");
674 0 : return 0;
675 : }
676 :
677 : /*
678 : * Allocate state block so tag methods have storage to record values.
679 : */
680 7615 : tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1);
681 7614 : if (tif->tif_data == NULL)
682 0 : goto bad;
683 7614 : sp = GetZIPState(tif);
684 7614 : sp->stream.zalloc = NULL;
685 7614 : sp->stream.zfree = NULL;
686 7614 : sp->stream.opaque = NULL;
687 7614 : sp->stream.data_type = Z_BINARY;
688 :
689 : /*
690 : * Override parent get/set field methods.
691 : */
692 7614 : sp->vgetparent = tif->tif_tagmethods.vgetfield;
693 7614 : tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
694 7614 : sp->vsetparent = tif->tif_tagmethods.vsetfield;
695 7614 : tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
696 :
697 : /* Default values for codec-specific fields */
698 7614 : sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
699 7614 : sp->state = 0;
700 : #if LIBDEFLATE_SUPPORT
701 7614 : sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE;
702 : #else
703 : sp->subcodec = DEFLATE_SUBCODEC_ZLIB;
704 : #endif
705 :
706 : /*
707 : * Install codec methods.
708 : */
709 7614 : tif->tif_fixuptags = ZIPFixupTags;
710 7614 : tif->tif_setupdecode = ZIPSetupDecode;
711 7614 : tif->tif_predecode = ZIPPreDecode;
712 7614 : tif->tif_decoderow = ZIPDecode;
713 7614 : tif->tif_decodestrip = ZIPDecode;
714 7614 : tif->tif_decodetile = ZIPDecode;
715 7614 : tif->tif_setupencode = ZIPSetupEncode;
716 7614 : tif->tif_preencode = ZIPPreEncode;
717 7614 : tif->tif_postencode = ZIPPostEncode;
718 7614 : tif->tif_encoderow = ZIPEncode;
719 7614 : tif->tif_encodestrip = ZIPEncode;
720 7614 : tif->tif_encodetile = ZIPEncode;
721 7614 : tif->tif_cleanup = ZIPCleanup;
722 : /*
723 : * Setup predictor setup.
724 : */
725 7614 : (void)TIFFPredictorInit(tif);
726 7615 : return (1);
727 0 : bad:
728 0 : TIFFErrorExtR(tif, module, "No space for ZIP state block");
729 0 : return (0);
730 : }
731 : #endif /* ZIP_SUPPORT */
|