Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibJPEG/jquant2.c view on Meta::CPAN
/*
* jquant2.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* 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.
*/
#define R_SCALE 2 /* scale R distances by this much */
#define G_SCALE 3 /* scale G distances by this much */
#define B_SCALE 1 /* and B by this much */
/* 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
#define C0_SCALE R_SCALE
#endif
#if RGB_BLUE == 0
#define C0_SCALE B_SCALE
#endif
#if RGB_GREEN == 1
#define C1_SCALE G_SCALE
#endif
#if RGB_RED == 2
#define C2_SCALE R_SCALE
#endif
#if RGB_BLUE == 2
#define C2_SCALE B_SCALE
#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;
( run in 0.871 second using v1.01-cache-2.11-cpan-b50b6a40fd4 )