1
/* $Id: tif_lzma.c,v 1.3 2011-02-22 21:55:13 fwarmerdam Exp $ */
4
* Copyright (c) 2010, Andrey Kiselev <dron@ak4719.spb.edu>
6
* Permission to use, copy, modify, distribute, and sell this software and
7
* its documentation for any purpose is hereby granted without fee, provided
8
* that (i) the above copyright notices and this permission notice appear in
9
* all copies of the software and related documentation, and (ii) the names of
10
* Sam Leffler and Silicon Graphics may not be used in any advertising or
11
* publicity relating to the software without the specific, prior written
12
* permission of Sam Leffler and Silicon Graphics.
14
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
31
* LZMA2 Compression Support
33
* You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details.
35
* The codec is derived from ZLIB codec (tif_zip.c).
38
#include "tif_predict.h"
44
* State block for each open TIFF file using LZMA2 compression/decompression.
47
TIFFPredictorState predict;
49
lzma_filter filters[LZMA_FILTERS_MAX + 1];
50
lzma_options_delta opt_delta; /* delta filter options */
51
lzma_options_lzma opt_lzma; /* LZMA2 filter options */
52
int preset; /* compression level */
53
lzma_check check; /* type of the integrity check */
54
int state; /* state flags */
55
#define LSTATE_INIT_DECODE 0x01
56
#define LSTATE_INIT_ENCODE 0x02
58
TIFFVGetMethod vgetparent; /* super-class method */
59
TIFFVSetMethod vsetparent; /* super-class method */
62
#define LState(tif) ((LZMAState*) (tif)->tif_data)
63
#define DecoderState(tif) LState(tif)
64
#define EncoderState(tif) LState(tif)
66
static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
67
static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
70
LZMAStrerror(lzma_ret ret)
74
return "operation completed successfully";
76
return "end of stream was reached";
78
return "input stream has no integrity check";
79
case LZMA_UNSUPPORTED_CHECK:
80
return "cannot calculate the integrity check";
82
return "integrity check type is now available";
84
return "cannot allocate memory";
85
case LZMA_MEMLIMIT_ERROR:
86
return "memory usage limit was reached";
87
case LZMA_FORMAT_ERROR:
88
return "file format not recognized";
89
case LZMA_OPTIONS_ERROR:
90
return "invalid or unsupported options";
92
return "data is corrupt";
94
return "no progress is possible (stream is truncated or corrupt)";
96
return "programming error";
98
return "unindentified liblzma error";
103
LZMAFixupTags(TIFF* tif)
110
LZMASetupDecode(TIFF* tif)
112
LZMAState* sp = DecoderState(tif);
116
/* if we were last encoding, terminate this mode */
117
if (sp->state & LSTATE_INIT_ENCODE) {
118
lzma_end(&sp->stream);
122
sp->state |= LSTATE_INIT_DECODE;
127
* Setup state for decoding a strip.
130
LZMAPreDecode(TIFF* tif, uint16 s)
132
static const char module[] = "LZMAPreDecode";
133
LZMAState* sp = DecoderState(tif);
139
if( (sp->state & LSTATE_INIT_DECODE) == 0 )
140
tif->tif_setupdecode(tif);
142
sp->stream.next_in = tif->tif_rawdata;
143
sp->stream.avail_in = (size_t) tif->tif_rawcc;
144
if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) {
145
TIFFErrorExt(tif->tif_clientdata, module,
146
"Liblzma cannot deal with buffers this size");
151
* Disable memory limit when decoding. UINT64_MAX is a flag to disable
152
* the limit, we are passing (uint64_t)-1 which should be the same.
154
ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0);
155
if (ret != LZMA_OK) {
156
TIFFErrorExt(tif->tif_clientdata, module,
157
"Error initializing the stream decoder, %s",
165
LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
167
static const char module[] = "LZMADecode";
168
LZMAState* sp = DecoderState(tif);
172
assert(sp->state == LSTATE_INIT_DECODE);
174
sp->stream.next_in = tif->tif_rawcp;
175
sp->stream.avail_in = (size_t) tif->tif_rawcc;
177
sp->stream.next_out = op;
178
sp->stream.avail_out = (size_t) occ;
179
if ((tmsize_t)sp->stream.avail_out != occ) {
180
TIFFErrorExt(tif->tif_clientdata, module,
181
"Liblzma cannot deal with buffers this size");
187
* Save the current stream state to properly recover from the
188
* decoding errors later.
190
const uint8_t *next_in = sp->stream.next_in;
191
size_t avail_in = sp->stream.avail_in;
193
lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
194
if (ret == LZMA_STREAM_END)
196
if (ret == LZMA_MEMLIMIT_ERROR) {
197
lzma_ret r = lzma_stream_decoder(&sp->stream,
198
lzma_memusage(&sp->stream), 0);
200
TIFFErrorExt(tif->tif_clientdata, module,
201
"Error initializing the stream decoder, %s",
205
sp->stream.next_in = next_in;
206
sp->stream.avail_in = avail_in;
209
if (ret != LZMA_OK) {
210
TIFFErrorExt(tif->tif_clientdata, module,
211
"Decoding error at scanline %lu, %s",
212
(unsigned long) tif->tif_row, LZMAStrerror(ret));
215
} while (sp->stream.avail_out > 0);
216
if (sp->stream.avail_out != 0) {
217
TIFFErrorExt(tif->tif_clientdata, module,
218
"Not enough data at scanline %lu (short %lu bytes)",
219
(unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out);
223
tif->tif_rawcp = sp->stream.next_in;
224
tif->tif_rawcc = sp->stream.avail_in;
230
LZMASetupEncode(TIFF* tif)
232
LZMAState* sp = EncoderState(tif);
235
if (sp->state & LSTATE_INIT_DECODE) {
236
lzma_end(&sp->stream);
240
sp->state |= LSTATE_INIT_ENCODE;
245
* Reset encoding state at the start of a strip.
248
LZMAPreEncode(TIFF* tif, uint16 s)
250
static const char module[] = "LZMAPreEncode";
251
LZMAState *sp = EncoderState(tif);
255
if( sp->state != LSTATE_INIT_ENCODE )
256
tif->tif_setupencode(tif);
258
sp->stream.next_out = tif->tif_rawdata;
259
sp->stream.avail_out = (size_t)tif->tif_rawdatasize;
260
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
261
TIFFErrorExt(tif->tif_clientdata, module,
262
"Liblzma cannot deal with buffers this size");
265
return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK);
269
* Encode a chunk of pixels.
272
LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
274
static const char module[] = "LZMAEncode";
275
LZMAState *sp = EncoderState(tif);
278
assert(sp->state == LSTATE_INIT_ENCODE);
281
sp->stream.next_in = bp;
282
sp->stream.avail_in = (size_t) cc;
283
if ((tmsize_t)sp->stream.avail_in != cc) {
284
TIFFErrorExt(tif->tif_clientdata, module,
285
"Liblzma cannot deal with buffers this size");
289
lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
290
if (ret != LZMA_OK) {
291
TIFFErrorExt(tif->tif_clientdata, module,
292
"Encoding error at scanline %lu, %s",
293
(unsigned long) tif->tif_row, LZMAStrerror(ret));
296
if (sp->stream.avail_out == 0) {
297
tif->tif_rawcc = tif->tif_rawdatasize;
299
sp->stream.next_out = tif->tif_rawdata;
300
sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */
302
} while (sp->stream.avail_in > 0);
307
* Finish off an encoded strip by flushing the last
308
* string and tacking on an End Of Information code.
311
LZMAPostEncode(TIFF* tif)
313
static const char module[] = "LZMAPostEncode";
314
LZMAState *sp = EncoderState(tif);
317
sp->stream.avail_in = 0;
319
ret = lzma_code(&sp->stream, LZMA_FINISH);
321
case LZMA_STREAM_END:
323
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
325
tif->tif_rawdatasize - sp->stream.avail_out;
327
sp->stream.next_out = tif->tif_rawdata;
328
sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
332
TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s",
336
} while (ret != LZMA_STREAM_END);
341
LZMACleanup(TIFF* tif)
343
LZMAState* sp = LState(tif);
347
(void)TIFFPredictorCleanup(tif);
349
tif->tif_tagmethods.vgetfield = sp->vgetparent;
350
tif->tif_tagmethods.vsetfield = sp->vsetparent;
353
lzma_end(&sp->stream);
357
tif->tif_data = NULL;
359
_TIFFSetDefaultCompressionState(tif);
363
LZMAVSetField(TIFF* tif, uint32 tag, va_list ap)
365
static const char module[] = "LZMAVSetField";
366
LZMAState* sp = LState(tif);
369
case TIFFTAG_LZMAPRESET:
370
sp->preset = (int) va_arg(ap, int);
371
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
372
if (sp->state & LSTATE_INIT_ENCODE) {
373
lzma_ret ret = lzma_stream_encoder(&sp->stream,
376
if (ret != LZMA_OK) {
377
TIFFErrorExt(tif->tif_clientdata, module,
384
return (*sp->vsetparent)(tif, tag, ap);
390
LZMAVGetField(TIFF* tif, uint32 tag, va_list ap)
392
LZMAState* sp = LState(tif);
395
case TIFFTAG_LZMAPRESET:
396
*va_arg(ap, int*) = sp->preset;
399
return (*sp->vgetparent)(tif, tag, ap);
404
static const TIFFField lzmaFields[] = {
405
{ TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED,
406
FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL },
410
TIFFInitLZMA(TIFF* tif, int scheme)
412
static const char module[] = "TIFFInitLZMA";
414
lzma_stream tmp_stream = LZMA_STREAM_INIT;
416
assert( scheme == COMPRESSION_LZMA );
419
* Merge codec-specific tag information.
421
if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) {
422
TIFFErrorExt(tif->tif_clientdata, module,
423
"Merging LZMA2 codec-specific tags failed");
428
* Allocate state block so tag methods have storage to record values.
430
tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState));
431
if (tif->tif_data == NULL)
434
memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream));
437
* Override parent get/set field methods.
439
sp->vgetparent = tif->tif_tagmethods.vgetfield;
440
tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */
441
sp->vsetparent = tif->tif_tagmethods.vsetfield;
442
tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */
444
/* Default values for codec-specific fields */
445
sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */
446
sp->check = LZMA_CHECK_NONE;
449
/* Data filters. So far we are using delta and LZMA2 filters only. */
450
sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE;
452
* The sample size in bytes seems to be reasonable distance for delta
455
sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ?
456
1 : tif->tif_dir.td_bitspersample / 8;
457
sp->filters[0].id = LZMA_FILTER_DELTA;
458
sp->filters[0].options = &sp->opt_delta;
460
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
461
sp->filters[1].id = LZMA_FILTER_LZMA2;
462
sp->filters[1].options = &sp->opt_lzma;
464
sp->filters[2].id = LZMA_VLI_UNKNOWN;
465
sp->filters[2].options = NULL;
468
* Install codec methods.
470
tif->tif_fixuptags = LZMAFixupTags;
471
tif->tif_setupdecode = LZMASetupDecode;
472
tif->tif_predecode = LZMAPreDecode;
473
tif->tif_decoderow = LZMADecode;
474
tif->tif_decodestrip = LZMADecode;
475
tif->tif_decodetile = LZMADecode;
476
tif->tif_setupencode = LZMASetupEncode;
477
tif->tif_preencode = LZMAPreEncode;
478
tif->tif_postencode = LZMAPostEncode;
479
tif->tif_encoderow = LZMAEncode;
480
tif->tif_encodestrip = LZMAEncode;
481
tif->tif_encodetile = LZMAEncode;
482
tif->tif_cleanup = LZMACleanup;
484
* Setup predictor setup.
486
(void) TIFFPredictorInit(tif);
489
TIFFErrorExt(tif->tif_clientdata, module,
490
"No space for LZMA2 state block");
493
#endif /* LZMA_SUPORT */
495
/* vim: set ts=8 sts=8 sw=8 noet: */