chromium/third_party/libjpeg_turbo/jquant1.c

/*
 * jquant1.c
 *
 * This file was part of the Independent JPEG Group's software:
 * Copyright (C) 1991-1996, Thomas G. Lane.
 * libjpeg-turbo Modifications:
 * Copyright (C) 2009, 2015, D. R. Commander.
 * For conditions of distribution and use, see the accompanying README.ijg
 * file.
 *
 * This file contains 1-pass color quantization (color mapping) routines.
 * These routines provide mapping to a fixed color map using equally spaced
 * color values.  Optional Floyd-Steinberg or ordered dithering is available.
 */

#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"

#ifdef QUANT_1PASS_SUPPORTED


/*
 * The main purpose of 1-pass quantization is to provide a fast, if not very
 * high quality, colormapped output capability.  A 2-pass quantizer usually
 * gives better visual quality; however, for quantized grayscale output this
 * quantizer is perfectly adequate.  Dithering is highly recommended with this
 * quantizer, though you can turn it off if you really want to.
 *
 * In 1-pass quantization the colormap must be chosen in advance of seeing the
 * image.  We use a map consisting of all combinations of Ncolors[i] color
 * values for the i'th component.  The Ncolors[] values are chosen so that
 * their product, the total number of colors, is no more than that requested.
 * (In most cases, the product will be somewhat less.)
 *
 * Since the colormap is orthogonal, the representative value for each color
 * component can be determined without considering the other components;
 * then these indexes can be combined into a colormap index by a standard
 * N-dimensional-array-subscript calculation.  Most of the arithmetic involved
 * can be precalculated and stored in the lookup table colorindex[].
 * colorindex[i][j] maps pixel value j in component i to the nearest
 * representative value (grid plane) for that component; this index is
 * multiplied by the array stride for component i, so that the
 * index of the colormap entry closest to a given pixel value is just
 *    sum( colorindex[component-number][pixel-component-value] )
 * Aside from being fast, this scheme allows for variable spacing between
 * representative values with no additional lookup cost.
 *
 * If gamma correction has been applied in color conversion, it might be wise
 * to adjust the color grid spacing so that the representative colors are
 * equidistant in linear space.  At this writing, gamma correction is not
 * implemented by jdcolor, so nothing is done here.
 */


/* Declarations for ordered dithering.
 *
 * We use a standard 16x16 ordered dither array.  The basic concept of ordered
 * dithering is described in many references, for instance Dale Schumacher's
 * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
 * In place of Schumacher's comparisons against a "threshold" value, we add a
 * "dither" value to the input pixel and then round the result to the nearest
 * output value.  The dither value is equivalent to (0.5 - threshold) times
 * the distance between output values.  For ordered dithering, we assume that
 * the output colors are equally spaced; if not, results will probably be
 * 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.
 * We can skip the separate range-limiting step by extending the colorindex
 * table in both directions.
 */

#define ODITHER_SIZE
/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
#define ODITHER_CELLS
#define ODITHER_MASK

ODITHER_MATRIX;
ODITHER_MATRIX_PTR;

static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] =;


/* Declarations for Floyd-Steinberg dithering.
 *
 * Errors are accumulated into the array fserrors[], at a resolution of
 * 1/16th of a pixel count.  The error at a given pixel is propagated
 * to its not-yet-processed neighbors using the standard F-S fractions,
 *              ...     (here)  7/16
 *              3/16    5/16    1/16
 * We work left-to-right on even rows, right-to-left on odd rows.
 *
 * We can get away with a single array (holding one row's worth of errors)
 * by using it to store the current row's errors at pixel columns not yet
 * processed, but the next row's errors at columns already processed.  We
 * need only a few extra variables to hold the errors immediately around the
 * current column.  (If we are lucky, those variables are in registers, but
 * even if not, they're probably cheaper to access than array elements are.)
 *
 * The fserrors[] array is indexed [component#][position].
 * We provide (#columns + 2) entries per component; the extra entry at each
 * end saves us from special-casing the first and last pixels.
 */

#if BITS_IN_JSAMPLE == 8
FSERROR;          /* 16 bits should be enough */
LOCFSERROR;         /* use 'int' for calculation temps */
#else
typedef JLONG FSERROR;          /* may need more than 16 bits */
typedef JLONG LOCFSERROR;       /* be sure calculation temps are big enough */
#endif

FSERRPTR;      /* pointer to error array */


/* Private subobject */

#define MAX_Q_COMPS

my_cquantizer;

my_cquantize_ptr;


/*
 * Policy-making subroutines for create_colormap and create_colorindex.
 * These routines determine the colormap to be used.  The rest of the module
 * only assumes that the colormap is orthogonal.
 *
 *  * select_ncolors decides how to divvy up the available colors
 *    among the components.
 *  * output_value defines the set of representative values for a component.
 *  * largest_input_value defines the mapping from input values to
 *    representative values for a component.
 * Note that the latter two routines may impose different policies for
 * different components, though this is not currently done.
 */


LOCAL(int)
select_ncolors(j_decompress_ptr cinfo, int Ncolors[])
/* Determine allocation of desired colors to components, */
/* and fill in Ncolors[] array to indicate choice. */
/* Return value is total number of colors (product of Ncolors[] values). */
{}


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 */
{}


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 */
{}


/*
 * Create the colormap.
 */

LOCAL(void)
create_colormap(j_decompress_ptr cinfo)
{}


/*
 * Create the color index table.
 */

LOCAL(void)
create_colorindex(j_decompress_ptr cinfo)
{}


/*
 * Create an ordered-dither array for a component having ncolors
 * distinct output values.
 */

LOCAL(ODITHER_MATRIX_PTR)
make_odither_array(j_decompress_ptr cinfo, int ncolors)
{}


/*
 * Create the ordered-dither tables.
 * Components having the same number of representative colors may
 * share a dither table.
 */

LOCAL(void)
create_odither_tables(j_decompress_ptr cinfo)
{}


/*
 * Map some rows of pixels to the output colormapped representation.
 */

METHODDEF(void)
color_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
               JSAMPARRAY output_buf, int num_rows)
/* General case, no dithering */
{}


METHODDEF(void)
color_quantize3(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
                JSAMPARRAY output_buf, int num_rows)
/* Fast path for out_color_components==3, no dithering */
{}


METHODDEF(void)
quantize_ord_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
                    JSAMPARRAY output_buf, int num_rows)
/* General case, with ordered dithering */
{}


METHODDEF(void)
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 */
{}


METHODDEF(void)
quantize_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
                   JSAMPARRAY output_buf, int num_rows)
/* General case, with Floyd-Steinberg dithering */
{}


/*
 * Allocate workspace for Floyd-Steinberg errors.
 */

LOCAL(void)
alloc_fs_workspace(j_decompress_ptr cinfo)
{}


/*
 * Initialize for one-pass color quantization.
 */

METHODDEF(void)
start_pass_1_quant(j_decompress_ptr cinfo, boolean is_pre_scan)
{}


/*
 * Finish up at the end of the pass.
 */

METHODDEF(void)
finish_pass_1_quant(j_decompress_ptr cinfo)
{}


/*
 * Switch to a new external colormap between output passes.
 * Shouldn't get to this module!
 */

METHODDEF(void)
new_color_map_1_quant(j_decompress_ptr cinfo)
{}


/*
 * Module initialization routine for 1-pass color quantization.
 */

GLOBAL(void)
jinit_1pass_quantizer(j_decompress_ptr cinfo)
{}

#endif /* QUANT_1PASS_SUPPORTED */