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