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