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