3 * Copyright (c) 2010, Andrey Kiselev <dron@ak4719.spb.edu>
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.
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.
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
30 * LZMA2 Compression Support
32 * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details.
34 * The codec is derived from ZLIB codec (tif_zip.c).
37 #include "tif_predict.h"
43 * State block for each open TIFF file using LZMA2 compression/decompression.
46 TIFFPredictorState predict
;
48 lzma_filter filters
[LZMA_FILTERS_MAX
+ 1];
49 lzma_options_delta opt_delta
; /* delta filter options */
50 lzma_options_lzma opt_lzma
; /* LZMA2 filter options */
51 int preset
; /* compression level */
52 lzma_check check
; /* type of the integrity check */
53 int state
; /* state flags */
54 #define LSTATE_INIT_DECODE 0x01
55 #define LSTATE_INIT_ENCODE 0x02
57 TIFFVGetMethod vgetparent
; /* super-class method */
58 TIFFVSetMethod vsetparent
; /* super-class method */
61 #define LState(tif) ((LZMAState*) (tif)->tif_data)
62 #define DecoderState(tif) LState(tif)
63 #define EncoderState(tif) LState(tif)
65 static int LZMAEncode(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
);
66 static int LZMADecode(TIFF
* tif
, uint8
* op
, tmsize_t occ
, uint16 s
);
69 LZMAStrerror(lzma_ret ret
)
73 return "operation completed successfully";
75 return "end of stream was reached";
77 return "input stream has no integrity check";
78 case LZMA_UNSUPPORTED_CHECK
:
79 return "cannot calculate the integrity check";
81 return "integrity check type is now available";
83 return "cannot allocate memory";
84 case LZMA_MEMLIMIT_ERROR
:
85 return "memory usage limit was reached";
86 case LZMA_FORMAT_ERROR
:
87 return "file format not recognized";
88 case LZMA_OPTIONS_ERROR
:
89 return "invalid or unsupported options";
91 return "data is corrupt";
93 return "no progress is possible (stream is truncated or corrupt)";
95 return "programming error";
97 return "unindentified liblzma error";
102 LZMAFixupTags(TIFF
* tif
)
109 LZMASetupDecode(TIFF
* tif
)
111 LZMAState
* sp
= DecoderState(tif
);
115 /* if we were last encoding, terminate this mode */
116 if (sp
->state
& LSTATE_INIT_ENCODE
) {
117 lzma_end(&sp
->stream
);
121 sp
->state
|= LSTATE_INIT_DECODE
;
126 * Setup state for decoding a strip.
129 LZMAPreDecode(TIFF
* tif
, uint16 s
)
131 static const char module[] = "LZMAPreDecode";
132 LZMAState
* sp
= DecoderState(tif
);
138 if( (sp
->state
& LSTATE_INIT_DECODE
) == 0 )
139 tif
->tif_setupdecode(tif
);
141 sp
->stream
.next_in
= tif
->tif_rawdata
;
142 sp
->stream
.avail_in
= (size_t) tif
->tif_rawcc
;
143 if ((tmsize_t
)sp
->stream
.avail_in
!= tif
->tif_rawcc
) {
144 TIFFErrorExt(tif
->tif_clientdata
, module,
145 "Liblzma cannot deal with buffers this size");
150 * Disable memory limit when decoding. UINT64_MAX is a flag to disable
151 * the limit, we are passing (uint64_t)-1 which should be the same.
153 ret
= lzma_stream_decoder(&sp
->stream
, (uint64_t)-1, 0);
154 if (ret
!= LZMA_OK
) {
155 TIFFErrorExt(tif
->tif_clientdata
, module,
156 "Error initializing the stream decoder, %s",
164 LZMADecode(TIFF
* tif
, uint8
* op
, tmsize_t occ
, uint16 s
)
166 static const char module[] = "LZMADecode";
167 LZMAState
* sp
= DecoderState(tif
);
171 assert(sp
->state
== LSTATE_INIT_DECODE
);
173 sp
->stream
.next_in
= tif
->tif_rawcp
;
174 sp
->stream
.avail_in
= (size_t) tif
->tif_rawcc
;
176 sp
->stream
.next_out
= op
;
177 sp
->stream
.avail_out
= (size_t) occ
;
178 if ((tmsize_t
)sp
->stream
.avail_out
!= occ
) {
179 TIFFErrorExt(tif
->tif_clientdata
, module,
180 "Liblzma cannot deal with buffers this size");
186 * Save the current stream state to properly recover from the
187 * decoding errors later.
189 const uint8_t *next_in
= sp
->stream
.next_in
;
190 size_t avail_in
= sp
->stream
.avail_in
;
192 lzma_ret ret
= lzma_code(&sp
->stream
, LZMA_RUN
);
193 if (ret
== LZMA_STREAM_END
)
195 if (ret
== LZMA_MEMLIMIT_ERROR
) {
196 lzma_ret r
= lzma_stream_decoder(&sp
->stream
,
197 lzma_memusage(&sp
->stream
), 0);
199 TIFFErrorExt(tif
->tif_clientdata
, module,
200 "Error initializing the stream decoder, %s",
204 sp
->stream
.next_in
= next_in
;
205 sp
->stream
.avail_in
= avail_in
;
208 if (ret
!= LZMA_OK
) {
209 TIFFErrorExt(tif
->tif_clientdata
, module,
210 "Decoding error at scanline %lu, %s",
211 (unsigned long) tif
->tif_row
, LZMAStrerror(ret
));
214 } while (sp
->stream
.avail_out
> 0);
215 if (sp
->stream
.avail_out
!= 0) {
216 TIFFErrorExt(tif
->tif_clientdata
, module,
217 "Not enough data at scanline %lu (short %lu bytes)",
218 (unsigned long) tif
->tif_row
, (unsigned long) sp
->stream
.avail_out
);
222 tif
->tif_rawcp
= (uint8
*)sp
->stream
.next_in
; /* cast away const */
223 tif
->tif_rawcc
= sp
->stream
.avail_in
;
229 LZMASetupEncode(TIFF
* tif
)
231 LZMAState
* sp
= EncoderState(tif
);
234 if (sp
->state
& LSTATE_INIT_DECODE
) {
235 lzma_end(&sp
->stream
);
239 sp
->state
|= LSTATE_INIT_ENCODE
;
244 * Reset encoding state at the start of a strip.
247 LZMAPreEncode(TIFF
* tif
, uint16 s
)
249 static const char module[] = "LZMAPreEncode";
250 LZMAState
*sp
= EncoderState(tif
);
254 if( sp
->state
!= LSTATE_INIT_ENCODE
)
255 tif
->tif_setupencode(tif
);
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");
264 return (lzma_stream_encoder(&sp
->stream
, sp
->filters
, sp
->check
) == LZMA_OK
);
268 * Encode a chunk of pixels.
271 LZMAEncode(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
)
273 static const char module[] = "LZMAEncode";
274 LZMAState
*sp
= EncoderState(tif
);
277 assert(sp
->state
== LSTATE_INIT_ENCODE
);
280 sp
->stream
.next_in
= bp
;
281 sp
->stream
.avail_in
= (size_t) cc
;
282 if ((tmsize_t
)sp
->stream
.avail_in
!= cc
) {
283 TIFFErrorExt(tif
->tif_clientdata
, module,
284 "Liblzma cannot deal with buffers this size");
288 lzma_ret ret
= lzma_code(&sp
->stream
, LZMA_RUN
);
289 if (ret
!= LZMA_OK
) {
290 TIFFErrorExt(tif
->tif_clientdata
, module,
291 "Encoding error at scanline %lu, %s",
292 (unsigned long) tif
->tif_row
, LZMAStrerror(ret
));
295 if (sp
->stream
.avail_out
== 0) {
296 tif
->tif_rawcc
= tif
->tif_rawdatasize
;
298 sp
->stream
.next_out
= tif
->tif_rawdata
;
299 sp
->stream
.avail_out
= (size_t)tif
->tif_rawdatasize
; /* this is a safe typecast, as check is made already in LZMAPreEncode */
301 } while (sp
->stream
.avail_in
> 0);
306 * Finish off an encoded strip by flushing the last
307 * string and tacking on an End Of Information code.
310 LZMAPostEncode(TIFF
* tif
)
312 static const char module[] = "LZMAPostEncode";
313 LZMAState
*sp
= EncoderState(tif
);
316 sp
->stream
.avail_in
= 0;
318 ret
= lzma_code(&sp
->stream
, LZMA_FINISH
);
320 case LZMA_STREAM_END
:
322 if ((tmsize_t
)sp
->stream
.avail_out
!= tif
->tif_rawdatasize
) {
324 tif
->tif_rawdatasize
- sp
->stream
.avail_out
;
326 sp
->stream
.next_out
= tif
->tif_rawdata
;
327 sp
->stream
.avail_out
= (size_t)tif
->tif_rawdatasize
; /* this is a safe typecast, as check is made already in ZIPPreEncode */
331 TIFFErrorExt(tif
->tif_clientdata
, module, "Liblzma error: %s",
335 } while (ret
!= LZMA_STREAM_END
);
340 LZMACleanup(TIFF
* tif
)
342 LZMAState
* sp
= LState(tif
);
346 (void)TIFFPredictorCleanup(tif
);
348 tif
->tif_tagmethods
.vgetfield
= sp
->vgetparent
;
349 tif
->tif_tagmethods
.vsetfield
= sp
->vsetparent
;
352 lzma_end(&sp
->stream
);
356 tif
->tif_data
= NULL
;
358 _TIFFSetDefaultCompressionState(tif
);
362 LZMAVSetField(TIFF
* tif
, uint32 tag
, va_list ap
)
364 static const char module[] = "LZMAVSetField";
365 LZMAState
* sp
= LState(tif
);
368 case TIFFTAG_LZMAPRESET
:
369 sp
->preset
= (int) va_arg(ap
, int);
370 lzma_lzma_preset(&sp
->opt_lzma
, sp
->preset
);
371 if (sp
->state
& LSTATE_INIT_ENCODE
) {
372 lzma_ret ret
= lzma_stream_encoder(&sp
->stream
,
375 if (ret
!= LZMA_OK
) {
376 TIFFErrorExt(tif
->tif_clientdata
, module,
383 return (*sp
->vsetparent
)(tif
, tag
, ap
);
389 LZMAVGetField(TIFF
* tif
, uint32 tag
, va_list ap
)
391 LZMAState
* sp
= LState(tif
);
394 case TIFFTAG_LZMAPRESET
:
395 *va_arg(ap
, int*) = sp
->preset
;
398 return (*sp
->vgetparent
)(tif
, tag
, ap
);
403 static const TIFFField lzmaFields
[] = {
404 { TIFFTAG_LZMAPRESET
, 0, 0, TIFF_ANY
, 0, TIFF_SETGET_INT
, TIFF_SETGET_UNDEFINED
,
405 FIELD_PSEUDO
, TRUE
, FALSE
, "LZMA2 Compression Preset", NULL
},
409 TIFFInitLZMA(TIFF
* tif
, int scheme
)
411 static const char module[] = "TIFFInitLZMA";
413 lzma_stream tmp_stream
= LZMA_STREAM_INIT
;
415 assert( scheme
== COMPRESSION_LZMA
);
418 * Merge codec-specific tag information.
420 if (!_TIFFMergeFields(tif
, lzmaFields
, TIFFArrayCount(lzmaFields
))) {
421 TIFFErrorExt(tif
->tif_clientdata
, module,
422 "Merging LZMA2 codec-specific tags failed");
427 * Allocate state block so tag methods have storage to record values.
429 tif
->tif_data
= (uint8
*) _TIFFmalloc(sizeof(LZMAState
));
430 if (tif
->tif_data
== NULL
)
433 memcpy(&sp
->stream
, &tmp_stream
, sizeof(lzma_stream
));
436 * Override parent get/set field methods.
438 sp
->vgetparent
= tif
->tif_tagmethods
.vgetfield
;
439 tif
->tif_tagmethods
.vgetfield
= LZMAVGetField
; /* hook for codec tags */
440 sp
->vsetparent
= tif
->tif_tagmethods
.vsetfield
;
441 tif
->tif_tagmethods
.vsetfield
= LZMAVSetField
; /* hook for codec tags */
443 /* Default values for codec-specific fields */
444 sp
->preset
= LZMA_PRESET_DEFAULT
; /* default comp. level */
445 sp
->check
= LZMA_CHECK_NONE
;
448 /* Data filters. So far we are using delta and LZMA2 filters only. */
449 sp
->opt_delta
.type
= LZMA_DELTA_TYPE_BYTE
;
451 * The sample size in bytes seems to be reasonable distance for delta
454 sp
->opt_delta
.dist
= (tif
->tif_dir
.td_bitspersample
% 8) ?
455 1 : tif
->tif_dir
.td_bitspersample
/ 8;
456 sp
->filters
[0].id
= LZMA_FILTER_DELTA
;
457 sp
->filters
[0].options
= &sp
->opt_delta
;
459 lzma_lzma_preset(&sp
->opt_lzma
, sp
->preset
);
460 sp
->filters
[1].id
= LZMA_FILTER_LZMA2
;
461 sp
->filters
[1].options
= &sp
->opt_lzma
;
463 sp
->filters
[2].id
= LZMA_VLI_UNKNOWN
;
464 sp
->filters
[2].options
= NULL
;
467 * Install codec methods.
469 tif
->tif_fixuptags
= LZMAFixupTags
;
470 tif
->tif_setupdecode
= LZMASetupDecode
;
471 tif
->tif_predecode
= LZMAPreDecode
;
472 tif
->tif_decoderow
= LZMADecode
;
473 tif
->tif_decodestrip
= LZMADecode
;
474 tif
->tif_decodetile
= LZMADecode
;
475 tif
->tif_setupencode
= LZMASetupEncode
;
476 tif
->tif_preencode
= LZMAPreEncode
;
477 tif
->tif_postencode
= LZMAPostEncode
;
478 tif
->tif_encoderow
= LZMAEncode
;
479 tif
->tif_encodestrip
= LZMAEncode
;
480 tif
->tif_encodetile
= LZMAEncode
;
481 tif
->tif_cleanup
= LZMACleanup
;
483 * Setup predictor setup.
485 (void) TIFFPredictorInit(tif
);
488 TIFFErrorExt(tif
->tif_clientdata
, module,
489 "No space for LZMA2 state block");
492 #endif /* LZMA_SUPORT */
494 /* vim: set ts=8 sts=8 sw=8 noet: */