1 /* $Id: tif_lzma.c,v 1.4 2011-12-22 00:29:29 bfriesen Exp $ */ 2 3 /* 4 * Copyright (c) 2010, Andrey Kiselev <dron (at) ak4719.spb.edu> 5 * 6 * Permission to use, copy, modify, distribute, and sell this software and 7 * its documentation for any purpose is hereby granted without fee, provided 8 * that (i) the above copyright notices and this permission notice appear in 9 * all copies of the software and related documentation, and (ii) the names of 10 * Sam Leffler and Silicon Graphics may not be used in any advertising or 11 * publicity relating to the software without the specific, prior written 12 * permission of Sam Leffler and Silicon Graphics. 13 * 14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 17 * 18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 23 * OF THIS SOFTWARE. 24 */ 25 26 #include "tiffiop.h" 27 #ifdef LZMA_SUPPORT 28 /* 29 * TIFF Library. 30 * 31 * LZMA2 Compression Support 32 * 33 * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details. 34 * 35 * The codec is derived from ZLIB codec (tif_zip.c). 36 */ 37 38 #include "tif_predict.h" 39 #include "lzma.h" 40 41 #include <stdio.h> 42 43 /* 44 * State block for each open TIFF file using LZMA2 compression/decompression. 45 */ 46 typedef struct { 47 TIFFPredictorState predict; 48 lzma_stream stream; 49 lzma_filter filters[LZMA_FILTERS_MAX + 1]; 50 lzma_options_delta opt_delta; /* delta filter options */ 51 lzma_options_lzma opt_lzma; /* LZMA2 filter options */ 52 int preset; /* compression level */ 53 lzma_check check; /* type of the integrity check */ 54 int state; /* state flags */ 55 #define LSTATE_INIT_DECODE 0x01 56 #define LSTATE_INIT_ENCODE 0x02 57 58 TIFFVGetMethod vgetparent; /* super-class method */ 59 TIFFVSetMethod vsetparent; /* super-class method */ 60 } LZMAState; 61 62 #define LState(tif) ((LZMAState*) (tif)->tif_data) 63 #define DecoderState(tif) LState(tif) 64 #define EncoderState(tif) LState(tif) 65 66 static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); 67 static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s); 68 69 static const char * 70 LZMAStrerror(lzma_ret ret) 71 { 72 switch (ret) { 73 case LZMA_OK: 74 return "operation completed successfully"; 75 case LZMA_STREAM_END: 76 return "end of stream was reached"; 77 case LZMA_NO_CHECK: 78 return "input stream has no integrity check"; 79 case LZMA_UNSUPPORTED_CHECK: 80 return "cannot calculate the integrity check"; 81 case LZMA_GET_CHECK: 82 return "integrity check type is now available"; 83 case LZMA_MEM_ERROR: 84 return "cannot allocate memory"; 85 case LZMA_MEMLIMIT_ERROR: 86 return "memory usage limit was reached"; 87 case LZMA_FORMAT_ERROR: 88 return "file format not recognized"; 89 case LZMA_OPTIONS_ERROR: 90 return "invalid or unsupported options"; 91 case LZMA_DATA_ERROR: 92 return "data is corrupt"; 93 case LZMA_BUF_ERROR: 94 return "no progress is possible (stream is truncated or corrupt)"; 95 case LZMA_PROG_ERROR: 96 return "programming error"; 97 default: 98 return "unindentified liblzma error"; 99 } 100 } 101 102 static int 103 LZMAFixupTags(TIFF* tif) 104 { 105 (void) tif; 106 return 1; 107 } 108 109 static int 110 LZMASetupDecode(TIFF* tif) 111 { 112 LZMAState* sp = DecoderState(tif); 113 114 assert(sp != NULL); 115 116 /* if we were last encoding, terminate this mode */ 117 if (sp->state & LSTATE_INIT_ENCODE) { 118 lzma_end(&sp->stream); 119 sp->state = 0; 120 } 121 122 sp->state |= LSTATE_INIT_DECODE; 123 return 1; 124 } 125 126 /* 127 * Setup state for decoding a strip. 128 */ 129 static int 130 LZMAPreDecode(TIFF* tif, uint16 s) 131 { 132 static const char module[] = "LZMAPreDecode"; 133 LZMAState* sp = DecoderState(tif); 134 lzma_ret ret; 135 136 (void) s; 137 assert(sp != NULL); 138 139 if( (sp->state & LSTATE_INIT_DECODE) == 0 ) 140 tif->tif_setupdecode(tif); 141 142 sp->stream.next_in = tif->tif_rawdata; 143 sp->stream.avail_in = (size_t) tif->tif_rawcc; 144 if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) { 145 TIFFErrorExt(tif->tif_clientdata, module, 146 "Liblzma cannot deal with buffers this size"); 147 return 0; 148 } 149 150 /* 151 * Disable memory limit when decoding. UINT64_MAX is a flag to disable 152 * the limit, we are passing (uint64_t)-1 which should be the same. 153 */ 154 ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); 155 if (ret != LZMA_OK) { 156 TIFFErrorExt(tif->tif_clientdata, module, 157 "Error initializing the stream decoder, %s", 158 LZMAStrerror(ret)); 159 return 0; 160 } 161 return 1; 162 } 163 164 static int 165 LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s) 166 { 167 static const char module[] = "LZMADecode"; 168 LZMAState* sp = DecoderState(tif); 169 170 (void) s; 171 assert(sp != NULL); 172 assert(sp->state == LSTATE_INIT_DECODE); 173 174 sp->stream.next_in = tif->tif_rawcp; 175 sp->stream.avail_in = (size_t) tif->tif_rawcc; 176 177 sp->stream.next_out = op; 178 sp->stream.avail_out = (size_t) occ; 179 if ((tmsize_t)sp->stream.avail_out != occ) { 180 TIFFErrorExt(tif->tif_clientdata, module, 181 "Liblzma cannot deal with buffers this size"); 182 return 0; 183 } 184 185 do { 186 /* 187 * Save the current stream state to properly recover from the 188 * decoding errors later. 189 */ 190 const uint8_t *next_in = sp->stream.next_in; 191 size_t avail_in = sp->stream.avail_in; 192 193 lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); 194 if (ret == LZMA_STREAM_END) 195 break; 196 if (ret == LZMA_MEMLIMIT_ERROR) { 197 lzma_ret r = lzma_stream_decoder(&sp->stream, 198 lzma_memusage(&sp->stream), 0); 199 if (r != LZMA_OK) { 200 TIFFErrorExt(tif->tif_clientdata, module, 201 "Error initializing the stream decoder, %s", 202 LZMAStrerror(r)); 203 break; 204 } 205 sp->stream.next_in = next_in; 206 sp->stream.avail_in = avail_in; 207 continue; 208 } 209 if (ret != LZMA_OK) { 210 TIFFErrorExt(tif->tif_clientdata, module, 211 "Decoding error at scanline %lu, %s", 212 (unsigned long) tif->tif_row, LZMAStrerror(ret)); 213 break; 214 } 215 } while (sp->stream.avail_out > 0); 216 if (sp->stream.avail_out != 0) { 217 TIFFErrorExt(tif->tif_clientdata, module, 218 "Not enough data at scanline %lu (short %lu bytes)", 219 (unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out); 220 return 0; 221 } 222 223 tif->tif_rawcp = (uint8 *)sp->stream.next_in; /* cast away const */ 224 tif->tif_rawcc = sp->stream.avail_in; 225 226 return 1; 227 } 228 229 static int 230 LZMASetupEncode(TIFF* tif) 231 { 232 LZMAState* sp = EncoderState(tif); 233 234 assert(sp != NULL); 235 if (sp->state & LSTATE_INIT_DECODE) { 236 lzma_end(&sp->stream); 237 sp->state = 0; 238 } 239 240 sp->state |= LSTATE_INIT_ENCODE; 241 return 1; 242 } 243 244 /* 245 * Reset encoding state at the start of a strip. 246 */ 247 static int 248 LZMAPreEncode(TIFF* tif, uint16 s) 249 { 250 static const char module[] = "LZMAPreEncode"; 251 LZMAState *sp = EncoderState(tif); 252 253 (void) s; 254 assert(sp != NULL); 255 if( sp->state != LSTATE_INIT_ENCODE ) 256 tif->tif_setupencode(tif); 257 258 sp->stream.next_out = tif->tif_rawdata; 259 sp->stream.avail_out = (size_t)tif->tif_rawdatasize; 260 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { 261 TIFFErrorExt(tif->tif_clientdata, module, 262 "Liblzma cannot deal with buffers this size"); 263 return 0; 264 } 265 return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK); 266 } 267 268 /* 269 * Encode a chunk of pixels. 270 */ 271 static int 272 LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) 273 { 274 static const char module[] = "LZMAEncode"; 275 LZMAState *sp = EncoderState(tif); 276 277 assert(sp != NULL); 278 assert(sp->state == LSTATE_INIT_ENCODE); 279 280 (void) s; 281 sp->stream.next_in = bp; 282 sp->stream.avail_in = (size_t) cc; 283 if ((tmsize_t)sp->stream.avail_in != cc) { 284 TIFFErrorExt(tif->tif_clientdata, module, 285 "Liblzma cannot deal with buffers this size"); 286 return 0; 287 } 288 do { 289 lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); 290 if (ret != LZMA_OK) { 291 TIFFErrorExt(tif->tif_clientdata, module, 292 "Encoding error at scanline %lu, %s", 293 (unsigned long) tif->tif_row, LZMAStrerror(ret)); 294 return 0; 295 } 296 if (sp->stream.avail_out == 0) { 297 tif->tif_rawcc = tif->tif_rawdatasize; 298 TIFFFlushData1(tif); 299 sp->stream.next_out = tif->tif_rawdata; 300 sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */ 301 } 302 } while (sp->stream.avail_in > 0); 303 return 1; 304 } 305 306 /* 307 * Finish off an encoded strip by flushing the last 308 * string and tacking on an End Of Information code. 309 */ 310 static int 311 LZMAPostEncode(TIFF* tif) 312 { 313 static const char module[] = "LZMAPostEncode"; 314 LZMAState *sp = EncoderState(tif); 315 lzma_ret ret; 316 317 sp->stream.avail_in = 0; 318 do { 319 ret = lzma_code(&sp->stream, LZMA_FINISH); 320 switch (ret) { 321 case LZMA_STREAM_END: 322 case LZMA_OK: 323 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { 324 tif->tif_rawcc = 325 tif->tif_rawdatasize - sp->stream.avail_out; 326 TIFFFlushData1(tif); 327 sp->stream.next_out = tif->tif_rawdata; 328 sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ 329 } 330 break; 331 default: 332 TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s", 333 LZMAStrerror(ret)); 334 return 0; 335 } 336 } while (ret != LZMA_STREAM_END); 337 return 1; 338 } 339 340 static void 341 LZMACleanup(TIFF* tif) 342 { 343 LZMAState* sp = LState(tif); 344 345 assert(sp != 0); 346 347 (void)TIFFPredictorCleanup(tif); 348 349 tif->tif_tagmethods.vgetfield = sp->vgetparent; 350 tif->tif_tagmethods.vsetfield = sp->vsetparent; 351 352 if (sp->state) { 353 lzma_end(&sp->stream); 354 sp->state = 0; 355 } 356 _TIFFfree(sp); 357 tif->tif_data = NULL; 358 359 _TIFFSetDefaultCompressionState(tif); 360 } 361 362 static int 363 LZMAVSetField(TIFF* tif, uint32 tag, va_list ap) 364 { 365 static const char module[] = "LZMAVSetField"; 366 LZMAState* sp = LState(tif); 367 368 switch (tag) { 369 case TIFFTAG_LZMAPRESET: 370 sp->preset = (int) va_arg(ap, int); 371 lzma_lzma_preset(&sp->opt_lzma, sp->preset); 372 if (sp->state & LSTATE_INIT_ENCODE) { 373 lzma_ret ret = lzma_stream_encoder(&sp->stream, 374 sp->filters, 375 sp->check); 376 if (ret != LZMA_OK) { 377 TIFFErrorExt(tif->tif_clientdata, module, 378 "Liblzma error: %s", 379 LZMAStrerror(ret)); 380 } 381 } 382 return 1; 383 default: 384 return (*sp->vsetparent)(tif, tag, ap); 385 } 386 /*NOTREACHED*/ 387 } 388 389 static int 390 LZMAVGetField(TIFF* tif, uint32 tag, va_list ap) 391 { 392 LZMAState* sp = LState(tif); 393 394 switch (tag) { 395 case TIFFTAG_LZMAPRESET: 396 *va_arg(ap, int*) = sp->preset; 397 break; 398 default: 399 return (*sp->vgetparent)(tif, tag, ap); 400 } 401 return 1; 402 } 403 404 static const TIFFField lzmaFields[] = { 405 { TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, 406 FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL }, 407 }; 408 409 int 410 TIFFInitLZMA(TIFF* tif, int scheme) 411 { 412 static const char module[] = "TIFFInitLZMA"; 413 LZMAState* sp; 414 lzma_stream tmp_stream = LZMA_STREAM_INIT; 415 416 assert( scheme == COMPRESSION_LZMA ); 417 418 /* 419 * Merge codec-specific tag information. 420 */ 421 if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) { 422 TIFFErrorExt(tif->tif_clientdata, module, 423 "Merging LZMA2 codec-specific tags failed"); 424 return 0; 425 } 426 427 /* 428 * Allocate state block so tag methods have storage to record values. 429 */ 430 tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState)); 431 if (tif->tif_data == NULL) 432 goto bad; 433 sp = LState(tif); 434 memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); 435 436 /* 437 * Override parent get/set field methods. 438 */ 439 sp->vgetparent = tif->tif_tagmethods.vgetfield; 440 tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ 441 sp->vsetparent = tif->tif_tagmethods.vsetfield; 442 tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ 443 444 /* Default values for codec-specific fields */ 445 sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ 446 sp->check = LZMA_CHECK_NONE; 447 sp->state = 0; 448 449 /* Data filters. So far we are using delta and LZMA2 filters only. */ 450 sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; 451 /* 452 * The sample size in bytes seems to be reasonable distance for delta 453 * filter. 454 */ 455 sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ? 456 1 : tif->tif_dir.td_bitspersample / 8; 457 sp->filters[0].id = LZMA_FILTER_DELTA; 458 sp->filters[0].options = &sp->opt_delta; 459 460 lzma_lzma_preset(&sp->opt_lzma, sp->preset); 461 sp->filters[1].id = LZMA_FILTER_LZMA2; 462 sp->filters[1].options = &sp->opt_lzma; 463 464 sp->filters[2].id = LZMA_VLI_UNKNOWN; 465 sp->filters[2].options = NULL; 466 467 /* 468 * Install codec methods. 469 */ 470 tif->tif_fixuptags = LZMAFixupTags; 471 tif->tif_setupdecode = LZMASetupDecode; 472 tif->tif_predecode = LZMAPreDecode; 473 tif->tif_decoderow = LZMADecode; 474 tif->tif_decodestrip = LZMADecode; 475 tif->tif_decodetile = LZMADecode; 476 tif->tif_setupencode = LZMASetupEncode; 477 tif->tif_preencode = LZMAPreEncode; 478 tif->tif_postencode = LZMAPostEncode; 479 tif->tif_encoderow = LZMAEncode; 480 tif->tif_encodestrip = LZMAEncode; 481 tif->tif_encodetile = LZMAEncode; 482 tif->tif_cleanup = LZMACleanup; 483 /* 484 * Setup predictor setup. 485 */ 486 (void) TIFFPredictorInit(tif); 487 return 1; 488 bad: 489 TIFFErrorExt(tif->tif_clientdata, module, 490 "No space for LZMA2 state block"); 491 return 0; 492 } 493 #endif /* LZMA_SUPORT */ 494 495 /* vim: set ts=8 sts=8 sw=8 noet: */ 496