| OLD | NEW |
| 1 /* $Id: tif_zip.c,v 1.31 2011-01-06 16:00:23 fwarmerdam Exp $ */ | 1 /* $Id: tif_zip.c,v 1.33 2014-12-25 18:29:11 erouault Exp $ */ |
| 2 | 2 |
| 3 /* | 3 /* |
| 4 * Copyright (c) 1995-1997 Sam Leffler | 4 * Copyright (c) 1995-1997 Sam Leffler |
| 5 * Copyright (c) 1995-1997 Silicon Graphics, Inc. | 5 * Copyright (c) 1995-1997 Silicon Graphics, Inc. |
| 6 * | 6 * |
| 7 * Permission to use, copy, modify, distribute, and sell this software and | 7 * Permission to use, copy, modify, distribute, and sell this software and |
| 8 * its documentation for any purpose is hereby granted without fee, provided | 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 | 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 | 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 | 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 | 12 * publicity relating to the software without the specific, prior written |
| 13 * permission of Sam Leffler and Silicon Graphics. | 13 * permission of Sam Leffler and Silicon Graphics. |
| 14 * | 14 * |
| 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, |
| 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY |
| 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. |
| 18 * | 18 * |
| 19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | 19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR |
| 20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | 20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, |
| 21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | 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 | 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 | 23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
| 24 * OF THIS SOFTWARE. | 24 * OF THIS SOFTWARE. |
| 25 */ | 25 */ |
| 26 |
| 26 #include "tiffiop.h" | 27 #include "tiffiop.h" |
| 27 #ifdef ZIP_SUPPORT | 28 #ifdef ZIP_SUPPORT |
| 28 /* | 29 /* |
| 29 * TIFF Library. | 30 * TIFF Library. |
| 30 * | 31 * |
| 31 * ZIP (aka Deflate) Compression Support | 32 * ZIP (aka Deflate) Compression Support |
| 32 * | 33 * |
| 33 * This file is simply an interface to the zlib library written by | 34 * 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 * 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 * 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 * 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 * which was not possible with versions prior to 0.95. Note also that |
| 38 * older versions of this codec avoided this bug by supressing the header | 39 * 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 * entirely. This means that files written with the old library cannot |
| 40 * be read; they should be converted to a different compression scheme | 41 * be read; they should be converted to a different compression scheme |
| 41 * and then reconverted. | 42 * and then reconverted. |
| 42 * | 43 * |
| 43 * The data format used by the zlib library is described in the files | 44 * 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 * 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 * 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 * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz. |
| 47 */ | 48 */ |
| 48 #include "tif_predict.h" | 49 #include "tif_predict.h" |
| 49 #include "../zlib_v128/zlib.h" | 50 #include "../zlib_v128/zlib.h" |
| 50 | 51 |
| 51 #include <stdio.h> | 52 #include <stdio.h> |
| 52 | 53 |
| 53 /* | 54 /* |
| 54 * Sigh, ZLIB_VERSION is defined as a string so there's no | 55 * 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 * way to do a proper check here. Instead we guess based |
| 56 * on the presence of #defines that were added between the | 57 * on the presence of #defines that were added between the |
| 57 * 0.95 and 1.0 distributions. | 58 * 0.95 and 1.0 distributions. |
| 58 */ | 59 */ |
| 59 #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED) | 60 #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED) |
| 60 #error "Antiquated ZLIB software; you must use version 1.0 or later" | 61 #error "Antiquated ZLIB software; you must use version 1.0 or later" |
| 61 #endif | 62 #endif |
| 62 | 63 |
| 64 #define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg) |
| 65 |
| 63 /* | 66 /* |
| 64 * State block for each open TIFF | 67 * State block for each open TIFF |
| 65 * file using ZIP compression/decompression. | 68 * file using ZIP compression/decompression. |
| 66 */ | 69 */ |
| 67 typedef struct { | 70 typedef struct { |
| 68 TIFFPredictorState predict; | 71 TIFFPredictorState predict; |
| 69 z_stream stream; | 72 z_stream stream; |
| 70 int zipquality; /* compression level */ | 73 int zipquality; /* compression level */ |
| 71 int state; /* state flags */ | 74 int state; /* state flags */ |
| 72 #define ZSTATE_INIT_DECODE 0x01 | 75 #define ZSTATE_INIT_DECODE 0x01 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 98 | 101 |
| 99 assert(sp != NULL); | 102 assert(sp != NULL); |
| 100 | 103 |
| 101 /* if we were last encoding, terminate this mode */ | 104 /* if we were last encoding, terminate this mode */ |
| 102 if (sp->state & ZSTATE_INIT_ENCODE) { | 105 if (sp->state & ZSTATE_INIT_ENCODE) { |
| 103 deflateEnd(&sp->stream); | 106 deflateEnd(&sp->stream); |
| 104 sp->state = 0; | 107 sp->state = 0; |
| 105 } | 108 } |
| 106 | 109 |
| 107 if (inflateInit(&sp->stream) != Z_OK) { | 110 if (inflateInit(&sp->stream) != Z_OK) { |
| 108 » » TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); | 111 » » TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); |
| 109 return (0); | 112 return (0); |
| 110 } else { | 113 } else { |
| 111 sp->state |= ZSTATE_INIT_DECODE; | 114 sp->state |= ZSTATE_INIT_DECODE; |
| 112 return (1); | 115 return (1); |
| 113 } | 116 } |
| 114 } | 117 } |
| 115 | 118 |
| 116 /* | 119 /* |
| 117 * Setup state for decoding a strip. | 120 * Setup state for decoding a strip. |
| 118 */ | 121 */ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with
buffers this size"); | 169 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with
buffers this size"); |
| 167 return (0); | 170 return (0); |
| 168 } | 171 } |
| 169 do { | 172 do { |
| 170 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); | 173 int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); |
| 171 if (state == Z_STREAM_END) | 174 if (state == Z_STREAM_END) |
| 172 break; | 175 break; |
| 173 if (state == Z_DATA_ERROR) { | 176 if (state == Z_DATA_ERROR) { |
| 174 TIFFErrorExt(tif->tif_clientdata, module, | 177 TIFFErrorExt(tif->tif_clientdata, module, |
| 175 "Decoding error at scanline %lu, %s", | 178 "Decoding error at scanline %lu, %s", |
| 176 » » » (unsigned long) tif->tif_row, sp->stream.msg); | 179 » » » (unsigned long) tif->tif_row, SAFE_MSG(sp)); |
| 177 if (inflateSync(&sp->stream) != Z_OK) | 180 if (inflateSync(&sp->stream) != Z_OK) |
| 178 return (0); | 181 return (0); |
| 179 continue; | 182 continue; |
| 180 } | 183 } |
| 181 if (state != Z_OK) { | 184 if (state != Z_OK) { |
| 182 » » » TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %
s", | 185 » » » TIFFErrorExt(tif->tif_clientdata, module, |
| 183 » » » sp->stream.msg); | 186 » » » » "ZLib error: %s", SAFE_MSG(sp)); |
| 184 return (0); | 187 return (0); |
| 185 } | 188 } |
| 186 } while (sp->stream.avail_out > 0); | 189 } while (sp->stream.avail_out > 0); |
| 187 if (sp->stream.avail_out != 0) { | 190 if (sp->stream.avail_out != 0) { |
| 188 TIFFErrorExt(tif->tif_clientdata, module, | 191 TIFFErrorExt(tif->tif_clientdata, module, |
| 189 "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT
" bytes)", | 192 "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT
" bytes)", |
| 190 (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.ava
il_out); | 193 (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.ava
il_out); |
| 191 return (0); | 194 return (0); |
| 192 } | 195 } |
| 193 | 196 |
| 194 tif->tif_rawcp = sp->stream.next_in; | 197 tif->tif_rawcp = sp->stream.next_in; |
| 195 tif->tif_rawcc = sp->stream.avail_in; | 198 tif->tif_rawcc = sp->stream.avail_in; |
| 196 | 199 |
| 197 return (1); | 200 return (1); |
| 198 } | 201 } |
| 199 | 202 |
| 200 static int | 203 static int |
| 201 ZIPSetupEncode(TIFF* tif) | 204 ZIPSetupEncode(TIFF* tif) |
| 202 { | 205 { |
| 203 static const char module[] = "ZIPSetupEncode"; | 206 static const char module[] = "ZIPSetupEncode"; |
| 204 ZIPState* sp = EncoderState(tif); | 207 ZIPState* sp = EncoderState(tif); |
| 205 | 208 |
| 206 assert(sp != NULL); | 209 assert(sp != NULL); |
| 207 if (sp->state & ZSTATE_INIT_DECODE) { | 210 if (sp->state & ZSTATE_INIT_DECODE) { |
| 208 inflateEnd(&sp->stream); | 211 inflateEnd(&sp->stream); |
| 209 sp->state = 0; | 212 sp->state = 0; |
| 210 } | 213 } |
| 211 | 214 |
| 212 if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) { | 215 if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) { |
| 213 » » TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); | 216 » » TIFFErrorExt(tif->tif_clientdata, module, "%s", SAFE_MSG(sp)); |
| 214 return (0); | 217 return (0); |
| 215 } else { | 218 } else { |
| 216 sp->state |= ZSTATE_INIT_ENCODE; | 219 sp->state |= ZSTATE_INIT_ENCODE; |
| 217 return (1); | 220 return (1); |
| 218 } | 221 } |
| 219 } | 222 } |
| 220 | 223 |
| 221 /* | 224 /* |
| 222 * Reset encoding state at the start of a strip. | 225 * Reset encoding state at the start of a strip. |
| 223 */ | 226 */ |
| 224 static int | 227 static int |
| 225 ZIPPreEncode(TIFF* tif, uint16 s) | 228 ZIPPreEncode(TIFF* tif, uint16 s) |
| 226 { | 229 { |
| 227 static const char module[] = "ZIPPreEncode"; | 230 static const char module[] = "ZIPPreEncode"; |
| 228 ZIPState *sp = EncoderState(tif); | 231 ZIPState *sp = EncoderState(tif); |
| 229 | 232 |
| 230 (void) s; | 233 (void) s; |
| 231 assert(sp != NULL); | 234 assert(sp != NULL); |
| 232 if( sp->state != ZSTATE_INIT_ENCODE ) | 235 if( sp->state != ZSTATE_INIT_ENCODE ) |
| 233 tif->tif_setupencode( tif ); | 236 tif->tif_setupencode( tif ); |
| 234 | 237 |
| 235 sp->stream.next_out = tif->tif_rawdata; | 238 sp->stream.next_out = tif->tif_rawdata; |
| 236 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, | 239 assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, |
| 237 we need to simplify this code to reflect a ZLib that is likely updat
ed | 240 we need to simplify this code to reflect a ZLib that is likely updat
ed |
| 238 to deal with 8byte memory sizes, though this code will respond | 241 to deal with 8byte memory sizes, though this code will respond |
| 239 apropriately even before we simplify it */ | 242 apropriately even before we simplify it */ |
| 240 » sp->stream.avail_out = (uInt)tif->tif_rawdatasize; | 243 » sp->stream.avail_out = tif->tif_rawdatasize; |
| 241 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) | 244 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) |
| 242 { | 245 { |
| 243 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with
buffers this size"); | 246 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with
buffers this size"); |
| 244 return (0); | 247 return (0); |
| 245 } | 248 } |
| 246 return (deflateReset(&sp->stream) == Z_OK); | 249 return (deflateReset(&sp->stream) == Z_OK); |
| 247 } | 250 } |
| 248 | 251 |
| 249 /* | 252 /* |
| 250 * Encode a chunk of pixels. | 253 * Encode a chunk of pixels. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 265 to deal with 8byte memory sizes, though this code will respond | 268 to deal with 8byte memory sizes, though this code will respond |
| 266 apropriately even before we simplify it */ | 269 apropriately even before we simplify it */ |
| 267 sp->stream.avail_in = (uInt) cc; | 270 sp->stream.avail_in = (uInt) cc; |
| 268 if ((tmsize_t)sp->stream.avail_in != cc) | 271 if ((tmsize_t)sp->stream.avail_in != cc) |
| 269 { | 272 { |
| 270 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with
buffers this size"); | 273 TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with
buffers this size"); |
| 271 return (0); | 274 return (0); |
| 272 } | 275 } |
| 273 do { | 276 do { |
| 274 if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { | 277 if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { |
| 275 » » » TIFFErrorExt(tif->tif_clientdata, module, "Encoder error
: %s", | 278 » » » TIFFErrorExt(tif->tif_clientdata, module, |
| 276 » » » sp->stream.msg); | 279 » » » » "Encoder error: %s", |
| 280 » » » » SAFE_MSG(sp)); |
| 277 return (0); | 281 return (0); |
| 278 } | 282 } |
| 279 if (sp->stream.avail_out == 0) { | 283 if (sp->stream.avail_out == 0) { |
| 280 tif->tif_rawcc = tif->tif_rawdatasize; | 284 tif->tif_rawcc = tif->tif_rawdatasize; |
| 281 TIFFFlushData1(tif); | 285 TIFFFlushData1(tif); |
| 282 sp->stream.next_out = tif->tif_rawdata; | 286 sp->stream.next_out = tif->tif_rawdata; |
| 283 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /*
this is a safe typecast, as check is made already in ZIPPreEncode */ | 287 sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /*
this is a safe typecast, as check is made already in ZIPPreEncode */ |
| 284 } | 288 } |
| 285 } while (sp->stream.avail_in > 0); | 289 } while (sp->stream.avail_in > 0); |
| 286 return (1); | 290 return (1); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 305 case Z_OK: | 309 case Z_OK: |
| 306 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasi
ze) | 310 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasi
ze) |
| 307 { | 311 { |
| 308 tif->tif_rawcc = tif->tif_rawdatasize - sp->str
eam.avail_out; | 312 tif->tif_rawcc = tif->tif_rawdatasize - sp->str
eam.avail_out; |
| 309 TIFFFlushData1(tif); | 313 TIFFFlushData1(tif); |
| 310 sp->stream.next_out = tif->tif_rawdata; | 314 sp->stream.next_out = tif->tif_rawdata; |
| 311 sp->stream.avail_out = (uInt) tif->tif_rawdatasi
ze; /* this is a safe typecast, as check is made already in ZIPPreEncode */ | 315 sp->stream.avail_out = (uInt) tif->tif_rawdatasi
ze; /* this is a safe typecast, as check is made already in ZIPPreEncode */ |
| 312 } | 316 } |
| 313 break; | 317 break; |
| 314 default: | 318 default: |
| 315 » » » TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %
s", | 319 » » » TIFFErrorExt(tif->tif_clientdata, module, |
| 316 » » » sp->stream.msg); | 320 » » » » "ZLib error: %s", SAFE_MSG(sp)); |
| 317 return (0); | 321 return (0); |
| 318 } | 322 } |
| 319 } while (state != Z_STREAM_END); | 323 } while (state != Z_STREAM_END); |
| 320 return (1); | 324 return (1); |
| 321 } | 325 } |
| 322 | 326 |
| 323 static void | 327 static void |
| 324 ZIPCleanup(TIFF* tif) | 328 ZIPCleanup(TIFF* tif) |
| 325 { | 329 { |
| 326 ZIPState* sp = ZState(tif); | 330 ZIPState* sp = ZState(tif); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 351 static const char module[] = "ZIPVSetField"; | 355 static const char module[] = "ZIPVSetField"; |
| 352 ZIPState* sp = ZState(tif); | 356 ZIPState* sp = ZState(tif); |
| 353 | 357 |
| 354 switch (tag) { | 358 switch (tag) { |
| 355 case TIFFTAG_ZIPQUALITY: | 359 case TIFFTAG_ZIPQUALITY: |
| 356 sp->zipquality = (int) va_arg(ap, int); | 360 sp->zipquality = (int) va_arg(ap, int); |
| 357 if ( sp->state&ZSTATE_INIT_ENCODE ) { | 361 if ( sp->state&ZSTATE_INIT_ENCODE ) { |
| 358 if (deflateParams(&sp->stream, | 362 if (deflateParams(&sp->stream, |
| 359 sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) { | 363 sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) { |
| 360 TIFFErrorExt(tif->tif_clientdata, module, "ZLib
error: %s", | 364 TIFFErrorExt(tif->tif_clientdata, module, "ZLib
error: %s", |
| 361 » » » » sp->stream.msg); | 365 » » » » » SAFE_MSG(sp)); |
| 362 return (0); | 366 return (0); |
| 363 } | 367 } |
| 364 } | 368 } |
| 365 return (1); | 369 return (1); |
| 366 default: | 370 default: |
| 367 return (*sp->vsetparent)(tif, tag, ap); | 371 return (*sp->vsetparent)(tif, tag, ap); |
| 368 } | 372 } |
| 369 /*NOTREACHED*/ | 373 /*NOTREACHED*/ |
| 370 } | 374 } |
| 371 | 375 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 #endif /* ZIP_SUPORT */ | 463 #endif /* ZIP_SUPORT */ |
| 460 | 464 |
| 461 /* vim: set ts=8 sts=8 sw=8 noet: */ | 465 /* vim: set ts=8 sts=8 sw=8 noet: */ |
| 462 /* | 466 /* |
| 463 * Local Variables: | 467 * Local Variables: |
| 464 * mode: c | 468 * mode: c |
| 465 * c-basic-offset: 8 | 469 * c-basic-offset: 8 |
| 466 * fill-column: 78 | 470 * fill-column: 78 |
| 467 * End: | 471 * End: |
| 468 */ | 472 */ |
| 469 | |
| OLD | NEW |