Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: uzair Camera_LS_Y201 F7_Ethernet LCD_DISCO_F746NG NetworkAPI SDFileSystem mbed
jquant2.c
00001 /* 00002 * jquant2.c 00003 * 00004 * Copyright (C) 1991-1996, Thomas G. Lane. 00005 * Modified 2011 by Guido Vollbeding. 00006 * This file is part of the Independent JPEG Group's software. 00007 * For conditions of distribution and use, see the accompanying README file. 00008 * 00009 * This file contains 2-pass color quantization (color mapping) routines. 00010 * These routines provide selection of a custom color map for an image, 00011 * followed by mapping of the image to that color map, with optional 00012 * Floyd-Steinberg dithering. 00013 * It is also possible to use just the second pass to map to an arbitrary 00014 * externally-given color map. 00015 * 00016 * Note: ordered dithering is not supported, since there isn't any fast 00017 * way to compute intercolor distances; it's unclear that ordered dither's 00018 * fundamental assumptions even hold with an irregularly spaced color map. 00019 */ 00020 00021 #define JPEG_INTERNALS 00022 #include "jinclude.h" 00023 #include "jpeglib.h" 00024 00025 #ifdef QUANT_2PASS_SUPPORTED 00026 00027 00028 /* 00029 * This module implements the well-known Heckbert paradigm for color 00030 * quantization. Most of the ideas used here can be traced back to 00031 * Heckbert's seminal paper 00032 * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", 00033 * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. 00034 * 00035 * In the first pass over the image, we accumulate a histogram showing the 00036 * usage count of each possible color. To keep the histogram to a reasonable 00037 * size, we reduce the precision of the input; typical practice is to retain 00038 * 5 or 6 bits per color, so that 8 or 4 different input values are counted 00039 * in the same histogram cell. 00040 * 00041 * Next, the color-selection step begins with a box representing the whole 00042 * color space, and repeatedly splits the "largest" remaining box until we 00043 * have as many boxes as desired colors. Then the mean color in each 00044 * remaining box becomes one of the possible output colors. 00045 * 00046 * The second pass over the image maps each input pixel to the closest output 00047 * color (optionally after applying a Floyd-Steinberg dithering correction). 00048 * This mapping is logically trivial, but making it go fast enough requires 00049 * considerable care. 00050 * 00051 * Heckbert-style quantizers vary a good deal in their policies for choosing 00052 * the "largest" box and deciding where to cut it. The particular policies 00053 * used here have proved out well in experimental comparisons, but better ones 00054 * may yet be found. 00055 * 00056 * In earlier versions of the IJG code, this module quantized in YCbCr color 00057 * space, processing the raw upsampled data without a color conversion step. 00058 * This allowed the color conversion math to be done only once per colormap 00059 * entry, not once per pixel. However, that optimization precluded other 00060 * useful optimizations (such as merging color conversion with upsampling) 00061 * and it also interfered with desired capabilities such as quantizing to an 00062 * externally-supplied colormap. We have therefore abandoned that approach. 00063 * The present code works in the post-conversion color space, typically RGB. 00064 * 00065 * To improve the visual quality of the results, we actually work in scaled 00066 * RGB space, giving G distances more weight than R, and R in turn more than 00067 * B. To do everything in integer math, we must use integer scale factors. 00068 * The 2/3/1 scale factors used here correspond loosely to the relative 00069 * weights of the colors in the NTSC grayscale equation. 00070 * If you want to use this code to quantize a non-RGB color space, you'll 00071 * probably need to change these scale factors. 00072 */ 00073 00074 #define R_SCALE 2 /* scale R distances by this much */ 00075 #define G_SCALE 3 /* scale G distances by this much */ 00076 #define B_SCALE 1 /* and B by this much */ 00077 00078 /* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined 00079 * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B 00080 * and B,G,R orders. If you define some other weird order in jmorecfg.h, 00081 * you'll get compile errors until you extend this logic. In that case 00082 * you'll probably want to tweak the histogram sizes too. 00083 */ 00084 00085 #if RGB_RED == 0 00086 #define C0_SCALE R_SCALE 00087 #endif 00088 #if RGB_BLUE == 0 00089 #define C0_SCALE B_SCALE 00090 #endif 00091 #if RGB_GREEN == 1 00092 #define C1_SCALE G_SCALE 00093 #endif 00094 #if RGB_RED == 2 00095 #define C2_SCALE R_SCALE 00096 #endif 00097 #if RGB_BLUE == 2 00098 #define C2_SCALE B_SCALE 00099 #endif 00100 00101 00102 /* 00103 * First we have the histogram data structure and routines for creating it. 00104 * 00105 * The number of bits of precision can be adjusted by changing these symbols. 00106 * We recommend keeping 6 bits for G and 5 each for R and B. 00107 * If you have plenty of memory and cycles, 6 bits all around gives marginally 00108 * better results; if you are short of memory, 5 bits all around will save 00109 * some space but degrade the results. 00110 * To maintain a fully accurate histogram, we'd need to allocate a "long" 00111 * (preferably unsigned long) for each cell. In practice this is overkill; 00112 * we can get by with 16 bits per cell. Few of the cell counts will overflow, 00113 * and clamping those that do overflow to the maximum value will give close- 00114 * enough results. This reduces the recommended histogram size from 256Kb 00115 * to 128Kb, which is a useful savings on PC-class machines. 00116 * (In the second pass the histogram space is re-used for pixel mapping data; 00117 * in that capacity, each cell must be able to store zero to the number of 00118 * desired colors. 16 bits/cell is plenty for that too.) 00119 * Since the JPEG code is intended to run in small memory model on 80x86 00120 * machines, we can't just allocate the histogram in one chunk. Instead 00121 * of a true 3-D array, we use a row of pointers to 2-D arrays. Each 00122 * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and 00123 * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that 00124 * on 80x86 machines, the pointer row is in near memory but the actual 00125 * arrays are in far memory (same arrangement as we use for image arrays). 00126 */ 00127 00128 #define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ 00129 00130 /* These will do the right thing for either R,G,B or B,G,R color order, 00131 * but you may not like the results for other color orders. 00132 */ 00133 #define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ 00134 #define HIST_C1_BITS 6 /* bits of precision in G histogram */ 00135 #define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ 00136 00137 /* Number of elements along histogram axes. */ 00138 #define HIST_C0_ELEMS (1<<HIST_C0_BITS) 00139 #define HIST_C1_ELEMS (1<<HIST_C1_BITS) 00140 #define HIST_C2_ELEMS (1<<HIST_C2_BITS) 00141 00142 /* These are the amounts to shift an input value to get a histogram index. */ 00143 #define C0_SHIFT (BITS_IN_JSAMPLE-HIST_C0_BITS) 00144 #define C1_SHIFT (BITS_IN_JSAMPLE-HIST_C1_BITS) 00145 #define C2_SHIFT (BITS_IN_JSAMPLE-HIST_C2_BITS) 00146 00147 00148 typedef UINT16 histcell; /* histogram cell; prefer an unsigned type */ 00149 00150 typedef histcell FAR * histptr; /* for pointers to histogram cells */ 00151 00152 typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */ 00153 typedef hist1d FAR * hist2d; /* type for the 2nd-level pointers */ 00154 typedef hist2d * hist3d; /* type for top-level pointer */ 00155 00156 00157 /* Declarations for Floyd-Steinberg dithering. 00158 * 00159 * Errors are accumulated into the array fserrors[], at a resolution of 00160 * 1/16th of a pixel count. The error at a given pixel is propagated 00161 * to its not-yet-processed neighbors using the standard F-S fractions, 00162 * ... (here) 7/16 00163 * 3/16 5/16 1/16 00164 * We work left-to-right on even rows, right-to-left on odd rows. 00165 * 00166 * We can get away with a single array (holding one row's worth of errors) 00167 * by using it to store the current row's errors at pixel columns not yet 00168 * processed, but the next row's errors at columns already processed. We 00169 * need only a few extra variables to hold the errors immediately around the 00170 * current column. (If we are lucky, those variables are in registers, but 00171 * even if not, they're probably cheaper to access than array elements are.) 00172 * 00173 * The fserrors[] array has (#columns + 2) entries; the extra entry at 00174 * each end saves us from special-casing the first and last pixels. 00175 * Each entry is three values long, one value for each color component. 00176 * 00177 * Note: on a wide image, we might not have enough room in a PC's near data 00178 * segment to hold the error array; so it is allocated with alloc_large. 00179 */ 00180 00181 #if BITS_IN_JSAMPLE == 8 00182 typedef INT16 FSERROR; /* 16 bits should be enough */ 00183 typedef int LOCFSERROR; /* use 'int' for calculation temps */ 00184 #else 00185 typedef INT32 FSERROR; /* may need more than 16 bits */ 00186 typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ 00187 #endif 00188 00189 typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ 00190 00191 00192 /* Private subobject */ 00193 00194 typedef struct { 00195 struct jpeg_color_quantizer pub; /* public fields */ 00196 00197 /* Space for the eventually created colormap is stashed here */ 00198 JSAMPARRAY sv_colormap; /* colormap allocated at init time */ 00199 int desired; /* desired # of colors = size of colormap */ 00200 00201 /* Variables for accumulating image statistics */ 00202 hist3d histogram; /* pointer to the histogram */ 00203 00204 boolean needs_zeroed; /* TRUE if next pass must zero histogram */ 00205 00206 /* Variables for Floyd-Steinberg dithering */ 00207 FSERRPTR fserrors; /* accumulated errors */ 00208 boolean on_odd_row; /* flag to remember which row we are on */ 00209 int * error_limiter; /* table for clamping the applied error */ 00210 } my_cquantizer; 00211 00212 typedef my_cquantizer * my_cquantize_ptr; 00213 00214 00215 /* 00216 * Prescan some rows of pixels. 00217 * In this module the prescan simply updates the histogram, which has been 00218 * initialized to zeroes by start_pass. 00219 * An output_buf parameter is required by the method signature, but no data 00220 * is actually output (in fact the buffer controller is probably passing a 00221 * NULL pointer). 00222 */ 00223 00224 METHODDEF(void) 00225 prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 00226 JSAMPARRAY output_buf, int num_rows) 00227 { 00228 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 00229 register JSAMPROW ptr; 00230 register histptr histp; 00231 register hist3d histogram = cquantize->histogram; 00232 int row; 00233 JDIMENSION col; 00234 JDIMENSION width = cinfo->output_width; 00235 00236 for (row = 0; row < num_rows; row++) { 00237 ptr = input_buf[row]; 00238 for (col = width; col > 0; col--) { 00239 /* get pixel value and index into the histogram */ 00240 histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] 00241 [GETJSAMPLE(ptr[1]) >> C1_SHIFT] 00242 [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; 00243 /* increment, check for overflow and undo increment if so. */ 00244 if (++(*histp) <= 0) 00245 (*histp)--; 00246 ptr += 3; 00247 } 00248 } 00249 } 00250 00251 00252 /* 00253 * Next we have the really interesting routines: selection of a colormap 00254 * given the completed histogram. 00255 * These routines work with a list of "boxes", each representing a rectangular 00256 * subset of the input color space (to histogram precision). 00257 */ 00258 00259 typedef struct { 00260 /* The bounds of the box (inclusive); expressed as histogram indexes */ 00261 int c0min, c0max; 00262 int c1min, c1max; 00263 int c2min, c2max; 00264 /* The volume (actually 2-norm) of the box */ 00265 INT32 volume; 00266 /* The number of nonzero histogram cells within this box */ 00267 long colorcount; 00268 } box; 00269 00270 typedef box * boxptr; 00271 00272 00273 LOCAL(boxptr) 00274 find_biggest_color_pop (boxptr boxlist, int numboxes) 00275 /* Find the splittable box with the largest color population */ 00276 /* Returns NULL if no splittable boxes remain */ 00277 { 00278 register boxptr boxp; 00279 register int i; 00280 register long maxc = 0; 00281 boxptr which = NULL; 00282 00283 for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { 00284 if (boxp->colorcount > maxc && boxp->volume > 0) { 00285 which = boxp; 00286 maxc = boxp->colorcount; 00287 } 00288 } 00289 return which; 00290 } 00291 00292 00293 LOCAL(boxptr) 00294 find_biggest_volume (boxptr boxlist, int numboxes) 00295 /* Find the splittable box with the largest (scaled) volume */ 00296 /* Returns NULL if no splittable boxes remain */ 00297 { 00298 register boxptr boxp; 00299 register int i; 00300 register INT32 maxv = 0; 00301 boxptr which = NULL; 00302 00303 for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { 00304 if (boxp->volume > maxv) { 00305 which = boxp; 00306 maxv = boxp->volume; 00307 } 00308 } 00309 return which; 00310 } 00311 00312 00313 LOCAL(void) 00314 update_box (j_decompress_ptr cinfo, boxptr boxp) 00315 /* Shrink the min/max bounds of a box to enclose only nonzero elements, */ 00316 /* and recompute its volume and population */ 00317 { 00318 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 00319 hist3d histogram = cquantize->histogram; 00320 histptr histp; 00321 int c0,c1,c2; 00322 int c0min,c0max,c1min,c1max,c2min,c2max; 00323 INT32 dist0,dist1,dist2; 00324 long ccount; 00325 00326 c0min = boxp->c0min; c0max = boxp->c0max; 00327 c1min = boxp->c1min; c1max = boxp->c1max; 00328 c2min = boxp->c2min; c2max = boxp->c2max; 00329 00330 if (c0max > c0min) 00331 for (c0 = c0min; c0 <= c0max; c0++) 00332 for (c1 = c1min; c1 <= c1max; c1++) { 00333 histp = & histogram[c0][c1][c2min]; 00334 for (c2 = c2min; c2 <= c2max; c2++) 00335 if (*histp++ != 0) { 00336 boxp->c0min = c0min = c0; 00337 goto have_c0min; 00338 } 00339 } 00340 have_c0min: 00341 if (c0max > c0min) 00342 for (c0 = c0max; c0 >= c0min; c0--) 00343 for (c1 = c1min; c1 <= c1max; c1++) { 00344 histp = & histogram[c0][c1][c2min]; 00345 for (c2 = c2min; c2 <= c2max; c2++) 00346 if (*histp++ != 0) { 00347 boxp->c0max = c0max = c0; 00348 goto have_c0max; 00349 } 00350 } 00351 have_c0max: 00352 if (c1max > c1min) 00353 for (c1 = c1min; c1 <= c1max; c1++) 00354 for (c0 = c0min; c0 <= c0max; c0++) { 00355 histp = & histogram[c0][c1][c2min]; 00356 for (c2 = c2min; c2 <= c2max; c2++) 00357 if (*histp++ != 0) { 00358 boxp->c1min = c1min = c1; 00359 goto have_c1min; 00360 } 00361 } 00362 have_c1min: 00363 if (c1max > c1min) 00364 for (c1 = c1max; c1 >= c1min; c1--) 00365 for (c0 = c0min; c0 <= c0max; c0++) { 00366 histp = & histogram[c0][c1][c2min]; 00367 for (c2 = c2min; c2 <= c2max; c2++) 00368 if (*histp++ != 0) { 00369 boxp->c1max = c1max = c1; 00370 goto have_c1max; 00371 } 00372 } 00373 have_c1max: 00374 if (c2max > c2min) 00375 for (c2 = c2min; c2 <= c2max; c2++) 00376 for (c0 = c0min; c0 <= c0max; c0++) { 00377 histp = & histogram[c0][c1min][c2]; 00378 for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) 00379 if (*histp != 0) { 00380 boxp->c2min = c2min = c2; 00381 goto have_c2min; 00382 } 00383 } 00384 have_c2min: 00385 if (c2max > c2min) 00386 for (c2 = c2max; c2 >= c2min; c2--) 00387 for (c0 = c0min; c0 <= c0max; c0++) { 00388 histp = & histogram[c0][c1min][c2]; 00389 for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) 00390 if (*histp != 0) { 00391 boxp->c2max = c2max = c2; 00392 goto have_c2max; 00393 } 00394 } 00395 have_c2max: 00396 00397 /* Update box volume. 00398 * We use 2-norm rather than real volume here; this biases the method 00399 * against making long narrow boxes, and it has the side benefit that 00400 * a box is splittable iff norm > 0. 00401 * Since the differences are expressed in histogram-cell units, 00402 * we have to shift back to JSAMPLE units to get consistent distances; 00403 * after which, we scale according to the selected distance scale factors. 00404 */ 00405 dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; 00406 dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; 00407 dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; 00408 boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2; 00409 00410 /* Now scan remaining volume of box and compute population */ 00411 ccount = 0; 00412 for (c0 = c0min; c0 <= c0max; c0++) 00413 for (c1 = c1min; c1 <= c1max; c1++) { 00414 histp = & histogram[c0][c1][c2min]; 00415 for (c2 = c2min; c2 <= c2max; c2++, histp++) 00416 if (*histp != 0) { 00417 ccount++; 00418 } 00419 } 00420 boxp->colorcount = ccount; 00421 } 00422 00423 00424 LOCAL(int) 00425 median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, 00426 int desired_colors) 00427 /* Repeatedly select and split the largest box until we have enough boxes */ 00428 { 00429 int n,lb; 00430 int c0,c1,c2,cmax; 00431 register boxptr b1,b2; 00432 00433 while (numboxes < desired_colors) { 00434 /* Select box to split. 00435 * Current algorithm: by population for first half, then by volume. 00436 */ 00437 if (numboxes*2 <= desired_colors) { 00438 b1 = find_biggest_color_pop(boxlist, numboxes); 00439 } else { 00440 b1 = find_biggest_volume(boxlist, numboxes); 00441 } 00442 if (b1 == NULL) /* no splittable boxes left! */ 00443 break; 00444 b2 = &boxlist[numboxes]; /* where new box will go */ 00445 /* Copy the color bounds to the new box. */ 00446 b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; 00447 b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; 00448 /* Choose which axis to split the box on. 00449 * Current algorithm: longest scaled axis. 00450 * See notes in update_box about scaling distances. 00451 */ 00452 c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; 00453 c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; 00454 c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; 00455 /* We want to break any ties in favor of green, then red, blue last. 00456 * This code does the right thing for R,G,B or B,G,R color orders only. 00457 */ 00458 #if RGB_RED == 0 00459 cmax = c1; n = 1; 00460 if (c0 > cmax) { cmax = c0; n = 0; } 00461 if (c2 > cmax) { n = 2; } 00462 #else 00463 cmax = c1; n = 1; 00464 if (c2 > cmax) { cmax = c2; n = 2; } 00465 if (c0 > cmax) { n = 0; } 00466 #endif 00467 /* Choose split point along selected axis, and update box bounds. 00468 * Current algorithm: split at halfway point. 00469 * (Since the box has been shrunk to minimum volume, 00470 * any split will produce two nonempty subboxes.) 00471 * Note that lb value is max for lower box, so must be < old max. 00472 */ 00473 switch (n) { 00474 case 0: 00475 lb = (b1->c0max + b1->c0min) / 2; 00476 b1->c0max = lb; 00477 b2->c0min = lb+1; 00478 break; 00479 case 1: 00480 lb = (b1->c1max + b1->c1min) / 2; 00481 b1->c1max = lb; 00482 b2->c1min = lb+1; 00483 break; 00484 case 2: 00485 lb = (b1->c2max + b1->c2min) / 2; 00486 b1->c2max = lb; 00487 b2->c2min = lb+1; 00488 break; 00489 } 00490 /* Update stats for boxes */ 00491 update_box(cinfo, b1); 00492 update_box(cinfo, b2); 00493 numboxes++; 00494 } 00495 return numboxes; 00496 } 00497 00498 00499 LOCAL(void) 00500 compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) 00501 /* Compute representative color for a box, put it in colormap[icolor] */ 00502 { 00503 /* Current algorithm: mean weighted by pixels (not colors) */ 00504 /* Note it is important to get the rounding correct! */ 00505 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 00506 hist3d histogram = cquantize->histogram; 00507 histptr histp; 00508 int c0,c1,c2; 00509 int c0min,c0max,c1min,c1max,c2min,c2max; 00510 long count; 00511 long total = 0; 00512 long c0total = 0; 00513 long c1total = 0; 00514 long c2total = 0; 00515 00516 c0min = boxp->c0min; c0max = boxp->c0max; 00517 c1min = boxp->c1min; c1max = boxp->c1max; 00518 c2min = boxp->c2min; c2max = boxp->c2max; 00519 00520 for (c0 = c0min; c0 <= c0max; c0++) 00521 for (c1 = c1min; c1 <= c1max; c1++) { 00522 histp = & histogram[c0][c1][c2min]; 00523 for (c2 = c2min; c2 <= c2max; c2++) { 00524 if ((count = *histp++) != 0) { 00525 total += count; 00526 c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count; 00527 c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count; 00528 c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count; 00529 } 00530 } 00531 } 00532 00533 cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total); 00534 cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total); 00535 cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total); 00536 } 00537 00538 00539 LOCAL(void) 00540 select_colors (j_decompress_ptr cinfo, int desired_colors) 00541 /* Master routine for color selection */ 00542 { 00543 boxptr boxlist; 00544 int numboxes; 00545 int i; 00546 00547 /* Allocate workspace for box list */ 00548 boxlist = (boxptr) (*cinfo->mem->alloc_small) 00549 ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box)); 00550 /* Initialize one box containing whole space */ 00551 numboxes = 1; 00552 boxlist[0].c0min = 0; 00553 boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; 00554 boxlist[0].c1min = 0; 00555 boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; 00556 boxlist[0].c2min = 0; 00557 boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; 00558 /* Shrink it to actually-used volume and set its statistics */ 00559 update_box(cinfo, & boxlist[0]); 00560 /* Perform median-cut to produce final box list */ 00561 numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); 00562 /* Compute the representative color for each box, fill colormap */ 00563 for (i = 0; i < numboxes; i++) 00564 compute_color(cinfo, & boxlist[i], i); 00565 cinfo->actual_number_of_colors = numboxes; 00566 TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); 00567 } 00568 00569 00570 /* 00571 * These routines are concerned with the time-critical task of mapping input 00572 * colors to the nearest color in the selected colormap. 00573 * 00574 * We re-use the histogram space as an "inverse color map", essentially a 00575 * cache for the results of nearest-color searches. All colors within a 00576 * histogram cell will be mapped to the same colormap entry, namely the one 00577 * closest to the cell's center. This may not be quite the closest entry to 00578 * the actual input color, but it's almost as good. A zero in the cache 00579 * indicates we haven't found the nearest color for that cell yet; the array 00580 * is cleared to zeroes before starting the mapping pass. When we find the 00581 * nearest color for a cell, its colormap index plus one is recorded in the 00582 * cache for future use. The pass2 scanning routines call fill_inverse_cmap 00583 * when they need to use an unfilled entry in the cache. 00584 * 00585 * Our method of efficiently finding nearest colors is based on the "locally 00586 * sorted search" idea described by Heckbert and on the incremental distance 00587 * calculation described by Spencer W. Thomas in chapter III.1 of Graphics 00588 * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that 00589 * the distances from a given colormap entry to each cell of the histogram can 00590 * be computed quickly using an incremental method: the differences between 00591 * distances to adjacent cells themselves differ by a constant. This allows a 00592 * fairly fast implementation of the "brute force" approach of computing the 00593 * distance from every colormap entry to every histogram cell. Unfortunately, 00594 * it needs a work array to hold the best-distance-so-far for each histogram 00595 * cell (because the inner loop has to be over cells, not colormap entries). 00596 * The work array elements have to be INT32s, so the work array would need 00597 * 256Kb at our recommended precision. This is not feasible in DOS machines. 00598 * 00599 * To get around these problems, we apply Thomas' method to compute the 00600 * nearest colors for only the cells within a small subbox of the histogram. 00601 * The work array need be only as big as the subbox, so the memory usage 00602 * problem is solved. Furthermore, we need not fill subboxes that are never 00603 * referenced in pass2; many images use only part of the color gamut, so a 00604 * fair amount of work is saved. An additional advantage of this 00605 * approach is that we can apply Heckbert's locality criterion to quickly 00606 * eliminate colormap entries that are far away from the subbox; typically 00607 * three-fourths of the colormap entries are rejected by Heckbert's criterion, 00608 * and we need not compute their distances to individual cells in the subbox. 00609 * The speed of this approach is heavily influenced by the subbox size: too 00610 * small means too much overhead, too big loses because Heckbert's criterion 00611 * can't eliminate as many colormap entries. Empirically the best subbox 00612 * size seems to be about 1/512th of the histogram (1/8th in each direction). 00613 * 00614 * Thomas' article also describes a refined method which is asymptotically 00615 * faster than the brute-force method, but it is also far more complex and 00616 * cannot efficiently be applied to small subboxes. It is therefore not 00617 * useful for programs intended to be portable to DOS machines. On machines 00618 * with plenty of memory, filling the whole histogram in one shot with Thomas' 00619 * refined method might be faster than the present code --- but then again, 00620 * it might not be any faster, and it's certainly more complicated. 00621 */ 00622 00623 00624 /* log2(histogram cells in update box) for each axis; this can be adjusted */ 00625 #define BOX_C0_LOG (HIST_C0_BITS-3) 00626 #define BOX_C1_LOG (HIST_C1_BITS-3) 00627 #define BOX_C2_LOG (HIST_C2_BITS-3) 00628 00629 #define BOX_C0_ELEMS (1<<BOX_C0_LOG) /* # of hist cells in update box */ 00630 #define BOX_C1_ELEMS (1<<BOX_C1_LOG) 00631 #define BOX_C2_ELEMS (1<<BOX_C2_LOG) 00632 00633 #define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG) 00634 #define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG) 00635 #define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG) 00636 00637 00638 /* 00639 * The next three routines implement inverse colormap filling. They could 00640 * all be folded into one big routine, but splitting them up this way saves 00641 * some stack space (the mindist[] and bestdist[] arrays need not coexist) 00642 * and may allow some compilers to produce better code by registerizing more 00643 * inner-loop variables. 00644 */ 00645 00646 LOCAL(int) 00647 find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, 00648 JSAMPLE colorlist[]) 00649 /* Locate the colormap entries close enough to an update box to be candidates 00650 * for the nearest entry to some cell(s) in the update box. The update box 00651 * is specified by the center coordinates of its first cell. The number of 00652 * candidate colormap entries is returned, and their colormap indexes are 00653 * placed in colorlist[]. 00654 * This routine uses Heckbert's "locally sorted search" criterion to select 00655 * the colors that need further consideration. 00656 */ 00657 { 00658 int numcolors = cinfo->actual_number_of_colors; 00659 int maxc0, maxc1, maxc2; 00660 int centerc0, centerc1, centerc2; 00661 int i, x, ncolors; 00662 INT32 minmaxdist, min_dist, max_dist, tdist; 00663 INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ 00664 00665 /* Compute true coordinates of update box's upper corner and center. 00666 * Actually we compute the coordinates of the center of the upper-corner 00667 * histogram cell, which are the upper bounds of the volume we care about. 00668 * Note that since ">>" rounds down, the "center" values may be closer to 00669 * min than to max; hence comparisons to them must be "<=", not "<". 00670 */ 00671 maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); 00672 centerc0 = (minc0 + maxc0) >> 1; 00673 maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); 00674 centerc1 = (minc1 + maxc1) >> 1; 00675 maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); 00676 centerc2 = (minc2 + maxc2) >> 1; 00677 00678 /* For each color in colormap, find: 00679 * 1. its minimum squared-distance to any point in the update box 00680 * (zero if color is within update box); 00681 * 2. its maximum squared-distance to any point in the update box. 00682 * Both of these can be found by considering only the corners of the box. 00683 * We save the minimum distance for each color in mindist[]; 00684 * only the smallest maximum distance is of interest. 00685 */ 00686 minmaxdist = 0x7FFFFFFFL; 00687 00688 for (i = 0; i < numcolors; i++) { 00689 /* We compute the squared-c0-distance term, then add in the other two. */ 00690 x = GETJSAMPLE(cinfo->colormap[0][i]); 00691 if (x < minc0) { 00692 tdist = (x - minc0) * C0_SCALE; 00693 min_dist = tdist*tdist; 00694 tdist = (x - maxc0) * C0_SCALE; 00695 max_dist = tdist*tdist; 00696 } else if (x > maxc0) { 00697 tdist = (x - maxc0) * C0_SCALE; 00698 min_dist = tdist*tdist; 00699 tdist = (x - minc0) * C0_SCALE; 00700 max_dist = tdist*tdist; 00701 } else { 00702 /* within cell range so no contribution to min_dist */ 00703 min_dist = 0; 00704 if (x <= centerc0) { 00705 tdist = (x - maxc0) * C0_SCALE; 00706 max_dist = tdist*tdist; 00707 } else { 00708 tdist = (x - minc0) * C0_SCALE; 00709 max_dist = tdist*tdist; 00710 } 00711 } 00712 00713 x = GETJSAMPLE(cinfo->colormap[1][i]); 00714 if (x < minc1) { 00715 tdist = (x - minc1) * C1_SCALE; 00716 min_dist += tdist*tdist; 00717 tdist = (x - maxc1) * C1_SCALE; 00718 max_dist += tdist*tdist; 00719 } else if (x > maxc1) { 00720 tdist = (x - maxc1) * C1_SCALE; 00721 min_dist += tdist*tdist; 00722 tdist = (x - minc1) * C1_SCALE; 00723 max_dist += tdist*tdist; 00724 } else { 00725 /* within cell range so no contribution to min_dist */ 00726 if (x <= centerc1) { 00727 tdist = (x - maxc1) * C1_SCALE; 00728 max_dist += tdist*tdist; 00729 } else { 00730 tdist = (x - minc1) * C1_SCALE; 00731 max_dist += tdist*tdist; 00732 } 00733 } 00734 00735 x = GETJSAMPLE(cinfo->colormap[2][i]); 00736 if (x < minc2) { 00737 tdist = (x - minc2) * C2_SCALE; 00738 min_dist += tdist*tdist; 00739 tdist = (x - maxc2) * C2_SCALE; 00740 max_dist += tdist*tdist; 00741 } else if (x > maxc2) { 00742 tdist = (x - maxc2) * C2_SCALE; 00743 min_dist += tdist*tdist; 00744 tdist = (x - minc2) * C2_SCALE; 00745 max_dist += tdist*tdist; 00746 } else { 00747 /* within cell range so no contribution to min_dist */ 00748 if (x <= centerc2) { 00749 tdist = (x - maxc2) * C2_SCALE; 00750 max_dist += tdist*tdist; 00751 } else { 00752 tdist = (x - minc2) * C2_SCALE; 00753 max_dist += tdist*tdist; 00754 } 00755 } 00756 00757 mindist[i] = min_dist; /* save away the results */ 00758 if (max_dist < minmaxdist) 00759 minmaxdist = max_dist; 00760 } 00761 00762 /* Now we know that no cell in the update box is more than minmaxdist 00763 * away from some colormap entry. Therefore, only colors that are 00764 * within minmaxdist of some part of the box need be considered. 00765 */ 00766 ncolors = 0; 00767 for (i = 0; i < numcolors; i++) { 00768 if (mindist[i] <= minmaxdist) 00769 colorlist[ncolors++] = (JSAMPLE) i; 00770 } 00771 return ncolors; 00772 } 00773 00774 00775 LOCAL(void) 00776 find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, 00777 int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) 00778 /* Find the closest colormap entry for each cell in the update box, 00779 * given the list of candidate colors prepared by find_nearby_colors. 00780 * Return the indexes of the closest entries in the bestcolor[] array. 00781 * This routine uses Thomas' incremental distance calculation method to 00782 * find the distance from a colormap entry to successive cells in the box. 00783 */ 00784 { 00785 int ic0, ic1, ic2; 00786 int i, icolor; 00787 register INT32 * bptr; /* pointer into bestdist[] array */ 00788 JSAMPLE * cptr; /* pointer into bestcolor[] array */ 00789 INT32 dist0, dist1; /* initial distance values */ 00790 register INT32 dist2; /* current distance in inner loop */ 00791 INT32 xx0, xx1; /* distance increments */ 00792 register INT32 xx2; 00793 INT32 inc0, inc1, inc2; /* initial values for increments */ 00794 /* This array holds the distance to the nearest-so-far color for each cell */ 00795 INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; 00796 00797 /* Initialize best-distance for each cell of the update box */ 00798 bptr = bestdist; 00799 for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--) 00800 *bptr++ = 0x7FFFFFFFL; 00801 00802 /* For each color selected by find_nearby_colors, 00803 * compute its distance to the center of each cell in the box. 00804 * If that's less than best-so-far, update best distance and color number. 00805 */ 00806 00807 /* Nominal steps between cell centers ("x" in Thomas article) */ 00808 #define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) 00809 #define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) 00810 #define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) 00811 00812 for (i = 0; i < numcolors; i++) { 00813 icolor = GETJSAMPLE(colorlist[i]); 00814 /* Compute (square of) distance from minc0/c1/c2 to this color */ 00815 inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; 00816 dist0 = inc0*inc0; 00817 inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; 00818 dist0 += inc1*inc1; 00819 inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; 00820 dist0 += inc2*inc2; 00821 /* Form the initial difference increments */ 00822 inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; 00823 inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; 00824 inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; 00825 /* Now loop over all cells in box, updating distance per Thomas method */ 00826 bptr = bestdist; 00827 cptr = bestcolor; 00828 xx0 = inc0; 00829 for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) { 00830 dist1 = dist0; 00831 xx1 = inc1; 00832 for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) { 00833 dist2 = dist1; 00834 xx2 = inc2; 00835 for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) { 00836 if (dist2 < *bptr) { 00837 *bptr = dist2; 00838 *cptr = (JSAMPLE) icolor; 00839 } 00840 dist2 += xx2; 00841 xx2 += 2 * STEP_C2 * STEP_C2; 00842 bptr++; 00843 cptr++; 00844 } 00845 dist1 += xx1; 00846 xx1 += 2 * STEP_C1 * STEP_C1; 00847 } 00848 dist0 += xx0; 00849 xx0 += 2 * STEP_C0 * STEP_C0; 00850 } 00851 } 00852 } 00853 00854 00855 LOCAL(void) 00856 fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) 00857 /* Fill the inverse-colormap entries in the update box that contains */ 00858 /* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ 00859 /* we can fill as many others as we wish.) */ 00860 { 00861 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 00862 hist3d histogram = cquantize->histogram; 00863 int minc0, minc1, minc2; /* lower left corner of update box */ 00864 int ic0, ic1, ic2; 00865 register JSAMPLE * cptr; /* pointer into bestcolor[] array */ 00866 register histptr cachep; /* pointer into main cache array */ 00867 /* This array lists the candidate colormap indexes. */ 00868 JSAMPLE colorlist[MAXNUMCOLORS]; 00869 int numcolors; /* number of candidate colors */ 00870 /* This array holds the actually closest colormap index for each cell. */ 00871 JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; 00872 00873 /* Convert cell coordinates to update box ID */ 00874 c0 >>= BOX_C0_LOG; 00875 c1 >>= BOX_C1_LOG; 00876 c2 >>= BOX_C2_LOG; 00877 00878 /* Compute true coordinates of update box's origin corner. 00879 * Actually we compute the coordinates of the center of the corner 00880 * histogram cell, which are the lower bounds of the volume we care about. 00881 */ 00882 minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); 00883 minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); 00884 minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); 00885 00886 /* Determine which colormap entries are close enough to be candidates 00887 * for the nearest entry to some cell in the update box. 00888 */ 00889 numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); 00890 00891 /* Determine the actually nearest colors. */ 00892 find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, 00893 bestcolor); 00894 00895 /* Save the best color numbers (plus 1) in the main cache array */ 00896 c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ 00897 c1 <<= BOX_C1_LOG; 00898 c2 <<= BOX_C2_LOG; 00899 cptr = bestcolor; 00900 for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { 00901 for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { 00902 cachep = & histogram[c0+ic0][c1+ic1][c2]; 00903 for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { 00904 *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1); 00905 } 00906 } 00907 } 00908 } 00909 00910 00911 /* 00912 * Map some rows of pixels to the output colormapped representation. 00913 */ 00914 00915 METHODDEF(void) 00916 pass2_no_dither (j_decompress_ptr cinfo, 00917 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) 00918 /* This version performs no dithering */ 00919 { 00920 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 00921 hist3d histogram = cquantize->histogram; 00922 register JSAMPROW inptr, outptr; 00923 register histptr cachep; 00924 register int c0, c1, c2; 00925 int row; 00926 JDIMENSION col; 00927 JDIMENSION width = cinfo->output_width; 00928 00929 for (row = 0; row < num_rows; row++) { 00930 inptr = input_buf[row]; 00931 outptr = output_buf[row]; 00932 for (col = width; col > 0; col--) { 00933 /* get pixel value and index into the cache */ 00934 c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; 00935 c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; 00936 c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; 00937 cachep = & histogram[c0][c1][c2]; 00938 /* If we have not seen this color before, find nearest colormap entry */ 00939 /* and update the cache */ 00940 if (*cachep == 0) 00941 fill_inverse_cmap(cinfo, c0,c1,c2); 00942 /* Now emit the colormap index for this cell */ 00943 *outptr++ = (JSAMPLE) (*cachep - 1); 00944 } 00945 } 00946 } 00947 00948 00949 METHODDEF(void) 00950 pass2_fs_dither (j_decompress_ptr cinfo, 00951 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) 00952 /* This version performs Floyd-Steinberg dithering */ 00953 { 00954 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 00955 hist3d histogram = cquantize->histogram; 00956 register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ 00957 LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ 00958 LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ 00959 register FSERRPTR errorptr; /* => fserrors[] at column before current */ 00960 JSAMPROW inptr; /* => current input pixel */ 00961 JSAMPROW outptr; /* => current output pixel */ 00962 histptr cachep; 00963 int dir; /* +1 or -1 depending on direction */ 00964 int dir3; /* 3*dir, for advancing inptr & errorptr */ 00965 int row; 00966 JDIMENSION col; 00967 JDIMENSION width = cinfo->output_width; 00968 JSAMPLE *range_limit = cinfo->sample_range_limit; 00969 int *error_limit = cquantize->error_limiter; 00970 JSAMPROW colormap0 = cinfo->colormap[0]; 00971 JSAMPROW colormap1 = cinfo->colormap[1]; 00972 JSAMPROW colormap2 = cinfo->colormap[2]; 00973 SHIFT_TEMPS 00974 00975 for (row = 0; row < num_rows; row++) { 00976 inptr = input_buf[row]; 00977 outptr = output_buf[row]; 00978 if (cquantize->on_odd_row) { 00979 /* work right to left in this row */ 00980 inptr += (width-1) * 3; /* so point to rightmost pixel */ 00981 outptr += width-1; 00982 dir = -1; 00983 dir3 = -3; 00984 errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */ 00985 cquantize->on_odd_row = FALSE; /* flip for next time */ 00986 } else { 00987 /* work left to right in this row */ 00988 dir = 1; 00989 dir3 = 3; 00990 errorptr = cquantize->fserrors; /* => entry before first real column */ 00991 cquantize->on_odd_row = TRUE; /* flip for next time */ 00992 } 00993 /* Preset error values: no error propagated to first pixel from left */ 00994 cur0 = cur1 = cur2 = 0; 00995 /* and no error propagated to row below yet */ 00996 belowerr0 = belowerr1 = belowerr2 = 0; 00997 bpreverr0 = bpreverr1 = bpreverr2 = 0; 00998 00999 for (col = width; col > 0; col--) { 01000 /* curN holds the error propagated from the previous pixel on the 01001 * current line. Add the error propagated from the previous line 01002 * to form the complete error correction term for this pixel, and 01003 * round the error term (which is expressed * 16) to an integer. 01004 * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct 01005 * for either sign of the error value. 01006 * Note: errorptr points to *previous* column's array entry. 01007 */ 01008 cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4); 01009 cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4); 01010 cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4); 01011 /* Limit the error using transfer function set by init_error_limit. 01012 * See comments with init_error_limit for rationale. 01013 */ 01014 cur0 = error_limit[cur0]; 01015 cur1 = error_limit[cur1]; 01016 cur2 = error_limit[cur2]; 01017 /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. 01018 * The maximum error is +- MAXJSAMPLE (or less with error limiting); 01019 * this sets the required size of the range_limit array. 01020 */ 01021 cur0 += GETJSAMPLE(inptr[0]); 01022 cur1 += GETJSAMPLE(inptr[1]); 01023 cur2 += GETJSAMPLE(inptr[2]); 01024 cur0 = GETJSAMPLE(range_limit[cur0]); 01025 cur1 = GETJSAMPLE(range_limit[cur1]); 01026 cur2 = GETJSAMPLE(range_limit[cur2]); 01027 /* Index into the cache with adjusted pixel value */ 01028 cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT]; 01029 /* If we have not seen this color before, find nearest colormap */ 01030 /* entry and update the cache */ 01031 if (*cachep == 0) 01032 fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); 01033 /* Now emit the colormap index for this cell */ 01034 { register int pixcode = *cachep - 1; 01035 *outptr = (JSAMPLE) pixcode; 01036 /* Compute representation error for this pixel */ 01037 cur0 -= GETJSAMPLE(colormap0[pixcode]); 01038 cur1 -= GETJSAMPLE(colormap1[pixcode]); 01039 cur2 -= GETJSAMPLE(colormap2[pixcode]); 01040 } 01041 /* Compute error fractions to be propagated to adjacent pixels. 01042 * Add these into the running sums, and simultaneously shift the 01043 * next-line error sums left by 1 column. 01044 */ 01045 { register LOCFSERROR bnexterr, delta; 01046 01047 bnexterr = cur0; /* Process component 0 */ 01048 delta = cur0 * 2; 01049 cur0 += delta; /* form error * 3 */ 01050 errorptr[0] = (FSERROR) (bpreverr0 + cur0); 01051 cur0 += delta; /* form error * 5 */ 01052 bpreverr0 = belowerr0 + cur0; 01053 belowerr0 = bnexterr; 01054 cur0 += delta; /* form error * 7 */ 01055 bnexterr = cur1; /* Process component 1 */ 01056 delta = cur1 * 2; 01057 cur1 += delta; /* form error * 3 */ 01058 errorptr[1] = (FSERROR) (bpreverr1 + cur1); 01059 cur1 += delta; /* form error * 5 */ 01060 bpreverr1 = belowerr1 + cur1; 01061 belowerr1 = bnexterr; 01062 cur1 += delta; /* form error * 7 */ 01063 bnexterr = cur2; /* Process component 2 */ 01064 delta = cur2 * 2; 01065 cur2 += delta; /* form error * 3 */ 01066 errorptr[2] = (FSERROR) (bpreverr2 + cur2); 01067 cur2 += delta; /* form error * 5 */ 01068 bpreverr2 = belowerr2 + cur2; 01069 belowerr2 = bnexterr; 01070 cur2 += delta; /* form error * 7 */ 01071 } 01072 /* At this point curN contains the 7/16 error value to be propagated 01073 * to the next pixel on the current line, and all the errors for the 01074 * next line have been shifted over. We are therefore ready to move on. 01075 */ 01076 inptr += dir3; /* Advance pixel pointers to next column */ 01077 outptr += dir; 01078 errorptr += dir3; /* advance errorptr to current column */ 01079 } 01080 /* Post-loop cleanup: we must unload the final error values into the 01081 * final fserrors[] entry. Note we need not unload belowerrN because 01082 * it is for the dummy column before or after the actual array. 01083 */ 01084 errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ 01085 errorptr[1] = (FSERROR) bpreverr1; 01086 errorptr[2] = (FSERROR) bpreverr2; 01087 } 01088 } 01089 01090 01091 /* 01092 * Initialize the error-limiting transfer function (lookup table). 01093 * The raw F-S error computation can potentially compute error values of up to 01094 * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be 01095 * much less, otherwise obviously wrong pixels will be created. (Typical 01096 * effects include weird fringes at color-area boundaries, isolated bright 01097 * pixels in a dark area, etc.) The standard advice for avoiding this problem 01098 * is to ensure that the "corners" of the color cube are allocated as output 01099 * colors; then repeated errors in the same direction cannot cause cascading 01100 * error buildup. However, that only prevents the error from getting 01101 * completely out of hand; Aaron Giles reports that error limiting improves 01102 * the results even with corner colors allocated. 01103 * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty 01104 * well, but the smoother transfer function used below is even better. Thanks 01105 * to Aaron Giles for this idea. 01106 */ 01107 01108 LOCAL(void) 01109 init_error_limit (j_decompress_ptr cinfo) 01110 /* Allocate and fill in the error_limiter table */ 01111 { 01112 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 01113 int * table; 01114 int in, out; 01115 01116 table = (int *) (*cinfo->mem->alloc_small) 01117 ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int)); 01118 table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ 01119 cquantize->error_limiter = table; 01120 01121 #define STEPSIZE ((MAXJSAMPLE+1)/16) 01122 /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ 01123 out = 0; 01124 for (in = 0; in < STEPSIZE; in++, out++) { 01125 table[in] = out; table[-in] = -out; 01126 } 01127 /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ 01128 for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) { 01129 table[in] = out; table[-in] = -out; 01130 } 01131 /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ 01132 for (; in <= MAXJSAMPLE; in++) { 01133 table[in] = out; table[-in] = -out; 01134 } 01135 #undef STEPSIZE 01136 } 01137 01138 01139 /* 01140 * Finish up at the end of each pass. 01141 */ 01142 01143 METHODDEF(void) 01144 finish_pass1 (j_decompress_ptr cinfo) 01145 { 01146 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 01147 01148 /* Select the representative colors and fill in cinfo->colormap */ 01149 cinfo->colormap = cquantize->sv_colormap; 01150 select_colors(cinfo, cquantize->desired); 01151 /* Force next pass to zero the color index table */ 01152 cquantize->needs_zeroed = TRUE; 01153 } 01154 01155 01156 METHODDEF(void) 01157 finish_pass2 (j_decompress_ptr cinfo) 01158 { 01159 /* no work */ 01160 } 01161 01162 01163 /* 01164 * Initialize for each processing pass. 01165 */ 01166 01167 METHODDEF(void) 01168 start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) 01169 { 01170 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 01171 hist3d histogram = cquantize->histogram; 01172 int i; 01173 01174 /* Only F-S dithering or no dithering is supported. */ 01175 /* If user asks for ordered dither, give him F-S. */ 01176 if (cinfo->dither_mode != JDITHER_NONE) 01177 cinfo->dither_mode = JDITHER_FS; 01178 01179 if (is_pre_scan) { 01180 /* Set up method pointers */ 01181 cquantize->pub.color_quantize = prescan_quantize; 01182 cquantize->pub.finish_pass = finish_pass1; 01183 cquantize->needs_zeroed = TRUE; /* Always zero histogram */ 01184 } else { 01185 /* Set up method pointers */ 01186 if (cinfo->dither_mode == JDITHER_FS) 01187 cquantize->pub.color_quantize = pass2_fs_dither; 01188 else 01189 cquantize->pub.color_quantize = pass2_no_dither; 01190 cquantize->pub.finish_pass = finish_pass2; 01191 01192 /* Make sure color count is acceptable */ 01193 i = cinfo->actual_number_of_colors; 01194 if (i < 1) 01195 ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); 01196 if (i > MAXNUMCOLORS) 01197 ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); 01198 01199 if (cinfo->dither_mode == JDITHER_FS) { 01200 size_t arraysize = (size_t) ((cinfo->output_width + 2) * 01201 (3 * SIZEOF(FSERROR))); 01202 /* Allocate Floyd-Steinberg workspace if we didn't already. */ 01203 if (cquantize->fserrors == NULL) 01204 cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) 01205 ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); 01206 /* Initialize the propagated errors to zero. */ 01207 FMEMZERO((void FAR *) cquantize->fserrors, arraysize); 01208 /* Make the error-limit table if we didn't already. */ 01209 if (cquantize->error_limiter == NULL) 01210 init_error_limit(cinfo); 01211 cquantize->on_odd_row = FALSE; 01212 } 01213 01214 } 01215 /* Zero the histogram or inverse color map, if necessary */ 01216 if (cquantize->needs_zeroed) { 01217 for (i = 0; i < HIST_C0_ELEMS; i++) { 01218 FMEMZERO((void FAR *) histogram[i], 01219 HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); 01220 } 01221 cquantize->needs_zeroed = FALSE; 01222 } 01223 } 01224 01225 01226 /* 01227 * Switch to a new external colormap between output passes. 01228 */ 01229 01230 METHODDEF(void) 01231 new_color_map_2_quant (j_decompress_ptr cinfo) 01232 { 01233 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 01234 01235 /* Reset the inverse color map */ 01236 cquantize->needs_zeroed = TRUE; 01237 } 01238 01239 01240 /* 01241 * Module initialization routine for 2-pass color quantization. 01242 */ 01243 01244 GLOBAL(void) 01245 jinit_2pass_quantizer (j_decompress_ptr cinfo) 01246 { 01247 my_cquantize_ptr cquantize; 01248 int i; 01249 01250 cquantize = (my_cquantize_ptr) 01251 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 01252 SIZEOF(my_cquantizer)); 01253 cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; 01254 cquantize->pub.start_pass = start_pass_2_quant; 01255 cquantize->pub.new_color_map = new_color_map_2_quant; 01256 cquantize->fserrors = NULL; /* flag optional arrays not allocated */ 01257 cquantize->error_limiter = NULL; 01258 01259 /* Make sure jdmaster didn't give me a case I can't handle */ 01260 if (cinfo->out_color_components != 3) 01261 ERREXIT(cinfo, JERR_NOTIMPL); 01262 01263 /* Allocate the histogram/inverse colormap storage */ 01264 cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) 01265 ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d)); 01266 for (i = 0; i < HIST_C0_ELEMS; i++) { 01267 cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) 01268 ((j_common_ptr) cinfo, JPOOL_IMAGE, 01269 HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); 01270 } 01271 cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ 01272 01273 /* Allocate storage for the completed colormap, if required. 01274 * We do this now since it is FAR storage and may affect 01275 * the memory manager's space calculations. 01276 */ 01277 if (cinfo->enable_2pass_quant) { 01278 /* Make sure color count is acceptable */ 01279 int desired = cinfo->desired_number_of_colors; 01280 /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ 01281 if (desired < 8) 01282 ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); 01283 /* Make sure colormap indexes can be represented by JSAMPLEs */ 01284 if (desired > MAXNUMCOLORS) 01285 ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); 01286 cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) 01287 ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); 01288 cquantize->desired = desired; 01289 } else 01290 cquantize->sv_colormap = NULL; 01291 01292 /* Only F-S dithering or no dithering is supported. */ 01293 /* If user asks for ordered dither, give him F-S. */ 01294 if (cinfo->dither_mode != JDITHER_NONE) 01295 cinfo->dither_mode = JDITHER_FS; 01296 01297 /* Allocate Floyd-Steinberg workspace if necessary. 01298 * This isn't really needed until pass 2, but again it is FAR storage. 01299 * Although we will cope with a later change in dither_mode, 01300 * we do not promise to honor max_memory_to_use if dither_mode changes. 01301 */ 01302 if (cinfo->dither_mode == JDITHER_FS) { 01303 cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) 01304 ((j_common_ptr) cinfo, JPOOL_IMAGE, 01305 (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); 01306 /* Might as well create the error-limiting table too. */ 01307 init_error_limit(cinfo); 01308 } 01309 } 01310 01311 #endif /* QUANT_2PASS_SUPPORTED */
Generated on Wed Jul 13 2022 18:56:09 by
