[1.5] jp2_read_boxhdr() call ignores return value
[openjpeg.git] / thirdparty / libtiff / tif_zip.c
1 /* $Id: tif_zip.c,v 1.11.2.4 2010-06-08 18:50:43 bfriesen Exp $ */
2
3 /*
4  * Copyright (c) 1995-1997 Sam Leffler
5  * Copyright (c) 1995-1997 Silicon Graphics, Inc.
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and 
8  * its documentation for any purpose is hereby granted without fee, provided
9  * that (i) the above copyright notices and this permission notice appear in
10  * all copies of the software and related documentation, and (ii) the names of
11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
12  * publicity relating to the software without the specific, prior written
13  * permission of Sam Leffler and Silicon Graphics.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
18  * 
19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
24  * OF THIS SOFTWARE.
25  */
26
27 #include "tiffiop.h"
28 #ifdef ZIP_SUPPORT
29 /*
30  * TIFF Library.
31  *
32  * ZIP (aka Deflate) Compression Support
33  *
34  * This file is simply an interface to the zlib library written by
35  * Jean-loup Gailly and Mark Adler.  You must use version 1.0 or later
36  * of the library: this code assumes the 1.0 API and also depends on
37  * the ability to write the zlib header multiple times (one per strip)
38  * which was not possible with versions prior to 0.95.  Note also that
39  * older versions of this codec avoided this bug by supressing the header
40  * entirely.  This means that files written with the old library cannot
41  * be read; they should be converted to a different compression scheme
42  * and then reconverted.
43  *
44  * The data format used by the zlib library is described in the files
45  * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
46  * directory ftp://ftp.uu.net/pub/archiving/zip/doc.  The library was
47  * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
48  */
49 #include "tif_predict.h"
50 #include "zlib.h"
51
52 #include <stdio.h>
53
54 /*
55  * Sigh, ZLIB_VERSION is defined as a string so there's no
56  * way to do a proper check here.  Instead we guess based
57  * on the presence of #defines that were added between the
58  * 0.95 and 1.0 distributions.
59  */
60 #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
61 #error "Antiquated ZLIB software; you must use version 1.0 or later"
62 #endif
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*, tidata_t, tsize_t, tsample_t);
85 static  int ZIPDecode(TIFF*, tidata_t, tsize_t, tsample_t);
86
87 static int
88 ZIPSetupDecode(TIFF* tif)
89 {
90         ZIPState* sp = DecoderState(tif);
91         static const char module[] = "ZIPSetupDecode";
92
93         assert(sp != NULL);
94         
95         /* if we were last encoding, terminate this mode */
96         if (sp->state & ZSTATE_INIT_ENCODE) {
97             deflateEnd(&sp->stream);
98             sp->state = 0;
99         }
100
101         if (inflateInit(&sp->stream) != Z_OK) {
102                 TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
103                 return (0);
104         } else {
105                 sp->state |= ZSTATE_INIT_DECODE;
106                 return (1);
107         }
108 }
109
110 /*
111  * Setup state for decoding a strip.
112  */
113 static int
114 ZIPPreDecode(TIFF* tif, tsample_t s)
115 {
116         ZIPState* sp = DecoderState(tif);
117
118         (void) s;
119         assert(sp != NULL);
120
121         if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
122             tif->tif_setupdecode( tif );
123
124         sp->stream.next_in = tif->tif_rawdata;
125         sp->stream.avail_in = tif->tif_rawcc;
126         return (inflateReset(&sp->stream) == Z_OK);
127 }
128
129 static int
130 ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
131 {
132         ZIPState* sp = DecoderState(tif);
133         static const char module[] = "ZIPDecode";
134
135         (void) s;
136         assert(sp != NULL);
137         assert(sp->state == ZSTATE_INIT_DECODE);
138
139         sp->stream.next_out = op;
140         sp->stream.avail_out = occ;
141         do {
142                 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
143                 if (state == Z_STREAM_END)
144                         break;
145                 if (state == Z_DATA_ERROR) {
146                         TIFFErrorExt(tif->tif_clientdata, module,
147                             "%s: Decoding error at scanline %d, %s",
148                             tif->tif_name, tif->tif_row, sp->stream.msg);
149                         if (inflateSync(&sp->stream) != Z_OK)
150                                 return (0);
151                         continue;
152                 }
153                 if (state != Z_OK) {
154                         TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
155                             tif->tif_name, sp->stream.msg);
156                         return (0);
157                 }
158         } while (sp->stream.avail_out > 0);
159         if (sp->stream.avail_out != 0) {
160                 TIFFErrorExt(tif->tif_clientdata, module,
161                     "%s: Not enough data at scanline %d (short %d bytes)",
162                     tif->tif_name, tif->tif_row, sp->stream.avail_out);
163                 return (0);
164         }
165         return (1);
166 }
167
168 static int
169 ZIPSetupEncode(TIFF* tif)
170 {
171         ZIPState* sp = EncoderState(tif);
172         static const char module[] = "ZIPSetupEncode";
173
174         assert(sp != NULL);
175         if (sp->state & ZSTATE_INIT_DECODE) {
176             inflateEnd(&sp->stream);
177             sp->state = 0;
178         }
179
180         if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
181                 TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
182                 return (0);
183         } else {
184                 sp->state |= ZSTATE_INIT_ENCODE;
185                 return (1);
186         }
187 }
188
189 /*
190  * Reset encoding state at the start of a strip.
191  */
192 static int
193 ZIPPreEncode(TIFF* tif, tsample_t s)
194 {
195         ZIPState *sp = EncoderState(tif);
196
197         (void) s;
198         assert(sp != NULL);
199         if( sp->state != ZSTATE_INIT_ENCODE )
200             tif->tif_setupencode( tif );
201
202         sp->stream.next_out = tif->tif_rawdata;
203         sp->stream.avail_out = tif->tif_rawdatasize;
204         return (deflateReset(&sp->stream) == Z_OK);
205 }
206
207 /*
208  * Encode a chunk of pixels.
209  */
210 static int
211 ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
212 {
213         ZIPState *sp = EncoderState(tif);
214         static const char module[] = "ZIPEncode";
215
216         assert(sp != NULL);
217         assert(sp->state == ZSTATE_INIT_ENCODE);
218
219         (void) s;
220         sp->stream.next_in = bp;
221         sp->stream.avail_in = cc;
222         do {
223                 if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
224                         TIFFErrorExt(tif->tif_clientdata, module, "%s: Encoder error: %s",
225                             tif->tif_name, sp->stream.msg);
226                         return (0);
227                 }
228                 if (sp->stream.avail_out == 0) {
229                         tif->tif_rawcc = tif->tif_rawdatasize;
230                         TIFFFlushData1(tif);
231                         sp->stream.next_out = tif->tif_rawdata;
232                         sp->stream.avail_out = tif->tif_rawdatasize;
233                 }
234         } while (sp->stream.avail_in > 0);
235         return (1);
236 }
237
238 /*
239  * Finish off an encoded strip by flushing the last
240  * string and tacking on an End Of Information code.
241  */
242 static int
243 ZIPPostEncode(TIFF* tif)
244 {
245         ZIPState *sp = EncoderState(tif);
246         static const char module[] = "ZIPPostEncode";
247         int state;
248
249         sp->stream.avail_in = 0;
250         do {
251                 state = deflate(&sp->stream, Z_FINISH);
252                 switch (state) {
253                 case Z_STREAM_END:
254                 case Z_OK:
255                     if ((int)sp->stream.avail_out != (int)tif->tif_rawdatasize)
256                     {
257                             tif->tif_rawcc =
258                                 tif->tif_rawdatasize - sp->stream.avail_out;
259                             TIFFFlushData1(tif);
260                             sp->stream.next_out = tif->tif_rawdata;
261                             sp->stream.avail_out = tif->tif_rawdatasize;
262                     }
263                     break;
264                 default:
265                         TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
266                         tif->tif_name, sp->stream.msg);
267                     return (0);
268                 }
269         } while (state != Z_STREAM_END);
270         return (1);
271 }
272
273 static void
274 ZIPCleanup(TIFF* tif)
275 {
276         ZIPState* sp = ZState(tif);
277
278         assert(sp != 0);
279
280         (void)TIFFPredictorCleanup(tif);
281
282         tif->tif_tagmethods.vgetfield = sp->vgetparent;
283         tif->tif_tagmethods.vsetfield = sp->vsetparent;
284
285         if (sp->state & ZSTATE_INIT_ENCODE) {
286             deflateEnd(&sp->stream);
287             sp->state = 0;
288         } else if( sp->state & ZSTATE_INIT_DECODE) {
289             inflateEnd(&sp->stream);
290             sp->state = 0;
291         }
292         _TIFFfree(sp);
293         tif->tif_data = NULL;
294
295         _TIFFSetDefaultCompressionState(tif);
296 }
297
298 static int
299 ZIPVSetField(TIFF* tif, ttag_t tag, va_list ap)
300 {
301         ZIPState* sp = ZState(tif);
302         static const char module[] = "ZIPVSetField";
303
304         switch (tag) {
305         case TIFFTAG_ZIPQUALITY:
306                 sp->zipquality = va_arg(ap, int);
307                 if ( sp->state&ZSTATE_INIT_ENCODE ) {
308                         if (deflateParams(&sp->stream,
309                             sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
310                                 TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
311                                     tif->tif_name, sp->stream.msg);
312                                 return (0);
313                         }
314                 }
315                 return (1);
316         default:
317                 return (*sp->vsetparent)(tif, tag, ap);
318         }
319         /*NOTREACHED*/
320 }
321
322 static int
323 ZIPVGetField(TIFF* tif, ttag_t tag, va_list ap)
324 {
325         ZIPState* sp = ZState(tif);
326
327         switch (tag) {
328         case TIFFTAG_ZIPQUALITY:
329                 *va_arg(ap, int*) = sp->zipquality;
330                 break;
331         default:
332                 return (*sp->vgetparent)(tif, tag, ap);
333         }
334         return (1);
335 }
336
337 static const TIFFFieldInfo zipFieldInfo[] = {
338     { TIFFTAG_ZIPQUALITY,        0, 0,  TIFF_ANY,       FIELD_PSEUDO,
339       TRUE,     FALSE,  "" },
340 };
341
342 int
343 TIFFInitZIP(TIFF* tif, int scheme)
344 {
345         static const char module[] = "TIFFInitZIP";
346         ZIPState* sp;
347
348         assert( (scheme == COMPRESSION_DEFLATE)
349                 || (scheme == COMPRESSION_ADOBE_DEFLATE));
350
351         /*
352          * Merge codec-specific tag information.
353          */
354         if (!_TIFFMergeFieldInfo(tif, zipFieldInfo,
355                                  TIFFArrayCount(zipFieldInfo))) {
356                 TIFFErrorExt(tif->tif_clientdata, module,
357                              "Merging Deflate codec-specific tags failed");
358                 return 0;
359         }
360
361         /*
362          * Allocate state block so tag methods have storage to record values.
363          */
364         tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (ZIPState));
365         if (tif->tif_data == NULL)
366                 goto bad;
367         sp = ZState(tif);
368         sp->stream.zalloc = NULL;
369         sp->stream.zfree = NULL;
370         sp->stream.opaque = NULL;
371         sp->stream.data_type = Z_BINARY;
372
373         /*
374          * Override parent get/set field methods.
375          */
376         sp->vgetparent = tif->tif_tagmethods.vgetfield;
377         tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
378         sp->vsetparent = tif->tif_tagmethods.vsetfield;
379         tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
380
381         /* Default values for codec-specific fields */
382         sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
383         sp->state = 0;
384
385         /*
386          * Install codec methods.
387          */
388         tif->tif_setupdecode = ZIPSetupDecode;
389         tif->tif_predecode = ZIPPreDecode;
390         tif->tif_decoderow = ZIPDecode;
391         tif->tif_decodestrip = ZIPDecode;
392         tif->tif_decodetile = ZIPDecode;
393         tif->tif_setupencode = ZIPSetupEncode;
394         tif->tif_preencode = ZIPPreEncode;
395         tif->tif_postencode = ZIPPostEncode;
396         tif->tif_encoderow = ZIPEncode;
397         tif->tif_encodestrip = ZIPEncode;
398         tif->tif_encodetile = ZIPEncode;
399         tif->tif_cleanup = ZIPCleanup;
400         /*
401          * Setup predictor setup.
402          */
403         (void) TIFFPredictorInit(tif);
404         return (1);
405 bad:
406         TIFFErrorExt(tif->tif_clientdata, module,
407                      "No space for ZIP state block");
408         return (0);
409 }
410 #endif /* ZIP_SUPORT */
411
412 /* vim: set ts=8 sts=8 sw=8 noet: */
413 /*
414  * Local Variables:
415  * mode: c
416  * c-basic-offset: 8
417  * fill-column: 78
418  * End:
419  */