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 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
ZIPFixupTags(TIFF * tif)88 ZIPFixupTags(TIFF* tif)
89 {
90 (void) tif;
91 return (1);
92 }
93
94 static int
ZIPSetupDecode(TIFF * tif)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
ZIPPreDecode(TIFF * tif,uint16 s)125 ZIPPreDecode(TIFF* tif, uint16 s)
126 {
127 static const char module[] = "ZIPPreDecode";
128 ZIPState* sp = DecoderState(tif);
129
130 (void) s;
131 assert(sp != NULL);
132
133 if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
134 tif->tif_setupdecode( tif );
135
136 sp->stream.next_in = tif->tif_rawdata;
137 assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
138 we need to simplify this code to reflect a ZLib that is likely updated
139 to deal with 8byte memory sizes, though this code will respond
140 appropriately even before we simplify it */
141 sp->stream.avail_in = (uInt) tif->tif_rawcc;
142 if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
143 {
144 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
145 return (0);
146 }
147 return (inflateReset(&sp->stream) == Z_OK);
148 }
149
150 static int
ZIPDecode(TIFF * tif,uint8 * op,tmsize_t occ,uint16 s)151 ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
152 {
153 static const char module[] = "ZIPDecode";
154 ZIPState* sp = DecoderState(tif);
155
156 (void) s;
157 assert(sp != NULL);
158 assert(sp->state == ZSTATE_INIT_DECODE);
159
160 sp->stream.next_in = tif->tif_rawcp;
161 sp->stream.avail_in = (uInt) tif->tif_rawcc;
162
163 sp->stream.next_out = op;
164 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
165 we need to simplify this code to reflect a ZLib that is likely updated
166 to deal with 8byte memory sizes, though this code will respond
167 appropriately even before we simplify it */
168 sp->stream.avail_out = (uInt) occ;
169 if ((tmsize_t)sp->stream.avail_out != occ)
170 {
171 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
172 return (0);
173 }
174 do {
175 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
176 if (state == Z_STREAM_END)
177 break;
178 if (state == Z_DATA_ERROR) {
179 TIFFErrorExt(tif->tif_clientdata, module,
180 "Decoding error at scanline %lu, %s",
181 (unsigned long) tif->tif_row, SAFE_MSG(sp));
182 if (inflateSync(&sp->stream) != Z_OK)
183 return (0);
184 continue;
185 }
186 if (state != Z_OK) {
187 TIFFErrorExt(tif->tif_clientdata, module,
188 "ZLib error: %s", SAFE_MSG(sp));
189 return (0);
190 }
191 } while (sp->stream.avail_out > 0);
192 if (sp->stream.avail_out != 0) {
193 TIFFErrorExt(tif->tif_clientdata, module,
194 "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
195 (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
196 return (0);
197 }
198
199 tif->tif_rawcp = sp->stream.next_in;
200 tif->tif_rawcc = sp->stream.avail_in;
201
202 return (1);
203 }
204
205 static int
ZIPSetupEncode(TIFF * tif)206 ZIPSetupEncode(TIFF* tif)
207 {
208 static const char module[] = "ZIPSetupEncode";
209 ZIPState* sp = EncoderState(tif);
210
211 assert(sp != NULL);
212 if (sp->state & ZSTATE_INIT_DECODE) {
213 inflateEnd(&sp->stream);
214 sp->state = 0;
215 }
216
217 if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
218 TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp));
219 return (0);
220 } else {
221 sp->state |= ZSTATE_INIT_ENCODE;
222 return (1);
223 }
224 }
225
226 /*
227 * Reset encoding state at the start of a strip.
228 */
229 static int
ZIPPreEncode(TIFF * tif,uint16 s)230 ZIPPreEncode(TIFF* tif, uint16 s)
231 {
232 static const char module[] = "ZIPPreEncode";
233 ZIPState *sp = EncoderState(tif);
234
235 (void) s;
236 assert(sp != NULL);
237 if( sp->state != ZSTATE_INIT_ENCODE )
238 tif->tif_setupencode( tif );
239
240 sp->stream.next_out = tif->tif_rawdata;
241 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
242 we need to simplify this code to reflect a ZLib that is likely updated
243 to deal with 8byte memory sizes, though this code will respond
244 appropriately even before we simplify it */
245 sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
246 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
247 {
248 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
249 return (0);
250 }
251 return (deflateReset(&sp->stream) == Z_OK);
252 }
253
254 /*
255 * Encode a chunk of pixels.
256 */
257 static int
ZIPEncode(TIFF * tif,uint8 * bp,tmsize_t cc,uint16 s)258 ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
259 {
260 static const char module[] = "ZIPEncode";
261 ZIPState *sp = EncoderState(tif);
262
263 assert(sp != NULL);
264 assert(sp->state == ZSTATE_INIT_ENCODE);
265
266 (void) s;
267 sp->stream.next_in = bp;
268 assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
269 we need to simplify this code to reflect a ZLib that is likely updated
270 to deal with 8byte memory sizes, though this code will respond
271 appropriately even before we simplify it */
272 sp->stream.avail_in = (uInt) cc;
273 if ((tmsize_t)sp->stream.avail_in != cc)
274 {
275 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
276 return (0);
277 }
278 do {
279 if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
280 TIFFErrorExt(tif->tif_clientdata, module,
281 "Encoder error: %s",
282 SAFE_MSG(sp));
283 return (0);
284 }
285 if (sp->stream.avail_out == 0) {
286 tif->tif_rawcc = tif->tif_rawdatasize;
287 TIFFFlushData1(tif);
288 sp->stream.next_out = tif->tif_rawdata;
289 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
290 }
291 } while (sp->stream.avail_in > 0);
292 return (1);
293 }
294
295 /*
296 * Finish off an encoded strip by flushing the last
297 * string and tacking on an End Of Information code.
298 */
299 static int
ZIPPostEncode(TIFF * tif)300 ZIPPostEncode(TIFF* tif)
301 {
302 static const char module[] = "ZIPPostEncode";
303 ZIPState *sp = EncoderState(tif);
304 int state;
305
306 sp->stream.avail_in = 0;
307 do {
308 state = deflate(&sp->stream, Z_FINISH);
309 switch (state) {
310 case Z_STREAM_END:
311 case Z_OK:
312 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
313 {
314 tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out;
315 TIFFFlushData1(tif);
316 sp->stream.next_out = tif->tif_rawdata;
317 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
318 }
319 break;
320 default:
321 TIFFErrorExt(tif->tif_clientdata, module,
322 "ZLib error: %s", SAFE_MSG(sp));
323 return (0);
324 }
325 } while (state != Z_STREAM_END);
326 return (1);
327 }
328
329 static void
ZIPCleanup(TIFF * tif)330 ZIPCleanup(TIFF* tif)
331 {
332 ZIPState* sp = ZState(tif);
333
334 assert(sp != 0);
335
336 (void)TIFFPredictorCleanup(tif);
337
338 tif->tif_tagmethods.vgetfield = sp->vgetparent;
339 tif->tif_tagmethods.vsetfield = sp->vsetparent;
340
341 if (sp->state & ZSTATE_INIT_ENCODE) {
342 deflateEnd(&sp->stream);
343 sp->state = 0;
344 } else if( sp->state & ZSTATE_INIT_DECODE) {
345 inflateEnd(&sp->stream);
346 sp->state = 0;
347 }
348 _TIFFfree(sp);
349 tif->tif_data = NULL;
350
351 _TIFFSetDefaultCompressionState(tif);
352 }
353
354 static int
ZIPVSetField(TIFF * tif,uint32 tag,va_list ap)355 ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
356 {
357 static const char module[] = "ZIPVSetField";
358 ZIPState* sp = ZState(tif);
359
360 switch (tag) {
361 case TIFFTAG_ZIPQUALITY:
362 sp->zipquality = (int) va_arg(ap, int);
363 if ( sp->state&ZSTATE_INIT_ENCODE ) {
364 if (deflateParams(&sp->stream,
365 sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
366 TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
367 SAFE_MSG(sp));
368 return (0);
369 }
370 }
371 return (1);
372 default:
373 return (*sp->vsetparent)(tif, tag, ap);
374 }
375 /*NOTREACHED*/
376 }
377
378 static int
ZIPVGetField(TIFF * tif,uint32 tag,va_list ap)379 ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
380 {
381 ZIPState* sp = ZState(tif);
382
383 switch (tag) {
384 case TIFFTAG_ZIPQUALITY:
385 *va_arg(ap, int*) = sp->zipquality;
386 break;
387 default:
388 return (*sp->vgetparent)(tif, tag, ap);
389 }
390 return (1);
391 }
392
393 static const TIFFField zipFields[] = {
394 { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
395 };
396
397 int
TIFFInitZIP(TIFF * tif,int scheme)398 TIFFInitZIP(TIFF* tif, int scheme)
399 {
400 static const char module[] = "TIFFInitZIP";
401 ZIPState* sp;
402
403 assert( (scheme == COMPRESSION_DEFLATE)
404 || (scheme == COMPRESSION_ADOBE_DEFLATE));
405
406 /*
407 * Merge codec-specific tag information.
408 */
409 if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) {
410 TIFFErrorExt(tif->tif_clientdata, module,
411 "Merging Deflate codec-specific tags failed");
412 return 0;
413 }
414
415 /*
416 * Allocate state block so tag methods have storage to record values.
417 */
418 tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
419 if (tif->tif_data == NULL)
420 goto bad;
421 sp = ZState(tif);
422 sp->stream.zalloc = NULL;
423 sp->stream.zfree = NULL;
424 sp->stream.opaque = NULL;
425 sp->stream.data_type = Z_BINARY;
426
427 /*
428 * Override parent get/set field methods.
429 */
430 sp->vgetparent = tif->tif_tagmethods.vgetfield;
431 tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
432 sp->vsetparent = tif->tif_tagmethods.vsetfield;
433 tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
434
435 /* Default values for codec-specific fields */
436 sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
437 sp->state = 0;
438
439 /*
440 * Install codec methods.
441 */
442 tif->tif_fixuptags = ZIPFixupTags;
443 tif->tif_setupdecode = ZIPSetupDecode;
444 tif->tif_predecode = ZIPPreDecode;
445 tif->tif_decoderow = ZIPDecode;
446 tif->tif_decodestrip = ZIPDecode;
447 tif->tif_decodetile = ZIPDecode;
448 tif->tif_setupencode = ZIPSetupEncode;
449 tif->tif_preencode = ZIPPreEncode;
450 tif->tif_postencode = ZIPPostEncode;
451 tif->tif_encoderow = ZIPEncode;
452 tif->tif_encodestrip = ZIPEncode;
453 tif->tif_encodetile = ZIPEncode;
454 tif->tif_cleanup = ZIPCleanup;
455 /*
456 * Setup predictor setup.
457 */
458 (void) TIFFPredictorInit(tif);
459 return (1);
460 bad:
461 TIFFErrorExt(tif->tif_clientdata, module,
462 "No space for ZIP state block");
463 return (0);
464 }
465 #endif /* ZIP_SUPPORT */
466
467 /* vim: set ts=8 sts=8 sw=8 noet: */
468 /*
469 * Local Variables:
470 * mode: c
471 * c-basic-offset: 8
472 * fill-column: 78
473 * End:
474 */
475