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