19f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
29f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jquant2.c
39f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
49f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Copyright (C) 1991-1996, Thomas G. Lane.
59f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file is part of the Independent JPEG Group's software.
69f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * For conditions of distribution and use, see the accompanying README file.
79f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
89f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file contains 2-pass color quantization (color mapping) routines.
99f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * These routines provide selection of a custom color map for an image,
109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * followed by mapping of the image to that color map, with optional
119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Floyd-Steinberg dithering.
129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * It is also possible to use just the second pass to map to an arbitrary
139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * externally-given color map.
149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note: ordered dithering is not supported, since there isn't any fast
169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * way to compute intercolor distances; it's unclear that ordered dither's
179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * fundamental assumptions even hold with an irregularly spaced color map.
189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define JPEG_INTERNALS
219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jinclude.h"
229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jpeglib.h"
239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef QUANT_2PASS_SUPPORTED
259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This module implements the well-known Heckbert paradigm for color
299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * quantization.  Most of the ideas used here can be traced back to
309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Heckbert's seminal paper
319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *   Heckbert, Paul.  "Color Image Quantization for Frame Buffer Display",
329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *   Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In the first pass over the image, we accumulate a histogram showing the
359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * usage count of each possible color.  To keep the histogram to a reasonable
369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * size, we reduce the precision of the input; typical practice is to retain
379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 5 or 6 bits per color, so that 8 or 4 different input values are counted
389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * in the same histogram cell.
399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Next, the color-selection step begins with a box representing the whole
419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * color space, and repeatedly splits the "largest" remaining box until we
429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * have as many boxes as desired colors.  Then the mean color in each
439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * remaining box becomes one of the possible output colors.
449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The second pass over the image maps each input pixel to the closest output
469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * color (optionally after applying a Floyd-Steinberg dithering correction).
479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This mapping is logically trivial, but making it go fast enough requires
489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * considerable care.
499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Heckbert-style quantizers vary a good deal in their policies for choosing
519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the "largest" box and deciding where to cut it.  The particular policies
529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * used here have proved out well in experimental comparisons, but better ones
539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * may yet be found.
549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In earlier versions of the IJG code, this module quantized in YCbCr color
569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * space, processing the raw upsampled data without a color conversion step.
579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This allowed the color conversion math to be done only once per colormap
589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * entry, not once per pixel.  However, that optimization precluded other
599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * useful optimizations (such as merging color conversion with upsampling)
609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and it also interfered with desired capabilities such as quantizing to an
619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * externally-supplied colormap.  We have therefore abandoned that approach.
629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The present code works in the post-conversion color space, typically RGB.
639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * To improve the visual quality of the results, we actually work in scaled
659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * RGB space, giving G distances more weight than R, and R in turn more than
669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * B.  To do everything in integer math, we must use integer scale factors.
679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The 2/3/1 scale factors used here correspond loosely to the relative
689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * weights of the colors in the NTSC grayscale equation.
699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * If you want to use this code to quantize a non-RGB color space, you'll
709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * probably need to change these scale factors.
719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define R_SCALE 2		/* scale R distances by this much */
749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define G_SCALE 3		/* scale G distances by this much */
759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define B_SCALE 1		/* and B by this much */
769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * in jmorecfg.h.  As the code stands, it will do the right thing for R,G,B
799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and B,G,R orders.  If you define some other weird order in jmorecfg.h,
809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * you'll get compile errors until you extend this logic.  In that case
819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * you'll probably want to tweak the histogram sizes too.
829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if RGB_RED == 0
859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C0_SCALE R_SCALE
869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if RGB_BLUE == 0
889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C0_SCALE B_SCALE
899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if RGB_GREEN == 1
919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C1_SCALE G_SCALE
929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if RGB_RED == 2
949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C2_SCALE R_SCALE
959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if RGB_BLUE == 2
979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C2_SCALE B_SCALE
989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
1029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * First we have the histogram data structure and routines for creating it.
1039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
1049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The number of bits of precision can be adjusted by changing these symbols.
1059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We recommend keeping 6 bits for G and 5 each for R and B.
1069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * If you have plenty of memory and cycles, 6 bits all around gives marginally
1079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * better results; if you are short of memory, 5 bits all around will save
1089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * some space but degrade the results.
1099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * To maintain a fully accurate histogram, we'd need to allocate a "long"
1109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (preferably unsigned long) for each cell.  In practice this is overkill;
1119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * we can get by with 16 bits per cell.  Few of the cell counts will overflow,
1129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and clamping those that do overflow to the maximum value will give close-
1139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * enough results.  This reduces the recommended histogram size from 256Kb
1149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to 128Kb, which is a useful savings on PC-class machines.
1159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (In the second pass the histogram space is re-used for pixel mapping data;
1169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * in that capacity, each cell must be able to store zero to the number of
1179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * desired colors.  16 bits/cell is plenty for that too.)
1189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Since the JPEG code is intended to run in small memory model on 80x86
1199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * machines, we can't just allocate the histogram in one chunk.  Instead
1209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * of a true 3-D array, we use a row of pointers to 2-D arrays.  Each
1219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
1229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries.  Note that
1239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * on 80x86 machines, the pointer row is in near memory but the actual
1249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * arrays are in far memory (same arrangement as we use for image arrays).
1259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define MAXNUMCOLORS  (MAXJSAMPLE+1) /* maximum size of colormap */
1289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* These will do the right thing for either R,G,B or B,G,R color order,
1309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * but you may not like the results for other color orders.
1319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define HIST_C0_BITS  5		/* bits of precision in R/B histogram */
1339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define HIST_C1_BITS  6		/* bits of precision in G histogram */
1349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define HIST_C2_BITS  5		/* bits of precision in B/R histogram */
1359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Number of elements along histogram axes. */
1379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define HIST_C0_ELEMS  (1<<HIST_C0_BITS)
1389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define HIST_C1_ELEMS  (1<<HIST_C1_BITS)
1399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define HIST_C2_ELEMS  (1<<HIST_C2_BITS)
1409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* These are the amounts to shift an input value to get a histogram index. */
1429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C0_SHIFT  (BITS_IN_JSAMPLE-HIST_C0_BITS)
1439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C1_SHIFT  (BITS_IN_JSAMPLE-HIST_C1_BITS)
1449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define C2_SHIFT  (BITS_IN_JSAMPLE-HIST_C2_BITS)
1459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef UINT16 histcell;	/* histogram cell; prefer an unsigned type */
1489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef histcell FAR * histptr;	/* for pointers to histogram cells */
1509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */
1529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef hist1d FAR * hist2d;	/* type for the 2nd-level pointers */
1539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef hist2d * hist3d;	/* type for top-level pointer */
1549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Declarations for Floyd-Steinberg dithering.
1579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
1589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Errors are accumulated into the array fserrors[], at a resolution of
1599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1/16th of a pixel count.  The error at a given pixel is propagated
1609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to its not-yet-processed neighbors using the standard F-S fractions,
1619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *		...	(here)	7/16
1629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *		3/16	5/16	1/16
1639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We work left-to-right on even rows, right-to-left on odd rows.
1649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
1659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We can get away with a single array (holding one row's worth of errors)
1669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by using it to store the current row's errors at pixel columns not yet
1679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * processed, but the next row's errors at columns already processed.  We
1689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * need only a few extra variables to hold the errors immediately around the
1699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * current column.  (If we are lucky, those variables are in registers, but
1709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * even if not, they're probably cheaper to access than array elements are.)
1719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
1729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The fserrors[] array has (#columns + 2) entries; the extra entry at
1739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * each end saves us from special-casing the first and last pixels.
1749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Each entry is three values long, one value for each color component.
1759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
1769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note: on a wide image, we might not have enough room in a PC's near data
1779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * segment to hold the error array; so it is allocated with alloc_large.
1789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if BITS_IN_JSAMPLE == 8
1819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef INT16 FSERROR;		/* 16 bits should be enough */
1829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef int LOCFSERROR;		/* use 'int' for calculation temps */
1839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else
1849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef INT32 FSERROR;		/* may need more than 16 bits */
1859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef INT32 LOCFSERROR;	/* be sure calculation temps are big enough */
1869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
1879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef FSERROR FAR *FSERRPTR;	/* pointer to error array (in FAR storage!) */
1899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Private subobject */
1929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef struct {
1949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  struct jpeg_color_quantizer pub; /* public fields */
1959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Space for the eventually created colormap is stashed here */
1979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPARRAY sv_colormap;	/* colormap allocated at init time */
1989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int desired;			/* desired # of colors = size of colormap */
1999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Variables for accumulating image statistics */
2019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  hist3d histogram;		/* pointer to the histogram */
2029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boolean needs_zeroed;		/* TRUE if next pass must zero histogram */
2049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Variables for Floyd-Steinberg dithering */
2069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  FSERRPTR fserrors;		/* accumulated errors */
2079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boolean on_odd_row;		/* flag to remember which row we are on */
2089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int * error_limiter;		/* table for clamping the applied error */
2099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} my_cquantizer;
2109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef my_cquantizer * my_cquantize_ptr;
2129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
2159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Prescan some rows of pixels.
2169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In this module the prescan simply updates the histogram, which has been
2179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * initialized to zeroes by start_pass.
2189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * An output_buf parameter is required by the method signature, but no data
2199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * is actually output (in fact the buffer controller is probably passing a
2209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * NULL pointer).
2219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
2229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
2249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectprescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
2259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		  JSAMPARRAY output_buf, int num_rows)
2269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
2279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
2289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register JSAMPROW ptr;
2299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register histptr histp;
2309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register hist3d histogram = cquantize->histogram;
2319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int row;
2329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION col;
2339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION width = cinfo->output_width;
2349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (row = 0; row < num_rows; row++) {
2369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ptr = input_buf[row];
2379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (col = width; col > 0; col--) {
2389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* get pixel value and index into the histogram */
2399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
2409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			 [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
2419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			 [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
2429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* increment, check for overflow and undo increment if so. */
2439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (++(*histp) <= 0)
2449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	(*histp)--;
2459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ptr += 3;
2469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
2479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
2489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
2499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
2529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Next we have the really interesting routines: selection of a colormap
2539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * given the completed histogram.
2549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * These routines work with a list of "boxes", each representing a rectangular
2559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * subset of the input color space (to histogram precision).
2569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
2579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef struct {
2599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* The bounds of the box (inclusive); expressed as histogram indexes */
2609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c0min, c0max;
2619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c1min, c1max;
2629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c2min, c2max;
2639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* The volume (actually 2-norm) of the box */
2649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 volume;
2659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* The number of nonzero histogram cells within this box */
2669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  long colorcount;
2679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} box;
2689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef box * boxptr;
2709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(boxptr)
2739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfind_biggest_color_pop (boxptr boxlist, int numboxes)
2749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Find the splittable box with the largest color population */
2759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Returns NULL if no splittable boxes remain */
2769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
2779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register boxptr boxp;
2789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register int i;
2799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register long maxc = 0;
2809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxptr which = NULL;
2819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
2839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (boxp->colorcount > maxc && boxp->volume > 0) {
2849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      which = boxp;
2859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      maxc = boxp->colorcount;
2869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
2879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
2889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  return which;
2899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
2909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(boxptr)
2939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfind_biggest_volume (boxptr boxlist, int numboxes)
2949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Find the splittable box with the largest (scaled) volume */
2959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Returns NULL if no splittable boxes remain */
2969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
2979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register boxptr boxp;
2989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register int i;
2999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register INT32 maxv = 0;
3009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxptr which = NULL;
3019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
3039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (boxp->volume > maxv) {
3049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      which = boxp;
3059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      maxv = boxp->volume;
3069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
3079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
3089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  return which;
3099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
3109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
3139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectupdate_box (j_decompress_ptr cinfo, boxptr boxp)
3149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
3159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* and recompute its volume and population */
3169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
3179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
3189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  hist3d histogram = cquantize->histogram;
3199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  histptr histp;
3209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c0,c1,c2;
3219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c0min,c0max,c1min,c1max,c2min,c2max;
3229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 dist0,dist1,dist2;
3239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  long ccount;
3249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c0min = boxp->c0min;  c0max = boxp->c0max;
3269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c1min = boxp->c1min;  c1max = boxp->c1max;
3279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c2min = boxp->c2min;  c2max = boxp->c2max;
3289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (c0max > c0min)
3309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c0 = c0min; c0 <= c0max; c0++)
3319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c1 = c1min; c1 <= c1max; c1++) {
3329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	histp = & histogram[c0][c1][c2min];
3339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (c2 = c2min; c2 <= c2max; c2++)
3349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  if (*histp++ != 0) {
3359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    boxp->c0min = c0min = c0;
3369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    goto have_c0min;
3379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
3389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
3399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project have_c0min:
3409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (c0max > c0min)
3419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c0 = c0max; c0 >= c0min; c0--)
3429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c1 = c1min; c1 <= c1max; c1++) {
3439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	histp = & histogram[c0][c1][c2min];
3449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (c2 = c2min; c2 <= c2max; c2++)
3459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  if (*histp++ != 0) {
3469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    boxp->c0max = c0max = c0;
3479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    goto have_c0max;
3489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
3499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
3509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project have_c0max:
3519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (c1max > c1min)
3529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c1 = c1min; c1 <= c1max; c1++)
3539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c0 = c0min; c0 <= c0max; c0++) {
3549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	histp = & histogram[c0][c1][c2min];
3559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (c2 = c2min; c2 <= c2max; c2++)
3569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  if (*histp++ != 0) {
3579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    boxp->c1min = c1min = c1;
3589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    goto have_c1min;
3599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
3609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
3619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project have_c1min:
3629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (c1max > c1min)
3639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c1 = c1max; c1 >= c1min; c1--)
3649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c0 = c0min; c0 <= c0max; c0++) {
3659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	histp = & histogram[c0][c1][c2min];
3669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (c2 = c2min; c2 <= c2max; c2++)
3679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  if (*histp++ != 0) {
3689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    boxp->c1max = c1max = c1;
3699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    goto have_c1max;
3709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
3719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
3729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project have_c1max:
3739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (c2max > c2min)
3749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c2 = c2min; c2 <= c2max; c2++)
3759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c0 = c0min; c0 <= c0max; c0++) {
3769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	histp = & histogram[c0][c1min][c2];
3779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
3789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  if (*histp != 0) {
3799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    boxp->c2min = c2min = c2;
3809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    goto have_c2min;
3819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
3829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
3839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project have_c2min:
3849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (c2max > c2min)
3859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c2 = c2max; c2 >= c2min; c2--)
3869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c0 = c0min; c0 <= c0max; c0++) {
3879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	histp = & histogram[c0][c1min][c2];
3889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
3899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  if (*histp != 0) {
3909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    boxp->c2max = c2max = c2;
3919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    goto have_c2max;
3929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
3939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
3949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project have_c2max:
3959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Update box volume.
3979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * We use 2-norm rather than real volume here; this biases the method
3989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * against making long narrow boxes, and it has the side benefit that
3999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * a box is splittable iff norm > 0.
4009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * Since the differences are expressed in histogram-cell units,
4019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * we have to shift back to JSAMPLE units to get consistent distances;
4029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * after which, we scale according to the selected distance scale factors.
4039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
4049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
4059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
4069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
4079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
4089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
4099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Now scan remaining volume of box and compute population */
4109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  ccount = 0;
4119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (c0 = c0min; c0 <= c0max; c0++)
4129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c1 = c1min; c1 <= c1max; c1++) {
4139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      histp = & histogram[c0][c1][c2min];
4149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c2 = c2min; c2 <= c2max; c2++, histp++)
4159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	if (*histp != 0) {
4169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  ccount++;
4179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	}
4189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
4199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxp->colorcount = ccount;
4209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
4219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
4229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
4239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(int)
4249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectmedian_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
4259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    int desired_colors)
4269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Repeatedly select and split the largest box until we have enough boxes */
4279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
4289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int n,lb;
4299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c0,c1,c2,cmax;
4309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register boxptr b1,b2;
4319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
4329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  while (numboxes < desired_colors) {
4339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Select box to split.
4349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * Current algorithm: by population for first half, then by volume.
4359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     */
4369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (numboxes*2 <= desired_colors) {
4379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b1 = find_biggest_color_pop(boxlist, numboxes);
4389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else {
4399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b1 = find_biggest_volume(boxlist, numboxes);
4409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
4419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (b1 == NULL)		/* no splittable boxes left! */
4429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      break;
4439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    b2 = &boxlist[numboxes];	/* where new box will go */
4449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Copy the color bounds to the new box. */
4459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
4469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
4479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Choose which axis to split the box on.
4489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * Current algorithm: longest scaled axis.
4499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * See notes in update_box about scaling distances.
4509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     */
4519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
4529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
4539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
4549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* We want to break any ties in favor of green, then red, blue last.
4559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * This code does the right thing for R,G,B or B,G,R color orders only.
4569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     */
4579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#if RGB_RED == 0
4589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cmax = c1; n = 1;
4599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (c0 > cmax) { cmax = c0; n = 0; }
4609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (c2 > cmax) { n = 2; }
4619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else
4629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cmax = c1; n = 1;
4639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (c2 > cmax) { cmax = c2; n = 2; }
4649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (c0 > cmax) { n = 0; }
4659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
4669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Choose split point along selected axis, and update box bounds.
4679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * Current algorithm: split at halfway point.
4689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * (Since the box has been shrunk to minimum volume,
4699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * any split will produce two nonempty subboxes.)
4709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * Note that lb value is max for lower box, so must be < old max.
4719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     */
4729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    switch (n) {
4739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    case 0:
4749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      lb = (b1->c0max + b1->c0min) / 2;
4759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b1->c0max = lb;
4769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b2->c0min = lb+1;
4779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      break;
4789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    case 1:
4799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      lb = (b1->c1max + b1->c1min) / 2;
4809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b1->c1max = lb;
4819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b2->c1min = lb+1;
4829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      break;
4839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    case 2:
4849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      lb = (b1->c2max + b1->c2min) / 2;
4859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b1->c2max = lb;
4869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      b2->c2min = lb+1;
4879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      break;
4889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
4899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Update stats for boxes */
4909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    update_box(cinfo, b1);
4919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    update_box(cinfo, b2);
4929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    numboxes++;
4939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
4949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  return numboxes;
4959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
4969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
4979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
4989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
4999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectcompute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
5009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Compute representative color for a box, put it in colormap[icolor] */
5019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
5029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Current algorithm: mean weighted by pixels (not colors) */
5039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Note it is important to get the rounding correct! */
5049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
5059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  hist3d histogram = cquantize->histogram;
5069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  histptr histp;
5079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c0,c1,c2;
5089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int c0min,c0max,c1min,c1max,c2min,c2max;
5099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  long count;
5109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  long total = 0;
5119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  long c0total = 0;
5129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  long c1total = 0;
5139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  long c2total = 0;
5149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c0min = boxp->c0min;  c0max = boxp->c0max;
5169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c1min = boxp->c1min;  c1max = boxp->c1max;
5179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c2min = boxp->c2min;  c2max = boxp->c2max;
5189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (c0 = c0min; c0 <= c0max; c0++)
5209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (c1 = c1min; c1 <= c1max; c1++) {
5219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      histp = & histogram[c0][c1][c2min];
5229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (c2 = c2min; c2 <= c2max; c2++) {
5239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	if ((count = *histp++) != 0) {
5249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  total += count;
5259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count;
5269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count;
5279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count;
5289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	}
5299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
5309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
5319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
5339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
5349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
5359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
5369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
5399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectselect_colors (j_decompress_ptr cinfo, int desired_colors)
5409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Master routine for color selection */
5419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
5429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxptr boxlist;
5439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int numboxes;
5449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int i;
5459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Allocate workspace for box list */
5479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxlist = (boxptr) (*cinfo->mem->alloc_small)
5489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
5499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Initialize one box containing whole space */
5509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  numboxes = 1;
5519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxlist[0].c0min = 0;
5529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
5539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxlist[0].c1min = 0;
5549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
5559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxlist[0].c2min = 0;
5569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
5579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Shrink it to actually-used volume and set its statistics */
5589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  update_box(cinfo, & boxlist[0]);
5599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Perform median-cut to produce final box list */
5609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
5619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Compute the representative color for each box, fill colormap */
5629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = 0; i < numboxes; i++)
5639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    compute_color(cinfo, & boxlist[i], i);
5649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cinfo->actual_number_of_colors = numboxes;
5659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
5669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
5679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
5699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
5709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * These routines are concerned with the time-critical task of mapping input
5719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * colors to the nearest color in the selected colormap.
5729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
5739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * We re-use the histogram space as an "inverse color map", essentially a
5749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * cache for the results of nearest-color searches.  All colors within a
5759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * histogram cell will be mapped to the same colormap entry, namely the one
5769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * closest to the cell's center.  This may not be quite the closest entry to
5779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the actual input color, but it's almost as good.  A zero in the cache
5789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * indicates we haven't found the nearest color for that cell yet; the array
5799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * is cleared to zeroes before starting the mapping pass.  When we find the
5809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * nearest color for a cell, its colormap index plus one is recorded in the
5819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * cache for future use.  The pass2 scanning routines call fill_inverse_cmap
5829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * when they need to use an unfilled entry in the cache.
5839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
5849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Our method of efficiently finding nearest colors is based on the "locally
5859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * sorted search" idea described by Heckbert and on the incremental distance
5869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
5879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Gems II (James Arvo, ed.  Academic Press, 1991).  Thomas points out that
5889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the distances from a given colormap entry to each cell of the histogram can
5899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * be computed quickly using an incremental method: the differences between
5909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * distances to adjacent cells themselves differ by a constant.  This allows a
5919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * fairly fast implementation of the "brute force" approach of computing the
5929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * distance from every colormap entry to every histogram cell.  Unfortunately,
5939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * it needs a work array to hold the best-distance-so-far for each histogram
5949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * cell (because the inner loop has to be over cells, not colormap entries).
5959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The work array elements have to be INT32s, so the work array would need
5969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 256Kb at our recommended precision.  This is not feasible in DOS machines.
5979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
5989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * To get around these problems, we apply Thomas' method to compute the
5999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * nearest colors for only the cells within a small subbox of the histogram.
6009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The work array need be only as big as the subbox, so the memory usage
6019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * problem is solved.  Furthermore, we need not fill subboxes that are never
6029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * referenced in pass2; many images use only part of the color gamut, so a
6039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * fair amount of work is saved.  An additional advantage of this
6049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * approach is that we can apply Heckbert's locality criterion to quickly
6059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * eliminate colormap entries that are far away from the subbox; typically
6069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * three-fourths of the colormap entries are rejected by Heckbert's criterion,
6079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and we need not compute their distances to individual cells in the subbox.
6089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The speed of this approach is heavily influenced by the subbox size: too
6099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * small means too much overhead, too big loses because Heckbert's criterion
6109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * can't eliminate as many colormap entries.  Empirically the best subbox
6119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * size seems to be about 1/512th of the histogram (1/8th in each direction).
6129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
6139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Thomas' article also describes a refined method which is asymptotically
6149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * faster than the brute-force method, but it is also far more complex and
6159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * cannot efficiently be applied to small subboxes.  It is therefore not
6169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * useful for programs intended to be portable to DOS machines.  On machines
6179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * with plenty of memory, filling the whole histogram in one shot with Thomas'
6189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * refined method might be faster than the present code --- but then again,
6199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * it might not be any faster, and it's certainly more complicated.
6209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
6219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* log2(histogram cells in update box) for each axis; this can be adjusted */
6249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C0_LOG  (HIST_C0_BITS-3)
6259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C1_LOG  (HIST_C1_BITS-3)
6269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C2_LOG  (HIST_C2_BITS-3)
6279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C0_ELEMS  (1<<BOX_C0_LOG) /* # of hist cells in update box */
6299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C1_ELEMS  (1<<BOX_C1_LOG)
6309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C2_ELEMS  (1<<BOX_C2_LOG)
6319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C0_SHIFT  (C0_SHIFT + BOX_C0_LOG)
6339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C1_SHIFT  (C1_SHIFT + BOX_C1_LOG)
6349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define BOX_C2_SHIFT  (C2_SHIFT + BOX_C2_LOG)
6359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
6389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The next three routines implement inverse colormap filling.  They could
6399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * all be folded into one big routine, but splitting them up this way saves
6409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * some stack space (the mindist[] and bestdist[] arrays need not coexist)
6419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and may allow some compilers to produce better code by registerizing more
6429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * inner-loop variables.
6439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
6449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(int)
6469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfind_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
6479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		    JSAMPLE colorlist[])
6489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Locate the colormap entries close enough to an update box to be candidates
6499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * for the nearest entry to some cell(s) in the update box.  The update box
6509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * is specified by the center coordinates of its first cell.  The number of
6519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * candidate colormap entries is returned, and their colormap indexes are
6529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * placed in colorlist[].
6539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This routine uses Heckbert's "locally sorted search" criterion to select
6549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the colors that need further consideration.
6559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
6569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
6579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int numcolors = cinfo->actual_number_of_colors;
6589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int maxc0, maxc1, maxc2;
6599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int centerc0, centerc1, centerc2;
6609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int i, x, ncolors;
6619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 minmaxdist, min_dist, max_dist, tdist;
6629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 mindist[MAXNUMCOLORS];	/* min distance to colormap entry i */
6639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Compute true coordinates of update box's upper corner and center.
6659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * Actually we compute the coordinates of the center of the upper-corner
6669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * histogram cell, which are the upper bounds of the volume we care about.
6679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * Note that since ">>" rounds down, the "center" values may be closer to
6689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * min than to max; hence comparisons to them must be "<=", not "<".
6699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
6709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
6719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  centerc0 = (minc0 + maxc0) >> 1;
6729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
6739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  centerc1 = (minc1 + maxc1) >> 1;
6749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
6759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  centerc2 = (minc2 + maxc2) >> 1;
6769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* For each color in colormap, find:
6789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   *  1. its minimum squared-distance to any point in the update box
6799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   *     (zero if color is within update box);
6809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   *  2. its maximum squared-distance to any point in the update box.
6819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * Both of these can be found by considering only the corners of the box.
6829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * We save the minimum distance for each color in mindist[];
6839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * only the smallest maximum distance is of interest.
6849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
6859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  minmaxdist = 0x7FFFFFFFL;
6869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
6879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = 0; i < numcolors; i++) {
6889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* We compute the squared-c0-distance term, then add in the other two. */
6899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    x = GETJSAMPLE(cinfo->colormap[0][i]);
6909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (x < minc0) {
6919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - minc0) * C0_SCALE;
6929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      min_dist = tdist*tdist;
6939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - maxc0) * C0_SCALE;
6949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      max_dist = tdist*tdist;
6959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else if (x > maxc0) {
6969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - maxc0) * C0_SCALE;
6979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      min_dist = tdist*tdist;
6989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - minc0) * C0_SCALE;
6999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      max_dist = tdist*tdist;
7009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else {
7019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* within cell range so no contribution to min_dist */
7029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      min_dist = 0;
7039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (x <= centerc0) {
7049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	tdist = (x - maxc0) * C0_SCALE;
7059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	max_dist = tdist*tdist;
7069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      } else {
7079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	tdist = (x - minc0) * C0_SCALE;
7089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	max_dist = tdist*tdist;
7099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
7109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
7119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
7129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    x = GETJSAMPLE(cinfo->colormap[1][i]);
7139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (x < minc1) {
7149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - minc1) * C1_SCALE;
7159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      min_dist += tdist*tdist;
7169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - maxc1) * C1_SCALE;
7179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      max_dist += tdist*tdist;
7189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else if (x > maxc1) {
7199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - maxc1) * C1_SCALE;
7209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      min_dist += tdist*tdist;
7219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - minc1) * C1_SCALE;
7229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      max_dist += tdist*tdist;
7239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else {
7249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* within cell range so no contribution to min_dist */
7259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (x <= centerc1) {
7269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	tdist = (x - maxc1) * C1_SCALE;
7279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	max_dist += tdist*tdist;
7289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      } else {
7299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	tdist = (x - minc1) * C1_SCALE;
7309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	max_dist += tdist*tdist;
7319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
7329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
7339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
7349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    x = GETJSAMPLE(cinfo->colormap[2][i]);
7359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (x < minc2) {
7369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - minc2) * C2_SCALE;
7379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      min_dist += tdist*tdist;
7389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - maxc2) * C2_SCALE;
7399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      max_dist += tdist*tdist;
7409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else if (x > maxc2) {
7419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - maxc2) * C2_SCALE;
7429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      min_dist += tdist*tdist;
7439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      tdist = (x - minc2) * C2_SCALE;
7449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      max_dist += tdist*tdist;
7459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else {
7469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* within cell range so no contribution to min_dist */
7479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (x <= centerc2) {
7489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	tdist = (x - maxc2) * C2_SCALE;
7499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	max_dist += tdist*tdist;
7509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      } else {
7519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	tdist = (x - minc2) * C2_SCALE;
7529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	max_dist += tdist*tdist;
7539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
7549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
7559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
7569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    mindist[i] = min_dist;	/* save away the results */
7579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (max_dist < minmaxdist)
7589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      minmaxdist = max_dist;
7599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
7609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
7619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Now we know that no cell in the update box is more than minmaxdist
7629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * away from some colormap entry.  Therefore, only colors that are
7639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * within minmaxdist of some part of the box need be considered.
7649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
7659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  ncolors = 0;
7669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = 0; i < numcolors; i++) {
7679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (mindist[i] <= minmaxdist)
7689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      colorlist[ncolors++] = (JSAMPLE) i;
7699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
7709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  return ncolors;
7719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
7729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
7739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
7749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
7759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfind_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
7769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		  int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
7779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Find the closest colormap entry for each cell in the update box,
7789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * given the list of candidate colors prepared by find_nearby_colors.
7799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Return the indexes of the closest entries in the bestcolor[] array.
7809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This routine uses Thomas' incremental distance calculation method to
7819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * find the distance from a colormap entry to successive cells in the box.
7829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
7839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
7849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int ic0, ic1, ic2;
7859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int i, icolor;
7869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register INT32 * bptr;	/* pointer into bestdist[] array */
7879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPLE * cptr;		/* pointer into bestcolor[] array */
7889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 dist0, dist1;		/* initial distance values */
7899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register INT32 dist2;		/* current distance in inner loop */
7909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 xx0, xx1;		/* distance increments */
7919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register INT32 xx2;
7929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 inc0, inc1, inc2;	/* initial values for increments */
7939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* This array holds the distance to the nearest-so-far color for each cell */
7949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
7959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
7969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Initialize best-distance for each cell of the update box */
7979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  bptr = bestdist;
7989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
7999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    *bptr++ = 0x7FFFFFFFL;
8009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* For each color selected by find_nearby_colors,
8029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * compute its distance to the center of each cell in the box.
8039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * If that's less than best-so-far, update best distance and color number.
8049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
8059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Nominal steps between cell centers ("x" in Thomas article) */
8079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define STEP_C0  ((1 << C0_SHIFT) * C0_SCALE)
8089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define STEP_C1  ((1 << C1_SHIFT) * C1_SCALE)
8099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)
8109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = 0; i < numcolors; i++) {
8129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    icolor = GETJSAMPLE(colorlist[i]);
8139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Compute (square of) distance from minc0/c1/c2 to this color */
8149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
8159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    dist0 = inc0*inc0;
8169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
8179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    dist0 += inc1*inc1;
8189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
8199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    dist0 += inc2*inc2;
8209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Form the initial difference increments */
8219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
8229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
8239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
8249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Now loop over all cells in box, updating distance per Thomas method */
8259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    bptr = bestdist;
8269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cptr = bestcolor;
8279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    xx0 = inc0;
8289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
8299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      dist1 = dist0;
8309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      xx1 = inc1;
8319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
8329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	dist2 = dist1;
8339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	xx2 = inc2;
8349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
8359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  if (dist2 < *bptr) {
8369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    *bptr = dist2;
8379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    *cptr = (JSAMPLE) icolor;
8389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
8399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  dist2 += xx2;
8409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  xx2 += 2 * STEP_C2 * STEP_C2;
8419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  bptr++;
8429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  cptr++;
8439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	}
8449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	dist1 += xx1;
8459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	xx1 += 2 * STEP_C1 * STEP_C1;
8469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
8479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      dist0 += xx0;
8489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      xx0 += 2 * STEP_C0 * STEP_C0;
8499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
8509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
8519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
8529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
8559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
8569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Fill the inverse-colormap entries in the update box that contains */
8579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* histogram cell c0/c1/c2.  (Only that one cell MUST be filled, but */
8589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* we can fill as many others as we wish.) */
8599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
8609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
8619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  hist3d histogram = cquantize->histogram;
8629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int minc0, minc1, minc2;	/* lower left corner of update box */
8639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int ic0, ic1, ic2;
8649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register JSAMPLE * cptr;	/* pointer into bestcolor[] array */
8659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register histptr cachep;	/* pointer into main cache array */
8669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* This array lists the candidate colormap indexes. */
8679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPLE colorlist[MAXNUMCOLORS];
8689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int numcolors;		/* number of candidate colors */
8699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* This array holds the actually closest colormap index for each cell. */
8709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
8719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Convert cell coordinates to update box ID */
8739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c0 >>= BOX_C0_LOG;
8749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c1 >>= BOX_C1_LOG;
8759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c2 >>= BOX_C2_LOG;
8769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Compute true coordinates of update box's origin corner.
8789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * Actually we compute the coordinates of the center of the corner
8799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * histogram cell, which are the lower bounds of the volume we care about.
8809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
8819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
8829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
8839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
8849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Determine which colormap entries are close enough to be candidates
8869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * for the nearest entry to some cell in the update box.
8879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
8889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
8899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Determine the actually nearest colors. */
8919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
8929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		   bestcolor);
8939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
8949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Save the best color numbers (plus 1) in the main cache array */
8959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c0 <<= BOX_C0_LOG;		/* convert ID back to base cell indexes */
8969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c1 <<= BOX_C1_LOG;
8979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  c2 <<= BOX_C2_LOG;
8989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cptr = bestcolor;
8999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
9009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
9019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cachep = & histogram[c0+ic0][c1+ic1][c2];
9029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
9039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	*cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
9049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
9059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
9069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
9079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
9089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
9119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Map some rows of pixels to the output colormapped representation.
9129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
9139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
9159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectpass2_no_dither (j_decompress_ptr cinfo,
9169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
9179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* This version performs no dithering */
9189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
9199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
9209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  hist3d histogram = cquantize->histogram;
9219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register JSAMPROW inptr, outptr;
9229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register histptr cachep;
9239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register int c0, c1, c2;
9249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int row;
9259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION col;
9269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION width = cinfo->output_width;
9279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (row = 0; row < num_rows; row++) {
9299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inptr = input_buf[row];
9309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    outptr = output_buf[row];
9319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (col = width; col > 0; col--) {
9329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* get pixel value and index into the cache */
9339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
9349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
9359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
9369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cachep = & histogram[c0][c1][c2];
9379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* If we have not seen this color before, find nearest colormap entry */
9389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* and update the cache */
9399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (*cachep == 0)
9409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	fill_inverse_cmap(cinfo, c0,c1,c2);
9419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Now emit the colormap index for this cell */
9429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      *outptr++ = (JSAMPLE) (*cachep - 1);
9439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
9449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
9459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
9469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
9499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectpass2_fs_dither (j_decompress_ptr cinfo,
9509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
9519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* This version performs Floyd-Steinberg dithering */
9529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
9539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
9549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  hist3d histogram = cquantize->histogram;
9559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register LOCFSERROR cur0, cur1, cur2;	/* current error or pixel value */
9569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
9579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
9589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register FSERRPTR errorptr;	/* => fserrors[] at column before current */
9599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPROW inptr;		/* => current input pixel */
9609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPROW outptr;		/* => current output pixel */
9619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  histptr cachep;
9629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int dir;			/* +1 or -1 depending on direction */
9639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int dir3;			/* 3*dir, for advancing inptr & errorptr */
9649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int row;
9659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION col;
9669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION width = cinfo->output_width;
9679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPLE *range_limit = cinfo->sample_range_limit;
9689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int *error_limit = cquantize->error_limiter;
9699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPROW colormap0 = cinfo->colormap[0];
9709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPROW colormap1 = cinfo->colormap[1];
9719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPROW colormap2 = cinfo->colormap[2];
9729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  SHIFT_TEMPS
9739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (row = 0; row < num_rows; row++) {
9759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inptr = input_buf[row];
9769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    outptr = output_buf[row];
9779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (cquantize->on_odd_row) {
9789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* work right to left in this row */
9799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      inptr += (width-1) * 3;	/* so point to rightmost pixel */
9809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      outptr += width-1;
9819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      dir = -1;
9829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      dir3 = -3;
9839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */
9849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cquantize->on_odd_row = FALSE; /* flip for next time */
9859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else {
9869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* work left to right in this row */
9879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      dir = 1;
9889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      dir3 = 3;
9899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      errorptr = cquantize->fserrors; /* => entry before first real column */
9909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cquantize->on_odd_row = TRUE; /* flip for next time */
9919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
9929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Preset error values: no error propagated to first pixel from left */
9939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cur0 = cur1 = cur2 = 0;
9949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* and no error propagated to row below yet */
9959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    belowerr0 = belowerr1 = belowerr2 = 0;
9969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    bpreverr0 = bpreverr1 = bpreverr2 = 0;
9979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
9989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (col = width; col > 0; col--) {
9999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* curN holds the error propagated from the previous pixel on the
10009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * current line.  Add the error propagated from the previous line
10019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * to form the complete error correction term for this pixel, and
10029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * round the error term (which is expressed * 16) to an integer.
10039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
10049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * for either sign of the error value.
10059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * Note: errorptr points to *previous* column's array entry.
10069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       */
10079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
10089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
10099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
10109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Limit the error using transfer function set by init_error_limit.
10119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * See comments with init_error_limit for rationale.
10129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       */
10139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur0 = error_limit[cur0];
10149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur1 = error_limit[cur1];
10159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur2 = error_limit[cur2];
10169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
10179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * The maximum error is +- MAXJSAMPLE (or less with error limiting);
10189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * this sets the required size of the range_limit array.
10199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       */
10209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur0 += GETJSAMPLE(inptr[0]);
10219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur1 += GETJSAMPLE(inptr[1]);
10229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur2 += GETJSAMPLE(inptr[2]);
10239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur0 = GETJSAMPLE(range_limit[cur0]);
10249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur1 = GETJSAMPLE(range_limit[cur1]);
10259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cur2 = GETJSAMPLE(range_limit[cur2]);
10269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Index into the cache with adjusted pixel value */
10279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
10289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* If we have not seen this color before, find nearest colormap */
10299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* entry and update the cache */
10309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (*cachep == 0)
10319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
10329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Now emit the colormap index for this cell */
10339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      { register int pixcode = *cachep - 1;
10349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	*outptr = (JSAMPLE) pixcode;
10359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	/* Compute representation error for this pixel */
10369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur0 -= GETJSAMPLE(colormap0[pixcode]);
10379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur1 -= GETJSAMPLE(colormap1[pixcode]);
10389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur2 -= GETJSAMPLE(colormap2[pixcode]);
10399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
10409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Compute error fractions to be propagated to adjacent pixels.
10419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * Add these into the running sums, and simultaneously shift the
10429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * next-line error sums left by 1 column.
10439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       */
10449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      { register LOCFSERROR bnexterr, delta;
10459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
10469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	bnexterr = cur0;	/* Process component 0 */
10479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	delta = cur0 * 2;
10489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur0 += delta;		/* form error * 3 */
10499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	errorptr[0] = (FSERROR) (bpreverr0 + cur0);
10509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur0 += delta;		/* form error * 5 */
10519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	bpreverr0 = belowerr0 + cur0;
10529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	belowerr0 = bnexterr;
10539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur0 += delta;		/* form error * 7 */
10549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	bnexterr = cur1;	/* Process component 1 */
10559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	delta = cur1 * 2;
10569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur1 += delta;		/* form error * 3 */
10579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	errorptr[1] = (FSERROR) (bpreverr1 + cur1);
10589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur1 += delta;		/* form error * 5 */
10599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	bpreverr1 = belowerr1 + cur1;
10609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	belowerr1 = bnexterr;
10619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur1 += delta;		/* form error * 7 */
10629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	bnexterr = cur2;	/* Process component 2 */
10639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	delta = cur2 * 2;
10649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur2 += delta;		/* form error * 3 */
10659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	errorptr[2] = (FSERROR) (bpreverr2 + cur2);
10669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur2 += delta;		/* form error * 5 */
10679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	bpreverr2 = belowerr2 + cur2;
10689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	belowerr2 = bnexterr;
10699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cur2 += delta;		/* form error * 7 */
10709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
10719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* At this point curN contains the 7/16 error value to be propagated
10729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * to the next pixel on the current line, and all the errors for the
10739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       * next line have been shifted over.  We are therefore ready to move on.
10749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       */
10759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      inptr += dir3;		/* Advance pixel pointers to next column */
10769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      outptr += dir;
10779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      errorptr += dir3;		/* advance errorptr to current column */
10789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
10799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Post-loop cleanup: we must unload the final error values into the
10809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * final fserrors[] entry.  Note we need not unload belowerrN because
10819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * it is for the dummy column before or after the actual array.
10829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     */
10839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
10849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    errorptr[1] = (FSERROR) bpreverr1;
10859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    errorptr[2] = (FSERROR) bpreverr2;
10869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
10879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
10889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
10899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
10909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
10919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Initialize the error-limiting transfer function (lookup table).
10929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The raw F-S error computation can potentially compute error values of up to
10939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * +- MAXJSAMPLE.  But we want the maximum correction applied to a pixel to be
10949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * much less, otherwise obviously wrong pixels will be created.  (Typical
10959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * effects include weird fringes at color-area boundaries, isolated bright
10969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * pixels in a dark area, etc.)  The standard advice for avoiding this problem
10979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * is to ensure that the "corners" of the color cube are allocated as output
10989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * colors; then repeated errors in the same direction cannot cause cascading
10999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * error buildup.  However, that only prevents the error from getting
11009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * completely out of hand; Aaron Giles reports that error limiting improves
11019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the results even with corner colors allocated.
11029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
11039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * well, but the smoother transfer function used below is even better.  Thanks
11049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to Aaron Giles for this idea.
11059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
11069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
11089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectinit_error_limit (j_decompress_ptr cinfo)
11099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Allocate and fill in the error_limiter table */
11109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
11119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
11129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int * table;
11139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int in, out;
11149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  table = (int *) (*cinfo->mem->alloc_small)
11169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int));
11179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  table += MAXJSAMPLE;		/* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
11189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->error_limiter = table;
11199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define STEPSIZE ((MAXJSAMPLE+1)/16)
11219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
11229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  out = 0;
11239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (in = 0; in < STEPSIZE; in++, out++) {
11249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    table[in] = out; table[-in] = -out;
11259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
11269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
11279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) {
11289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    table[in] = out; table[-in] = -out;
11299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
11309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
11319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (; in <= MAXJSAMPLE; in++) {
11329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    table[in] = out; table[-in] = -out;
11339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
11349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#undef STEPSIZE
11359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
11369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
11399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Finish up at the end of each pass.
11409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
11419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
11439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfinish_pass1 (j_decompress_ptr cinfo)
11449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
11459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
11469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Select the representative colors and fill in cinfo->colormap */
11489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cinfo->colormap = cquantize->sv_colormap;
11499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  select_colors(cinfo, cquantize->desired);
11509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Force next pass to zero the color index table */
11519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->needs_zeroed = TRUE;
11529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
11539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
11569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfinish_pass2 (j_decompress_ptr cinfo)
11579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
11589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* no work */
11599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
11609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
11639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Initialize for each processing pass.
11649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
11659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
11679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectstart_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
11689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
11699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
11709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  hist3d histogram = cquantize->histogram;
11719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int i;
11729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Only F-S dithering or no dithering is supported. */
11749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* If user asks for ordered dither, give him F-S. */
11759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (cinfo->dither_mode != JDITHER_NONE)
11769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cinfo->dither_mode = JDITHER_FS;
11779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (is_pre_scan) {
11799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Set up method pointers */
11809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->pub.color_quantize = prescan_quantize;
11819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->pub.finish_pass = finish_pass1;
11829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->needs_zeroed = TRUE; /* Always zero histogram */
11839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  } else {
11849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Set up method pointers */
11859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (cinfo->dither_mode == JDITHER_FS)
11869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cquantize->pub.color_quantize = pass2_fs_dither;
11879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    else
11889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cquantize->pub.color_quantize = pass2_no_dither;
11899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->pub.finish_pass = finish_pass2;
11909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Make sure color count is acceptable */
11929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    i = cinfo->actual_number_of_colors;
11939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (i < 1)
11949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
11959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (i > MAXNUMCOLORS)
11969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
11979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
11989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (cinfo->dither_mode == JDITHER_FS) {
11999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      size_t arraysize = (size_t) ((cinfo->output_width + 2) *
12009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				   (3 * SIZEOF(FSERROR)));
12019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Allocate Floyd-Steinberg workspace if we didn't already. */
12029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (cquantize->fserrors == NULL)
12039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
12049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
12059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Initialize the propagated errors to zero. */
12069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      jzero_far((void FAR *) cquantize->fserrors, arraysize);
12079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Make the error-limit table if we didn't already. */
12089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (cquantize->error_limiter == NULL)
12099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	init_error_limit(cinfo);
12109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      cquantize->on_odd_row = FALSE;
12119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
12129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
12149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Zero the histogram or inverse color map, if necessary */
12159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (cquantize->needs_zeroed) {
12169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (i = 0; i < HIST_C0_ELEMS; i++) {
12179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      jzero_far((void FAR *) histogram[i],
12189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
12199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
12209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->needs_zeroed = FALSE;
12219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
12229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
12239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
12269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Switch to a new external colormap between output passes.
12279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
12289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
12309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectnew_color_map_2_quant (j_decompress_ptr cinfo)
12319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
12329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
12339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Reset the inverse color map */
12359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->needs_zeroed = TRUE;
12369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
12379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
12409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Module initialization routine for 2-pass color quantization.
12419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
12429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void)
12449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjinit_2pass_quantizer (j_decompress_ptr cinfo)
12459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
12469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_cquantize_ptr cquantize;
12479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int i;
12489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize = (my_cquantize_ptr)
12509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
12519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				SIZEOF(my_cquantizer));
12529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
12539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->pub.start_pass = start_pass_2_quant;
12549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->pub.new_color_map = new_color_map_2_quant;
12559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->fserrors = NULL;	/* flag optional arrays not allocated */
12569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->error_limiter = NULL;
12579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Make sure jdmaster didn't give me a case I can't handle */
12599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (cinfo->out_color_components != 3)
12609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ERREXIT(cinfo, JERR_NOTIMPL);
12619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Allocate the histogram/inverse colormap storage */
12639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
12649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
12659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (i = 0; i < HIST_C0_ELEMS; i++) {
12669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
12679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ((j_common_ptr) cinfo, JPOOL_IMAGE,
12689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
12699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
12709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
12719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Allocate storage for the completed colormap, if required.
12739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * We do this now since it is FAR storage and may affect
12749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * the memory manager's space calculations.
12759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
12769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (cinfo->enable_2pass_quant) {
12779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Make sure color count is acceptable */
12789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    int desired = cinfo->desired_number_of_colors;
12799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
12809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (desired < 8)
12819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
12829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Make sure colormap indexes can be represented by JSAMPLEs */
12839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (desired > MAXNUMCOLORS)
12849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
12859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
12869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
12879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->desired = desired;
12889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  } else
12899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->sv_colormap = NULL;
12909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Only F-S dithering or no dithering is supported. */
12929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* If user asks for ordered dither, give him F-S. */
12939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (cinfo->dither_mode != JDITHER_NONE)
12949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cinfo->dither_mode = JDITHER_FS;
12959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
12969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Allocate Floyd-Steinberg workspace if necessary.
12979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * This isn't really needed until pass 2, but again it is FAR storage.
12989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * Although we will cope with a later change in dither_mode,
12999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * we do not promise to honor max_memory_to_use if dither_mode changes.
13009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
13019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (cinfo->dither_mode == JDITHER_FS) {
13029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
13039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ((j_common_ptr) cinfo, JPOOL_IMAGE,
13049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
13059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Might as well create the error-limiting table too. */
13069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    init_error_limit(cinfo);
13079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
13089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
13099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
13109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif /* QUANT_2PASS_SUPPORTED */
1311