tif_lzma.c 13 KB

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