2
0

tif_lzma.c 13 KB

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