Line data Source code
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 :
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 :
36 : #include "lzma.h"
37 : #include "tif_predict.h"
38 :
39 : #include <stdio.h>
40 :
41 : /*
42 : * State block for each open TIFF file using LZMA2 compression/decompression.
43 : */
44 : typedef struct
45 : {
46 : TIFFPredictorState predict;
47 : int read_error; /* whether a read error has occurred, and which should cause
48 : further reads in the same strip/tile to be aborted */
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 GetLZMAState(tif) ((LZMAState *)(tif)->tif_data)
64 : #define LZMADecoderState(tif) GetLZMAState(tif)
65 : #define LZMAEncoderState(tif) GetLZMAState(tif)
66 :
67 : static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
68 : static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
69 :
70 0 : static const char *LZMAStrerror(lzma_ret ret)
71 : {
72 0 : switch (ret)
73 : {
74 0 : case LZMA_OK:
75 0 : return "operation completed successfully";
76 0 : case LZMA_STREAM_END:
77 0 : return "end of stream was reached";
78 0 : case LZMA_NO_CHECK:
79 0 : return "input stream has no integrity check";
80 0 : case LZMA_UNSUPPORTED_CHECK:
81 0 : return "cannot calculate the integrity check";
82 0 : case LZMA_GET_CHECK:
83 0 : return "integrity check type is now available";
84 0 : case LZMA_MEM_ERROR:
85 0 : return "cannot allocate memory";
86 0 : case LZMA_MEMLIMIT_ERROR:
87 0 : return "memory usage limit was reached";
88 0 : case LZMA_FORMAT_ERROR:
89 0 : return "file format not recognized";
90 0 : case LZMA_OPTIONS_ERROR:
91 0 : return "invalid or unsupported options";
92 0 : case LZMA_DATA_ERROR:
93 0 : return "data is corrupt";
94 0 : case LZMA_BUF_ERROR:
95 0 : return "no progress is possible (stream is truncated or corrupt)";
96 0 : case LZMA_PROG_ERROR:
97 0 : return "programming error";
98 : #if LZMA_VERSION >= 50040000 /* 5.4.0 */
99 : case LZMA_SEEK_NEEDED:
100 : case LZMA_RET_INTERNAL1:
101 : case LZMA_RET_INTERNAL2:
102 : case LZMA_RET_INTERNAL3:
103 : case LZMA_RET_INTERNAL4:
104 : case LZMA_RET_INTERNAL5:
105 : case LZMA_RET_INTERNAL6:
106 : case LZMA_RET_INTERNAL7:
107 : case LZMA_RET_INTERNAL8:
108 : #endif
109 0 : default:
110 0 : return "unidentified liblzma error";
111 : }
112 : }
113 :
114 66 : static int LZMAFixupTags(TIFF *tif)
115 : {
116 : (void)tif;
117 66 : return 1;
118 : }
119 :
120 35 : static int LZMASetupDecode(TIFF *tif)
121 : {
122 35 : LZMAState *sp = LZMADecoderState(tif);
123 :
124 35 : assert(sp != NULL);
125 :
126 : /* if we were last encoding, terminate this mode */
127 35 : if (sp->state & LSTATE_INIT_ENCODE)
128 : {
129 2 : lzma_end(&sp->stream);
130 2 : sp->state = 0;
131 : }
132 :
133 35 : sp->state |= LSTATE_INIT_DECODE;
134 35 : return 1;
135 : }
136 :
137 : /*
138 : * Setup state for decoding a strip.
139 : */
140 40 : static int LZMAPreDecode(TIFF *tif, uint16_t s)
141 : {
142 : static const char module[] = "LZMAPreDecode";
143 40 : LZMAState *sp = LZMADecoderState(tif);
144 : lzma_ret ret;
145 :
146 : (void)s;
147 40 : assert(sp != NULL);
148 :
149 40 : if ((sp->state & LSTATE_INIT_DECODE) == 0)
150 2 : tif->tif_setupdecode(tif);
151 :
152 40 : sp->stream.next_in = tif->tif_rawdata;
153 40 : sp->stream.avail_in = (size_t)tif->tif_rawcc;
154 40 : if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
155 : {
156 0 : TIFFErrorExtR(tif, module,
157 : "Liblzma cannot deal with buffers this size");
158 0 : return 0;
159 : }
160 :
161 : /*
162 : * Disable memory limit when decoding. UINT64_MAX is a flag to disable
163 : * the limit, we are passing (uint64_t)-1 which should be the same.
164 : */
165 40 : ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0);
166 40 : if (ret != LZMA_OK)
167 : {
168 0 : TIFFErrorExtR(tif, module, "Error initializing the stream decoder, %s",
169 : LZMAStrerror(ret));
170 0 : return 0;
171 : }
172 :
173 40 : sp->read_error = 0;
174 :
175 40 : return 1;
176 : }
177 :
178 40 : static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
179 : {
180 : static const char module[] = "LZMADecode";
181 40 : LZMAState *sp = LZMADecoderState(tif);
182 :
183 : (void)s;
184 40 : assert(sp != NULL);
185 40 : assert(sp->state == LSTATE_INIT_DECODE);
186 :
187 40 : if (sp->read_error)
188 : {
189 0 : memset(op, 0, (size_t)occ);
190 0 : TIFFErrorExtR(tif, module,
191 : "LZMADecode: Scanline %" PRIu32 " cannot be read due to "
192 : "previous error",
193 : tif->tif_row);
194 0 : return 0;
195 : }
196 :
197 40 : sp->stream.next_in = tif->tif_rawcp;
198 40 : sp->stream.avail_in = (size_t)tif->tif_rawcc;
199 :
200 40 : sp->stream.next_out = op;
201 40 : sp->stream.avail_out = (size_t)occ;
202 40 : if ((tmsize_t)sp->stream.avail_out != occ)
203 : {
204 : // read_error not set here as this is a usage issue that can be
205 : // recovered in a following call.
206 0 : memset(op, 0, (size_t)occ);
207 0 : TIFFErrorExtR(tif, module,
208 : "Liblzma cannot deal with buffers this size");
209 0 : return 0;
210 : }
211 :
212 : do
213 : {
214 : /*
215 : * Save the current stream state to properly recover from the
216 : * decoding errors later.
217 : */
218 40 : const uint8_t *next_in = sp->stream.next_in;
219 40 : size_t avail_in = sp->stream.avail_in;
220 :
221 40 : lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
222 40 : if (ret == LZMA_STREAM_END)
223 40 : break;
224 0 : if (ret == LZMA_MEMLIMIT_ERROR)
225 : {
226 : lzma_ret r =
227 0 : lzma_stream_decoder(&sp->stream, lzma_memusage(&sp->stream), 0);
228 0 : if (r != LZMA_OK)
229 : {
230 0 : sp->read_error = 1;
231 0 : memset(op, 0, (size_t)occ);
232 0 : TIFFErrorExtR(tif, module,
233 : "Error initializing the stream decoder, %s",
234 : LZMAStrerror(r));
235 0 : break;
236 : }
237 0 : sp->stream.next_in = next_in;
238 0 : sp->stream.avail_in = avail_in;
239 0 : continue;
240 : }
241 0 : if (ret != LZMA_OK)
242 : {
243 0 : TIFFErrorExtR(tif, module,
244 : "Decoding error at scanline %" PRIu32 ", %s",
245 : tif->tif_row, LZMAStrerror(ret));
246 0 : break;
247 : }
248 0 : } while (sp->stream.avail_out > 0);
249 40 : if (sp->stream.avail_out != 0)
250 : {
251 0 : sp->read_error = 1;
252 0 : memset(sp->stream.next_out, 0, sp->stream.avail_out);
253 0 : TIFFErrorExtR(tif, module,
254 : "Not enough data at scanline %" PRIu32
255 : " (short %" TIFF_SIZE_FORMAT " bytes)",
256 : tif->tif_row, sp->stream.avail_out);
257 0 : return 0;
258 : }
259 :
260 40 : tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */
261 40 : tif->tif_rawcc = sp->stream.avail_in;
262 :
263 40 : return 1;
264 : }
265 :
266 17 : static int LZMASetupEncode(TIFF *tif)
267 : {
268 17 : LZMAState *sp = LZMAEncoderState(tif);
269 :
270 17 : assert(sp != NULL);
271 17 : if (sp->state & LSTATE_INIT_DECODE)
272 : {
273 0 : lzma_end(&sp->stream);
274 0 : sp->state = 0;
275 : }
276 :
277 17 : sp->state |= LSTATE_INIT_ENCODE;
278 17 : return 1;
279 : }
280 :
281 : /*
282 : * Reset encoding state at the start of a strip.
283 : */
284 17 : static int LZMAPreEncode(TIFF *tif, uint16_t s)
285 : {
286 : static const char module[] = "LZMAPreEncode";
287 17 : LZMAState *sp = LZMAEncoderState(tif);
288 : lzma_ret ret;
289 :
290 : (void)s;
291 17 : assert(sp != NULL);
292 17 : if (sp->state != LSTATE_INIT_ENCODE)
293 0 : tif->tif_setupencode(tif);
294 :
295 17 : sp->stream.next_out = tif->tif_rawdata;
296 17 : sp->stream.avail_out = (size_t)tif->tif_rawdatasize;
297 17 : if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
298 : {
299 0 : TIFFErrorExtR(tif, module,
300 : "Liblzma cannot deal with buffers this size");
301 0 : return 0;
302 : }
303 17 : ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check);
304 17 : if (ret != LZMA_OK)
305 : {
306 0 : TIFFErrorExtR(tif, module, "Error in lzma_stream_encoder(): %s",
307 : LZMAStrerror(ret));
308 0 : return 0;
309 : }
310 17 : return 1;
311 : }
312 :
313 : /*
314 : * Encode a chunk of pixels.
315 : */
316 17 : static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
317 : {
318 : static const char module[] = "LZMAEncode";
319 17 : LZMAState *sp = LZMAEncoderState(tif);
320 :
321 17 : assert(sp != NULL);
322 17 : assert(sp->state == LSTATE_INIT_ENCODE);
323 :
324 : (void)s;
325 17 : sp->stream.next_in = bp;
326 17 : sp->stream.avail_in = (size_t)cc;
327 17 : if ((tmsize_t)sp->stream.avail_in != cc)
328 : {
329 0 : TIFFErrorExtR(tif, module,
330 : "Liblzma cannot deal with buffers this size");
331 0 : return 0;
332 : }
333 : do
334 : {
335 17 : lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
336 17 : if (ret != LZMA_OK)
337 : {
338 0 : TIFFErrorExtR(tif, module,
339 : "Encoding error at scanline %" PRIu32 ", %s",
340 : tif->tif_row, LZMAStrerror(ret));
341 0 : return 0;
342 : }
343 17 : if (sp->stream.avail_out == 0)
344 : {
345 0 : tif->tif_rawcc = tif->tif_rawdatasize;
346 0 : if (!TIFFFlushData1(tif))
347 0 : return 0;
348 0 : sp->stream.next_out = tif->tif_rawdata;
349 0 : sp->stream.avail_out =
350 0 : (size_t)
351 0 : tif->tif_rawdatasize; /* this is a safe typecast, as check
352 : is made already in LZMAPreEncode */
353 : }
354 17 : } while (sp->stream.avail_in > 0);
355 17 : return 1;
356 : }
357 :
358 : /*
359 : * Finish off an encoded strip by flushing the last
360 : * string and tacking on an End Of Information code.
361 : */
362 17 : static int LZMAPostEncode(TIFF *tif)
363 : {
364 : static const char module[] = "LZMAPostEncode";
365 17 : LZMAState *sp = LZMAEncoderState(tif);
366 : lzma_ret ret;
367 :
368 17 : sp->stream.avail_in = 0;
369 : do
370 : {
371 17 : ret = lzma_code(&sp->stream, LZMA_FINISH);
372 17 : switch (ret)
373 : {
374 17 : case LZMA_STREAM_END:
375 : case LZMA_OK:
376 17 : if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
377 : {
378 17 : tif->tif_rawcc =
379 17 : tif->tif_rawdatasize - sp->stream.avail_out;
380 17 : if (!TIFFFlushData1(tif))
381 0 : return 0;
382 17 : sp->stream.next_out = tif->tif_rawdata;
383 17 : sp->stream.avail_out =
384 17 : (size_t)
385 17 : tif->tif_rawdatasize; /* this is a safe typecast, as
386 : check is made already in
387 : ZIPPreEncode */
388 : }
389 17 : break;
390 0 : case LZMA_NO_CHECK:
391 : case LZMA_UNSUPPORTED_CHECK:
392 : case LZMA_GET_CHECK:
393 : case LZMA_MEM_ERROR:
394 : case LZMA_MEMLIMIT_ERROR:
395 : case LZMA_FORMAT_ERROR:
396 : case LZMA_OPTIONS_ERROR:
397 : case LZMA_DATA_ERROR:
398 : case LZMA_BUF_ERROR:
399 : case LZMA_PROG_ERROR:
400 : #if LZMA_VERSION >= 50040000 /* 5.4.0 */
401 : case LZMA_SEEK_NEEDED:
402 : case LZMA_RET_INTERNAL1:
403 : case LZMA_RET_INTERNAL2:
404 : case LZMA_RET_INTERNAL3:
405 : case LZMA_RET_INTERNAL4:
406 : case LZMA_RET_INTERNAL5:
407 : case LZMA_RET_INTERNAL6:
408 : case LZMA_RET_INTERNAL7:
409 : case LZMA_RET_INTERNAL8:
410 : #endif
411 : default:
412 0 : TIFFErrorExtR(tif, module, "Liblzma error: %s",
413 : LZMAStrerror(ret));
414 0 : return 0;
415 : }
416 17 : } while (ret != LZMA_STREAM_END);
417 17 : return 1;
418 : }
419 :
420 119 : static void LZMACleanup(TIFF *tif)
421 : {
422 119 : LZMAState *sp = GetLZMAState(tif);
423 :
424 119 : assert(sp != 0);
425 :
426 119 : (void)TIFFPredictorCleanup(tif);
427 :
428 119 : tif->tif_tagmethods.vgetfield = sp->vgetparent;
429 119 : tif->tif_tagmethods.vsetfield = sp->vsetparent;
430 :
431 119 : if (sp->state)
432 : {
433 50 : lzma_end(&sp->stream);
434 50 : sp->state = 0;
435 : }
436 119 : _TIFFfreeExt(tif, sp);
437 119 : tif->tif_data = NULL;
438 :
439 119 : _TIFFSetDefaultCompressionState(tif);
440 119 : }
441 :
442 871 : static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap)
443 : {
444 : static const char module[] = "LZMAVSetField";
445 871 : LZMAState *sp = GetLZMAState(tif);
446 :
447 871 : switch (tag)
448 : {
449 24 : case TIFFTAG_LZMAPRESET:
450 24 : sp->preset = (int)va_arg(ap, int);
451 24 : lzma_lzma_preset(&sp->opt_lzma, sp->preset);
452 24 : if (sp->state & LSTATE_INIT_ENCODE)
453 : {
454 : lzma_ret ret =
455 0 : lzma_stream_encoder(&sp->stream, sp->filters, sp->check);
456 0 : if (ret != LZMA_OK)
457 : {
458 0 : TIFFErrorExtR(tif, module, "Liblzma error: %s",
459 : LZMAStrerror(ret));
460 : }
461 : }
462 24 : return 1;
463 847 : default:
464 847 : return (*sp->vsetparent)(tif, tag, ap);
465 : }
466 : /*NOTREACHED*/
467 : }
468 :
469 911 : static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap)
470 : {
471 911 : LZMAState *sp = GetLZMAState(tif);
472 :
473 911 : switch (tag)
474 : {
475 0 : case TIFFTAG_LZMAPRESET:
476 0 : *va_arg(ap, int *) = sp->preset;
477 0 : break;
478 911 : default:
479 911 : return (*sp->vgetparent)(tif, tag, ap);
480 : }
481 0 : return 1;
482 : }
483 :
484 : static const TIFFField lzmaFields[] = {
485 : {TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
486 : FALSE, "LZMA2 Compression Preset", NULL},
487 : };
488 :
489 119 : int TIFFInitLZMA(TIFF *tif, int scheme)
490 : {
491 : static const char module[] = "TIFFInitLZMA";
492 : LZMAState *sp;
493 119 : lzma_stream tmp_stream = LZMA_STREAM_INIT;
494 :
495 : (void)scheme;
496 119 : assert(scheme == COMPRESSION_LZMA);
497 :
498 : /*
499 : * Merge codec-specific tag information.
500 : */
501 119 : if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields)))
502 : {
503 0 : TIFFErrorExtR(tif, module, "Merging LZMA2 codec-specific tags failed");
504 0 : return 0;
505 : }
506 :
507 : /*
508 : * Allocate state block so tag methods have storage to record values.
509 : */
510 119 : tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZMAState));
511 119 : if (tif->tif_data == NULL)
512 0 : goto bad;
513 119 : sp = GetLZMAState(tif);
514 119 : memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream));
515 :
516 : /*
517 : * Override parent get/set field methods.
518 : */
519 119 : sp->vgetparent = tif->tif_tagmethods.vgetfield;
520 119 : tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */
521 119 : sp->vsetparent = tif->tif_tagmethods.vsetfield;
522 119 : tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */
523 :
524 : /* Default values for codec-specific fields */
525 119 : sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */
526 119 : sp->check = LZMA_CHECK_NONE;
527 119 : sp->state = 0;
528 :
529 : /* Data filters. So far we are using delta and LZMA2 filters only. */
530 119 : sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE;
531 : /*
532 : * The sample size in bytes seems to be reasonable distance for delta
533 : * filter.
534 : */
535 238 : sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8)
536 119 : ? 1
537 119 : : tif->tif_dir.td_bitspersample / 8;
538 119 : sp->filters[0].id = LZMA_FILTER_DELTA;
539 119 : sp->filters[0].options = &sp->opt_delta;
540 :
541 119 : lzma_lzma_preset(&sp->opt_lzma, sp->preset);
542 119 : sp->filters[1].id = LZMA_FILTER_LZMA2;
543 119 : sp->filters[1].options = &sp->opt_lzma;
544 :
545 119 : sp->filters[2].id = LZMA_VLI_UNKNOWN;
546 119 : sp->filters[2].options = NULL;
547 :
548 : /*
549 : * Install codec methods.
550 : */
551 119 : tif->tif_fixuptags = LZMAFixupTags;
552 119 : tif->tif_setupdecode = LZMASetupDecode;
553 119 : tif->tif_predecode = LZMAPreDecode;
554 119 : tif->tif_decoderow = LZMADecode;
555 119 : tif->tif_decodestrip = LZMADecode;
556 119 : tif->tif_decodetile = LZMADecode;
557 119 : tif->tif_setupencode = LZMASetupEncode;
558 119 : tif->tif_preencode = LZMAPreEncode;
559 119 : tif->tif_postencode = LZMAPostEncode;
560 119 : tif->tif_encoderow = LZMAEncode;
561 119 : tif->tif_encodestrip = LZMAEncode;
562 119 : tif->tif_encodetile = LZMAEncode;
563 119 : tif->tif_cleanup = LZMACleanup;
564 : /*
565 : * Setup predictor setup.
566 : */
567 119 : (void)TIFFPredictorInit(tif);
568 119 : return 1;
569 0 : bad:
570 0 : TIFFErrorExtR(tif, module, "No space for LZMA2 state block");
571 0 : return 0;
572 : }
573 : #endif /* LZMA_SUPPORT */
|