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
= (uint8
*)sp
->stream
.next_in
; /* cast away const */
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: */