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