2014.12.30 17:31 "[Tiff] [RFC PATCH] Supporting arithmetic encoding for JPEG compressed TIFF", by Even Rouault
Hi,
The proposed attached patch enables the use of arithmetic coding for JPEG
compressed TIFFs. Arithmetic coding is allowed by the TechNote ( http://www.remotesensing.org/libtiff/TIFFTechNote2.html ), although an
extension. Can lead to ~10% smaller files w.r.t optimized huffman coding (your
mileage may vary), all other things equals.
It needs runtime support of the JPEG library, which wasn't available in IJG
libjpeg because of the patents that were still inforce at the time of libjpeg development, but it is now available in libjpeg-turbo (which is now used as
the default libjpeg in some recent Linux distributions) and its derivatives.
Regarding the approach, I've opted for a new pseudo-tag, TIFFTAG_JPEGCODING:
#define TIFFTAG_JPEGCODING 65564 /* Coding algorithm for JPEG
compression */
#define JPEGCODING_HUFFMAN 0 /* Huffman coding (default) */
#define JPEGCODING_ARITHMETIC 1 /* Arithmetic coding */
Opinions?
(My inital approach was to add a new flag value JPEGTABLESMODE_ARITHMETIC = 4
to TIFFTAG_JPEGTABLESMODE but this was a bit awkward as there are no
arithmetic tables to be emitted in JpegTables tag.)
Even
--
Spatialys - Geospatial professional services
http://www.spatialys.com
Index: tif_jpeg.c
===================================================================
--- tif_jpeg.c (révision 28266)
+++ tif_jpeg.c (copie de travail)
@@ -173,6 +173,7 @@
int jpegquality; /* Compression quality level */
int jpegcolormode; /* Auto RGB<=>YCbCr convert? */
int jpegtablesmode; /* What to put in JPEGTables */
+ int jpegcoding; /* Huffman or arithmetic coding ? */
int ycbcrsampling_fetched;
} JPEGState;
@@ -192,7 +193,8 @@
{ TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL },
{ TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
{ TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL },
- { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL } + { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }, + { TIFFTAG_JPEGCODING, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }
};
/*
@@ -1774,8 +1776,12 @@
unsuppress_quant_table(sp, 0);
unsuppress_quant_table(sp, 1);
}
- if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
+ if (sp->jpegcoding == JPEGCODING_ARITHMETIC )
{
+ sp->cinfo.c.arith_code = TRUE;
+ }
+ else if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
+ {
/* Explicit suppression is only needed if we did not go through the */
/* prepare_JPEGTables() code path, which may be the case if updating */
/* an existing file */
@@ -2106,6 +2112,12 @@
sp->ycbcrsampling_fetched = 1;
/* should we be recomputing upsampling info here? */
return (*sp->vsetparent)(tif, tag, ap);
+ case TIFFTAG_JPEGCODING:
+ sp->jpegcoding = (int) va_arg(ap, int);
+ /* Disable huffman tables for arithmetic coding */
+ if( sp->jpegcoding == JPEGCODING_ARITHMETIC )
+ sp->jpegtablesmode &= ~JPEGTABLESMODE_HUFF;
+ return (1); /* pseudo tag */
default:
return (*sp->vsetparent)(tif, tag, ap);
}
@@ -2141,6 +2153,9 @@
case TIFFTAG_JPEGTABLESMODE:
*va_arg(ap, int*) = sp->jpegtablesmode;
break;
+ case TIFFTAG_JPEGCODING:
+ *va_arg(ap, int*) = sp->jpegcoding;
+ break;
default:
return (*sp->vgetparent)(tif, tag, ap);
}
@@ -2289,6 +2304,7 @@
sp->jpegquality = 75; /* Default IJG quality */
sp->jpegcolormode = JPEGCOLORMODE_RAW;
sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
+ sp->jpegcoding = JPEGCODING_HUFFMAN;
sp->ycbcrsampling_fetched = 0;
/*
Index: tiff.h
===================================================================
--- tiff.h (révision 28243)
+++ tiff.h (copie de travail)
@@ -603,6 +603,9 @@
#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */
#define PERSAMPLE_MERGED 0 /* present as a single value */
#define PERSAMPLE_MULTI 1 /* present as multiple values */
+#define TIFFTAG_JPEGCODING 65564 /* Coding algorithm for JPEG compression */
+#define JPEGCODING_HUFFMAN 0 /* Huffman coding (default) */
+#define JPEGCODING_ARITHMETIC 1 /* Arithmetic coding */
/*
* EXIF tags