xref: /reactos/dll/3rdparty/libtiff/tif_zip.c (revision 8a978a17)
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 <precomp.h>
26 #ifdef ZIP_SUPPORT
27 /*
28  * TIFF Library.
29  *
30  * ZIP (aka Deflate) Compression Support
31  *
32  * This file is simply 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: this code assumes the 1.0 API and also depends on
35  * the ability to write the zlib header multiple times (one per strip)
36  * which was not possible with versions prior to 0.95.  Note also that
37  * older versions of this codec avoided this bug by suppressing the header
38  * entirely.  This means that files written with the old library cannot
39  * be read; they should be converted to a different compression scheme
40  * and then reconverted.
41  *
42  * The data format used by the zlib library is described in the files
43  * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
44  * directory ftp://ftp.uu.net/pub/archiving/zip/doc.  The library was
45  * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
46  */
47 #include "tif_predict.h"
48 #include "zlib.h"
49 
50 #include <stdio.h>
51 
52 /*
53  * Sigh, ZLIB_VERSION is defined as a string so there's no
54  * way to do a proper check here.  Instead we guess based
55  * on the presence of #defines that were added between the
56  * 0.95 and 1.0 distributions.
57  */
58 #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
59 #error "Antiquated ZLIB software; you must use version 1.0 or later"
60 #endif
61 
62 #define SAFE_MSG(sp)   ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
63 
64 /*
65  * State block for each open TIFF
66  * file using ZIP compression/decompression.
67  */
68 typedef struct {
69 	TIFFPredictorState predict;
70         z_stream        stream;
71 	int             zipquality;            /* compression level */
72 	int             state;                 /* state flags */
73 #define ZSTATE_INIT_DECODE 0x01
74 #define ZSTATE_INIT_ENCODE 0x02
75 
76 	TIFFVGetMethod  vgetparent;            /* super-class method */
77 	TIFFVSetMethod  vsetparent;            /* super-class method */
78 } ZIPState;
79 
80 #define ZState(tif)             ((ZIPState*) (tif)->tif_data)
81 #define DecoderState(tif)       ZState(tif)
82 #define EncoderState(tif)       ZState(tif)
83 
84 static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
85 static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
86 
87 static int
88 ZIPFixupTags(TIFF* tif)
89 {
90 	(void) tif;
91 	return (1);
92 }
93 
94 static int
95 ZIPSetupDecode(TIFF* tif)
96 {
97 	static const char module[] = "ZIPSetupDecode";
98 	ZIPState* sp = DecoderState(tif);
99 
100 	assert(sp != NULL);
101 
102         /* if we were last encoding, terminate this mode */
103 	if (sp->state & ZSTATE_INIT_ENCODE) {
104 	    deflateEnd(&sp->stream);
105 	    sp->state = 0;
106 	}
107 
108 	/* This function can possibly be called several times by */
109 	/* PredictorSetupDecode() if this function succeeds but */
110 	/* PredictorSetup() fails */
111 	if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
112 	    inflateInit(&sp->stream) != Z_OK) {
113 		TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
114 		return (0);
115 	} else {
116 		sp->state |= ZSTATE_INIT_DECODE;
117 		return (1);
118 	}
119 }
120 
121 /*
122  * Setup state for decoding a strip.
123  */
124 static int
125 ZIPPreDecode(TIFF* tif, uint16 s)
126 {
127 	ZIPState* sp = DecoderState(tif);
128 
129 	(void) s;
130 	assert(sp != NULL);
131 
132 	if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
133             tif->tif_setupdecode( tif );
134 
135 	sp->stream.next_in = tif->tif_rawdata;
136 	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
137 	    we need to simplify this code to reflect a ZLib that is likely updated
138 	    to deal with 8byte memory sizes, though this code will respond
139 	    appropriately even before we simplify it */
140 	sp->stream.avail_in = (uint64)tif->tif_rawcc < 0xFFFFFFFFU ? (uInt) tif->tif_rawcc : 0xFFFFFFFFU;
141 	return (inflateReset(&sp->stream) == Z_OK);
142 }
143 
144 static int
145 ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
146 {
147 	static const char module[] = "ZIPDecode";
148 	ZIPState* sp = DecoderState(tif);
149 
150 	(void) s;
151 	assert(sp != NULL);
152 	assert(sp->state == ZSTATE_INIT_DECODE);
153 
154         sp->stream.next_in = tif->tif_rawcp;
155 
156 	sp->stream.next_out = op;
157 	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
158 	    we need to simplify this code to reflect a ZLib that is likely updated
159 	    to deal with 8byte memory sizes, though this code will respond
160 	    appropriately even before we simplify it */
161 	do {
162                 int state;
163                 uInt avail_in_before = (uint64)tif->tif_rawcc <= 0xFFFFFFFFU ? (uInt)tif->tif_rawcc : 0xFFFFFFFFU;
164                 uInt avail_out_before = (uint64)occ < 0xFFFFFFFFU ? (uInt) occ : 0xFFFFFFFFU;
165                 sp->stream.avail_in = avail_in_before;
166                 sp->stream.avail_out = avail_out_before;
167 		state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
168 		tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
169                 occ -= (avail_out_before - sp->stream.avail_out);
170 		if (state == Z_STREAM_END)
171 			break;
172 		if (state == Z_DATA_ERROR) {
173 			TIFFErrorExt(tif->tif_clientdata, module,
174 			    "Decoding error at scanline %lu, %s",
175 			     (unsigned long) tif->tif_row, SAFE_MSG(sp));
176 			return (0);
177 		}
178 		if (state != Z_OK) {
179 			TIFFErrorExt(tif->tif_clientdata, module,
180 				     "ZLib error: %s", SAFE_MSG(sp));
181 			return (0);
182 		}
183 	} while (occ > 0);
184 	if (occ != 0) {
185 		TIFFErrorExt(tif->tif_clientdata, module,
186 		    "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
187 		    (unsigned long) tif->tif_row, (TIFF_UINT64_T) occ);
188 		return (0);
189 	}
190 
191         tif->tif_rawcp = sp->stream.next_in;
192 
193 	return (1);
194 }
195 
196 static int
197 ZIPSetupEncode(TIFF* tif)
198 {
199 	static const char module[] = "ZIPSetupEncode";
200 	ZIPState* sp = EncoderState(tif);
201 
202 	assert(sp != NULL);
203 	if (sp->state & ZSTATE_INIT_DECODE) {
204 		inflateEnd(&sp->stream);
205 		sp->state = 0;
206 	}
207 
208 	if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
209 		TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
210 		return (0);
211 	} else {
212 		sp->state |= ZSTATE_INIT_ENCODE;
213 		return (1);
214 	}
215 }
216 
217 /*
218  * Reset encoding state at the start of a strip.
219  */
220 static int
221 ZIPPreEncode(TIFF* tif, uint16 s)
222 {
223 	ZIPState *sp = EncoderState(tif);
224 
225 	(void) s;
226 	assert(sp != NULL);
227 	if( sp->state != ZSTATE_INIT_ENCODE )
228             tif->tif_setupencode( tif );
229 
230 	sp->stream.next_out = tif->tif_rawdata;
231 	assert(sizeof(sp->stream.avail_out)==4);  /* if this assert gets raised,
232 	    we need to simplify this code to reflect a ZLib that is likely updated
233 	    to deal with 8byte memory sizes, though this code will respond
234 	    appropriately even before we simplify it */
235 	sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
236 	return (deflateReset(&sp->stream) == Z_OK);
237 }
238 
239 /*
240  * Encode a chunk of pixels.
241  */
242 static int
243 ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
244 {
245 	static const char module[] = "ZIPEncode";
246 	ZIPState *sp = EncoderState(tif);
247 
248 	assert(sp != NULL);
249 	assert(sp->state == ZSTATE_INIT_ENCODE);
250 
251 	(void) s;
252 	sp->stream.next_in = bp;
253 	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
254 	    we need to simplify this code to reflect a ZLib that is likely updated
255 	    to deal with 8byte memory sizes, though this code will respond
256 	    appropriately even before we simplify it */
257 	do {
258                 uInt avail_in_before = (uint64)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
259                 sp->stream.avail_in = avail_in_before;
260 		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
261 			TIFFErrorExt(tif->tif_clientdata, module,
262 				     "Encoder error: %s",
263 				     SAFE_MSG(sp));
264 			return (0);
265 		}
266 		if (sp->stream.avail_out == 0) {
267 			tif->tif_rawcc = tif->tif_rawdatasize;
268 			TIFFFlushData1(tif);
269 			sp->stream.next_out = tif->tif_rawdata;
270 			sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
271 		}
272 		cc -= (avail_in_before - sp->stream.avail_in);
273 	} while (cc > 0);
274 	return (1);
275 }
276 
277 /*
278  * Finish off an encoded strip by flushing the last
279  * string and tacking on an End Of Information code.
280  */
281 static int
282 ZIPPostEncode(TIFF* tif)
283 {
284 	static const char module[] = "ZIPPostEncode";
285 	ZIPState *sp = EncoderState(tif);
286 	int state;
287 
288 	sp->stream.avail_in = 0;
289 	do {
290 		state = deflate(&sp->stream, Z_FINISH);
291 		switch (state) {
292 		case Z_STREAM_END:
293 		case Z_OK:
294 			if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
295 			{
296 				tif->tif_rawcc =  tif->tif_rawdatasize - sp->stream.avail_out;
297 				TIFFFlushData1(tif);
298 				sp->stream.next_out = tif->tif_rawdata;
299 				sp->stream.avail_out = (uint64)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU;
300 			}
301 			break;
302 		default:
303 			TIFFErrorExt(tif->tif_clientdata, module,
304 				     "ZLib error: %s", SAFE_MSG(sp));
305 			return (0);
306 		}
307 	} while (state != Z_STREAM_END);
308 	return (1);
309 }
310 
311 static void
312 ZIPCleanup(TIFF* tif)
313 {
314 	ZIPState* sp = ZState(tif);
315 
316 	assert(sp != 0);
317 
318 	(void)TIFFPredictorCleanup(tif);
319 
320 	tif->tif_tagmethods.vgetfield = sp->vgetparent;
321 	tif->tif_tagmethods.vsetfield = sp->vsetparent;
322 
323 	if (sp->state & ZSTATE_INIT_ENCODE) {
324 		deflateEnd(&sp->stream);
325 		sp->state = 0;
326 	} else if( sp->state & ZSTATE_INIT_DECODE) {
327 		inflateEnd(&sp->stream);
328 		sp->state = 0;
329 	}
330 	_TIFFfree(sp);
331 	tif->tif_data = NULL;
332 
333 	_TIFFSetDefaultCompressionState(tif);
334 }
335 
336 static int
337 ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
338 {
339 	static const char module[] = "ZIPVSetField";
340 	ZIPState* sp = ZState(tif);
341 
342 	switch (tag) {
343 	case TIFFTAG_ZIPQUALITY:
344 		sp->zipquality = (int) va_arg(ap, int);
345 		if ( sp->state&ZSTATE_INIT_ENCODE ) {
346 			if (deflateParams(&sp->stream,
347 			    sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
348 				TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
349 					     SAFE_MSG(sp));
350 				return (0);
351 			}
352 		}
353 		return (1);
354 	default:
355 		return (*sp->vsetparent)(tif, tag, ap);
356 	}
357 	/*NOTREACHED*/
358 }
359 
360 static int
361 ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
362 {
363 	ZIPState* sp = ZState(tif);
364 
365 	switch (tag) {
366 	case TIFFTAG_ZIPQUALITY:
367 		*va_arg(ap, int*) = sp->zipquality;
368 		break;
369 	default:
370 		return (*sp->vgetparent)(tif, tag, ap);
371 	}
372 	return (1);
373 }
374 
375 static const TIFFField zipFields[] = {
376     { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
377 };
378 
379 int
380 TIFFInitZIP(TIFF* tif, int scheme)
381 {
382 	static const char module[] = "TIFFInitZIP";
383 	ZIPState* sp;
384 
385 	assert( (scheme == COMPRESSION_DEFLATE)
386 		|| (scheme == COMPRESSION_ADOBE_DEFLATE));
387 
388 	/*
389 	 * Merge codec-specific tag information.
390 	 */
391 	if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) {
392 		TIFFErrorExt(tif->tif_clientdata, module,
393 			     "Merging Deflate codec-specific tags failed");
394 		return 0;
395 	}
396 
397 	/*
398 	 * Allocate state block so tag methods have storage to record values.
399 	 */
400 	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
401 	if (tif->tif_data == NULL)
402 		goto bad;
403 	sp = ZState(tif);
404 	sp->stream.zalloc = NULL;
405 	sp->stream.zfree = NULL;
406 	sp->stream.opaque = NULL;
407 	sp->stream.data_type = Z_BINARY;
408 
409 	/*
410 	 * Override parent get/set field methods.
411 	 */
412 	sp->vgetparent = tif->tif_tagmethods.vgetfield;
413 	tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
414 	sp->vsetparent = tif->tif_tagmethods.vsetfield;
415 	tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
416 
417 	/* Default values for codec-specific fields */
418 	sp->zipquality = Z_DEFAULT_COMPRESSION;	/* default comp. level */
419 	sp->state = 0;
420 
421 	/*
422 	 * Install codec methods.
423 	 */
424 	tif->tif_fixuptags = ZIPFixupTags;
425 	tif->tif_setupdecode = ZIPSetupDecode;
426 	tif->tif_predecode = ZIPPreDecode;
427 	tif->tif_decoderow = ZIPDecode;
428 	tif->tif_decodestrip = ZIPDecode;
429 	tif->tif_decodetile = ZIPDecode;
430 	tif->tif_setupencode = ZIPSetupEncode;
431 	tif->tif_preencode = ZIPPreEncode;
432 	tif->tif_postencode = ZIPPostEncode;
433 	tif->tif_encoderow = ZIPEncode;
434 	tif->tif_encodestrip = ZIPEncode;
435 	tif->tif_encodetile = ZIPEncode;
436 	tif->tif_cleanup = ZIPCleanup;
437 	/*
438 	 * Setup predictor setup.
439 	 */
440 	(void) TIFFPredictorInit(tif);
441 	return (1);
442 bad:
443 	TIFFErrorExt(tif->tif_clientdata, module,
444 		     "No space for ZIP state block");
445 	return (0);
446 }
447 #endif /* ZIP_SUPPORT */
448 
449 /* vim: set ts=8 sts=8 sw=8 noet: */
450 /*
451  * Local Variables:
452  * mode: c
453  * c-basic-offset: 8
454  * fill-column: 78
455  * End:
456  */
457