/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains 2-pass color quantization (color mapping) routines.
* These routines provide selection of a custom color map for an image,
* followed by mapping of the image to that color map, with optional
* Floyd-Steinberg dithering.
* It is also possible to use just the second pass to map to an arbitrary
* externally-given color map.
*
* Note: ordered dithering is not supported, since there isn't any fast
* way to compute intercolor distances; it's unclear that ordered dither's
* fundamental assumptions even hold with an irregularly spaced color map.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#ifdef QUANT_2PASS_SUPPORTED
/*
* This module implements the well-known Heckbert paradigm for color
* quantization. Most of the ideas used here can be traced back to
* Heckbert's seminal paper
* Heckbert, Paul. "Color Image Quantization for Frame Buffer Display",
* Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
*
* In the first pass over the image, we accumulate a histogram showing the
* usage count of each possible color. To keep the histogram to a reasonable
* size, we reduce the precision of the input; typical practice is to retain
* 5 or 6 bits per color, so that 8 or 4 different input values are counted
* in the same histogram cell.
*
* Next, the color-selection step begins with a box representing the whole
* color space, and repeatedly splits the "largest" remaining box until we
* have as many boxes as desired colors. Then the mean color in each
* remaining box becomes one of the possible output colors.
*
* The second pass over the image maps each input pixel to the closest output
* color (optionally after applying a Floyd-Steinberg dithering correction).
* This mapping is logically trivial, but making it go fast enough requires
* considerable care.
*
* Heckbert-style quantizers vary a good deal in their policies for choosing
* the "largest" box and deciding where to cut it. The particular policies
* used here have proved out well in experimental comparisons, but better ones
* may yet be found.
*
* In earlier versions of the IJG code, this module quantized in YCbCr color
* space, processing the raw upsampled data without a color conversion step.
* This allowed the color conversion math to be done only once per colormap
* entry, not once per pixel. However, that optimization precluded other
* useful optimizations (such as merging color conversion with upsampling)
* and it also interfered with desired capabilities such as quantizing to an
* externally-supplied colormap. We have therefore abandoned that approach.
* The present code works in the post-conversion color space, typically RGB.
*
* To improve the visual quality of the results, we actually work in scaled
* RGB space, giving G distances more weight than R, and R in turn more than
* B. To do everything in integer math, we must use integer scale factors.
* The 2/3/1 scale factors used here correspond loosely to the relative
* weights of the colors in the NTSC grayscale equation.
* If you want to use this code to quantize a non-RGB color space, you'll
* probably need to change these scale factors.
*/
/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
* in jmorecfg.h. As the code stands, it will do the right thing for R,G,B
* and B,G,R orders. If you define some other weird order in jmorecfg.h,
* you'll get compile errors until you extend this logic. In that case
* you'll probably want to tweak the histogram sizes too.
*/
#if RGB_RED == 0
#endif
#if RGB_BLUE == 0
#endif
#if RGB_GREEN == 1
#endif
#if RGB_RED == 2
#endif
#if RGB_BLUE == 2
#endif
/*
* First we have the histogram data structure and routines for creating it.
*
* The number of bits of precision can be adjusted by changing these symbols.
* We recommend keeping 6 bits for G and 5 each for R and B.
* If you have plenty of memory and cycles, 6 bits all around gives marginally
* better results; if you are short of memory, 5 bits all around will save
* some space but degrade the results.
* To maintain a fully accurate histogram, we'd need to allocate a "long"
* (preferably unsigned long) for each cell. In practice this is overkill;
* we can get by with 16 bits per cell. Few of the cell counts will overflow,
* and clamping those that do overflow to the maximum value will give close-
* enough results. This reduces the recommended histogram size from 256Kb
* to 128Kb, which is a useful savings on PC-class machines.
* (In the second pass the histogram space is re-used for pixel mapping data;
* in that capacity, each cell must be able to store zero to the number of
* Since the JPEG code is intended to run in small memory model on 80x86
* machines, we can't just allocate the histogram in one chunk. Instead
* of a true 3-D array, we use a row of pointers to 2-D arrays. Each
* pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
* each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that
* on 80x86 machines, the pointer row is in near memory but the actual
* arrays are in far memory (same arrangement as we use for image arrays).
*/
/* These will do the right thing for either R,G,B or B,G,R color order,
* but you may not like the results for other color orders.
*/
/* Number of elements along histogram axes. */
/* These are the amounts to shift an input value to get a histogram index. */
/* 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 has (#columns + 2) entries; the extra entry at
* each end saves us from special-casing the first and last pixels.
* Each entry is three values long, one value for each color component.
*
* Note: on a wide image, we might not have enough room in a PC's near data
* segment to hold the error array; so it is allocated with alloc_large.
*/
#if BITS_IN_JSAMPLE == 8
#else
#endif
/* Private subobject */
typedef struct {
/* Space for the eventually created colormap is stashed here */
/* Variables for accumulating image statistics */
/* Variables for Floyd-Steinberg dithering */
/*
* Prescan some rows of pixels.
* In this module the prescan simply updates the histogram, which has been
* initialized to zeroes by start_pass.
* An output_buf parameter is required by the method signature, but no data
* is actually output (in fact the buffer controller is probably passing a
* NULL pointer).
*/
METHODDEF(void)
{
int row;
/* get pixel value and index into the histogram */
/* increment, check for overflow and undo increment if so. */
if (++(*histp) <= 0)
(*histp)--;
ptr += 3;
}
}
}
/*
* Next we have the really interesting routines: selection of a colormap
* given the completed histogram.
* These routines work with a list of "boxes", each representing a rectangular
* subset of the input color space (to histogram precision).
*/
typedef struct {
/* The bounds of the box (inclusive); expressed as histogram indexes */
/* The volume (actually 2-norm) of the box */
/* The number of nonzero histogram cells within this box */
long colorcount;
} box;
/* Find the splittable box with the largest color population */
/* Returns NULL if no splittable boxes remain */
{
register int i;
register long maxc = 0;
}
}
return which;
}
/* Find the splittable box with the largest (scaled) volume */
/* Returns NULL if no splittable boxes remain */
{
register int i;
}
}
return which;
}
LOCAL(void)
/* and recompute its volume and population */
{
long ccount;
if (*histp++ != 0) {
goto have_c0min;
}
}
if (*histp++ != 0) {
goto have_c0max;
}
}
if (*histp++ != 0) {
goto have_c1min;
}
}
if (*histp++ != 0) {
goto have_c1max;
}
}
if (*histp != 0) {
goto have_c2min;
}
}
if (*histp != 0) {
goto have_c2max;
}
}
/* Update box volume.
* We use 2-norm rather than real volume here; this biases the method
* against making long narrow boxes, and it has the side benefit that
* a box is splittable iff norm > 0.
* Since the differences are expressed in histogram-cell units,
* we have to shift back to JSAMPLE units to get consistent distances;
* after which, we scale according to the selected distance scale factors.
*/
/* Now scan remaining volume of box and compute population */
ccount = 0;
if (*histp != 0) {
ccount++;
}
}
}
LOCAL(int)
int desired_colors)
/* Repeatedly select and split the largest box until we have enough boxes */
{
int n,lb;
while (numboxes < desired_colors) {
/* Select box to split.
* Current algorithm: by population for first half, then by volume.
*/
} else {
}
break;
/* Copy the color bounds to the new box. */
/* Choose which axis to split the box on.
* Current algorithm: longest scaled axis.
* See notes in update_box about scaling distances.
*/
/* We want to break any ties in favor of green, then red, blue last.
* This code does the right thing for R,G,B or B,G,R color orders only.
*/
#if RGB_RED == 0
#else
#endif
/* Choose split point along selected axis, and update box bounds.
* Current algorithm: split at halfway point.
* (Since the box has been shrunk to minimum volume,
* any split will produce two nonempty subboxes.)
* Note that lb value is max for lower box, so must be < old max.
*/
switch (n) {
case 0:
break;
case 1:
break;
case 2:
break;
}
/* Update stats for boxes */
numboxes++;
}
return numboxes;
}
LOCAL(void)
/* Compute representative color for a box, put it in colormap[icolor] */
{
/* Current algorithm: mean weighted by pixels (not colors) */
/* Note it is important to get the rounding correct! */
long count;
long total = 0;
long c0total = 0;
long c1total = 0;
long c2total = 0;
}
}
}
}
LOCAL(void)
/* Master routine for color selection */
{
int numboxes;
int i;
/* Allocate workspace for box list */
/* Initialize one box containing whole space */
numboxes = 1;
/* Shrink it to actually-used volume and set its statistics */
/* Perform median-cut to produce final box list */
/* Compute the representative color for each box, fill colormap */
for (i = 0; i < numboxes; i++)
}
/*
* These routines are concerned with the time-critical task of mapping input
* colors to the nearest color in the selected colormap.
*
* We re-use the histogram space as an "inverse color map", essentially a
* cache for the results of nearest-color searches. All colors within a
* histogram cell will be mapped to the same colormap entry, namely the one
* closest to the cell's center. This may not be quite the closest entry to
* the actual input color, but it's almost as good. A zero in the cache
* indicates we haven't found the nearest color for that cell yet; the array
* is cleared to zeroes before starting the mapping pass. When we find the
* nearest color for a cell, its colormap index plus one is recorded in the
* cache for future use. The pass2 scanning routines call fill_inverse_cmap
* when they need to use an unfilled entry in the cache.
*
* Our method of efficiently finding nearest colors is based on the "locally
* sorted search" idea described by Heckbert and on the incremental distance
* calculation described by Spencer W. Thomas in chapter III.1 of Graphics
* Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that
* the distances from a given colormap entry to each cell of the histogram can
* be computed quickly using an incremental method: the differences between
* distances to adjacent cells themselves differ by a constant. This allows a
* fairly fast implementation of the "brute force" approach of computing the
* distance from every colormap entry to every histogram cell. Unfortunately,
* it needs a work array to hold the best-distance-so-far for each histogram
* cell (because the inner loop has to be over cells, not colormap entries).
* The work array elements have to be INT32s, so the work array would need
* 256Kb at our recommended precision. This is not feasible in DOS machines.
*
* To get around these problems, we apply Thomas' method to compute the
* nearest colors for only the cells within a small subbox of the histogram.
* The work array need be only as big as the subbox, so the memory usage
* problem is solved. Furthermore, we need not fill subboxes that are never
* referenced in pass2; many images use only part of the color gamut, so a
* fair amount of work is saved. An additional advantage of this
* approach is that we can apply Heckbert's locality criterion to quickly
* eliminate colormap entries that are far away from the subbox; typically
* three-fourths of the colormap entries are rejected by Heckbert's criterion,
* and we need not compute their distances to individual cells in the subbox.
* The speed of this approach is heavily influenced by the subbox size: too
* small means too much overhead, too big loses because Heckbert's criterion
* can't eliminate as many colormap entries. Empirically the best subbox
* size seems to be about 1/512th of the histogram (1/8th in each direction).
*
* Thomas' article also describes a refined method which is asymptotically
* faster than the brute-force method, but it is also far more complex and
* cannot efficiently be applied to small subboxes. It is therefore not
* useful for programs intended to be portable to DOS machines. On machines
* with plenty of memory, filling the whole histogram in one shot with Thomas'
* refined method might be faster than the present code --- but then again,
* it might not be any faster, and it's certainly more complicated.
*/
/* log2(histogram cells in update box) for each axis; this can be adjusted */
/*
* The next three routines implement inverse colormap filling. They could
* all be folded into one big routine, but splitting them up this way saves
* some stack space (the mindist[] and bestdist[] arrays need not coexist)
* and may allow some compilers to produce better code by registerizing more
* inner-loop variables.
*/
LOCAL(int)
/* Locate the colormap entries close enough to an update box to be candidates
* for the nearest entry to some cell(s) in the update box. The update box
* is specified by the center coordinates of its first cell. The number of
* candidate colormap entries is returned, and their colormap indexes are
* placed in colorlist[].
* This routine uses Heckbert's "locally sorted search" criterion to select
* the colors that need further consideration.
*/
{
int i, x, ncolors;
/* Compute true coordinates of update box's upper corner and center.
* Actually we compute the coordinates of the center of the upper-corner
* histogram cell, which are the upper bounds of the volume we care about.
* Note that since ">>" rounds down, the "center" values may be closer to
* min than to max; hence comparisons to them must be "<=", not "<".
*/
/* For each color in colormap, find:
* 1. its minimum squared-distance to any point in the update box
* (zero if color is within update box);
* 2. its maximum squared-distance to any point in the update box.
* Both of these can be found by considering only the corners of the box.
* We save the minimum distance for each color in mindist[];
* only the smallest maximum distance is of interest.
*/
minmaxdist = 0x7FFFFFFFL;
for (i = 0; i < numcolors; i++) {
/* We compute the squared-c0-distance term, then add in the other two. */
if (x < minc0) {
} else if (x > maxc0) {
} else {
/* within cell range so no contribution to min_dist */
min_dist = 0;
if (x <= centerc0) {
} else {
}
}
if (x < minc1) {
} else if (x > maxc1) {
} else {
/* within cell range so no contribution to min_dist */
if (x <= centerc1) {
} else {
}
}
if (x < minc2) {
} else if (x > maxc2) {
} else {
/* within cell range so no contribution to min_dist */
if (x <= centerc2) {
} else {
}
}
if (max_dist < minmaxdist)
}
/* Now we know that no cell in the update box is more than minmaxdist
* away from some colormap entry. Therefore, only colors that are
* within minmaxdist of some part of the box need be considered.
*/
ncolors = 0;
for (i = 0; i < numcolors; i++) {
if (mindist[i] <= minmaxdist)
}
return ncolors;
}
LOCAL(void)
/* Find the closest colormap entry for each cell in the update box,
* given the list of candidate colors prepared by find_nearby_colors.
* Return the indexes of the closest entries in the bestcolor[] array.
* This routine uses Thomas' incremental distance calculation method to
* find the distance from a colormap entry to successive cells in the box.
*/
{
int i, icolor;
/* This array holds the distance to the nearest-so-far color for each cell */
/* Initialize best-distance for each cell of the update box */
*bptr++ = 0x7FFFFFFFL;
/* For each color selected by find_nearby_colors,
* compute its distance to the center of each cell in the box.
* If that's less than best-so-far, update best distance and color number.
*/
/* Nominal steps between cell centers ("x" in Thomas article) */
for (i = 0; i < numcolors; i++) {
/* Form the initial difference increments */
/* Now loop over all cells in box, updating distance per Thomas method */
}
bptr++;
cptr++;
}
}
}
}
}
LOCAL(void)
/* Fill the inverse-colormap entries in the update box that contains */
/* we can fill as many others as we wish.) */
{
/* This array lists the candidate colormap indexes. */
/* This array holds the actually closest colormap index for each cell. */
/* Convert cell coordinates to update box ID */
/* Compute true coordinates of update box's origin corner.
* Actually we compute the coordinates of the center of the corner
* histogram cell, which are the lower bounds of the volume we care about.
*/
/* Determine which colormap entries are close enough to be candidates
* for the nearest entry to some cell in the update box.
*/
/* Determine the actually nearest colors. */
/* Save the best color numbers (plus 1) in the main cache array */
}
}
}
}
/*
* Map some rows of pixels to the output colormapped representation.
*/
METHODDEF(void)
/* This version performs no dithering */
{
int row;
/* get pixel value and index into the cache */
/* If we have not seen this color before, find nearest colormap entry */
/* and update the cache */
if (*cachep == 0)
/* Now emit the colormap index for this cell */
}
}
}
METHODDEF(void)
/* This version performs Floyd-Steinberg dithering */
{
int row;
if (cquantize->on_odd_row) {
/* work right to left in this row */
dir = -1;
dir3 = -3;
} else {
/* work left to right in this row */
dir = 1;
dir3 = 3;
}
/* Preset error values: no error propagated to first pixel from left */
/* and no error propagated to row below yet */
/* curN holds the error propagated from the previous pixel on the
* current line. Add the error propagated from the previous line
* to form the complete error correction term for this pixel, and
* round the error term (which is expressed * 16) to an integer.
* RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
* for either sign of the error value.
* Note: errorptr points to *previous* column's array entry.
*/
/* Limit the error using transfer function set by init_error_limit.
* See comments with init_error_limit for rationale.
*/
/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
* The maximum error is +- MAXJSAMPLE (or less with error limiting);
* this sets the required size of the range_limit array.
*/
/* Index into the cache with adjusted pixel value */
/* If we have not seen this color before, find nearest colormap */
/* entry and update the cache */
if (*cachep == 0)
/* Now emit the colormap index for this cell */
/* Compute representation error for this pixel */
}
/* Compute error fractions to be propagated to adjacent pixels.
* Add these into the running sums, and simultaneously shift the
* next-line error sums left by 1 column.
*/
}
/* At this point curN contains the 7/16 error value to be propagated
* to the next pixel on the current line, and all the errors for the
* next line have been shifted over. We are therefore ready to move on.
*/
}
/* Post-loop cleanup: we must unload the final error values into the
* final fserrors[] entry. Note we need not unload belowerrN because
* it is for the dummy column before or after the actual array.
*/
}
}
/*
* Initialize the error-limiting transfer function (lookup table).
* The raw F-S error computation can potentially compute error values of up to
* +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be
* much less, otherwise obviously wrong pixels will be created. (Typical
* effects include weird fringes at color-area boundaries, isolated bright
* pixels in a dark area, etc.) The standard advice for avoiding this problem
* is to ensure that the "corners" of the color cube are allocated as output
* colors; then repeated errors in the same direction cannot cause cascading
* error buildup. However, that only prevents the error from getting
* completely out of hand; Aaron Giles reports that error limiting improves
* the results even with corner colors allocated.
* A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
* well, but the smoother transfer function used below is even better. Thanks
* to Aaron Giles for this idea.
*/
LOCAL(void)
/* Allocate and fill in the error_limiter table */
{
int * table;
/* Map errors 1:1 up to +- MAXJSAMPLE/16 */
out = 0;
}
/* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
}
/* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
}
}
/*
* Finish up at the end of each pass.
*/
METHODDEF(void)
{
/* Select the representative colors and fill in cinfo->colormap */
/* Force next pass to zero the color index table */
}
METHODDEF(void)
{
/* no work */
}
/*
* Initialize for each processing pass.
*/
METHODDEF(void)
{
int i;
/* Only F-S dithering or no dithering is supported. */
/* If user asks for ordered dither, give him F-S. */
if (is_pre_scan) {
/* Set up method pointers */
} else {
/* Set up method pointers */
else
/* Make sure color count is acceptable */
i = cinfo->actual_number_of_colors;
if (i < 1)
if (i > MAXNUMCOLORS)
/* Allocate Floyd-Steinberg workspace if we didn't already. */
/* Initialize the propagated errors to zero. */
/* Make the error-limit table if we didn't already. */
}
}
/* Zero the histogram or inverse color map, if necessary */
if (cquantize->needs_zeroed) {
for (i = 0; i < HIST_C0_ELEMS; i++) {
}
}
}
/*
* Switch to a new external colormap between output passes.
*/
METHODDEF(void)
{
/* Reset the inverse color map */
}
/*
* Module initialization routine for 2-pass color quantization.
*/
GLOBAL(void)
{
int i;
/* Make sure jdmaster didn't give me a case I can't handle */
for (i = 0; i < HIST_C0_ELEMS; i++) {
}
/* Allocate storage for the completed colormap, if required.
* We do this now since it is FAR storage and may affect
* the memory manager's space calculations.
*/
if (cinfo->enable_2pass_quant) {
/* Make sure color count is acceptable */
/* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
if (desired < 8)
/* Make sure colormap indexes can be represented by JSAMPLEs */
if (desired > MAXNUMCOLORS)
} else
/* Only F-S dithering or no dithering is supported. */
/* If user asks for ordered dither, give him F-S. */
/* Allocate Floyd-Steinberg workspace if necessary.
* This isn't really needed until pass 2, but again it is FAR storage.
* Although we will cope with a later change in dither_mode,
* we do not promise to honor max_memory_to_use if dither_mode changes.
*/
/* Might as well create the error-limiting table too. */
}
}
#endif /* QUANT_2PASS_SUPPORTED */