Implement a new TIFF compression scheme LZMA reserving a new value 34925 for
Compression tag. As per bug http://bugzilla.maptools.org/show_bug.cgi?id=2221
This commit is contained in:
parent
f7aebc2647
commit
a2d72c2dd4
52
configure.ac
52
configure.ac
@ -658,6 +658,57 @@ if test "$HAVE_JBIG" = "yes" ; then
|
||||
|
||||
fi
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Check for liblzma2.
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
HAVE_LZMA=no
|
||||
|
||||
AC_ARG_ENABLE(lzma,
|
||||
AS_HELP_STRING([--disable-lzma],
|
||||
[disable liblzma usage (required for LZMA2 compression, enabled by default)]),,)
|
||||
AC_ARG_WITH(lzma-include-dir,
|
||||
AS_HELP_STRING([--with-lzma-include-dir=DIR],
|
||||
[location of liblzma headers]),,)
|
||||
AC_ARG_WITH(lzma-lib-dir,
|
||||
AS_HELP_STRING([--with-lzma-lib-dir=DIR],
|
||||
[location of liblzma library binary]),,)
|
||||
|
||||
if test "x$enable_lzma" != "xno" ; then
|
||||
|
||||
if test "x$with_lzma_lib_dir" != "x" ; then
|
||||
LDFLAGS="-L$with_lzma_lib_dir $LDFLAGS"
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(lzma, lzma_code, [lzma_lib=yes], [lzma_lib=no],)
|
||||
if test "$lzma_lib" = "no" -a "x$with_lzma_lib_dir" != "x"; then
|
||||
AC_MSG_ERROR([lzma library not found at $with_lzma_lib_dir])
|
||||
fi
|
||||
|
||||
if test "x$with_lzma_include_dir" != "x" ; then
|
||||
CPPFLAGS="-I$with_lzma_include_dir $CPPFLAGS"
|
||||
fi
|
||||
AC_CHECK_HEADER(lzma.h, [lzma_h=yes], [lzma_h=no])
|
||||
if test "$lzma_h" = "no" -a "x$with_lzma_include_dir" != "x" ; then
|
||||
AC_MSG_ERROR([Liblzma headers not found at $with_lzma_include_dir])
|
||||
fi
|
||||
|
||||
if test "$lzma_lib" = "yes" -a "$lzma_h" = "yes" ; then
|
||||
HAVE_LZMA=yes
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if test "$HAVE_LZMA" = "yes" ; then
|
||||
AC_DEFINE(LZMA_SUPPORT,1,[Support LZMA2 compression])
|
||||
LIBS="-llzma $LIBS"
|
||||
|
||||
if test "$HAVE_RPATH" = "yes" -a "x$with_lzma_lib_dir" != "x" ; then
|
||||
LIBDIR="-R $with_lzma_lib_dir $LIBDIR"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Should 8/12 bit jpeg mode be enabled?
|
||||
dnl ---------------------------------------------------------------------------
|
||||
@ -863,6 +914,7 @@ LOC_MSG([ JPEG support: ${HAVE_JPEG}])
|
||||
LOC_MSG([ Old JPEG support: ${HAVE_OJPEG}])
|
||||
LOC_MSG([ JPEG 8/12 bit dual mode: ${HAVE_JPEG12}])
|
||||
LOC_MSG([ ISO JBIG support: ${HAVE_JBIG}])
|
||||
LOC_MSG([ LZMA2 support: ${HAVE_LZMA}])
|
||||
LOC_MSG()
|
||||
LOC_MSG([ C++ support: ${HAVE_CXX}])
|
||||
LOC_MSG()
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tif_codec.c,v 1.14 2010-03-10 18:56:48 bfriesen Exp $ */
|
||||
/* $Id: tif_codec.c,v 1.15 2010-12-14 12:53:00 dron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
@ -69,6 +69,9 @@ static int NotConfigured(TIFF*, int);
|
||||
#ifndef LOGLUV_SUPPORT
|
||||
#define TIFFInitSGILog NotConfigured
|
||||
#endif
|
||||
#ifndef LZMA_SUPPORT
|
||||
#define TIFFInitLZMA NotConfigured
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compression schemes statically built into the library.
|
||||
@ -95,6 +98,7 @@ TIFFCodec _TIFFBuiltinCODECS[] = {
|
||||
{ "PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog },
|
||||
{ "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog },
|
||||
{ "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog },
|
||||
{ "LZMA", COMPRESSION_LZMA, TIFFInitLZMA },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -195,6 +195,9 @@
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Support LZMA2 compression */
|
||||
#undef LZMA_SUPPORT
|
||||
|
||||
/* Support LZW algorithm */
|
||||
#undef LZW_SUPPORT
|
||||
|
||||
|
476
libtiff/tif_lzma.c
Normal file
476
libtiff/tif_lzma.c
Normal file
@ -0,0 +1,476 @@
|
||||
/* $Id: tif_lzma.c,v 1.1 2010-12-14 12:53:00 dron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010, Andrey Kiselev <dron@ak4719.spb.edu>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that (i) the above copyright notices and this permission notice appear in
|
||||
* all copies of the software and related documentation, and (ii) the names of
|
||||
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
||||
* publicity relating to the software without the specific, prior written
|
||||
* permission of Sam Leffler and Silicon Graphics.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
||||
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
||||
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
||||
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
||||
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tiffiop.h"
|
||||
#ifdef LZMA_SUPPORT
|
||||
/*
|
||||
* TIFF Library.
|
||||
*
|
||||
* LZMA2 Compression Support
|
||||
*
|
||||
* You need an LZMA2 SDK to link with. See http://tukaani.org/xz/ for details.
|
||||
*
|
||||
* The codec is derived from ZLIB codec (tif_zip.c).
|
||||
*/
|
||||
|
||||
#include "tif_predict.h"
|
||||
#include "lzma.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* State block for each open TIFF file using LZMA2 compression/decompression.
|
||||
*/
|
||||
typedef struct {
|
||||
TIFFPredictorState predict;
|
||||
lzma_stream stream;
|
||||
lzma_filter filters[LZMA_FILTERS_MAX + 1];
|
||||
lzma_options_delta opt_delta; /* delta filter options */
|
||||
lzma_options_lzma opt_lzma; /* LZMA2 filter options */
|
||||
int preset; /* compression level */
|
||||
lzma_check check; /* type of the integrity check */
|
||||
int state; /* state flags */
|
||||
#define LSTATE_INIT_DECODE 0x01
|
||||
#define LSTATE_INIT_ENCODE 0x02
|
||||
|
||||
TIFFVGetMethod vgetparent; /* super-class method */
|
||||
TIFFVSetMethod vsetparent; /* super-class method */
|
||||
} LZMAState;
|
||||
|
||||
#define LState(tif) ((LZMAState*) (tif)->tif_data)
|
||||
#define DecoderState(tif) LState(tif)
|
||||
#define EncoderState(tif) LState(tif)
|
||||
|
||||
static int LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
|
||||
static int LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
|
||||
|
||||
static const char *
|
||||
LZMAStrerror(lzma_ret ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case LZMA_OK:
|
||||
return "operation completed successfully";
|
||||
case LZMA_STREAM_END:
|
||||
return "end of stream was reached";
|
||||
case LZMA_NO_CHECK:
|
||||
return "input stream has no integrity check";
|
||||
case LZMA_UNSUPPORTED_CHECK:
|
||||
return "cannot calculate the integrity check";
|
||||
case LZMA_GET_CHECK:
|
||||
return "integrity check type is now available";
|
||||
case LZMA_MEM_ERROR:
|
||||
return "cannot allocate memory";
|
||||
case LZMA_MEMLIMIT_ERROR:
|
||||
return "memory usage limit was reached";
|
||||
case LZMA_FORMAT_ERROR:
|
||||
return "file format not recognized";
|
||||
case LZMA_OPTIONS_ERROR:
|
||||
return "invalid or unsupported options";
|
||||
case LZMA_DATA_ERROR:
|
||||
return "data is corrupt";
|
||||
case LZMA_BUF_ERROR:
|
||||
return "no progress is possible (stream is truncated or corrupt)";
|
||||
case LZMA_PROG_ERROR:
|
||||
return "programming error";
|
||||
default:
|
||||
return "unindentified liblzma error";
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
LZMAFixupTags(TIFF* tif)
|
||||
{
|
||||
(void) tif;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
LZMASetupDecode(TIFF* tif)
|
||||
{
|
||||
LZMAState* sp = DecoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
|
||||
/* if we were last encoding, terminate this mode */
|
||||
if (sp->state & LSTATE_INIT_ENCODE) {
|
||||
lzma_end(&sp->stream);
|
||||
sp->state = 0;
|
||||
}
|
||||
|
||||
sp->state |= LSTATE_INIT_DECODE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup state for decoding a strip.
|
||||
*/
|
||||
static int
|
||||
LZMAPreDecode(TIFF* tif, uint16 s)
|
||||
{
|
||||
static const char module[] = "LZMAPreDecode";
|
||||
LZMAState* sp = DecoderState(tif);
|
||||
lzma_ret ret;
|
||||
|
||||
(void) s;
|
||||
assert(sp != NULL);
|
||||
|
||||
if( (sp->state & LSTATE_INIT_DECODE) == 0 )
|
||||
tif->tif_setupdecode(tif);
|
||||
|
||||
sp->stream.next_in = tif->tif_rawdata;
|
||||
sp->stream.avail_in = (size_t) tif->tif_rawcc;
|
||||
if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Liblzma cannot deal with buffers this size");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable memory limit when decoding. UINT64_MAX is a flag to disable
|
||||
* the limit, we are passing (uint64_t)-1 which should be the same.
|
||||
*/
|
||||
ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0);
|
||||
if (ret != LZMA_OK) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Error initializing the stream decoder, %s",
|
||||
LZMAStrerror(ret));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
LZMADecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
|
||||
{
|
||||
static const char module[] = "LZMADecode";
|
||||
LZMAState* sp = DecoderState(tif);
|
||||
|
||||
(void) s;
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == LSTATE_INIT_DECODE);
|
||||
|
||||
sp->stream.next_out = op;
|
||||
sp->stream.avail_out = (size_t) occ;
|
||||
if ((tmsize_t)sp->stream.avail_out != occ) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Liblzma cannot deal with buffers this size");
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
/*
|
||||
* Save the current stream state to properly recover from the
|
||||
* decoding errors later.
|
||||
*/
|
||||
const uint8_t *next_in = sp->stream.next_in;
|
||||
size_t avail_in = sp->stream.avail_in;
|
||||
|
||||
lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
|
||||
if (ret == LZMA_STREAM_END)
|
||||
break;
|
||||
if (ret == LZMA_MEMLIMIT_ERROR) {
|
||||
lzma_ret r = lzma_stream_decoder(&sp->stream,
|
||||
lzma_memusage(&sp->stream), 0);
|
||||
if (r != LZMA_OK) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Error initializing the stream decoder, %s",
|
||||
LZMAStrerror(r));
|
||||
break;
|
||||
}
|
||||
sp->stream.next_in = next_in;
|
||||
sp->stream.avail_in = avail_in;
|
||||
continue;
|
||||
}
|
||||
if (ret != LZMA_OK) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Decoding error at scanline %lu, %s",
|
||||
(unsigned long) tif->tif_row, LZMAStrerror(ret));
|
||||
break;
|
||||
}
|
||||
} while (sp->stream.avail_out > 0);
|
||||
if (sp->stream.avail_out != 0) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Not enough data at scanline %lu (short %lu bytes)",
|
||||
(unsigned long) tif->tif_row, (unsigned long) sp->stream.avail_out);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
LZMASetupEncode(TIFF* tif)
|
||||
{
|
||||
LZMAState* sp = EncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
if (sp->state & LSTATE_INIT_DECODE) {
|
||||
lzma_end(&sp->stream);
|
||||
sp->state = 0;
|
||||
}
|
||||
|
||||
sp->state |= LSTATE_INIT_ENCODE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset encoding state at the start of a strip.
|
||||
*/
|
||||
static int
|
||||
LZMAPreEncode(TIFF* tif, uint16 s)
|
||||
{
|
||||
static const char module[] = "LZMAPreEncode";
|
||||
LZMAState *sp = EncoderState(tif);
|
||||
|
||||
(void) s;
|
||||
assert(sp != NULL);
|
||||
if( sp->state != LSTATE_INIT_ENCODE )
|
||||
tif->tif_setupencode(tif);
|
||||
|
||||
sp->stream.next_out = tif->tif_rawdata;
|
||||
sp->stream.avail_out = (size_t)tif->tif_rawdatasize;
|
||||
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Liblzma cannot deal with buffers this size");
|
||||
return 0;
|
||||
}
|
||||
return (lzma_stream_encoder(&sp->stream, sp->filters, sp->check) == LZMA_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode a chunk of pixels.
|
||||
*/
|
||||
static int
|
||||
LZMAEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
|
||||
{
|
||||
static const char module[] = "LZMAEncode";
|
||||
LZMAState *sp = EncoderState(tif);
|
||||
|
||||
assert(sp != NULL);
|
||||
assert(sp->state == LSTATE_INIT_ENCODE);
|
||||
|
||||
(void) s;
|
||||
sp->stream.next_in = bp;
|
||||
sp->stream.avail_in = (size_t) cc;
|
||||
if ((tmsize_t)sp->stream.avail_in != cc) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Liblzma cannot deal with buffers this size");
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN);
|
||||
if (ret != LZMA_OK) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Encoding error at scanline %lu, %s",
|
||||
(unsigned long) tif->tif_row, LZMAStrerror(ret));
|
||||
return 0;
|
||||
}
|
||||
if (sp->stream.avail_out == 0) {
|
||||
tif->tif_rawcc = tif->tif_rawdatasize;
|
||||
TIFFFlushData1(tif);
|
||||
sp->stream.next_out = tif->tif_rawdata;
|
||||
sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */
|
||||
}
|
||||
} while (sp->stream.avail_in > 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish off an encoded strip by flushing the last
|
||||
* string and tacking on an End Of Information code.
|
||||
*/
|
||||
static int
|
||||
LZMAPostEncode(TIFF* tif)
|
||||
{
|
||||
static const char module[] = "LZMAPostEncode";
|
||||
LZMAState *sp = EncoderState(tif);
|
||||
lzma_ret ret;
|
||||
|
||||
sp->stream.avail_in = 0;
|
||||
do {
|
||||
ret = lzma_code(&sp->stream, LZMA_FINISH);
|
||||
switch (ret) {
|
||||
case LZMA_STREAM_END:
|
||||
case LZMA_OK:
|
||||
if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
|
||||
tif->tif_rawcc =
|
||||
tif->tif_rawdatasize - sp->stream.avail_out;
|
||||
TIFFFlushData1(tif);
|
||||
sp->stream.next_out = tif->tif_rawdata;
|
||||
sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
TIFFErrorExt(tif->tif_clientdata, module, "Liblzma error: %s",
|
||||
LZMAStrerror(ret));
|
||||
return 0;
|
||||
}
|
||||
} while (ret != LZMA_STREAM_END);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
LZMACleanup(TIFF* tif)
|
||||
{
|
||||
LZMAState* sp = LState(tif);
|
||||
|
||||
assert(sp != 0);
|
||||
|
||||
(void)TIFFPredictorCleanup(tif);
|
||||
|
||||
tif->tif_tagmethods.vgetfield = sp->vgetparent;
|
||||
tif->tif_tagmethods.vsetfield = sp->vsetparent;
|
||||
|
||||
lzma_end(&sp->stream);
|
||||
sp->state = 0;
|
||||
_TIFFfree(sp);
|
||||
tif->tif_data = NULL;
|
||||
|
||||
_TIFFSetDefaultCompressionState(tif);
|
||||
}
|
||||
|
||||
static int
|
||||
LZMAVSetField(TIFF* tif, uint32 tag, va_list ap)
|
||||
{
|
||||
LZMAState* sp = LState(tif);
|
||||
|
||||
switch (tag) {
|
||||
case TIFFTAG_LZMAPRESET:
|
||||
sp->preset = (int) va_arg(ap, int);
|
||||
if ( sp->state & LSTATE_INIT_ENCODE )
|
||||
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
|
||||
return 1;
|
||||
default:
|
||||
return (*sp->vsetparent)(tif, tag, ap);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
static int
|
||||
LZMAVGetField(TIFF* tif, uint32 tag, va_list ap)
|
||||
{
|
||||
LZMAState* sp = LState(tif);
|
||||
|
||||
switch (tag) {
|
||||
case TIFFTAG_LZMAPRESET:
|
||||
*va_arg(ap, int*) = sp->preset;
|
||||
break;
|
||||
default:
|
||||
return (*sp->vgetparent)(tif, tag, ap);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const TIFFField lzmaFields[] = {
|
||||
{ TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED,
|
||||
FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL },
|
||||
};
|
||||
|
||||
int
|
||||
TIFFInitLZMA(TIFF* tif, int scheme)
|
||||
{
|
||||
static const char module[] = "TIFFInitLZMA";
|
||||
LZMAState* sp;
|
||||
lzma_stream tmp_stream = LZMA_STREAM_INIT;
|
||||
|
||||
assert( scheme == COMPRESSION_LZMA );
|
||||
|
||||
/*
|
||||
* Merge codec-specific tag information.
|
||||
*/
|
||||
if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) {
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"Merging LZMA2 codec-specific tags failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate state block so tag methods have storage to record values.
|
||||
*/
|
||||
tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZMAState));
|
||||
if (tif->tif_data == NULL)
|
||||
goto bad;
|
||||
sp = LState(tif);
|
||||
memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream));
|
||||
|
||||
/*
|
||||
* Override parent get/set field methods.
|
||||
*/
|
||||
sp->vgetparent = tif->tif_tagmethods.vgetfield;
|
||||
tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */
|
||||
sp->vsetparent = tif->tif_tagmethods.vsetfield;
|
||||
tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */
|
||||
|
||||
/* Default values for codec-specific fields */
|
||||
sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */
|
||||
sp->check = LZMA_CHECK_NONE;
|
||||
sp->state = 0;
|
||||
|
||||
/* Data filters. So far we are using delta and LZMA2 filters only. */
|
||||
sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE;
|
||||
/*
|
||||
* The sample size in bytes seems to be reasonable distance for delta
|
||||
* filter.
|
||||
*/
|
||||
sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ?
|
||||
1 : tif->tif_dir.td_bitspersample / 8;
|
||||
sp->filters[0].id = LZMA_FILTER_DELTA;
|
||||
sp->filters[0].options = &sp->opt_delta;
|
||||
|
||||
lzma_lzma_preset(&sp->opt_lzma, sp->preset);
|
||||
sp->filters[1].id = LZMA_FILTER_LZMA2;
|
||||
sp->filters[1].options = &sp->opt_lzma;
|
||||
|
||||
sp->filters[2].id = LZMA_VLI_UNKNOWN;
|
||||
sp->filters[2].options = NULL;
|
||||
|
||||
/*
|
||||
* Install codec methods.
|
||||
*/
|
||||
tif->tif_fixuptags = LZMAFixupTags;
|
||||
tif->tif_setupdecode = LZMASetupDecode;
|
||||
tif->tif_predecode = LZMAPreDecode;
|
||||
tif->tif_decoderow = LZMADecode;
|
||||
tif->tif_decodestrip = LZMADecode;
|
||||
tif->tif_decodetile = LZMADecode;
|
||||
tif->tif_setupencode = LZMASetupEncode;
|
||||
tif->tif_preencode = LZMAPreEncode;
|
||||
tif->tif_postencode = LZMAPostEncode;
|
||||
tif->tif_encoderow = LZMAEncode;
|
||||
tif->tif_encodestrip = LZMAEncode;
|
||||
tif->tif_encodetile = LZMAEncode;
|
||||
tif->tif_cleanup = LZMACleanup;
|
||||
/*
|
||||
* Setup predictor setup.
|
||||
*/
|
||||
(void) TIFFPredictorInit(tif);
|
||||
return 1;
|
||||
bad:
|
||||
TIFFErrorExt(tif->tif_clientdata, module,
|
||||
"No space for LZMA2 state block");
|
||||
return 0;
|
||||
}
|
||||
#endif /* LZMA_SUPORT */
|
||||
|
||||
/* vim: set ts=8 sts=8 sw=8 noet: */
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tiff.h,v 1.65 2010-03-10 18:56:49 bfriesen Exp $ */
|
||||
/* $Id: tiff.h,v 1.66 2010-12-14 12:53:00 dron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
@ -187,6 +187,7 @@ typedef enum {
|
||||
#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */
|
||||
#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */
|
||||
#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */
|
||||
#define COMPRESSION_LZMA 34925 /* LZMA2 */
|
||||
#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */
|
||||
#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */
|
||||
#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */
|
||||
@ -567,6 +568,7 @@ typedef enum {
|
||||
#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/
|
||||
#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/
|
||||
#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */
|
||||
#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */
|
||||
|
||||
/*
|
||||
* EXIF tags
|
||||
|
22
man/tiffcp.1
22
man/tiffcp.1
@ -1,4 +1,4 @@
|
||||
.\" $Id: tiffcp.1,v 1.10 2010-06-03 17:01:02 fwarmerdam Exp $
|
||||
.\" $Id: tiffcp.1,v 1.11 2010-12-14 12:53:00 dron Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1988-1997 Sam Leffler
|
||||
.\" Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||
@ -83,10 +83,12 @@ for no compression,
|
||||
for PackBits compression,
|
||||
.B lzw
|
||||
for Lempel-Ziv & Welch compression,
|
||||
.B jpeg
|
||||
for baseline JPEG compression,
|
||||
.B zip
|
||||
for Deflate compression,
|
||||
.B lzma
|
||||
for LZMA compression,
|
||||
.B jpeg
|
||||
for baseline JPEG compression,
|
||||
.B g3
|
||||
for CCITT Group 3 (T.4) compression,
|
||||
and
|
||||
@ -118,16 +120,16 @@ list to the ``g3'' option; e.g.
|
||||
.B "\-c g3:2d:fill"
|
||||
to get 2D-encoded data with byte-aligned EOL codes.
|
||||
.IP
|
||||
.SM LZW
|
||||
.SM LZW, Deflate
|
||||
and
|
||||
.SM LZMA
|
||||
compression can be specified together with a
|
||||
.I predictor
|
||||
value.
|
||||
A predictor value of 2 causes
|
||||
each scanline of the output image to undergo horizontal
|
||||
differencing before it is encoded; a value
|
||||
of 1 forces each scanline to be encoded without differencing.
|
||||
LZW-specific options are specified by appending a ``:''-separated
|
||||
list to the ``lzw'' option; e.g.
|
||||
A predictor value of 2 causes each scanline of the output image to undergo
|
||||
horizontal differencing before it is encoded; a value of 1 forces each
|
||||
scanline to be encoded without differencing. LZW-specific options are
|
||||
specified by appending a ``:''-separated list to the ``lzw'' option; e.g.
|
||||
.B "\-c lzw:2"
|
||||
for
|
||||
.SM LZW
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: tiffcp.c,v 1.47 2010-06-25 12:24:13 dron Exp $ */
|
||||
/* $Id: tiffcp.c,v 1.48 2010-12-14 12:53:00 dron Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988-1997 Sam Leffler
|
||||
@ -371,6 +371,11 @@ processCompressOptions(char* opt)
|
||||
if (cp)
|
||||
defpredictor = atoi(cp+1);
|
||||
defcompression = COMPRESSION_ADOBE_DEFLATE;
|
||||
} else if (strneq(opt, "lzma", 4)) {
|
||||
char* cp = strchr(opt, ':');
|
||||
if (cp)
|
||||
defpredictor = atoi(cp+1);
|
||||
defcompression = COMPRESSION_LZMA;
|
||||
} else if (strneq(opt, "jbig", 4)) {
|
||||
defcompression = COMPRESSION_JBIG;
|
||||
} else if (strneq(opt, "sgilog", 6)) {
|
||||
@ -403,6 +408,7 @@ char* stuff[] = {
|
||||
"",
|
||||
" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
|
||||
" -c zip[:opts] compress output with deflate encoding",
|
||||
" -c lzma[:opts] compress output with LZMA encoding",
|
||||
" -c jpeg[:opts] compress output with JPEG encoding",
|
||||
" -c jbig compress output with ISO JBIG encoding",
|
||||
" -c packbits compress output with packbits encoding",
|
||||
@ -423,7 +429,7 @@ char* stuff[] = {
|
||||
" r output color image as RGB rather than YCbCr",
|
||||
"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality",
|
||||
"",
|
||||
"LZW and deflate options:",
|
||||
"LZW, Deflate (ZIP) and LZMA options:",
|
||||
" # set predictor value",
|
||||
"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
|
||||
"",
|
||||
@ -698,6 +704,7 @@ tiffcp(TIFF* in, TIFF* out)
|
||||
case COMPRESSION_LZW:
|
||||
case COMPRESSION_ADOBE_DEFLATE:
|
||||
case COMPRESSION_DEFLATE:
|
||||
case COMPRESSION_LZMA:
|
||||
if (predictor != (uint16)-1)
|
||||
TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user