Vastly improve 12-bit JPEG integration
The Gordian knot that 7fec5074f9 attempted
to unravel was caused by the fact that there are several
data-precision-dependent (JSAMPLE-dependent) fields and methods in the
exposed libjpeg API structures, and if you change the exposed libjpeg
API structures, then you have to change the whole API. If you change
the whole API, then you have to provide a whole new library to support
the new API, and that makes it difficult to support multiple data
precisions in the same application. (It is not impossible, as example.c
demonstrated, but using data-precision-dependent libjpeg API structures
would have made the cjpeg, djpeg, and jpegtran source code hard to read,
so it made more sense to build, install, and package 12-bit-specific
versions of those applications.)
Unfortunately, the result of that initial integration effort was an
unreadable and unmaintainable mess, which is a problem for a library
that is an ISO/ITU-T reference implementation. Also, as I dug into the
problem of lossless JPEG support, I realized that 16-bit lossless JPEG
images are a thing, and supporting yet another version of the libjpeg
API just for those images is untenable.
In fact, however, the touch points for JSAMPLE in the exposed libjpeg
API structures are minimal:
- The colormap and sample_range_limit fields in jpeg_decompress_struct
- The alloc_sarray() and access_virt_sarray() methods in
jpeg_memory_mgr
- jpeg_write_scanlines() and jpeg_write_raw_data()
- jpeg_read_scanlines() and jpeg_read_raw_data()
- jpeg_skip_scanlines() and jpeg_crop_scanline()
(This is subtle, but both of those functions use JSAMPLE-dependent
opaque structures behind the scenes.)
It is much more readable and maintainable to provide 12-bit-specific
versions of those six top-level API functions and to document that the
aforementioned methods and fields must be type-cast when using 12-bit
samples. Since that eliminates the need to provide a 12-bit-specific
version of the exposed libjpeg API structures, we can:
- Compile only the precision-dependent libjpeg modules (the
coefficient buffer controllers, the colorspace converters, the
DCT/IDCT managers, the main buffer controllers, the preprocessing
and postprocessing controller, the downsampler and upsamplers, the
quantizers, the integer DCT methods, and the IDCT methods) for
multiple data precisions.
- Introduce 12-bit-specific methods into the various internal
structures defined in jpegint.h.
- Create precision-independent data type, macro, method, field, and
function names that are prefixed by an underscore, and use an
internal header to convert those into precision-dependent data
type, macro, method, field, and function names, based on the value
of BITS_IN_JSAMPLE, when compiling the precision-dependent libjpeg
modules.
- Expose precision-dependent jinit*() functions for each of the
precision-dependent libjpeg modules.
- Abstract the precision-dependent libjpeg modules by calling the
appropriate precision-dependent jinit*() function, based on the
value of cinfo->data_precision, from top-level libjpeg API
functions.
This commit is contained in:
156
jquant1.c
156
jquant1.c
@@ -15,7 +15,8 @@
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglibint.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsamplecomp.h"
|
||||
|
||||
#ifdef QUANT_1PASS_SUPPORTED
|
||||
|
||||
@@ -66,7 +67,7 @@
|
||||
* worse, since the dither may be too much or too little at a given point.
|
||||
*
|
||||
* The normal calculation would be to form pixel value + dither, range-limit
|
||||
* this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
|
||||
* this to 0.._MAXJSAMPLE, and then index into the colorindex table as usual.
|
||||
* We can skip the separate range-limiting step by extending the colorindex
|
||||
* table in both directions.
|
||||
*/
|
||||
@@ -144,13 +145,13 @@ typedef struct {
|
||||
struct jpeg_color_quantizer pub; /* public fields */
|
||||
|
||||
/* Initially allocated colormap is saved here */
|
||||
JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
|
||||
_JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
|
||||
int sv_actual; /* number of entries in use */
|
||||
|
||||
JSAMPARRAY colorindex; /* Precomputed mapping for speed */
|
||||
_JSAMPARRAY colorindex; /* Precomputed mapping for speed */
|
||||
/* colorindex[i][j] = index of color closest to pixel value j in component i,
|
||||
* premultiplied as described above. Since colormap indexes must fit into
|
||||
* JSAMPLEs, the entries of this array will too.
|
||||
* _JSAMPLEs, the entries of this array will too.
|
||||
*/
|
||||
boolean is_padded; /* is the colorindex padded for odither? */
|
||||
|
||||
@@ -248,24 +249,24 @@ select_ncolors(j_decompress_ptr cinfo, int Ncolors[])
|
||||
LOCAL(int)
|
||||
output_value(j_decompress_ptr cinfo, int ci, int j, int maxj)
|
||||
/* Return j'th output value, where j will range from 0 to maxj */
|
||||
/* The output values must fall in 0..MAXJSAMPLE in increasing order */
|
||||
/* The output values must fall in 0.._MAXJSAMPLE in increasing order */
|
||||
{
|
||||
/* We always provide values 0 and MAXJSAMPLE for each component;
|
||||
/* We always provide values 0 and _MAXJSAMPLE for each component;
|
||||
* any additional values are equally spaced between these limits.
|
||||
* (Forcing the upper and lower values to the limits ensures that
|
||||
* dithering can't produce a color outside the selected gamut.)
|
||||
*/
|
||||
return (int)(((JLONG)j * MAXJSAMPLE + maxj / 2) / maxj);
|
||||
return (int)(((JLONG)j * _MAXJSAMPLE + maxj / 2) / maxj);
|
||||
}
|
||||
|
||||
|
||||
LOCAL(int)
|
||||
largest_input_value(j_decompress_ptr cinfo, int ci, int j, int maxj)
|
||||
/* Return largest input value that should map to j'th output value */
|
||||
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
|
||||
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= _MAXJSAMPLE */
|
||||
{
|
||||
/* Breakpoints are halfway between values returned by output_value */
|
||||
return (int)(((JLONG)(2 * j + 1) * MAXJSAMPLE + maxj) / (2 * maxj));
|
||||
return (int)(((JLONG)(2 * j + 1) * _MAXJSAMPLE + maxj) / (2 * maxj));
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +278,7 @@ LOCAL(void)
|
||||
create_colormap(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
JSAMPARRAY colormap; /* Created colormap */
|
||||
_JSAMPARRAY colormap; /* Created colormap */
|
||||
int total_colors; /* Number of distinct output colors */
|
||||
int i, j, k, nci, blksize, blkdist, ptr, val;
|
||||
|
||||
@@ -296,7 +297,7 @@ create_colormap(j_decompress_ptr cinfo)
|
||||
/* The colors are ordered in the map in standard row-major order, */
|
||||
/* i.e. rightmost (highest-indexed) color changes most rapidly. */
|
||||
|
||||
colormap = (*cinfo->mem->alloc_sarray)
|
||||
colormap = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)total_colors, (JDIMENSION)cinfo->out_color_components);
|
||||
|
||||
@@ -315,7 +316,7 @@ create_colormap(j_decompress_ptr cinfo)
|
||||
for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
|
||||
/* fill in blksize entries beginning at ptr */
|
||||
for (k = 0; k < blksize; k++)
|
||||
colormap[i][ptr + k] = (JSAMPLE)val;
|
||||
colormap[i][ptr + k] = (_JSAMPLE)val;
|
||||
}
|
||||
}
|
||||
blkdist = blksize; /* blksize of this color is blkdist of next */
|
||||
@@ -337,25 +338,25 @@ LOCAL(void)
|
||||
create_colorindex(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
JSAMPROW indexptr;
|
||||
_JSAMPROW indexptr;
|
||||
int i, j, k, nci, blksize, val, pad;
|
||||
|
||||
/* For ordered dither, we pad the color index tables by MAXJSAMPLE in
|
||||
* each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
|
||||
/* For ordered dither, we pad the color index tables by _MAXJSAMPLE in
|
||||
* each direction (input index values can be -_MAXJSAMPLE .. 2*_MAXJSAMPLE).
|
||||
* This is not necessary in the other dithering modes. However, we
|
||||
* flag whether it was done in case user changes dithering mode.
|
||||
*/
|
||||
if (cinfo->dither_mode == JDITHER_ORDERED) {
|
||||
pad = MAXJSAMPLE * 2;
|
||||
pad = _MAXJSAMPLE * 2;
|
||||
cquantize->is_padded = TRUE;
|
||||
} else {
|
||||
pad = 0;
|
||||
cquantize->is_padded = FALSE;
|
||||
}
|
||||
|
||||
cquantize->colorindex = (*cinfo->mem->alloc_sarray)
|
||||
cquantize->colorindex = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION)(MAXJSAMPLE + 1 + pad),
|
||||
(JDIMENSION)(_MAXJSAMPLE + 1 + pad),
|
||||
(JDIMENSION)cinfo->out_color_components);
|
||||
|
||||
/* blksize is number of adjacent repeated entries for a component */
|
||||
@@ -368,24 +369,24 @@ create_colorindex(j_decompress_ptr cinfo)
|
||||
|
||||
/* adjust colorindex pointers to provide padding at negative indexes. */
|
||||
if (pad)
|
||||
cquantize->colorindex[i] += MAXJSAMPLE;
|
||||
cquantize->colorindex[i] += _MAXJSAMPLE;
|
||||
|
||||
/* in loop, val = index of current output value, */
|
||||
/* and k = largest j that maps to current val */
|
||||
indexptr = cquantize->colorindex[i];
|
||||
val = 0;
|
||||
k = largest_input_value(cinfo, i, 0, nci - 1);
|
||||
for (j = 0; j <= MAXJSAMPLE; j++) {
|
||||
for (j = 0; j <= _MAXJSAMPLE; j++) {
|
||||
while (j > k) /* advance val if past boundary */
|
||||
k = largest_input_value(cinfo, i, ++val, nci - 1);
|
||||
/* premultiply so that no multiplication needed in main processing */
|
||||
indexptr[j] = (JSAMPLE)(val * blksize);
|
||||
indexptr[j] = (_JSAMPLE)(val * blksize);
|
||||
}
|
||||
/* Pad at both ends if necessary */
|
||||
if (pad)
|
||||
for (j = 1; j <= MAXJSAMPLE; j++) {
|
||||
for (j = 1; j <= _MAXJSAMPLE; j++) {
|
||||
indexptr[-j] = indexptr[0];
|
||||
indexptr[MAXJSAMPLE + j] = indexptr[MAXJSAMPLE];
|
||||
indexptr[_MAXJSAMPLE + j] = indexptr[_MAXJSAMPLE];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -406,16 +407,16 @@ make_odither_array(j_decompress_ptr cinfo, int ncolors)
|
||||
odither = (ODITHER_MATRIX_PTR)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(ODITHER_MATRIX));
|
||||
/* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
|
||||
/* The inter-value distance for this color is _MAXJSAMPLE/(ncolors-1).
|
||||
* Hence the dither value for the matrix cell with fill order f
|
||||
* (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
|
||||
* (f=0..N-1) should be (N-1-2*f)/(2*N) * _MAXJSAMPLE/(ncolors-1).
|
||||
* On 16-bit-int machine, be careful to avoid overflow.
|
||||
*/
|
||||
den = 2 * ODITHER_CELLS * ((JLONG)(ncolors - 1));
|
||||
for (j = 0; j < ODITHER_SIZE; j++) {
|
||||
for (k = 0; k < ODITHER_SIZE; k++) {
|
||||
num = ((JLONG)(ODITHER_CELLS - 1 -
|
||||
2 * ((int)base_dither_matrix[j][k]))) * MAXJSAMPLE;
|
||||
2 * ((int)base_dither_matrix[j][k]))) * _MAXJSAMPLE;
|
||||
/* Ensure round towards zero despite C's lack of consistency
|
||||
* about rounding negative values in integer division...
|
||||
*/
|
||||
@@ -460,14 +461,14 @@ create_odither_tables(j_decompress_ptr cinfo)
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
color_quantize(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* General case, no dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
JSAMPARRAY colorindex = cquantize->colorindex;
|
||||
_JSAMPARRAY colorindex = cquantize->colorindex;
|
||||
register int pixcode, ci;
|
||||
register JSAMPROW ptrin, ptrout;
|
||||
register _JSAMPROW ptrin, ptrout;
|
||||
int row;
|
||||
JDIMENSION col;
|
||||
JDIMENSION width = cinfo->output_width;
|
||||
@@ -481,23 +482,23 @@ color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
pixcode += colorindex[ci][*ptrin++];
|
||||
}
|
||||
*ptrout++ = (JSAMPLE)pixcode;
|
||||
*ptrout++ = (_JSAMPLE)pixcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
color_quantize3(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* Fast path for out_color_components==3, no dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
register int pixcode;
|
||||
register JSAMPROW ptrin, ptrout;
|
||||
JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
register _JSAMPROW ptrin, ptrout;
|
||||
_JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
_JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
_JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
int row;
|
||||
JDIMENSION col;
|
||||
JDIMENSION width = cinfo->output_width;
|
||||
@@ -509,21 +510,21 @@ color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
pixcode = colorindex0[*ptrin++];
|
||||
pixcode += colorindex1[*ptrin++];
|
||||
pixcode += colorindex2[*ptrin++];
|
||||
*ptrout++ = (JSAMPLE)pixcode;
|
||||
*ptrout++ = (_JSAMPLE)pixcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
quantize_ord_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* General case, with ordered dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
register JSAMPROW input_ptr;
|
||||
register JSAMPROW output_ptr;
|
||||
JSAMPROW colorindex_ci;
|
||||
register _JSAMPROW input_ptr;
|
||||
register _JSAMPROW output_ptr;
|
||||
_JSAMPROW colorindex_ci;
|
||||
int *dither; /* points to active row of dither matrix */
|
||||
int row_index, col_index; /* current indexes into dither matrix */
|
||||
int nc = cinfo->out_color_components;
|
||||
@@ -534,7 +535,7 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
/* Initialize output values to 0 so can process components separately */
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(JSAMPLE)));
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(_JSAMPLE)));
|
||||
row_index = cquantize->row_index;
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
input_ptr = input_buf[row] + ci;
|
||||
@@ -544,11 +545,11 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
col_index = 0;
|
||||
|
||||
for (col = width; col > 0; col--) {
|
||||
/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
|
||||
/* Form pixel value + dither, range-limit to 0.._MAXJSAMPLE,
|
||||
* select output value, accumulate into output code for this pixel.
|
||||
* Range-limiting need not be done explicitly, as we have extended
|
||||
* the colorindex table to produce the right answers for out-of-range
|
||||
* inputs. The maximum dither is +- MAXJSAMPLE; this sets the
|
||||
* inputs. The maximum dither is +- _MAXJSAMPLE; this sets the
|
||||
* required amount of padding.
|
||||
*/
|
||||
*output_ptr +=
|
||||
@@ -566,17 +567,17 @@ quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
quantize3_ord_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* Fast path for out_color_components==3, with ordered dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
register int pixcode;
|
||||
register JSAMPROW input_ptr;
|
||||
register JSAMPROW output_ptr;
|
||||
JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
register _JSAMPROW input_ptr;
|
||||
register _JSAMPROW output_ptr;
|
||||
_JSAMPROW colorindex0 = cquantize->colorindex[0];
|
||||
_JSAMPROW colorindex1 = cquantize->colorindex[1];
|
||||
_JSAMPROW colorindex2 = cquantize->colorindex[2];
|
||||
int *dither0; /* points to active row of dither matrix */
|
||||
int *dither1;
|
||||
int *dither2;
|
||||
@@ -598,7 +599,7 @@ quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
pixcode = colorindex0[(*input_ptr++) + dither0[col_index]];
|
||||
pixcode += colorindex1[(*input_ptr++) + dither1[col_index]];
|
||||
pixcode += colorindex2[(*input_ptr++) + dither2[col_index]];
|
||||
*output_ptr++ = (JSAMPLE)pixcode;
|
||||
*output_ptr++ = (_JSAMPLE)pixcode;
|
||||
col_index = (col_index + 1) & ODITHER_MASK;
|
||||
}
|
||||
row_index = (row_index + 1) & ODITHER_MASK;
|
||||
@@ -608,8 +609,8 @@ quantize3_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
quantize_fs_dither(j_decompress_ptr cinfo, _JSAMPARRAY input_buf,
|
||||
_JSAMPARRAY output_buf, int num_rows)
|
||||
/* General case, with Floyd-Steinberg dithering */
|
||||
{
|
||||
my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize;
|
||||
@@ -619,10 +620,10 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
LOCFSERROR bnexterr; /* error for below/next col */
|
||||
LOCFSERROR delta;
|
||||
register FSERRPTR errorptr; /* => fserrors[] at column before current */
|
||||
register JSAMPROW input_ptr;
|
||||
register JSAMPROW output_ptr;
|
||||
JSAMPROW colorindex_ci;
|
||||
JSAMPROW colormap_ci;
|
||||
register _JSAMPROW input_ptr;
|
||||
register _JSAMPROW output_ptr;
|
||||
_JSAMPROW colorindex_ci;
|
||||
_JSAMPROW colormap_ci;
|
||||
int pixcode;
|
||||
int nc = cinfo->out_color_components;
|
||||
int dir; /* 1 for left-to-right, -1 for right-to-left */
|
||||
@@ -631,12 +632,12 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
int row;
|
||||
JDIMENSION col;
|
||||
JDIMENSION width = cinfo->output_width;
|
||||
JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
_JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
|
||||
SHIFT_TEMPS
|
||||
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
/* Initialize output values to 0 so can process components separately */
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(JSAMPLE)));
|
||||
jzero_far((void *)output_buf[row], (size_t)(width * sizeof(_JSAMPLE)));
|
||||
for (ci = 0; ci < nc; ci++) {
|
||||
input_ptr = input_buf[row] + ci;
|
||||
output_ptr = output_buf[row];
|
||||
@@ -670,15 +671,15 @@ quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
||||
* Note: errorptr points to *previous* column's array entry.
|
||||
*/
|
||||
cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
|
||||
/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
|
||||
* The maximum error is +- MAXJSAMPLE; this sets the required size
|
||||
/* Form pixel value + error, and range-limit to 0.._MAXJSAMPLE.
|
||||
* The maximum error is +- _MAXJSAMPLE; this sets the required size
|
||||
* of the range_limit array.
|
||||
*/
|
||||
cur += *input_ptr;
|
||||
cur = range_limit[cur];
|
||||
/* Select output value, accumulate into output code for this pixel */
|
||||
pixcode = colorindex_ci[cur];
|
||||
*output_ptr += (JSAMPLE)pixcode;
|
||||
*output_ptr += (_JSAMPLE)pixcode;
|
||||
/* Compute actual representation error at this pixel */
|
||||
/* Note: we can do this even though we don't have the final */
|
||||
/* pixel code, because the colormap is orthogonal. */
|
||||
@@ -745,22 +746,22 @@ start_pass_1_quant(j_decompress_ptr cinfo, boolean is_pre_scan)
|
||||
int i;
|
||||
|
||||
/* Install my colormap. */
|
||||
cinfo->colormap = cquantize->sv_colormap;
|
||||
cinfo->colormap = (JSAMPARRAY)cquantize->sv_colormap;
|
||||
cinfo->actual_number_of_colors = cquantize->sv_actual;
|
||||
|
||||
/* Initialize for desired dithering mode. */
|
||||
switch (cinfo->dither_mode) {
|
||||
case JDITHER_NONE:
|
||||
if (cinfo->out_color_components == 3)
|
||||
cquantize->pub.color_quantize = color_quantize3;
|
||||
cquantize->pub._color_quantize = color_quantize3;
|
||||
else
|
||||
cquantize->pub.color_quantize = color_quantize;
|
||||
cquantize->pub._color_quantize = color_quantize;
|
||||
break;
|
||||
case JDITHER_ORDERED:
|
||||
if (cinfo->out_color_components == 3)
|
||||
cquantize->pub.color_quantize = quantize3_ord_dither;
|
||||
cquantize->pub._color_quantize = quantize3_ord_dither;
|
||||
else
|
||||
cquantize->pub.color_quantize = quantize_ord_dither;
|
||||
cquantize->pub._color_quantize = quantize_ord_dither;
|
||||
cquantize->row_index = 0; /* initialize state for ordered dither */
|
||||
/* If user changed to ordered dither from another mode,
|
||||
* we must recreate the color index table with padding.
|
||||
@@ -773,7 +774,7 @@ start_pass_1_quant(j_decompress_ptr cinfo, boolean is_pre_scan)
|
||||
create_odither_tables(cinfo);
|
||||
break;
|
||||
case JDITHER_FS:
|
||||
cquantize->pub.color_quantize = quantize_fs_dither;
|
||||
cquantize->pub._color_quantize = quantize_fs_dither;
|
||||
cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
|
||||
/* Allocate Floyd-Steinberg workspace if didn't already. */
|
||||
if (cquantize->fserrors[0] == NULL)
|
||||
@@ -818,10 +819,13 @@ new_color_map_1_quant(j_decompress_ptr cinfo)
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_1pass_quantizer(j_decompress_ptr cinfo)
|
||||
_jinit_1pass_quantizer(j_decompress_ptr cinfo)
|
||||
{
|
||||
my_cquantize_ptr cquantize;
|
||||
|
||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
||||
|
||||
cquantize = (my_cquantize_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
|
||||
sizeof(my_cquantizer));
|
||||
@@ -835,9 +839,9 @@ jinit_1pass_quantizer(j_decompress_ptr cinfo)
|
||||
/* Make sure my internal arrays won't overflow */
|
||||
if (cinfo->out_color_components > MAX_Q_COMPS)
|
||||
ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
|
||||
/* Make sure colormap indexes can be represented by JSAMPLEs */
|
||||
if (cinfo->desired_number_of_colors > (MAXJSAMPLE + 1))
|
||||
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE + 1);
|
||||
/* Make sure colormap indexes can be represented by _JSAMPLEs */
|
||||
if (cinfo->desired_number_of_colors > (_MAXJSAMPLE + 1))
|
||||
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, _MAXJSAMPLE + 1);
|
||||
|
||||
/* Create the colormap and color index table. */
|
||||
create_colormap(cinfo);
|
||||
|
||||
Reference in New Issue
Block a user