1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * jquant2.c 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * This file was part of the Independent JPEG Group's software: 5cb93a386Sopenharmony_ci * Copyright (C) 1991-1996, Thomas G. Lane. 6cb93a386Sopenharmony_ci * libjpeg-turbo Modifications: 7cb93a386Sopenharmony_ci * Copyright (C) 2009, 2014-2015, 2020, D. R. Commander. 8cb93a386Sopenharmony_ci * For conditions of distribution and use, see the accompanying README.ijg 9cb93a386Sopenharmony_ci * file. 10cb93a386Sopenharmony_ci * 11cb93a386Sopenharmony_ci * This file contains 2-pass color quantization (color mapping) routines. 12cb93a386Sopenharmony_ci * These routines provide selection of a custom color map for an image, 13cb93a386Sopenharmony_ci * followed by mapping of the image to that color map, with optional 14cb93a386Sopenharmony_ci * Floyd-Steinberg dithering. 15cb93a386Sopenharmony_ci * It is also possible to use just the second pass to map to an arbitrary 16cb93a386Sopenharmony_ci * externally-given color map. 17cb93a386Sopenharmony_ci * 18cb93a386Sopenharmony_ci * Note: ordered dithering is not supported, since there isn't any fast 19cb93a386Sopenharmony_ci * way to compute intercolor distances; it's unclear that ordered dither's 20cb93a386Sopenharmony_ci * fundamental assumptions even hold with an irregularly spaced color map. 21cb93a386Sopenharmony_ci */ 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci#define JPEG_INTERNALS 24cb93a386Sopenharmony_ci#include "jinclude.h" 25cb93a386Sopenharmony_ci#include "jpeglib.h" 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci#ifdef QUANT_2PASS_SUPPORTED 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci/* 31cb93a386Sopenharmony_ci * This module implements the well-known Heckbert paradigm for color 32cb93a386Sopenharmony_ci * quantization. Most of the ideas used here can be traced back to 33cb93a386Sopenharmony_ci * Heckbert's seminal paper 34cb93a386Sopenharmony_ci * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", 35cb93a386Sopenharmony_ci * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. 36cb93a386Sopenharmony_ci * 37cb93a386Sopenharmony_ci * In the first pass over the image, we accumulate a histogram showing the 38cb93a386Sopenharmony_ci * usage count of each possible color. To keep the histogram to a reasonable 39cb93a386Sopenharmony_ci * size, we reduce the precision of the input; typical practice is to retain 40cb93a386Sopenharmony_ci * 5 or 6 bits per color, so that 8 or 4 different input values are counted 41cb93a386Sopenharmony_ci * in the same histogram cell. 42cb93a386Sopenharmony_ci * 43cb93a386Sopenharmony_ci * Next, the color-selection step begins with a box representing the whole 44cb93a386Sopenharmony_ci * color space, and repeatedly splits the "largest" remaining box until we 45cb93a386Sopenharmony_ci * have as many boxes as desired colors. Then the mean color in each 46cb93a386Sopenharmony_ci * remaining box becomes one of the possible output colors. 47cb93a386Sopenharmony_ci * 48cb93a386Sopenharmony_ci * The second pass over the image maps each input pixel to the closest output 49cb93a386Sopenharmony_ci * color (optionally after applying a Floyd-Steinberg dithering correction). 50cb93a386Sopenharmony_ci * This mapping is logically trivial, but making it go fast enough requires 51cb93a386Sopenharmony_ci * considerable care. 52cb93a386Sopenharmony_ci * 53cb93a386Sopenharmony_ci * Heckbert-style quantizers vary a good deal in their policies for choosing 54cb93a386Sopenharmony_ci * the "largest" box and deciding where to cut it. The particular policies 55cb93a386Sopenharmony_ci * used here have proved out well in experimental comparisons, but better ones 56cb93a386Sopenharmony_ci * may yet be found. 57cb93a386Sopenharmony_ci * 58cb93a386Sopenharmony_ci * In earlier versions of the IJG code, this module quantized in YCbCr color 59cb93a386Sopenharmony_ci * space, processing the raw upsampled data without a color conversion step. 60cb93a386Sopenharmony_ci * This allowed the color conversion math to be done only once per colormap 61cb93a386Sopenharmony_ci * entry, not once per pixel. However, that optimization precluded other 62cb93a386Sopenharmony_ci * useful optimizations (such as merging color conversion with upsampling) 63cb93a386Sopenharmony_ci * and it also interfered with desired capabilities such as quantizing to an 64cb93a386Sopenharmony_ci * externally-supplied colormap. We have therefore abandoned that approach. 65cb93a386Sopenharmony_ci * The present code works in the post-conversion color space, typically RGB. 66cb93a386Sopenharmony_ci * 67cb93a386Sopenharmony_ci * To improve the visual quality of the results, we actually work in scaled 68cb93a386Sopenharmony_ci * RGB space, giving G distances more weight than R, and R in turn more than 69cb93a386Sopenharmony_ci * B. To do everything in integer math, we must use integer scale factors. 70cb93a386Sopenharmony_ci * The 2/3/1 scale factors used here correspond loosely to the relative 71cb93a386Sopenharmony_ci * weights of the colors in the NTSC grayscale equation. 72cb93a386Sopenharmony_ci * If you want to use this code to quantize a non-RGB color space, you'll 73cb93a386Sopenharmony_ci * probably need to change these scale factors. 74cb93a386Sopenharmony_ci */ 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci#define R_SCALE 2 /* scale R distances by this much */ 77cb93a386Sopenharmony_ci#define G_SCALE 3 /* scale G distances by this much */ 78cb93a386Sopenharmony_ci#define B_SCALE 1 /* and B by this much */ 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_cistatic const int c_scales[3] = { R_SCALE, G_SCALE, B_SCALE }; 81cb93a386Sopenharmony_ci#define C0_SCALE c_scales[rgb_red[cinfo->out_color_space]] 82cb93a386Sopenharmony_ci#define C1_SCALE c_scales[rgb_green[cinfo->out_color_space]] 83cb93a386Sopenharmony_ci#define C2_SCALE c_scales[rgb_blue[cinfo->out_color_space]] 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci/* 86cb93a386Sopenharmony_ci * First we have the histogram data structure and routines for creating it. 87cb93a386Sopenharmony_ci * 88cb93a386Sopenharmony_ci * The number of bits of precision can be adjusted by changing these symbols. 89cb93a386Sopenharmony_ci * We recommend keeping 6 bits for G and 5 each for R and B. 90cb93a386Sopenharmony_ci * If you have plenty of memory and cycles, 6 bits all around gives marginally 91cb93a386Sopenharmony_ci * better results; if you are short of memory, 5 bits all around will save 92cb93a386Sopenharmony_ci * some space but degrade the results. 93cb93a386Sopenharmony_ci * To maintain a fully accurate histogram, we'd need to allocate a "long" 94cb93a386Sopenharmony_ci * (preferably unsigned long) for each cell. In practice this is overkill; 95cb93a386Sopenharmony_ci * we can get by with 16 bits per cell. Few of the cell counts will overflow, 96cb93a386Sopenharmony_ci * and clamping those that do overflow to the maximum value will give close- 97cb93a386Sopenharmony_ci * enough results. This reduces the recommended histogram size from 256Kb 98cb93a386Sopenharmony_ci * to 128Kb, which is a useful savings on PC-class machines. 99cb93a386Sopenharmony_ci * (In the second pass the histogram space is re-used for pixel mapping data; 100cb93a386Sopenharmony_ci * in that capacity, each cell must be able to store zero to the number of 101cb93a386Sopenharmony_ci * desired colors. 16 bits/cell is plenty for that too.) 102cb93a386Sopenharmony_ci * Since the JPEG code is intended to run in small memory model on 80x86 103cb93a386Sopenharmony_ci * machines, we can't just allocate the histogram in one chunk. Instead 104cb93a386Sopenharmony_ci * of a true 3-D array, we use a row of pointers to 2-D arrays. Each 105cb93a386Sopenharmony_ci * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and 106cb93a386Sopenharmony_ci * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. 107cb93a386Sopenharmony_ci */ 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci#define MAXNUMCOLORS (MAXJSAMPLE + 1) /* maximum size of colormap */ 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci/* These will do the right thing for either R,G,B or B,G,R color order, 112cb93a386Sopenharmony_ci * but you may not like the results for other color orders. 113cb93a386Sopenharmony_ci */ 114cb93a386Sopenharmony_ci#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ 115cb93a386Sopenharmony_ci#define HIST_C1_BITS 6 /* bits of precision in G histogram */ 116cb93a386Sopenharmony_ci#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci/* Number of elements along histogram axes. */ 119cb93a386Sopenharmony_ci#define HIST_C0_ELEMS (1 << HIST_C0_BITS) 120cb93a386Sopenharmony_ci#define HIST_C1_ELEMS (1 << HIST_C1_BITS) 121cb93a386Sopenharmony_ci#define HIST_C2_ELEMS (1 << HIST_C2_BITS) 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci/* These are the amounts to shift an input value to get a histogram index. */ 124cb93a386Sopenharmony_ci#define C0_SHIFT (BITS_IN_JSAMPLE - HIST_C0_BITS) 125cb93a386Sopenharmony_ci#define C1_SHIFT (BITS_IN_JSAMPLE - HIST_C1_BITS) 126cb93a386Sopenharmony_ci#define C2_SHIFT (BITS_IN_JSAMPLE - HIST_C2_BITS) 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_citypedef UINT16 histcell; /* histogram cell; prefer an unsigned type */ 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_citypedef histcell *histptr; /* for pointers to histogram cells */ 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_citypedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */ 134cb93a386Sopenharmony_citypedef hist1d *hist2d; /* type for the 2nd-level pointers */ 135cb93a386Sopenharmony_citypedef hist2d *hist3d; /* type for top-level pointer */ 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci/* Declarations for Floyd-Steinberg dithering. 139cb93a386Sopenharmony_ci * 140cb93a386Sopenharmony_ci * Errors are accumulated into the array fserrors[], at a resolution of 141cb93a386Sopenharmony_ci * 1/16th of a pixel count. The error at a given pixel is propagated 142cb93a386Sopenharmony_ci * to its not-yet-processed neighbors using the standard F-S fractions, 143cb93a386Sopenharmony_ci * ... (here) 7/16 144cb93a386Sopenharmony_ci * 3/16 5/16 1/16 145cb93a386Sopenharmony_ci * We work left-to-right on even rows, right-to-left on odd rows. 146cb93a386Sopenharmony_ci * 147cb93a386Sopenharmony_ci * We can get away with a single array (holding one row's worth of errors) 148cb93a386Sopenharmony_ci * by using it to store the current row's errors at pixel columns not yet 149cb93a386Sopenharmony_ci * processed, but the next row's errors at columns already processed. We 150cb93a386Sopenharmony_ci * need only a few extra variables to hold the errors immediately around the 151cb93a386Sopenharmony_ci * current column. (If we are lucky, those variables are in registers, but 152cb93a386Sopenharmony_ci * even if not, they're probably cheaper to access than array elements are.) 153cb93a386Sopenharmony_ci * 154cb93a386Sopenharmony_ci * The fserrors[] array has (#columns + 2) entries; the extra entry at 155cb93a386Sopenharmony_ci * each end saves us from special-casing the first and last pixels. 156cb93a386Sopenharmony_ci * Each entry is three values long, one value for each color component. 157cb93a386Sopenharmony_ci */ 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci#if BITS_IN_JSAMPLE == 8 160cb93a386Sopenharmony_citypedef INT16 FSERROR; /* 16 bits should be enough */ 161cb93a386Sopenharmony_citypedef int LOCFSERROR; /* use 'int' for calculation temps */ 162cb93a386Sopenharmony_ci#else 163cb93a386Sopenharmony_citypedef JLONG FSERROR; /* may need more than 16 bits */ 164cb93a386Sopenharmony_citypedef JLONG LOCFSERROR; /* be sure calculation temps are big enough */ 165cb93a386Sopenharmony_ci#endif 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_citypedef FSERROR *FSERRPTR; /* pointer to error array */ 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci/* Private subobject */ 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_citypedef struct { 173cb93a386Sopenharmony_ci struct jpeg_color_quantizer pub; /* public fields */ 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci /* Space for the eventually created colormap is stashed here */ 176cb93a386Sopenharmony_ci JSAMPARRAY sv_colormap; /* colormap allocated at init time */ 177cb93a386Sopenharmony_ci int desired; /* desired # of colors = size of colormap */ 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ci /* Variables for accumulating image statistics */ 180cb93a386Sopenharmony_ci hist3d histogram; /* pointer to the histogram */ 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci boolean needs_zeroed; /* TRUE if next pass must zero histogram */ 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_ci /* Variables for Floyd-Steinberg dithering */ 185cb93a386Sopenharmony_ci FSERRPTR fserrors; /* accumulated errors */ 186cb93a386Sopenharmony_ci boolean on_odd_row; /* flag to remember which row we are on */ 187cb93a386Sopenharmony_ci int *error_limiter; /* table for clamping the applied error */ 188cb93a386Sopenharmony_ci} my_cquantizer; 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_citypedef my_cquantizer *my_cquantize_ptr; 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci/* 194cb93a386Sopenharmony_ci * Prescan some rows of pixels. 195cb93a386Sopenharmony_ci * In this module the prescan simply updates the histogram, which has been 196cb93a386Sopenharmony_ci * initialized to zeroes by start_pass. 197cb93a386Sopenharmony_ci * An output_buf parameter is required by the method signature, but no data 198cb93a386Sopenharmony_ci * is actually output (in fact the buffer controller is probably passing a 199cb93a386Sopenharmony_ci * NULL pointer). 200cb93a386Sopenharmony_ci */ 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ciMETHODDEF(void) 203cb93a386Sopenharmony_ciprescan_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf, 204cb93a386Sopenharmony_ci JSAMPARRAY output_buf, int num_rows) 205cb93a386Sopenharmony_ci{ 206cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 207cb93a386Sopenharmony_ci register JSAMPROW ptr; 208cb93a386Sopenharmony_ci register histptr histp; 209cb93a386Sopenharmony_ci register hist3d histogram = cquantize->histogram; 210cb93a386Sopenharmony_ci int row; 211cb93a386Sopenharmony_ci JDIMENSION col; 212cb93a386Sopenharmony_ci JDIMENSION width = cinfo->output_width; 213cb93a386Sopenharmony_ci 214cb93a386Sopenharmony_ci for (row = 0; row < num_rows; row++) { 215cb93a386Sopenharmony_ci ptr = input_buf[row]; 216cb93a386Sopenharmony_ci for (col = width; col > 0; col--) { 217cb93a386Sopenharmony_ci /* get pixel value and index into the histogram */ 218cb93a386Sopenharmony_ci histp = &histogram[ptr[0] >> C0_SHIFT] 219cb93a386Sopenharmony_ci [ptr[1] >> C1_SHIFT] 220cb93a386Sopenharmony_ci [ptr[2] >> C2_SHIFT]; 221cb93a386Sopenharmony_ci /* increment, check for overflow and undo increment if so. */ 222cb93a386Sopenharmony_ci if (++(*histp) <= 0) 223cb93a386Sopenharmony_ci (*histp)--; 224cb93a386Sopenharmony_ci ptr += 3; 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci } 227cb93a386Sopenharmony_ci} 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ci 230cb93a386Sopenharmony_ci/* 231cb93a386Sopenharmony_ci * Next we have the really interesting routines: selection of a colormap 232cb93a386Sopenharmony_ci * given the completed histogram. 233cb93a386Sopenharmony_ci * These routines work with a list of "boxes", each representing a rectangular 234cb93a386Sopenharmony_ci * subset of the input color space (to histogram precision). 235cb93a386Sopenharmony_ci */ 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_citypedef struct { 238cb93a386Sopenharmony_ci /* The bounds of the box (inclusive); expressed as histogram indexes */ 239cb93a386Sopenharmony_ci int c0min, c0max; 240cb93a386Sopenharmony_ci int c1min, c1max; 241cb93a386Sopenharmony_ci int c2min, c2max; 242cb93a386Sopenharmony_ci /* The volume (actually 2-norm) of the box */ 243cb93a386Sopenharmony_ci JLONG volume; 244cb93a386Sopenharmony_ci /* The number of nonzero histogram cells within this box */ 245cb93a386Sopenharmony_ci long colorcount; 246cb93a386Sopenharmony_ci} box; 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_citypedef box *boxptr; 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_ci 251cb93a386Sopenharmony_ciLOCAL(boxptr) 252cb93a386Sopenharmony_cifind_biggest_color_pop(boxptr boxlist, int numboxes) 253cb93a386Sopenharmony_ci/* Find the splittable box with the largest color population */ 254cb93a386Sopenharmony_ci/* Returns NULL if no splittable boxes remain */ 255cb93a386Sopenharmony_ci{ 256cb93a386Sopenharmony_ci register boxptr boxp; 257cb93a386Sopenharmony_ci register int i; 258cb93a386Sopenharmony_ci register long maxc = 0; 259cb93a386Sopenharmony_ci boxptr which = NULL; 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ci for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { 262cb93a386Sopenharmony_ci if (boxp->colorcount > maxc && boxp->volume > 0) { 263cb93a386Sopenharmony_ci which = boxp; 264cb93a386Sopenharmony_ci maxc = boxp->colorcount; 265cb93a386Sopenharmony_ci } 266cb93a386Sopenharmony_ci } 267cb93a386Sopenharmony_ci return which; 268cb93a386Sopenharmony_ci} 269cb93a386Sopenharmony_ci 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_ciLOCAL(boxptr) 272cb93a386Sopenharmony_cifind_biggest_volume(boxptr boxlist, int numboxes) 273cb93a386Sopenharmony_ci/* Find the splittable box with the largest (scaled) volume */ 274cb93a386Sopenharmony_ci/* Returns NULL if no splittable boxes remain */ 275cb93a386Sopenharmony_ci{ 276cb93a386Sopenharmony_ci register boxptr boxp; 277cb93a386Sopenharmony_ci register int i; 278cb93a386Sopenharmony_ci register JLONG maxv = 0; 279cb93a386Sopenharmony_ci boxptr which = NULL; 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ci for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { 282cb93a386Sopenharmony_ci if (boxp->volume > maxv) { 283cb93a386Sopenharmony_ci which = boxp; 284cb93a386Sopenharmony_ci maxv = boxp->volume; 285cb93a386Sopenharmony_ci } 286cb93a386Sopenharmony_ci } 287cb93a386Sopenharmony_ci return which; 288cb93a386Sopenharmony_ci} 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_ciLOCAL(void) 292cb93a386Sopenharmony_ciupdate_box(j_decompress_ptr cinfo, boxptr boxp) 293cb93a386Sopenharmony_ci/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ 294cb93a386Sopenharmony_ci/* and recompute its volume and population */ 295cb93a386Sopenharmony_ci{ 296cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 297cb93a386Sopenharmony_ci hist3d histogram = cquantize->histogram; 298cb93a386Sopenharmony_ci histptr histp; 299cb93a386Sopenharmony_ci int c0, c1, c2; 300cb93a386Sopenharmony_ci int c0min, c0max, c1min, c1max, c2min, c2max; 301cb93a386Sopenharmony_ci JLONG dist0, dist1, dist2; 302cb93a386Sopenharmony_ci long ccount; 303cb93a386Sopenharmony_ci 304cb93a386Sopenharmony_ci c0min = boxp->c0min; c0max = boxp->c0max; 305cb93a386Sopenharmony_ci c1min = boxp->c1min; c1max = boxp->c1max; 306cb93a386Sopenharmony_ci c2min = boxp->c2min; c2max = boxp->c2max; 307cb93a386Sopenharmony_ci 308cb93a386Sopenharmony_ci if (c0max > c0min) 309cb93a386Sopenharmony_ci for (c0 = c0min; c0 <= c0max; c0++) 310cb93a386Sopenharmony_ci for (c1 = c1min; c1 <= c1max; c1++) { 311cb93a386Sopenharmony_ci histp = &histogram[c0][c1][c2min]; 312cb93a386Sopenharmony_ci for (c2 = c2min; c2 <= c2max; c2++) 313cb93a386Sopenharmony_ci if (*histp++ != 0) { 314cb93a386Sopenharmony_ci boxp->c0min = c0min = c0; 315cb93a386Sopenharmony_ci goto have_c0min; 316cb93a386Sopenharmony_ci } 317cb93a386Sopenharmony_ci } 318cb93a386Sopenharmony_cihave_c0min: 319cb93a386Sopenharmony_ci if (c0max > c0min) 320cb93a386Sopenharmony_ci for (c0 = c0max; c0 >= c0min; c0--) 321cb93a386Sopenharmony_ci for (c1 = c1min; c1 <= c1max; c1++) { 322cb93a386Sopenharmony_ci histp = &histogram[c0][c1][c2min]; 323cb93a386Sopenharmony_ci for (c2 = c2min; c2 <= c2max; c2++) 324cb93a386Sopenharmony_ci if (*histp++ != 0) { 325cb93a386Sopenharmony_ci boxp->c0max = c0max = c0; 326cb93a386Sopenharmony_ci goto have_c0max; 327cb93a386Sopenharmony_ci } 328cb93a386Sopenharmony_ci } 329cb93a386Sopenharmony_cihave_c0max: 330cb93a386Sopenharmony_ci if (c1max > c1min) 331cb93a386Sopenharmony_ci for (c1 = c1min; c1 <= c1max; c1++) 332cb93a386Sopenharmony_ci for (c0 = c0min; c0 <= c0max; c0++) { 333cb93a386Sopenharmony_ci histp = &histogram[c0][c1][c2min]; 334cb93a386Sopenharmony_ci for (c2 = c2min; c2 <= c2max; c2++) 335cb93a386Sopenharmony_ci if (*histp++ != 0) { 336cb93a386Sopenharmony_ci boxp->c1min = c1min = c1; 337cb93a386Sopenharmony_ci goto have_c1min; 338cb93a386Sopenharmony_ci } 339cb93a386Sopenharmony_ci } 340cb93a386Sopenharmony_cihave_c1min: 341cb93a386Sopenharmony_ci if (c1max > c1min) 342cb93a386Sopenharmony_ci for (c1 = c1max; c1 >= c1min; c1--) 343cb93a386Sopenharmony_ci for (c0 = c0min; c0 <= c0max; c0++) { 344cb93a386Sopenharmony_ci histp = &histogram[c0][c1][c2min]; 345cb93a386Sopenharmony_ci for (c2 = c2min; c2 <= c2max; c2++) 346cb93a386Sopenharmony_ci if (*histp++ != 0) { 347cb93a386Sopenharmony_ci boxp->c1max = c1max = c1; 348cb93a386Sopenharmony_ci goto have_c1max; 349cb93a386Sopenharmony_ci } 350cb93a386Sopenharmony_ci } 351cb93a386Sopenharmony_cihave_c1max: 352cb93a386Sopenharmony_ci if (c2max > c2min) 353cb93a386Sopenharmony_ci for (c2 = c2min; c2 <= c2max; c2++) 354cb93a386Sopenharmony_ci for (c0 = c0min; c0 <= c0max; c0++) { 355cb93a386Sopenharmony_ci histp = &histogram[c0][c1min][c2]; 356cb93a386Sopenharmony_ci for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) 357cb93a386Sopenharmony_ci if (*histp != 0) { 358cb93a386Sopenharmony_ci boxp->c2min = c2min = c2; 359cb93a386Sopenharmony_ci goto have_c2min; 360cb93a386Sopenharmony_ci } 361cb93a386Sopenharmony_ci } 362cb93a386Sopenharmony_cihave_c2min: 363cb93a386Sopenharmony_ci if (c2max > c2min) 364cb93a386Sopenharmony_ci for (c2 = c2max; c2 >= c2min; c2--) 365cb93a386Sopenharmony_ci for (c0 = c0min; c0 <= c0max; c0++) { 366cb93a386Sopenharmony_ci histp = &histogram[c0][c1min][c2]; 367cb93a386Sopenharmony_ci for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) 368cb93a386Sopenharmony_ci if (*histp != 0) { 369cb93a386Sopenharmony_ci boxp->c2max = c2max = c2; 370cb93a386Sopenharmony_ci goto have_c2max; 371cb93a386Sopenharmony_ci } 372cb93a386Sopenharmony_ci } 373cb93a386Sopenharmony_cihave_c2max: 374cb93a386Sopenharmony_ci 375cb93a386Sopenharmony_ci /* Update box volume. 376cb93a386Sopenharmony_ci * We use 2-norm rather than real volume here; this biases the method 377cb93a386Sopenharmony_ci * against making long narrow boxes, and it has the side benefit that 378cb93a386Sopenharmony_ci * a box is splittable iff norm > 0. 379cb93a386Sopenharmony_ci * Since the differences are expressed in histogram-cell units, 380cb93a386Sopenharmony_ci * we have to shift back to JSAMPLE units to get consistent distances; 381cb93a386Sopenharmony_ci * after which, we scale according to the selected distance scale factors. 382cb93a386Sopenharmony_ci */ 383cb93a386Sopenharmony_ci dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; 384cb93a386Sopenharmony_ci dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; 385cb93a386Sopenharmony_ci dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; 386cb93a386Sopenharmony_ci boxp->volume = dist0 * dist0 + dist1 * dist1 + dist2 * dist2; 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci /* Now scan remaining volume of box and compute population */ 389cb93a386Sopenharmony_ci ccount = 0; 390cb93a386Sopenharmony_ci for (c0 = c0min; c0 <= c0max; c0++) 391cb93a386Sopenharmony_ci for (c1 = c1min; c1 <= c1max; c1++) { 392cb93a386Sopenharmony_ci histp = &histogram[c0][c1][c2min]; 393cb93a386Sopenharmony_ci for (c2 = c2min; c2 <= c2max; c2++, histp++) 394cb93a386Sopenharmony_ci if (*histp != 0) { 395cb93a386Sopenharmony_ci ccount++; 396cb93a386Sopenharmony_ci } 397cb93a386Sopenharmony_ci } 398cb93a386Sopenharmony_ci boxp->colorcount = ccount; 399cb93a386Sopenharmony_ci} 400cb93a386Sopenharmony_ci 401cb93a386Sopenharmony_ci 402cb93a386Sopenharmony_ciLOCAL(int) 403cb93a386Sopenharmony_cimedian_cut(j_decompress_ptr cinfo, boxptr boxlist, int numboxes, 404cb93a386Sopenharmony_ci int desired_colors) 405cb93a386Sopenharmony_ci/* Repeatedly select and split the largest box until we have enough boxes */ 406cb93a386Sopenharmony_ci{ 407cb93a386Sopenharmony_ci int n, lb; 408cb93a386Sopenharmony_ci int c0, c1, c2, cmax; 409cb93a386Sopenharmony_ci register boxptr b1, b2; 410cb93a386Sopenharmony_ci 411cb93a386Sopenharmony_ci while (numboxes < desired_colors) { 412cb93a386Sopenharmony_ci /* Select box to split. 413cb93a386Sopenharmony_ci * Current algorithm: by population for first half, then by volume. 414cb93a386Sopenharmony_ci */ 415cb93a386Sopenharmony_ci if (numboxes * 2 <= desired_colors) { 416cb93a386Sopenharmony_ci b1 = find_biggest_color_pop(boxlist, numboxes); 417cb93a386Sopenharmony_ci } else { 418cb93a386Sopenharmony_ci b1 = find_biggest_volume(boxlist, numboxes); 419cb93a386Sopenharmony_ci } 420cb93a386Sopenharmony_ci if (b1 == NULL) /* no splittable boxes left! */ 421cb93a386Sopenharmony_ci break; 422cb93a386Sopenharmony_ci b2 = &boxlist[numboxes]; /* where new box will go */ 423cb93a386Sopenharmony_ci /* Copy the color bounds to the new box. */ 424cb93a386Sopenharmony_ci b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; 425cb93a386Sopenharmony_ci b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; 426cb93a386Sopenharmony_ci /* Choose which axis to split the box on. 427cb93a386Sopenharmony_ci * Current algorithm: longest scaled axis. 428cb93a386Sopenharmony_ci * See notes in update_box about scaling distances. 429cb93a386Sopenharmony_ci */ 430cb93a386Sopenharmony_ci c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; 431cb93a386Sopenharmony_ci c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; 432cb93a386Sopenharmony_ci c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; 433cb93a386Sopenharmony_ci /* We want to break any ties in favor of green, then red, blue last. 434cb93a386Sopenharmony_ci * This code does the right thing for R,G,B or B,G,R color orders only. 435cb93a386Sopenharmony_ci */ 436cb93a386Sopenharmony_ci if (rgb_red[cinfo->out_color_space] == 0) { 437cb93a386Sopenharmony_ci cmax = c1; n = 1; 438cb93a386Sopenharmony_ci if (c0 > cmax) { cmax = c0; n = 0; } 439cb93a386Sopenharmony_ci if (c2 > cmax) { n = 2; } 440cb93a386Sopenharmony_ci } else { 441cb93a386Sopenharmony_ci cmax = c1; n = 1; 442cb93a386Sopenharmony_ci if (c2 > cmax) { cmax = c2; n = 2; } 443cb93a386Sopenharmony_ci if (c0 > cmax) { n = 0; } 444cb93a386Sopenharmony_ci } 445cb93a386Sopenharmony_ci /* Choose split point along selected axis, and update box bounds. 446cb93a386Sopenharmony_ci * Current algorithm: split at halfway point. 447cb93a386Sopenharmony_ci * (Since the box has been shrunk to minimum volume, 448cb93a386Sopenharmony_ci * any split will produce two nonempty subboxes.) 449cb93a386Sopenharmony_ci * Note that lb value is max for lower box, so must be < old max. 450cb93a386Sopenharmony_ci */ 451cb93a386Sopenharmony_ci switch (n) { 452cb93a386Sopenharmony_ci case 0: 453cb93a386Sopenharmony_ci lb = (b1->c0max + b1->c0min) / 2; 454cb93a386Sopenharmony_ci b1->c0max = lb; 455cb93a386Sopenharmony_ci b2->c0min = lb + 1; 456cb93a386Sopenharmony_ci break; 457cb93a386Sopenharmony_ci case 1: 458cb93a386Sopenharmony_ci lb = (b1->c1max + b1->c1min) / 2; 459cb93a386Sopenharmony_ci b1->c1max = lb; 460cb93a386Sopenharmony_ci b2->c1min = lb + 1; 461cb93a386Sopenharmony_ci break; 462cb93a386Sopenharmony_ci case 2: 463cb93a386Sopenharmony_ci lb = (b1->c2max + b1->c2min) / 2; 464cb93a386Sopenharmony_ci b1->c2max = lb; 465cb93a386Sopenharmony_ci b2->c2min = lb + 1; 466cb93a386Sopenharmony_ci break; 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci /* Update stats for boxes */ 469cb93a386Sopenharmony_ci update_box(cinfo, b1); 470cb93a386Sopenharmony_ci update_box(cinfo, b2); 471cb93a386Sopenharmony_ci numboxes++; 472cb93a386Sopenharmony_ci } 473cb93a386Sopenharmony_ci return numboxes; 474cb93a386Sopenharmony_ci} 475cb93a386Sopenharmony_ci 476cb93a386Sopenharmony_ci 477cb93a386Sopenharmony_ciLOCAL(void) 478cb93a386Sopenharmony_cicompute_color(j_decompress_ptr cinfo, boxptr boxp, int icolor) 479cb93a386Sopenharmony_ci/* Compute representative color for a box, put it in colormap[icolor] */ 480cb93a386Sopenharmony_ci{ 481cb93a386Sopenharmony_ci /* Current algorithm: mean weighted by pixels (not colors) */ 482cb93a386Sopenharmony_ci /* Note it is important to get the rounding correct! */ 483cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 484cb93a386Sopenharmony_ci hist3d histogram = cquantize->histogram; 485cb93a386Sopenharmony_ci histptr histp; 486cb93a386Sopenharmony_ci int c0, c1, c2; 487cb93a386Sopenharmony_ci int c0min, c0max, c1min, c1max, c2min, c2max; 488cb93a386Sopenharmony_ci long count; 489cb93a386Sopenharmony_ci long total = 0; 490cb93a386Sopenharmony_ci long c0total = 0; 491cb93a386Sopenharmony_ci long c1total = 0; 492cb93a386Sopenharmony_ci long c2total = 0; 493cb93a386Sopenharmony_ci 494cb93a386Sopenharmony_ci c0min = boxp->c0min; c0max = boxp->c0max; 495cb93a386Sopenharmony_ci c1min = boxp->c1min; c1max = boxp->c1max; 496cb93a386Sopenharmony_ci c2min = boxp->c2min; c2max = boxp->c2max; 497cb93a386Sopenharmony_ci 498cb93a386Sopenharmony_ci for (c0 = c0min; c0 <= c0max; c0++) 499cb93a386Sopenharmony_ci for (c1 = c1min; c1 <= c1max; c1++) { 500cb93a386Sopenharmony_ci histp = &histogram[c0][c1][c2min]; 501cb93a386Sopenharmony_ci for (c2 = c2min; c2 <= c2max; c2++) { 502cb93a386Sopenharmony_ci if ((count = *histp++) != 0) { 503cb93a386Sopenharmony_ci total += count; 504cb93a386Sopenharmony_ci c0total += ((c0 << C0_SHIFT) + ((1 << C0_SHIFT) >> 1)) * count; 505cb93a386Sopenharmony_ci c1total += ((c1 << C1_SHIFT) + ((1 << C1_SHIFT) >> 1)) * count; 506cb93a386Sopenharmony_ci c2total += ((c2 << C2_SHIFT) + ((1 << C2_SHIFT) >> 1)) * count; 507cb93a386Sopenharmony_ci } 508cb93a386Sopenharmony_ci } 509cb93a386Sopenharmony_ci } 510cb93a386Sopenharmony_ci 511cb93a386Sopenharmony_ci cinfo->colormap[0][icolor] = (JSAMPLE)((c0total + (total >> 1)) / total); 512cb93a386Sopenharmony_ci cinfo->colormap[1][icolor] = (JSAMPLE)((c1total + (total >> 1)) / total); 513cb93a386Sopenharmony_ci cinfo->colormap[2][icolor] = (JSAMPLE)((c2total + (total >> 1)) / total); 514cb93a386Sopenharmony_ci} 515cb93a386Sopenharmony_ci 516cb93a386Sopenharmony_ci 517cb93a386Sopenharmony_ciLOCAL(void) 518cb93a386Sopenharmony_ciselect_colors(j_decompress_ptr cinfo, int desired_colors) 519cb93a386Sopenharmony_ci/* Master routine for color selection */ 520cb93a386Sopenharmony_ci{ 521cb93a386Sopenharmony_ci boxptr boxlist; 522cb93a386Sopenharmony_ci int numboxes; 523cb93a386Sopenharmony_ci int i; 524cb93a386Sopenharmony_ci 525cb93a386Sopenharmony_ci /* Allocate workspace for box list */ 526cb93a386Sopenharmony_ci boxlist = (boxptr)(*cinfo->mem->alloc_small) 527cb93a386Sopenharmony_ci ((j_common_ptr)cinfo, JPOOL_IMAGE, desired_colors * sizeof(box)); 528cb93a386Sopenharmony_ci /* Initialize one box containing whole space */ 529cb93a386Sopenharmony_ci numboxes = 1; 530cb93a386Sopenharmony_ci boxlist[0].c0min = 0; 531cb93a386Sopenharmony_ci boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; 532cb93a386Sopenharmony_ci boxlist[0].c1min = 0; 533cb93a386Sopenharmony_ci boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; 534cb93a386Sopenharmony_ci boxlist[0].c2min = 0; 535cb93a386Sopenharmony_ci boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; 536cb93a386Sopenharmony_ci /* Shrink it to actually-used volume and set its statistics */ 537cb93a386Sopenharmony_ci update_box(cinfo, &boxlist[0]); 538cb93a386Sopenharmony_ci /* Perform median-cut to produce final box list */ 539cb93a386Sopenharmony_ci numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); 540cb93a386Sopenharmony_ci /* Compute the representative color for each box, fill colormap */ 541cb93a386Sopenharmony_ci for (i = 0; i < numboxes; i++) 542cb93a386Sopenharmony_ci compute_color(cinfo, &boxlist[i], i); 543cb93a386Sopenharmony_ci cinfo->actual_number_of_colors = numboxes; 544cb93a386Sopenharmony_ci TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); 545cb93a386Sopenharmony_ci} 546cb93a386Sopenharmony_ci 547cb93a386Sopenharmony_ci 548cb93a386Sopenharmony_ci/* 549cb93a386Sopenharmony_ci * These routines are concerned with the time-critical task of mapping input 550cb93a386Sopenharmony_ci * colors to the nearest color in the selected colormap. 551cb93a386Sopenharmony_ci * 552cb93a386Sopenharmony_ci * We re-use the histogram space as an "inverse color map", essentially a 553cb93a386Sopenharmony_ci * cache for the results of nearest-color searches. All colors within a 554cb93a386Sopenharmony_ci * histogram cell will be mapped to the same colormap entry, namely the one 555cb93a386Sopenharmony_ci * closest to the cell's center. This may not be quite the closest entry to 556cb93a386Sopenharmony_ci * the actual input color, but it's almost as good. A zero in the cache 557cb93a386Sopenharmony_ci * indicates we haven't found the nearest color for that cell yet; the array 558cb93a386Sopenharmony_ci * is cleared to zeroes before starting the mapping pass. When we find the 559cb93a386Sopenharmony_ci * nearest color for a cell, its colormap index plus one is recorded in the 560cb93a386Sopenharmony_ci * cache for future use. The pass2 scanning routines call fill_inverse_cmap 561cb93a386Sopenharmony_ci * when they need to use an unfilled entry in the cache. 562cb93a386Sopenharmony_ci * 563cb93a386Sopenharmony_ci * Our method of efficiently finding nearest colors is based on the "locally 564cb93a386Sopenharmony_ci * sorted search" idea described by Heckbert and on the incremental distance 565cb93a386Sopenharmony_ci * calculation described by Spencer W. Thomas in chapter III.1 of Graphics 566cb93a386Sopenharmony_ci * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that 567cb93a386Sopenharmony_ci * the distances from a given colormap entry to each cell of the histogram can 568cb93a386Sopenharmony_ci * be computed quickly using an incremental method: the differences between 569cb93a386Sopenharmony_ci * distances to adjacent cells themselves differ by a constant. This allows a 570cb93a386Sopenharmony_ci * fairly fast implementation of the "brute force" approach of computing the 571cb93a386Sopenharmony_ci * distance from every colormap entry to every histogram cell. Unfortunately, 572cb93a386Sopenharmony_ci * it needs a work array to hold the best-distance-so-far for each histogram 573cb93a386Sopenharmony_ci * cell (because the inner loop has to be over cells, not colormap entries). 574cb93a386Sopenharmony_ci * The work array elements have to be JLONGs, so the work array would need 575cb93a386Sopenharmony_ci * 256Kb at our recommended precision. This is not feasible in DOS machines. 576cb93a386Sopenharmony_ci * 577cb93a386Sopenharmony_ci * To get around these problems, we apply Thomas' method to compute the 578cb93a386Sopenharmony_ci * nearest colors for only the cells within a small subbox of the histogram. 579cb93a386Sopenharmony_ci * The work array need be only as big as the subbox, so the memory usage 580cb93a386Sopenharmony_ci * problem is solved. Furthermore, we need not fill subboxes that are never 581cb93a386Sopenharmony_ci * referenced in pass2; many images use only part of the color gamut, so a 582cb93a386Sopenharmony_ci * fair amount of work is saved. An additional advantage of this 583cb93a386Sopenharmony_ci * approach is that we can apply Heckbert's locality criterion to quickly 584cb93a386Sopenharmony_ci * eliminate colormap entries that are far away from the subbox; typically 585cb93a386Sopenharmony_ci * three-fourths of the colormap entries are rejected by Heckbert's criterion, 586cb93a386Sopenharmony_ci * and we need not compute their distances to individual cells in the subbox. 587cb93a386Sopenharmony_ci * The speed of this approach is heavily influenced by the subbox size: too 588cb93a386Sopenharmony_ci * small means too much overhead, too big loses because Heckbert's criterion 589cb93a386Sopenharmony_ci * can't eliminate as many colormap entries. Empirically the best subbox 590cb93a386Sopenharmony_ci * size seems to be about 1/512th of the histogram (1/8th in each direction). 591cb93a386Sopenharmony_ci * 592cb93a386Sopenharmony_ci * Thomas' article also describes a refined method which is asymptotically 593cb93a386Sopenharmony_ci * faster than the brute-force method, but it is also far more complex and 594cb93a386Sopenharmony_ci * cannot efficiently be applied to small subboxes. It is therefore not 595cb93a386Sopenharmony_ci * useful for programs intended to be portable to DOS machines. On machines 596cb93a386Sopenharmony_ci * with plenty of memory, filling the whole histogram in one shot with Thomas' 597cb93a386Sopenharmony_ci * refined method might be faster than the present code --- but then again, 598cb93a386Sopenharmony_ci * it might not be any faster, and it's certainly more complicated. 599cb93a386Sopenharmony_ci */ 600cb93a386Sopenharmony_ci 601cb93a386Sopenharmony_ci 602cb93a386Sopenharmony_ci/* log2(histogram cells in update box) for each axis; this can be adjusted */ 603cb93a386Sopenharmony_ci#define BOX_C0_LOG (HIST_C0_BITS - 3) 604cb93a386Sopenharmony_ci#define BOX_C1_LOG (HIST_C1_BITS - 3) 605cb93a386Sopenharmony_ci#define BOX_C2_LOG (HIST_C2_BITS - 3) 606cb93a386Sopenharmony_ci 607cb93a386Sopenharmony_ci#define BOX_C0_ELEMS (1 << BOX_C0_LOG) /* # of hist cells in update box */ 608cb93a386Sopenharmony_ci#define BOX_C1_ELEMS (1 << BOX_C1_LOG) 609cb93a386Sopenharmony_ci#define BOX_C2_ELEMS (1 << BOX_C2_LOG) 610cb93a386Sopenharmony_ci 611cb93a386Sopenharmony_ci#define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG) 612cb93a386Sopenharmony_ci#define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG) 613cb93a386Sopenharmony_ci#define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG) 614cb93a386Sopenharmony_ci 615cb93a386Sopenharmony_ci 616cb93a386Sopenharmony_ci/* 617cb93a386Sopenharmony_ci * The next three routines implement inverse colormap filling. They could 618cb93a386Sopenharmony_ci * all be folded into one big routine, but splitting them up this way saves 619cb93a386Sopenharmony_ci * some stack space (the mindist[] and bestdist[] arrays need not coexist) 620cb93a386Sopenharmony_ci * and may allow some compilers to produce better code by registerizing more 621cb93a386Sopenharmony_ci * inner-loop variables. 622cb93a386Sopenharmony_ci */ 623cb93a386Sopenharmony_ci 624cb93a386Sopenharmony_ciLOCAL(int) 625cb93a386Sopenharmony_cifind_nearby_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2, 626cb93a386Sopenharmony_ci JSAMPLE colorlist[]) 627cb93a386Sopenharmony_ci/* Locate the colormap entries close enough to an update box to be candidates 628cb93a386Sopenharmony_ci * for the nearest entry to some cell(s) in the update box. The update box 629cb93a386Sopenharmony_ci * is specified by the center coordinates of its first cell. The number of 630cb93a386Sopenharmony_ci * candidate colormap entries is returned, and their colormap indexes are 631cb93a386Sopenharmony_ci * placed in colorlist[]. 632cb93a386Sopenharmony_ci * This routine uses Heckbert's "locally sorted search" criterion to select 633cb93a386Sopenharmony_ci * the colors that need further consideration. 634cb93a386Sopenharmony_ci */ 635cb93a386Sopenharmony_ci{ 636cb93a386Sopenharmony_ci int numcolors = cinfo->actual_number_of_colors; 637cb93a386Sopenharmony_ci int maxc0, maxc1, maxc2; 638cb93a386Sopenharmony_ci int centerc0, centerc1, centerc2; 639cb93a386Sopenharmony_ci int i, x, ncolors; 640cb93a386Sopenharmony_ci JLONG minmaxdist, min_dist, max_dist, tdist; 641cb93a386Sopenharmony_ci JLONG mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ 642cb93a386Sopenharmony_ci 643cb93a386Sopenharmony_ci /* Compute true coordinates of update box's upper corner and center. 644cb93a386Sopenharmony_ci * Actually we compute the coordinates of the center of the upper-corner 645cb93a386Sopenharmony_ci * histogram cell, which are the upper bounds of the volume we care about. 646cb93a386Sopenharmony_ci * Note that since ">>" rounds down, the "center" values may be closer to 647cb93a386Sopenharmony_ci * min than to max; hence comparisons to them must be "<=", not "<". 648cb93a386Sopenharmony_ci */ 649cb93a386Sopenharmony_ci maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); 650cb93a386Sopenharmony_ci centerc0 = (minc0 + maxc0) >> 1; 651cb93a386Sopenharmony_ci maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); 652cb93a386Sopenharmony_ci centerc1 = (minc1 + maxc1) >> 1; 653cb93a386Sopenharmony_ci maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); 654cb93a386Sopenharmony_ci centerc2 = (minc2 + maxc2) >> 1; 655cb93a386Sopenharmony_ci 656cb93a386Sopenharmony_ci /* For each color in colormap, find: 657cb93a386Sopenharmony_ci * 1. its minimum squared-distance to any point in the update box 658cb93a386Sopenharmony_ci * (zero if color is within update box); 659cb93a386Sopenharmony_ci * 2. its maximum squared-distance to any point in the update box. 660cb93a386Sopenharmony_ci * Both of these can be found by considering only the corners of the box. 661cb93a386Sopenharmony_ci * We save the minimum distance for each color in mindist[]; 662cb93a386Sopenharmony_ci * only the smallest maximum distance is of interest. 663cb93a386Sopenharmony_ci */ 664cb93a386Sopenharmony_ci minmaxdist = 0x7FFFFFFFL; 665cb93a386Sopenharmony_ci 666cb93a386Sopenharmony_ci for (i = 0; i < numcolors; i++) { 667cb93a386Sopenharmony_ci /* We compute the squared-c0-distance term, then add in the other two. */ 668cb93a386Sopenharmony_ci x = cinfo->colormap[0][i]; 669cb93a386Sopenharmony_ci if (x < minc0) { 670cb93a386Sopenharmony_ci tdist = (x - minc0) * C0_SCALE; 671cb93a386Sopenharmony_ci min_dist = tdist * tdist; 672cb93a386Sopenharmony_ci tdist = (x - maxc0) * C0_SCALE; 673cb93a386Sopenharmony_ci max_dist = tdist * tdist; 674cb93a386Sopenharmony_ci } else if (x > maxc0) { 675cb93a386Sopenharmony_ci tdist = (x - maxc0) * C0_SCALE; 676cb93a386Sopenharmony_ci min_dist = tdist * tdist; 677cb93a386Sopenharmony_ci tdist = (x - minc0) * C0_SCALE; 678cb93a386Sopenharmony_ci max_dist = tdist * tdist; 679cb93a386Sopenharmony_ci } else { 680cb93a386Sopenharmony_ci /* within cell range so no contribution to min_dist */ 681cb93a386Sopenharmony_ci min_dist = 0; 682cb93a386Sopenharmony_ci if (x <= centerc0) { 683cb93a386Sopenharmony_ci tdist = (x - maxc0) * C0_SCALE; 684cb93a386Sopenharmony_ci max_dist = tdist * tdist; 685cb93a386Sopenharmony_ci } else { 686cb93a386Sopenharmony_ci tdist = (x - minc0) * C0_SCALE; 687cb93a386Sopenharmony_ci max_dist = tdist * tdist; 688cb93a386Sopenharmony_ci } 689cb93a386Sopenharmony_ci } 690cb93a386Sopenharmony_ci 691cb93a386Sopenharmony_ci x = cinfo->colormap[1][i]; 692cb93a386Sopenharmony_ci if (x < minc1) { 693cb93a386Sopenharmony_ci tdist = (x - minc1) * C1_SCALE; 694cb93a386Sopenharmony_ci min_dist += tdist * tdist; 695cb93a386Sopenharmony_ci tdist = (x - maxc1) * C1_SCALE; 696cb93a386Sopenharmony_ci max_dist += tdist * tdist; 697cb93a386Sopenharmony_ci } else if (x > maxc1) { 698cb93a386Sopenharmony_ci tdist = (x - maxc1) * C1_SCALE; 699cb93a386Sopenharmony_ci min_dist += tdist * tdist; 700cb93a386Sopenharmony_ci tdist = (x - minc1) * C1_SCALE; 701cb93a386Sopenharmony_ci max_dist += tdist * tdist; 702cb93a386Sopenharmony_ci } else { 703cb93a386Sopenharmony_ci /* within cell range so no contribution to min_dist */ 704cb93a386Sopenharmony_ci if (x <= centerc1) { 705cb93a386Sopenharmony_ci tdist = (x - maxc1) * C1_SCALE; 706cb93a386Sopenharmony_ci max_dist += tdist * tdist; 707cb93a386Sopenharmony_ci } else { 708cb93a386Sopenharmony_ci tdist = (x - minc1) * C1_SCALE; 709cb93a386Sopenharmony_ci max_dist += tdist * tdist; 710cb93a386Sopenharmony_ci } 711cb93a386Sopenharmony_ci } 712cb93a386Sopenharmony_ci 713cb93a386Sopenharmony_ci x = cinfo->colormap[2][i]; 714cb93a386Sopenharmony_ci if (x < minc2) { 715cb93a386Sopenharmony_ci tdist = (x - minc2) * C2_SCALE; 716cb93a386Sopenharmony_ci min_dist += tdist * tdist; 717cb93a386Sopenharmony_ci tdist = (x - maxc2) * C2_SCALE; 718cb93a386Sopenharmony_ci max_dist += tdist * tdist; 719cb93a386Sopenharmony_ci } else if (x > maxc2) { 720cb93a386Sopenharmony_ci tdist = (x - maxc2) * C2_SCALE; 721cb93a386Sopenharmony_ci min_dist += tdist * tdist; 722cb93a386Sopenharmony_ci tdist = (x - minc2) * C2_SCALE; 723cb93a386Sopenharmony_ci max_dist += tdist * tdist; 724cb93a386Sopenharmony_ci } else { 725cb93a386Sopenharmony_ci /* within cell range so no contribution to min_dist */ 726cb93a386Sopenharmony_ci if (x <= centerc2) { 727cb93a386Sopenharmony_ci tdist = (x - maxc2) * C2_SCALE; 728cb93a386Sopenharmony_ci max_dist += tdist * tdist; 729cb93a386Sopenharmony_ci } else { 730cb93a386Sopenharmony_ci tdist = (x - minc2) * C2_SCALE; 731cb93a386Sopenharmony_ci max_dist += tdist * tdist; 732cb93a386Sopenharmony_ci } 733cb93a386Sopenharmony_ci } 734cb93a386Sopenharmony_ci 735cb93a386Sopenharmony_ci mindist[i] = min_dist; /* save away the results */ 736cb93a386Sopenharmony_ci if (max_dist < minmaxdist) 737cb93a386Sopenharmony_ci minmaxdist = max_dist; 738cb93a386Sopenharmony_ci } 739cb93a386Sopenharmony_ci 740cb93a386Sopenharmony_ci /* Now we know that no cell in the update box is more than minmaxdist 741cb93a386Sopenharmony_ci * away from some colormap entry. Therefore, only colors that are 742cb93a386Sopenharmony_ci * within minmaxdist of some part of the box need be considered. 743cb93a386Sopenharmony_ci */ 744cb93a386Sopenharmony_ci ncolors = 0; 745cb93a386Sopenharmony_ci for (i = 0; i < numcolors; i++) { 746cb93a386Sopenharmony_ci if (mindist[i] <= minmaxdist) 747cb93a386Sopenharmony_ci colorlist[ncolors++] = (JSAMPLE)i; 748cb93a386Sopenharmony_ci } 749cb93a386Sopenharmony_ci return ncolors; 750cb93a386Sopenharmony_ci} 751cb93a386Sopenharmony_ci 752cb93a386Sopenharmony_ci 753cb93a386Sopenharmony_ciLOCAL(void) 754cb93a386Sopenharmony_cifind_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2, 755cb93a386Sopenharmony_ci int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) 756cb93a386Sopenharmony_ci/* Find the closest colormap entry for each cell in the update box, 757cb93a386Sopenharmony_ci * given the list of candidate colors prepared by find_nearby_colors. 758cb93a386Sopenharmony_ci * Return the indexes of the closest entries in the bestcolor[] array. 759cb93a386Sopenharmony_ci * This routine uses Thomas' incremental distance calculation method to 760cb93a386Sopenharmony_ci * find the distance from a colormap entry to successive cells in the box. 761cb93a386Sopenharmony_ci */ 762cb93a386Sopenharmony_ci{ 763cb93a386Sopenharmony_ci int ic0, ic1, ic2; 764cb93a386Sopenharmony_ci int i, icolor; 765cb93a386Sopenharmony_ci register JLONG *bptr; /* pointer into bestdist[] array */ 766cb93a386Sopenharmony_ci JSAMPLE *cptr; /* pointer into bestcolor[] array */ 767cb93a386Sopenharmony_ci JLONG dist0, dist1; /* initial distance values */ 768cb93a386Sopenharmony_ci register JLONG dist2; /* current distance in inner loop */ 769cb93a386Sopenharmony_ci JLONG xx0, xx1; /* distance increments */ 770cb93a386Sopenharmony_ci register JLONG xx2; 771cb93a386Sopenharmony_ci JLONG inc0, inc1, inc2; /* initial values for increments */ 772cb93a386Sopenharmony_ci /* This array holds the distance to the nearest-so-far color for each cell */ 773cb93a386Sopenharmony_ci JLONG bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; 774cb93a386Sopenharmony_ci 775cb93a386Sopenharmony_ci /* Initialize best-distance for each cell of the update box */ 776cb93a386Sopenharmony_ci bptr = bestdist; 777cb93a386Sopenharmony_ci for (i = BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS - 1; i >= 0; i--) 778cb93a386Sopenharmony_ci *bptr++ = 0x7FFFFFFFL; 779cb93a386Sopenharmony_ci 780cb93a386Sopenharmony_ci /* For each color selected by find_nearby_colors, 781cb93a386Sopenharmony_ci * compute its distance to the center of each cell in the box. 782cb93a386Sopenharmony_ci * If that's less than best-so-far, update best distance and color number. 783cb93a386Sopenharmony_ci */ 784cb93a386Sopenharmony_ci 785cb93a386Sopenharmony_ci /* Nominal steps between cell centers ("x" in Thomas article) */ 786cb93a386Sopenharmony_ci#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) 787cb93a386Sopenharmony_ci#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) 788cb93a386Sopenharmony_ci#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) 789cb93a386Sopenharmony_ci 790cb93a386Sopenharmony_ci for (i = 0; i < numcolors; i++) { 791cb93a386Sopenharmony_ci icolor = colorlist[i]; 792cb93a386Sopenharmony_ci /* Compute (square of) distance from minc0/c1/c2 to this color */ 793cb93a386Sopenharmony_ci inc0 = (minc0 - cinfo->colormap[0][icolor]) * C0_SCALE; 794cb93a386Sopenharmony_ci dist0 = inc0 * inc0; 795cb93a386Sopenharmony_ci inc1 = (minc1 - cinfo->colormap[1][icolor]) * C1_SCALE; 796cb93a386Sopenharmony_ci dist0 += inc1 * inc1; 797cb93a386Sopenharmony_ci inc2 = (minc2 - cinfo->colormap[2][icolor]) * C2_SCALE; 798cb93a386Sopenharmony_ci dist0 += inc2 * inc2; 799cb93a386Sopenharmony_ci /* Form the initial difference increments */ 800cb93a386Sopenharmony_ci inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; 801cb93a386Sopenharmony_ci inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; 802cb93a386Sopenharmony_ci inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; 803cb93a386Sopenharmony_ci /* Now loop over all cells in box, updating distance per Thomas method */ 804cb93a386Sopenharmony_ci bptr = bestdist; 805cb93a386Sopenharmony_ci cptr = bestcolor; 806cb93a386Sopenharmony_ci xx0 = inc0; 807cb93a386Sopenharmony_ci for (ic0 = BOX_C0_ELEMS - 1; ic0 >= 0; ic0--) { 808cb93a386Sopenharmony_ci dist1 = dist0; 809cb93a386Sopenharmony_ci xx1 = inc1; 810cb93a386Sopenharmony_ci for (ic1 = BOX_C1_ELEMS - 1; ic1 >= 0; ic1--) { 811cb93a386Sopenharmony_ci dist2 = dist1; 812cb93a386Sopenharmony_ci xx2 = inc2; 813cb93a386Sopenharmony_ci for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--) { 814cb93a386Sopenharmony_ci if (dist2 < *bptr) { 815cb93a386Sopenharmony_ci *bptr = dist2; 816cb93a386Sopenharmony_ci *cptr = (JSAMPLE)icolor; 817cb93a386Sopenharmony_ci } 818cb93a386Sopenharmony_ci dist2 += xx2; 819cb93a386Sopenharmony_ci xx2 += 2 * STEP_C2 * STEP_C2; 820cb93a386Sopenharmony_ci bptr++; 821cb93a386Sopenharmony_ci cptr++; 822cb93a386Sopenharmony_ci } 823cb93a386Sopenharmony_ci dist1 += xx1; 824cb93a386Sopenharmony_ci xx1 += 2 * STEP_C1 * STEP_C1; 825cb93a386Sopenharmony_ci } 826cb93a386Sopenharmony_ci dist0 += xx0; 827cb93a386Sopenharmony_ci xx0 += 2 * STEP_C0 * STEP_C0; 828cb93a386Sopenharmony_ci } 829cb93a386Sopenharmony_ci } 830cb93a386Sopenharmony_ci} 831cb93a386Sopenharmony_ci 832cb93a386Sopenharmony_ci 833cb93a386Sopenharmony_ciLOCAL(void) 834cb93a386Sopenharmony_cifill_inverse_cmap(j_decompress_ptr cinfo, int c0, int c1, int c2) 835cb93a386Sopenharmony_ci/* Fill the inverse-colormap entries in the update box that contains */ 836cb93a386Sopenharmony_ci/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ 837cb93a386Sopenharmony_ci/* we can fill as many others as we wish.) */ 838cb93a386Sopenharmony_ci{ 839cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 840cb93a386Sopenharmony_ci hist3d histogram = cquantize->histogram; 841cb93a386Sopenharmony_ci int minc0, minc1, minc2; /* lower left corner of update box */ 842cb93a386Sopenharmony_ci int ic0, ic1, ic2; 843cb93a386Sopenharmony_ci register JSAMPLE *cptr; /* pointer into bestcolor[] array */ 844cb93a386Sopenharmony_ci register histptr cachep; /* pointer into main cache array */ 845cb93a386Sopenharmony_ci /* This array lists the candidate colormap indexes. */ 846cb93a386Sopenharmony_ci JSAMPLE colorlist[MAXNUMCOLORS]; 847cb93a386Sopenharmony_ci int numcolors; /* number of candidate colors */ 848cb93a386Sopenharmony_ci /* This array holds the actually closest colormap index for each cell. */ 849cb93a386Sopenharmony_ci JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; 850cb93a386Sopenharmony_ci 851cb93a386Sopenharmony_ci /* Convert cell coordinates to update box ID */ 852cb93a386Sopenharmony_ci c0 >>= BOX_C0_LOG; 853cb93a386Sopenharmony_ci c1 >>= BOX_C1_LOG; 854cb93a386Sopenharmony_ci c2 >>= BOX_C2_LOG; 855cb93a386Sopenharmony_ci 856cb93a386Sopenharmony_ci /* Compute true coordinates of update box's origin corner. 857cb93a386Sopenharmony_ci * Actually we compute the coordinates of the center of the corner 858cb93a386Sopenharmony_ci * histogram cell, which are the lower bounds of the volume we care about. 859cb93a386Sopenharmony_ci */ 860cb93a386Sopenharmony_ci minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); 861cb93a386Sopenharmony_ci minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); 862cb93a386Sopenharmony_ci minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); 863cb93a386Sopenharmony_ci 864cb93a386Sopenharmony_ci /* Determine which colormap entries are close enough to be candidates 865cb93a386Sopenharmony_ci * for the nearest entry to some cell in the update box. 866cb93a386Sopenharmony_ci */ 867cb93a386Sopenharmony_ci numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); 868cb93a386Sopenharmony_ci 869cb93a386Sopenharmony_ci /* Determine the actually nearest colors. */ 870cb93a386Sopenharmony_ci find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, 871cb93a386Sopenharmony_ci bestcolor); 872cb93a386Sopenharmony_ci 873cb93a386Sopenharmony_ci /* Save the best color numbers (plus 1) in the main cache array */ 874cb93a386Sopenharmony_ci c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ 875cb93a386Sopenharmony_ci c1 <<= BOX_C1_LOG; 876cb93a386Sopenharmony_ci c2 <<= BOX_C2_LOG; 877cb93a386Sopenharmony_ci cptr = bestcolor; 878cb93a386Sopenharmony_ci for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { 879cb93a386Sopenharmony_ci for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { 880cb93a386Sopenharmony_ci cachep = &histogram[c0 + ic0][c1 + ic1][c2]; 881cb93a386Sopenharmony_ci for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { 882cb93a386Sopenharmony_ci *cachep++ = (histcell)((*cptr++) + 1); 883cb93a386Sopenharmony_ci } 884cb93a386Sopenharmony_ci } 885cb93a386Sopenharmony_ci } 886cb93a386Sopenharmony_ci} 887cb93a386Sopenharmony_ci 888cb93a386Sopenharmony_ci 889cb93a386Sopenharmony_ci/* 890cb93a386Sopenharmony_ci * Map some rows of pixels to the output colormapped representation. 891cb93a386Sopenharmony_ci */ 892cb93a386Sopenharmony_ci 893cb93a386Sopenharmony_ciMETHODDEF(void) 894cb93a386Sopenharmony_cipass2_no_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, 895cb93a386Sopenharmony_ci JSAMPARRAY output_buf, int num_rows) 896cb93a386Sopenharmony_ci/* This version performs no dithering */ 897cb93a386Sopenharmony_ci{ 898cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 899cb93a386Sopenharmony_ci hist3d histogram = cquantize->histogram; 900cb93a386Sopenharmony_ci register JSAMPROW inptr, outptr; 901cb93a386Sopenharmony_ci register histptr cachep; 902cb93a386Sopenharmony_ci register int c0, c1, c2; 903cb93a386Sopenharmony_ci int row; 904cb93a386Sopenharmony_ci JDIMENSION col; 905cb93a386Sopenharmony_ci JDIMENSION width = cinfo->output_width; 906cb93a386Sopenharmony_ci 907cb93a386Sopenharmony_ci for (row = 0; row < num_rows; row++) { 908cb93a386Sopenharmony_ci inptr = input_buf[row]; 909cb93a386Sopenharmony_ci outptr = output_buf[row]; 910cb93a386Sopenharmony_ci for (col = width; col > 0; col--) { 911cb93a386Sopenharmony_ci /* get pixel value and index into the cache */ 912cb93a386Sopenharmony_ci c0 = (*inptr++) >> C0_SHIFT; 913cb93a386Sopenharmony_ci c1 = (*inptr++) >> C1_SHIFT; 914cb93a386Sopenharmony_ci c2 = (*inptr++) >> C2_SHIFT; 915cb93a386Sopenharmony_ci cachep = &histogram[c0][c1][c2]; 916cb93a386Sopenharmony_ci /* If we have not seen this color before, find nearest colormap entry */ 917cb93a386Sopenharmony_ci /* and update the cache */ 918cb93a386Sopenharmony_ci if (*cachep == 0) 919cb93a386Sopenharmony_ci fill_inverse_cmap(cinfo, c0, c1, c2); 920cb93a386Sopenharmony_ci /* Now emit the colormap index for this cell */ 921cb93a386Sopenharmony_ci *outptr++ = (JSAMPLE)(*cachep - 1); 922cb93a386Sopenharmony_ci } 923cb93a386Sopenharmony_ci } 924cb93a386Sopenharmony_ci} 925cb93a386Sopenharmony_ci 926cb93a386Sopenharmony_ci 927cb93a386Sopenharmony_ciMETHODDEF(void) 928cb93a386Sopenharmony_cipass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, 929cb93a386Sopenharmony_ci JSAMPARRAY output_buf, int num_rows) 930cb93a386Sopenharmony_ci/* This version performs Floyd-Steinberg dithering */ 931cb93a386Sopenharmony_ci{ 932cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 933cb93a386Sopenharmony_ci hist3d histogram = cquantize->histogram; 934cb93a386Sopenharmony_ci register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ 935cb93a386Sopenharmony_ci LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ 936cb93a386Sopenharmony_ci LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ 937cb93a386Sopenharmony_ci register FSERRPTR errorptr; /* => fserrors[] at column before current */ 938cb93a386Sopenharmony_ci JSAMPROW inptr; /* => current input pixel */ 939cb93a386Sopenharmony_ci JSAMPROW outptr; /* => current output pixel */ 940cb93a386Sopenharmony_ci histptr cachep; 941cb93a386Sopenharmony_ci int dir; /* +1 or -1 depending on direction */ 942cb93a386Sopenharmony_ci int dir3; /* 3*dir, for advancing inptr & errorptr */ 943cb93a386Sopenharmony_ci int row; 944cb93a386Sopenharmony_ci JDIMENSION col; 945cb93a386Sopenharmony_ci JDIMENSION width = cinfo->output_width; 946cb93a386Sopenharmony_ci JSAMPLE *range_limit = cinfo->sample_range_limit; 947cb93a386Sopenharmony_ci int *error_limit = cquantize->error_limiter; 948cb93a386Sopenharmony_ci JSAMPROW colormap0 = cinfo->colormap[0]; 949cb93a386Sopenharmony_ci JSAMPROW colormap1 = cinfo->colormap[1]; 950cb93a386Sopenharmony_ci JSAMPROW colormap2 = cinfo->colormap[2]; 951cb93a386Sopenharmony_ci SHIFT_TEMPS 952cb93a386Sopenharmony_ci 953cb93a386Sopenharmony_ci for (row = 0; row < num_rows; row++) { 954cb93a386Sopenharmony_ci inptr = input_buf[row]; 955cb93a386Sopenharmony_ci outptr = output_buf[row]; 956cb93a386Sopenharmony_ci if (cquantize->on_odd_row) { 957cb93a386Sopenharmony_ci /* work right to left in this row */ 958cb93a386Sopenharmony_ci inptr += (width - 1) * 3; /* so point to rightmost pixel */ 959cb93a386Sopenharmony_ci outptr += width - 1; 960cb93a386Sopenharmony_ci dir = -1; 961cb93a386Sopenharmony_ci dir3 = -3; 962cb93a386Sopenharmony_ci errorptr = cquantize->fserrors + (width + 1) * 3; /* => entry after last column */ 963cb93a386Sopenharmony_ci cquantize->on_odd_row = FALSE; /* flip for next time */ 964cb93a386Sopenharmony_ci } else { 965cb93a386Sopenharmony_ci /* work left to right in this row */ 966cb93a386Sopenharmony_ci dir = 1; 967cb93a386Sopenharmony_ci dir3 = 3; 968cb93a386Sopenharmony_ci errorptr = cquantize->fserrors; /* => entry before first real column */ 969cb93a386Sopenharmony_ci cquantize->on_odd_row = TRUE; /* flip for next time */ 970cb93a386Sopenharmony_ci } 971cb93a386Sopenharmony_ci /* Preset error values: no error propagated to first pixel from left */ 972cb93a386Sopenharmony_ci cur0 = cur1 = cur2 = 0; 973cb93a386Sopenharmony_ci /* and no error propagated to row below yet */ 974cb93a386Sopenharmony_ci belowerr0 = belowerr1 = belowerr2 = 0; 975cb93a386Sopenharmony_ci bpreverr0 = bpreverr1 = bpreverr2 = 0; 976cb93a386Sopenharmony_ci 977cb93a386Sopenharmony_ci for (col = width; col > 0; col--) { 978cb93a386Sopenharmony_ci /* curN holds the error propagated from the previous pixel on the 979cb93a386Sopenharmony_ci * current line. Add the error propagated from the previous line 980cb93a386Sopenharmony_ci * to form the complete error correction term for this pixel, and 981cb93a386Sopenharmony_ci * round the error term (which is expressed * 16) to an integer. 982cb93a386Sopenharmony_ci * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct 983cb93a386Sopenharmony_ci * for either sign of the error value. 984cb93a386Sopenharmony_ci * Note: errorptr points to *previous* column's array entry. 985cb93a386Sopenharmony_ci */ 986cb93a386Sopenharmony_ci cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3 + 0] + 8, 4); 987cb93a386Sopenharmony_ci cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3 + 1] + 8, 4); 988cb93a386Sopenharmony_ci cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3 + 2] + 8, 4); 989cb93a386Sopenharmony_ci /* Limit the error using transfer function set by init_error_limit. 990cb93a386Sopenharmony_ci * See comments with init_error_limit for rationale. 991cb93a386Sopenharmony_ci */ 992cb93a386Sopenharmony_ci cur0 = error_limit[cur0]; 993cb93a386Sopenharmony_ci cur1 = error_limit[cur1]; 994cb93a386Sopenharmony_ci cur2 = error_limit[cur2]; 995cb93a386Sopenharmony_ci /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. 996cb93a386Sopenharmony_ci * The maximum error is +- MAXJSAMPLE (or less with error limiting); 997cb93a386Sopenharmony_ci * this sets the required size of the range_limit array. 998cb93a386Sopenharmony_ci */ 999cb93a386Sopenharmony_ci cur0 += inptr[0]; 1000cb93a386Sopenharmony_ci cur1 += inptr[1]; 1001cb93a386Sopenharmony_ci cur2 += inptr[2]; 1002cb93a386Sopenharmony_ci cur0 = range_limit[cur0]; 1003cb93a386Sopenharmony_ci cur1 = range_limit[cur1]; 1004cb93a386Sopenharmony_ci cur2 = range_limit[cur2]; 1005cb93a386Sopenharmony_ci /* Index into the cache with adjusted pixel value */ 1006cb93a386Sopenharmony_ci cachep = 1007cb93a386Sopenharmony_ci &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT]; 1008cb93a386Sopenharmony_ci /* If we have not seen this color before, find nearest colormap */ 1009cb93a386Sopenharmony_ci /* entry and update the cache */ 1010cb93a386Sopenharmony_ci if (*cachep == 0) 1011cb93a386Sopenharmony_ci fill_inverse_cmap(cinfo, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, 1012cb93a386Sopenharmony_ci cur2 >> C2_SHIFT); 1013cb93a386Sopenharmony_ci /* Now emit the colormap index for this cell */ 1014cb93a386Sopenharmony_ci { 1015cb93a386Sopenharmony_ci register int pixcode = *cachep - 1; 1016cb93a386Sopenharmony_ci *outptr = (JSAMPLE)pixcode; 1017cb93a386Sopenharmony_ci /* Compute representation error for this pixel */ 1018cb93a386Sopenharmony_ci cur0 -= colormap0[pixcode]; 1019cb93a386Sopenharmony_ci cur1 -= colormap1[pixcode]; 1020cb93a386Sopenharmony_ci cur2 -= colormap2[pixcode]; 1021cb93a386Sopenharmony_ci } 1022cb93a386Sopenharmony_ci /* Compute error fractions to be propagated to adjacent pixels. 1023cb93a386Sopenharmony_ci * Add these into the running sums, and simultaneously shift the 1024cb93a386Sopenharmony_ci * next-line error sums left by 1 column. 1025cb93a386Sopenharmony_ci */ 1026cb93a386Sopenharmony_ci { 1027cb93a386Sopenharmony_ci register LOCFSERROR bnexterr; 1028cb93a386Sopenharmony_ci 1029cb93a386Sopenharmony_ci bnexterr = cur0; /* Process component 0 */ 1030cb93a386Sopenharmony_ci errorptr[0] = (FSERROR)(bpreverr0 + cur0 * 3); 1031cb93a386Sopenharmony_ci bpreverr0 = belowerr0 + cur0 * 5; 1032cb93a386Sopenharmony_ci belowerr0 = bnexterr; 1033cb93a386Sopenharmony_ci cur0 *= 7; 1034cb93a386Sopenharmony_ci bnexterr = cur1; /* Process component 1 */ 1035cb93a386Sopenharmony_ci errorptr[1] = (FSERROR)(bpreverr1 + cur1 * 3); 1036cb93a386Sopenharmony_ci bpreverr1 = belowerr1 + cur1 * 5; 1037cb93a386Sopenharmony_ci belowerr1 = bnexterr; 1038cb93a386Sopenharmony_ci cur1 *= 7; 1039cb93a386Sopenharmony_ci bnexterr = cur2; /* Process component 2 */ 1040cb93a386Sopenharmony_ci errorptr[2] = (FSERROR)(bpreverr2 + cur2 * 3); 1041cb93a386Sopenharmony_ci bpreverr2 = belowerr2 + cur2 * 5; 1042cb93a386Sopenharmony_ci belowerr2 = bnexterr; 1043cb93a386Sopenharmony_ci cur2 *= 7; 1044cb93a386Sopenharmony_ci } 1045cb93a386Sopenharmony_ci /* At this point curN contains the 7/16 error value to be propagated 1046cb93a386Sopenharmony_ci * to the next pixel on the current line, and all the errors for the 1047cb93a386Sopenharmony_ci * next line have been shifted over. We are therefore ready to move on. 1048cb93a386Sopenharmony_ci */ 1049cb93a386Sopenharmony_ci inptr += dir3; /* Advance pixel pointers to next column */ 1050cb93a386Sopenharmony_ci outptr += dir; 1051cb93a386Sopenharmony_ci errorptr += dir3; /* advance errorptr to current column */ 1052cb93a386Sopenharmony_ci } 1053cb93a386Sopenharmony_ci /* Post-loop cleanup: we must unload the final error values into the 1054cb93a386Sopenharmony_ci * final fserrors[] entry. Note we need not unload belowerrN because 1055cb93a386Sopenharmony_ci * it is for the dummy column before or after the actual array. 1056cb93a386Sopenharmony_ci */ 1057cb93a386Sopenharmony_ci errorptr[0] = (FSERROR)bpreverr0; /* unload prev errs into array */ 1058cb93a386Sopenharmony_ci errorptr[1] = (FSERROR)bpreverr1; 1059cb93a386Sopenharmony_ci errorptr[2] = (FSERROR)bpreverr2; 1060cb93a386Sopenharmony_ci } 1061cb93a386Sopenharmony_ci} 1062cb93a386Sopenharmony_ci 1063cb93a386Sopenharmony_ci 1064cb93a386Sopenharmony_ci/* 1065cb93a386Sopenharmony_ci * Initialize the error-limiting transfer function (lookup table). 1066cb93a386Sopenharmony_ci * The raw F-S error computation can potentially compute error values of up to 1067cb93a386Sopenharmony_ci * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be 1068cb93a386Sopenharmony_ci * much less, otherwise obviously wrong pixels will be created. (Typical 1069cb93a386Sopenharmony_ci * effects include weird fringes at color-area boundaries, isolated bright 1070cb93a386Sopenharmony_ci * pixels in a dark area, etc.) The standard advice for avoiding this problem 1071cb93a386Sopenharmony_ci * is to ensure that the "corners" of the color cube are allocated as output 1072cb93a386Sopenharmony_ci * colors; then repeated errors in the same direction cannot cause cascading 1073cb93a386Sopenharmony_ci * error buildup. However, that only prevents the error from getting 1074cb93a386Sopenharmony_ci * completely out of hand; Aaron Giles reports that error limiting improves 1075cb93a386Sopenharmony_ci * the results even with corner colors allocated. 1076cb93a386Sopenharmony_ci * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty 1077cb93a386Sopenharmony_ci * well, but the smoother transfer function used below is even better. Thanks 1078cb93a386Sopenharmony_ci * to Aaron Giles for this idea. 1079cb93a386Sopenharmony_ci */ 1080cb93a386Sopenharmony_ci 1081cb93a386Sopenharmony_ciLOCAL(void) 1082cb93a386Sopenharmony_ciinit_error_limit(j_decompress_ptr cinfo) 1083cb93a386Sopenharmony_ci/* Allocate and fill in the error_limiter table */ 1084cb93a386Sopenharmony_ci{ 1085cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 1086cb93a386Sopenharmony_ci int *table; 1087cb93a386Sopenharmony_ci int in, out; 1088cb93a386Sopenharmony_ci 1089cb93a386Sopenharmony_ci table = (int *)(*cinfo->mem->alloc_small) 1090cb93a386Sopenharmony_ci ((j_common_ptr)cinfo, JPOOL_IMAGE, (MAXJSAMPLE * 2 + 1) * sizeof(int)); 1091cb93a386Sopenharmony_ci table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ 1092cb93a386Sopenharmony_ci cquantize->error_limiter = table; 1093cb93a386Sopenharmony_ci 1094cb93a386Sopenharmony_ci#define STEPSIZE ((MAXJSAMPLE + 1) / 16) 1095cb93a386Sopenharmony_ci /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ 1096cb93a386Sopenharmony_ci out = 0; 1097cb93a386Sopenharmony_ci for (in = 0; in < STEPSIZE; in++, out++) { 1098cb93a386Sopenharmony_ci table[in] = out; table[-in] = -out; 1099cb93a386Sopenharmony_ci } 1100cb93a386Sopenharmony_ci /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ 1101cb93a386Sopenharmony_ci for (; in < STEPSIZE * 3; in++, out += (in & 1) ? 0 : 1) { 1102cb93a386Sopenharmony_ci table[in] = out; table[-in] = -out; 1103cb93a386Sopenharmony_ci } 1104cb93a386Sopenharmony_ci /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ 1105cb93a386Sopenharmony_ci for (; in <= MAXJSAMPLE; in++) { 1106cb93a386Sopenharmony_ci table[in] = out; table[-in] = -out; 1107cb93a386Sopenharmony_ci } 1108cb93a386Sopenharmony_ci#undef STEPSIZE 1109cb93a386Sopenharmony_ci} 1110cb93a386Sopenharmony_ci 1111cb93a386Sopenharmony_ci 1112cb93a386Sopenharmony_ci/* 1113cb93a386Sopenharmony_ci * Finish up at the end of each pass. 1114cb93a386Sopenharmony_ci */ 1115cb93a386Sopenharmony_ci 1116cb93a386Sopenharmony_ciMETHODDEF(void) 1117cb93a386Sopenharmony_cifinish_pass1(j_decompress_ptr cinfo) 1118cb93a386Sopenharmony_ci{ 1119cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 1120cb93a386Sopenharmony_ci 1121cb93a386Sopenharmony_ci /* Select the representative colors and fill in cinfo->colormap */ 1122cb93a386Sopenharmony_ci cinfo->colormap = cquantize->sv_colormap; 1123cb93a386Sopenharmony_ci select_colors(cinfo, cquantize->desired); 1124cb93a386Sopenharmony_ci /* Force next pass to zero the color index table */ 1125cb93a386Sopenharmony_ci cquantize->needs_zeroed = TRUE; 1126cb93a386Sopenharmony_ci} 1127cb93a386Sopenharmony_ci 1128cb93a386Sopenharmony_ci 1129cb93a386Sopenharmony_ciMETHODDEF(void) 1130cb93a386Sopenharmony_cifinish_pass2(j_decompress_ptr cinfo) 1131cb93a386Sopenharmony_ci{ 1132cb93a386Sopenharmony_ci /* no work */ 1133cb93a386Sopenharmony_ci} 1134cb93a386Sopenharmony_ci 1135cb93a386Sopenharmony_ci 1136cb93a386Sopenharmony_ci/* 1137cb93a386Sopenharmony_ci * Initialize for each processing pass. 1138cb93a386Sopenharmony_ci */ 1139cb93a386Sopenharmony_ci 1140cb93a386Sopenharmony_ciMETHODDEF(void) 1141cb93a386Sopenharmony_cistart_pass_2_quant(j_decompress_ptr cinfo, boolean is_pre_scan) 1142cb93a386Sopenharmony_ci{ 1143cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 1144cb93a386Sopenharmony_ci hist3d histogram = cquantize->histogram; 1145cb93a386Sopenharmony_ci int i; 1146cb93a386Sopenharmony_ci 1147cb93a386Sopenharmony_ci /* Only F-S dithering or no dithering is supported. */ 1148cb93a386Sopenharmony_ci /* If user asks for ordered dither, give them F-S. */ 1149cb93a386Sopenharmony_ci if (cinfo->dither_mode != JDITHER_NONE) 1150cb93a386Sopenharmony_ci cinfo->dither_mode = JDITHER_FS; 1151cb93a386Sopenharmony_ci 1152cb93a386Sopenharmony_ci if (is_pre_scan) { 1153cb93a386Sopenharmony_ci /* Set up method pointers */ 1154cb93a386Sopenharmony_ci cquantize->pub.color_quantize = prescan_quantize; 1155cb93a386Sopenharmony_ci cquantize->pub.finish_pass = finish_pass1; 1156cb93a386Sopenharmony_ci cquantize->needs_zeroed = TRUE; /* Always zero histogram */ 1157cb93a386Sopenharmony_ci } else { 1158cb93a386Sopenharmony_ci /* Set up method pointers */ 1159cb93a386Sopenharmony_ci if (cinfo->dither_mode == JDITHER_FS) 1160cb93a386Sopenharmony_ci cquantize->pub.color_quantize = pass2_fs_dither; 1161cb93a386Sopenharmony_ci else 1162cb93a386Sopenharmony_ci cquantize->pub.color_quantize = pass2_no_dither; 1163cb93a386Sopenharmony_ci cquantize->pub.finish_pass = finish_pass2; 1164cb93a386Sopenharmony_ci 1165cb93a386Sopenharmony_ci /* Make sure color count is acceptable */ 1166cb93a386Sopenharmony_ci i = cinfo->actual_number_of_colors; 1167cb93a386Sopenharmony_ci if (i < 1) 1168cb93a386Sopenharmony_ci ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); 1169cb93a386Sopenharmony_ci if (i > MAXNUMCOLORS) 1170cb93a386Sopenharmony_ci ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); 1171cb93a386Sopenharmony_ci 1172cb93a386Sopenharmony_ci if (cinfo->dither_mode == JDITHER_FS) { 1173cb93a386Sopenharmony_ci size_t arraysize = 1174cb93a386Sopenharmony_ci (size_t)((cinfo->output_width + 2) * (3 * sizeof(FSERROR))); 1175cb93a386Sopenharmony_ci /* Allocate Floyd-Steinberg workspace if we didn't already. */ 1176cb93a386Sopenharmony_ci if (cquantize->fserrors == NULL) 1177cb93a386Sopenharmony_ci cquantize->fserrors = (FSERRPTR)(*cinfo->mem->alloc_large) 1178cb93a386Sopenharmony_ci ((j_common_ptr)cinfo, JPOOL_IMAGE, arraysize); 1179cb93a386Sopenharmony_ci /* Initialize the propagated errors to zero. */ 1180cb93a386Sopenharmony_ci jzero_far((void *)cquantize->fserrors, arraysize); 1181cb93a386Sopenharmony_ci /* Make the error-limit table if we didn't already. */ 1182cb93a386Sopenharmony_ci if (cquantize->error_limiter == NULL) 1183cb93a386Sopenharmony_ci init_error_limit(cinfo); 1184cb93a386Sopenharmony_ci cquantize->on_odd_row = FALSE; 1185cb93a386Sopenharmony_ci } 1186cb93a386Sopenharmony_ci 1187cb93a386Sopenharmony_ci } 1188cb93a386Sopenharmony_ci /* Zero the histogram or inverse color map, if necessary */ 1189cb93a386Sopenharmony_ci if (cquantize->needs_zeroed) { 1190cb93a386Sopenharmony_ci for (i = 0; i < HIST_C0_ELEMS; i++) { 1191cb93a386Sopenharmony_ci jzero_far((void *)histogram[i], 1192cb93a386Sopenharmony_ci HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof(histcell)); 1193cb93a386Sopenharmony_ci } 1194cb93a386Sopenharmony_ci cquantize->needs_zeroed = FALSE; 1195cb93a386Sopenharmony_ci } 1196cb93a386Sopenharmony_ci} 1197cb93a386Sopenharmony_ci 1198cb93a386Sopenharmony_ci 1199cb93a386Sopenharmony_ci/* 1200cb93a386Sopenharmony_ci * Switch to a new external colormap between output passes. 1201cb93a386Sopenharmony_ci */ 1202cb93a386Sopenharmony_ci 1203cb93a386Sopenharmony_ciMETHODDEF(void) 1204cb93a386Sopenharmony_cinew_color_map_2_quant(j_decompress_ptr cinfo) 1205cb93a386Sopenharmony_ci{ 1206cb93a386Sopenharmony_ci my_cquantize_ptr cquantize = (my_cquantize_ptr)cinfo->cquantize; 1207cb93a386Sopenharmony_ci 1208cb93a386Sopenharmony_ci /* Reset the inverse color map */ 1209cb93a386Sopenharmony_ci cquantize->needs_zeroed = TRUE; 1210cb93a386Sopenharmony_ci} 1211cb93a386Sopenharmony_ci 1212cb93a386Sopenharmony_ci 1213cb93a386Sopenharmony_ci/* 1214cb93a386Sopenharmony_ci * Module initialization routine for 2-pass color quantization. 1215cb93a386Sopenharmony_ci */ 1216cb93a386Sopenharmony_ci 1217cb93a386Sopenharmony_ciGLOBAL(void) 1218cb93a386Sopenharmony_cijinit_2pass_quantizer(j_decompress_ptr cinfo) 1219cb93a386Sopenharmony_ci{ 1220cb93a386Sopenharmony_ci my_cquantize_ptr cquantize; 1221cb93a386Sopenharmony_ci int i; 1222cb93a386Sopenharmony_ci 1223cb93a386Sopenharmony_ci cquantize = (my_cquantize_ptr) 1224cb93a386Sopenharmony_ci (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 1225cb93a386Sopenharmony_ci sizeof(my_cquantizer)); 1226cb93a386Sopenharmony_ci cinfo->cquantize = (struct jpeg_color_quantizer *)cquantize; 1227cb93a386Sopenharmony_ci cquantize->pub.start_pass = start_pass_2_quant; 1228cb93a386Sopenharmony_ci cquantize->pub.new_color_map = new_color_map_2_quant; 1229cb93a386Sopenharmony_ci cquantize->fserrors = NULL; /* flag optional arrays not allocated */ 1230cb93a386Sopenharmony_ci cquantize->error_limiter = NULL; 1231cb93a386Sopenharmony_ci 1232cb93a386Sopenharmony_ci /* Make sure jdmaster didn't give me a case I can't handle */ 1233cb93a386Sopenharmony_ci if (cinfo->out_color_components != 3) 1234cb93a386Sopenharmony_ci ERREXIT(cinfo, JERR_NOTIMPL); 1235cb93a386Sopenharmony_ci 1236cb93a386Sopenharmony_ci /* Allocate the histogram/inverse colormap storage */ 1237cb93a386Sopenharmony_ci cquantize->histogram = (hist3d)(*cinfo->mem->alloc_small) 1238cb93a386Sopenharmony_ci ((j_common_ptr)cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * sizeof(hist2d)); 1239cb93a386Sopenharmony_ci for (i = 0; i < HIST_C0_ELEMS; i++) { 1240cb93a386Sopenharmony_ci cquantize->histogram[i] = (hist2d)(*cinfo->mem->alloc_large) 1241cb93a386Sopenharmony_ci ((j_common_ptr)cinfo, JPOOL_IMAGE, 1242cb93a386Sopenharmony_ci HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof(histcell)); 1243cb93a386Sopenharmony_ci } 1244cb93a386Sopenharmony_ci cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ 1245cb93a386Sopenharmony_ci 1246cb93a386Sopenharmony_ci /* Allocate storage for the completed colormap, if required. 1247cb93a386Sopenharmony_ci * We do this now since it may affect the memory manager's space 1248cb93a386Sopenharmony_ci * calculations. 1249cb93a386Sopenharmony_ci */ 1250cb93a386Sopenharmony_ci if (cinfo->enable_2pass_quant) { 1251cb93a386Sopenharmony_ci /* Make sure color count is acceptable */ 1252cb93a386Sopenharmony_ci int desired = cinfo->desired_number_of_colors; 1253cb93a386Sopenharmony_ci /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ 1254cb93a386Sopenharmony_ci if (desired < 8) 1255cb93a386Sopenharmony_ci ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); 1256cb93a386Sopenharmony_ci /* Make sure colormap indexes can be represented by JSAMPLEs */ 1257cb93a386Sopenharmony_ci if (desired > MAXNUMCOLORS) 1258cb93a386Sopenharmony_ci ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); 1259cb93a386Sopenharmony_ci cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) 1260cb93a386Sopenharmony_ci ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)desired, (JDIMENSION)3); 1261cb93a386Sopenharmony_ci cquantize->desired = desired; 1262cb93a386Sopenharmony_ci } else 1263cb93a386Sopenharmony_ci cquantize->sv_colormap = NULL; 1264cb93a386Sopenharmony_ci 1265cb93a386Sopenharmony_ci /* Only F-S dithering or no dithering is supported. */ 1266cb93a386Sopenharmony_ci /* If user asks for ordered dither, give them F-S. */ 1267cb93a386Sopenharmony_ci if (cinfo->dither_mode != JDITHER_NONE) 1268cb93a386Sopenharmony_ci cinfo->dither_mode = JDITHER_FS; 1269cb93a386Sopenharmony_ci 1270cb93a386Sopenharmony_ci /* Allocate Floyd-Steinberg workspace if necessary. 1271cb93a386Sopenharmony_ci * This isn't really needed until pass 2, but again it may affect the memory 1272cb93a386Sopenharmony_ci * manager's space calculations. Although we will cope with a later change 1273cb93a386Sopenharmony_ci * in dither_mode, we do not promise to honor max_memory_to_use if 1274cb93a386Sopenharmony_ci * dither_mode changes. 1275cb93a386Sopenharmony_ci */ 1276cb93a386Sopenharmony_ci if (cinfo->dither_mode == JDITHER_FS) { 1277cb93a386Sopenharmony_ci cquantize->fserrors = (FSERRPTR)(*cinfo->mem->alloc_large) 1278cb93a386Sopenharmony_ci ((j_common_ptr)cinfo, JPOOL_IMAGE, 1279cb93a386Sopenharmony_ci (size_t)((cinfo->output_width + 2) * (3 * sizeof(FSERROR)))); 1280cb93a386Sopenharmony_ci /* Might as well create the error-limiting table too. */ 1281cb93a386Sopenharmony_ci init_error_limit(cinfo); 1282cb93a386Sopenharmony_ci } 1283cb93a386Sopenharmony_ci} 1284cb93a386Sopenharmony_ci 1285cb93a386Sopenharmony_ci#endif /* QUANT_2PASS_SUPPORTED */ 1286