1 /* $Id: tif_lzma.c,v 1.4 2011-12-22 00:29:29 bfriesen 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
32 * LZMA2 Compression Support
34 * You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details.
36 * The codec is derived from ZLIB codec (tif_zip.c).
39 #include "tif_predict.h"
45 * State block for each open TIFF file using LZMA2 compression/decompression.
48 TIFFPredictorState predict
;
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
59 TIFFVGetMethod vgetparent
; /* super-class method */
60 TIFFVSetMethod vsetparent
; /* super-class method */
63 #define LState(tif) ((LZMAState*) (tif)->tif_data)
64 #define DecoderState(tif) LState(tif)
65 #define EncoderState(tif) LState(tif)
67 static int LZMAEncode(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
);
68 static int LZMADecode(TIFF
* tif
, uint8
* op
, tmsize_t occ
, uint16 s
);
71 LZMAStrerror(lzma_ret ret
)
75 return "operation completed successfully";
77 return "end of stream was reached";
79 return "input stream has no integrity check";
80 case LZMA_UNSUPPORTED_CHECK
:
81 return "cannot calculate the integrity check";
83 return "integrity check type is now available";
85 return "cannot allocate memory";
86 case LZMA_MEMLIMIT_ERROR
:
87 return "memory usage limit was reached";
88 case LZMA_FORMAT_ERROR
:
89 return "file format not recognized";
90 case LZMA_OPTIONS_ERROR
:
91 return "invalid or unsupported options";
93 return "data is corrupt";
95 return "no progress is possible (stream is truncated or corrupt)";
97 return "programming error";
99 return "unindentified liblzma error";
104 LZMAFixupTags(TIFF
* tif
)
111 LZMASetupDecode(TIFF
* tif
)
113 LZMAState
* sp
= DecoderState(tif
);
117 /* if we were last encoding, terminate this mode */
118 if (sp
->state
& LSTATE_INIT_ENCODE
) {
119 lzma_end(&sp
->stream
);
123 sp
->state
|= LSTATE_INIT_DECODE
;
128 * Setup state for decoding a strip.
131 LZMAPreDecode(TIFF
* tif
, uint16 s
)
133 static const char module
[] = "LZMAPreDecode";
134 LZMAState
* sp
= DecoderState(tif
);
140 if( (sp
->state
& LSTATE_INIT_DECODE
) == 0 )
141 tif
->tif_setupdecode(tif
);
143 sp
->stream
.next_in
= tif
->tif_rawdata
;
144 sp
->stream
.avail_in
= (size_t) tif
->tif_rawcc
;
145 if ((tmsize_t
)sp
->stream
.avail_in
!= tif
->tif_rawcc
) {
146 TIFFErrorExt(tif
->tif_clientdata
, module
,
147 "Liblzma cannot deal with buffers this size");
152 * Disable memory limit when decoding. UINT64_MAX is a flag to disable
153 * the limit, we are passing (uint64_t)-1 which should be the same.
155 ret
= lzma_stream_decoder(&sp
->stream
, (uint64_t)-1, 0);
156 if (ret
!= LZMA_OK
) {
157 TIFFErrorExt(tif
->tif_clientdata
, module
,
158 "Error initializing the stream decoder, %s",
166 LZMADecode(TIFF
* tif
, uint8
* op
, tmsize_t occ
, uint16 s
)
168 static const char module
[] = "LZMADecode";
169 LZMAState
* sp
= DecoderState(tif
);
173 assert(sp
->state
== LSTATE_INIT_DECODE
);
175 sp
->stream
.next_in
= tif
->tif_rawcp
;
176 sp
->stream
.avail_in
= (size_t) tif
->tif_rawcc
;
178 sp
->stream
.next_out
= op
;
179 sp
->stream
.avail_out
= (size_t) occ
;
180 if ((tmsize_t
)sp
->stream
.avail_out
!= occ
) {
181 TIFFErrorExt(tif
->tif_clientdata
, module
,
182 "Liblzma cannot deal with buffers this size");
188 * Save the current stream state to properly recover from the
189 * decoding errors later.
191 const uint8_t *next_in
= sp
->stream
.next_in
;
192 size_t avail_in
= sp
->stream
.avail_in
;
194 lzma_ret ret
= lzma_code(&sp
->stream
, LZMA_RUN
);
195 if (ret
== LZMA_STREAM_END
)
197 if (ret
== LZMA_MEMLIMIT_ERROR
) {
198 lzma_ret r
= lzma_stream_decoder(&sp
->stream
,
199 lzma_memusage(&sp
->stream
), 0);
201 TIFFErrorExt(tif
->tif_clientdata
, module
,
202 "Error initializing the stream decoder, %s",
206 sp
->stream
.next_in
= next_in
;
207 sp
->stream
.avail_in
= avail_in
;
210 if (ret
!= LZMA_OK
) {
211 TIFFErrorExt(tif
->tif_clientdata
, module
,
212 "Decoding error at scanline %lu, %s",
213 (unsigned long) tif
->tif_row
, LZMAStrerror(ret
));
216 } while (sp
->stream
.avail_out
> 0);
217 if (sp
->stream
.avail_out
!= 0) {
218 TIFFErrorExt(tif
->tif_clientdata
, module
,
219 "Not enough data at scanline %lu (short %lu bytes)",
220 (unsigned long) tif
->tif_row
, (unsigned long) sp
->stream
.avail_out
);
224 tif
->tif_rawcp
= (uint8
*)sp
->stream
.next_in
; /* cast away const */
225 tif
->tif_rawcc
= sp
->stream
.avail_in
;
231 LZMASetupEncode(TIFF
* tif
)
233 LZMAState
* sp
= EncoderState(tif
);
236 if (sp
->state
& LSTATE_INIT_DECODE
) {
237 lzma_end(&sp
->stream
);
241 sp
->state
|= LSTATE_INIT_ENCODE
;
246 * Reset encoding state at the start of a strip.
249 LZMAPreEncode(TIFF
* tif
, uint16 s
)
251 static const char module
[] = "LZMAPreEncode";
252 LZMAState
*sp
= EncoderState(tif
);
256 if( sp
->state
!= LSTATE_INIT_ENCODE
)
257 tif
->tif_setupencode(tif
);
259 sp
->stream
.next_out
= tif
->tif_rawdata
;
260 sp
->stream
.avail_out
= (size_t)tif
->tif_rawdatasize
;
261 if ((tmsize_t
)sp
->stream
.avail_out
!= tif
->tif_rawdatasize
) {
262 TIFFErrorExt(tif
->tif_clientdata
, module
,
263 "Liblzma cannot deal with buffers this size");
266 return (lzma_stream_encoder(&sp
->stream
, sp
->filters
, sp
->check
) == LZMA_OK
);
270 * Encode a chunk of pixels.
273 LZMAEncode(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
)
275 static const char module
[] = "LZMAEncode";
276 LZMAState
*sp
= EncoderState(tif
);
279 assert(sp
->state
== LSTATE_INIT_ENCODE
);
282 sp
->stream
.next_in
= bp
;
283 sp
->stream
.avail_in
= (size_t) cc
;
284 if ((tmsize_t
)sp
->stream
.avail_in
!= cc
) {
285 TIFFErrorExt(tif
->tif_clientdata
, module
,
286 "Liblzma cannot deal with buffers this size");
290 lzma_ret ret
= lzma_code(&sp
->stream
, LZMA_RUN
);
291 if (ret
!= LZMA_OK
) {
292 TIFFErrorExt(tif
->tif_clientdata
, module
,
293 "Encoding error at scanline %lu, %s",
294 (unsigned long) tif
->tif_row
, LZMAStrerror(ret
));
297 if (sp
->stream
.avail_out
== 0) {
298 tif
->tif_rawcc
= tif
->tif_rawdatasize
;
300 sp
->stream
.next_out
= tif
->tif_rawdata
;
301 sp
->stream
.avail_out
= (size_t)tif
->tif_rawdatasize
; /* this is a safe typecast, as check is made already in LZMAPreEncode */
303 } while (sp
->stream
.avail_in
> 0);
308 * Finish off an encoded strip by flushing the last
309 * string and tacking on an End Of Information code.
312 LZMAPostEncode(TIFF
* tif
)
314 static const char module
[] = "LZMAPostEncode";
315 LZMAState
*sp
= EncoderState(tif
);
318 sp
->stream
.avail_in
= 0;
320 ret
= lzma_code(&sp
->stream
, LZMA_FINISH
);
322 case LZMA_STREAM_END
:
324 if ((tmsize_t
)sp
->stream
.avail_out
!= tif
->tif_rawdatasize
) {
326 tif
->tif_rawdatasize
- sp
->stream
.avail_out
;
328 sp
->stream
.next_out
= tif
->tif_rawdata
;
329 sp
->stream
.avail_out
= (size_t)tif
->tif_rawdatasize
; /* this is a safe typecast, as check is made already in ZIPPreEncode */
333 TIFFErrorExt(tif
->tif_clientdata
, module
, "Liblzma error: %s",
337 } while (ret
!= LZMA_STREAM_END
);
342 LZMACleanup(TIFF
* tif
)
344 LZMAState
* sp
= LState(tif
);
348 (void)TIFFPredictorCleanup(tif
);
350 tif
->tif_tagmethods
.vgetfield
= sp
->vgetparent
;
351 tif
->tif_tagmethods
.vsetfield
= sp
->vsetparent
;
354 lzma_end(&sp
->stream
);
358 tif
->tif_data
= NULL
;
360 _TIFFSetDefaultCompressionState(tif
);
364 LZMAVSetField(TIFF
* tif
, uint32 tag
, va_list ap
)
366 static const char module
[] = "LZMAVSetField";
367 LZMAState
* sp
= LState(tif
);
370 case TIFFTAG_LZMAPRESET
:
371 sp
->preset
= (int) va_arg(ap
, int);
372 lzma_lzma_preset(&sp
->opt_lzma
, sp
->preset
);
373 if (sp
->state
& LSTATE_INIT_ENCODE
) {
374 lzma_ret ret
= lzma_stream_encoder(&sp
->stream
,
377 if (ret
!= LZMA_OK
) {
378 TIFFErrorExt(tif
->tif_clientdata
, module
,
385 return (*sp
->vsetparent
)(tif
, tag
, ap
);
391 LZMAVGetField(TIFF
* tif
, uint32 tag
, va_list ap
)
393 LZMAState
* sp
= LState(tif
);
396 case TIFFTAG_LZMAPRESET
:
397 *va_arg(ap
, int*) = sp
->preset
;
400 return (*sp
->vgetparent
)(tif
, tag
, ap
);
405 static const TIFFField lzmaFields
[] = {
406 { TIFFTAG_LZMAPRESET
, 0, 0, TIFF_ANY
, 0, TIFF_SETGET_INT
, TIFF_SETGET_UNDEFINED
,
407 FIELD_PSEUDO
, TRUE
, FALSE
, "LZMA2 Compression Preset", NULL
},
411 TIFFInitLZMA(TIFF
* tif
, int scheme
)
413 static const char module
[] = "TIFFInitLZMA";
415 lzma_stream tmp_stream
= LZMA_STREAM_INIT
;
417 assert( scheme
== COMPRESSION_LZMA
);
420 * Merge codec-specific tag information.
422 if (!_TIFFMergeFields(tif
, lzmaFields
, TIFFArrayCount(lzmaFields
))) {
423 TIFFErrorExt(tif
->tif_clientdata
, module
,
424 "Merging LZMA2 codec-specific tags failed");
429 * Allocate state block so tag methods have storage to record values.
431 tif
->tif_data
= (uint8
*) _TIFFmalloc(sizeof(LZMAState
));
432 if (tif
->tif_data
== NULL
)
435 memcpy(&sp
->stream
, &tmp_stream
, sizeof(lzma_stream
));
438 * Override parent get/set field methods.
440 sp
->vgetparent
= tif
->tif_tagmethods
.vgetfield
;
441 tif
->tif_tagmethods
.vgetfield
= LZMAVGetField
; /* hook for codec tags */
442 sp
->vsetparent
= tif
->tif_tagmethods
.vsetfield
;
443 tif
->tif_tagmethods
.vsetfield
= LZMAVSetField
; /* hook for codec tags */
445 /* Default values for codec-specific fields */
446 sp
->preset
= LZMA_PRESET_DEFAULT
; /* default comp. level */
447 sp
->check
= LZMA_CHECK_NONE
;
450 /* Data filters. So far we are using delta and LZMA2 filters only. */
451 sp
->opt_delta
.type
= LZMA_DELTA_TYPE_BYTE
;
453 * The sample size in bytes seems to be reasonable distance for delta
456 sp
->opt_delta
.dist
= (tif
->tif_dir
.td_bitspersample
% 8) ?
457 1 : tif
->tif_dir
.td_bitspersample
/ 8;
458 sp
->filters
[0].id
= LZMA_FILTER_DELTA
;
459 sp
->filters
[0].options
= &sp
->opt_delta
;
461 lzma_lzma_preset(&sp
->opt_lzma
, sp
->preset
);
462 sp
->filters
[1].id
= LZMA_FILTER_LZMA2
;
463 sp
->filters
[1].options
= &sp
->opt_lzma
;
465 sp
->filters
[2].id
= LZMA_VLI_UNKNOWN
;
466 sp
->filters
[2].options
= NULL
;
469 * Install codec methods.
471 tif
->tif_fixuptags
= LZMAFixupTags
;
472 tif
->tif_setupdecode
= LZMASetupDecode
;
473 tif
->tif_predecode
= LZMAPreDecode
;
474 tif
->tif_decoderow
= LZMADecode
;
475 tif
->tif_decodestrip
= LZMADecode
;
476 tif
->tif_decodetile
= LZMADecode
;
477 tif
->tif_setupencode
= LZMASetupEncode
;
478 tif
->tif_preencode
= LZMAPreEncode
;
479 tif
->tif_postencode
= LZMAPostEncode
;
480 tif
->tif_encoderow
= LZMAEncode
;
481 tif
->tif_encodestrip
= LZMAEncode
;
482 tif
->tif_encodetile
= LZMAEncode
;
483 tif
->tif_cleanup
= LZMACleanup
;
485 * Setup predictor setup.
487 (void) TIFFPredictorInit(tif
);
490 TIFFErrorExt(tif
->tif_clientdata
, module
,
491 "No space for LZMA2 state block");
494 #endif /* LZMA_SUPORT */
496 /* vim: set ts=8 sts=8 sw=8 noet: */