tif_lzma.c 16 KB

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