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