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