tif_lzma.c 15 KB

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