istereo
diff libs/libjpeg/jquant1.c @ 26:862a3329a8f0
wohooo, added a shitload of code from zlib/libpng/libjpeg. When the good lord was raining shared libraries the iphone held a fucking umbrella...
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Thu, 08 Sep 2011 06:28:38 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/libjpeg/jquant1.c Thu Sep 08 06:28:38 2011 +0300 1.3 @@ -0,0 +1,856 @@ 1.4 +/* 1.5 + * jquant1.c 1.6 + * 1.7 + * Copyright (C) 1991-1996, Thomas G. Lane. 1.8 + * This file is part of the Independent JPEG Group's software. 1.9 + * For conditions of distribution and use, see the accompanying README file. 1.10 + * 1.11 + * This file contains 1-pass color quantization (color mapping) routines. 1.12 + * These routines provide mapping to a fixed color map using equally spaced 1.13 + * color values. Optional Floyd-Steinberg or ordered dithering is available. 1.14 + */ 1.15 + 1.16 +#define JPEG_INTERNALS 1.17 +#include "jinclude.h" 1.18 +#include "jpeglib.h" 1.19 + 1.20 +#ifdef QUANT_1PASS_SUPPORTED 1.21 + 1.22 + 1.23 +/* 1.24 + * The main purpose of 1-pass quantization is to provide a fast, if not very 1.25 + * high quality, colormapped output capability. A 2-pass quantizer usually 1.26 + * gives better visual quality; however, for quantized grayscale output this 1.27 + * quantizer is perfectly adequate. Dithering is highly recommended with this 1.28 + * quantizer, though you can turn it off if you really want to. 1.29 + * 1.30 + * In 1-pass quantization the colormap must be chosen in advance of seeing the 1.31 + * image. We use a map consisting of all combinations of Ncolors[i] color 1.32 + * values for the i'th component. The Ncolors[] values are chosen so that 1.33 + * their product, the total number of colors, is no more than that requested. 1.34 + * (In most cases, the product will be somewhat less.) 1.35 + * 1.36 + * Since the colormap is orthogonal, the representative value for each color 1.37 + * component can be determined without considering the other components; 1.38 + * then these indexes can be combined into a colormap index by a standard 1.39 + * N-dimensional-array-subscript calculation. Most of the arithmetic involved 1.40 + * can be precalculated and stored in the lookup table colorindex[]. 1.41 + * colorindex[i][j] maps pixel value j in component i to the nearest 1.42 + * representative value (grid plane) for that component; this index is 1.43 + * multiplied by the array stride for component i, so that the 1.44 + * index of the colormap entry closest to a given pixel value is just 1.45 + * sum( colorindex[component-number][pixel-component-value] ) 1.46 + * Aside from being fast, this scheme allows for variable spacing between 1.47 + * representative values with no additional lookup cost. 1.48 + * 1.49 + * If gamma correction has been applied in color conversion, it might be wise 1.50 + * to adjust the color grid spacing so that the representative colors are 1.51 + * equidistant in linear space. At this writing, gamma correction is not 1.52 + * implemented by jdcolor, so nothing is done here. 1.53 + */ 1.54 + 1.55 + 1.56 +/* Declarations for ordered dithering. 1.57 + * 1.58 + * We use a standard 16x16 ordered dither array. The basic concept of ordered 1.59 + * dithering is described in many references, for instance Dale Schumacher's 1.60 + * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). 1.61 + * In place of Schumacher's comparisons against a "threshold" value, we add a 1.62 + * "dither" value to the input pixel and then round the result to the nearest 1.63 + * output value. The dither value is equivalent to (0.5 - threshold) times 1.64 + * the distance between output values. For ordered dithering, we assume that 1.65 + * the output colors are equally spaced; if not, results will probably be 1.66 + * worse, since the dither may be too much or too little at a given point. 1.67 + * 1.68 + * The normal calculation would be to form pixel value + dither, range-limit 1.69 + * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. 1.70 + * We can skip the separate range-limiting step by extending the colorindex 1.71 + * table in both directions. 1.72 + */ 1.73 + 1.74 +#define ODITHER_SIZE 16 /* dimension of dither matrix */ 1.75 +/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ 1.76 +#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ 1.77 +#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ 1.78 + 1.79 +typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; 1.80 +typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; 1.81 + 1.82 +static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { 1.83 + /* Bayer's order-4 dither array. Generated by the code given in 1.84 + * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. 1.85 + * The values in this array must range from 0 to ODITHER_CELLS-1. 1.86 + */ 1.87 + { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, 1.88 + { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, 1.89 + { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, 1.90 + { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, 1.91 + { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, 1.92 + { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, 1.93 + { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, 1.94 + { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, 1.95 + { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, 1.96 + { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, 1.97 + { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, 1.98 + { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, 1.99 + { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, 1.100 + { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, 1.101 + { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, 1.102 + { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } 1.103 +}; 1.104 + 1.105 + 1.106 +/* Declarations for Floyd-Steinberg dithering. 1.107 + * 1.108 + * Errors are accumulated into the array fserrors[], at a resolution of 1.109 + * 1/16th of a pixel count. The error at a given pixel is propagated 1.110 + * to its not-yet-processed neighbors using the standard F-S fractions, 1.111 + * ... (here) 7/16 1.112 + * 3/16 5/16 1/16 1.113 + * We work left-to-right on even rows, right-to-left on odd rows. 1.114 + * 1.115 + * We can get away with a single array (holding one row's worth of errors) 1.116 + * by using it to store the current row's errors at pixel columns not yet 1.117 + * processed, but the next row's errors at columns already processed. We 1.118 + * need only a few extra variables to hold the errors immediately around the 1.119 + * current column. (If we are lucky, those variables are in registers, but 1.120 + * even if not, they're probably cheaper to access than array elements are.) 1.121 + * 1.122 + * The fserrors[] array is indexed [component#][position]. 1.123 + * We provide (#columns + 2) entries per component; the extra entry at each 1.124 + * end saves us from special-casing the first and last pixels. 1.125 + * 1.126 + * Note: on a wide image, we might not have enough room in a PC's near data 1.127 + * segment to hold the error array; so it is allocated with alloc_large. 1.128 + */ 1.129 + 1.130 +#if BITS_IN_JSAMPLE == 8 1.131 +typedef INT16 FSERROR; /* 16 bits should be enough */ 1.132 +typedef int LOCFSERROR; /* use 'int' for calculation temps */ 1.133 +#else 1.134 +typedef INT32 FSERROR; /* may need more than 16 bits */ 1.135 +typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ 1.136 +#endif 1.137 + 1.138 +typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ 1.139 + 1.140 + 1.141 +/* Private subobject */ 1.142 + 1.143 +#define MAX_Q_COMPS 4 /* max components I can handle */ 1.144 + 1.145 +typedef struct { 1.146 + struct jpeg_color_quantizer pub; /* public fields */ 1.147 + 1.148 + /* Initially allocated colormap is saved here */ 1.149 + JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ 1.150 + int sv_actual; /* number of entries in use */ 1.151 + 1.152 + JSAMPARRAY colorindex; /* Precomputed mapping for speed */ 1.153 + /* colorindex[i][j] = index of color closest to pixel value j in component i, 1.154 + * premultiplied as described above. Since colormap indexes must fit into 1.155 + * JSAMPLEs, the entries of this array will too. 1.156 + */ 1.157 + boolean is_padded; /* is the colorindex padded for odither? */ 1.158 + 1.159 + int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ 1.160 + 1.161 + /* Variables for ordered dithering */ 1.162 + int row_index; /* cur row's vertical index in dither matrix */ 1.163 + ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ 1.164 + 1.165 + /* Variables for Floyd-Steinberg dithering */ 1.166 + FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ 1.167 + boolean on_odd_row; /* flag to remember which row we are on */ 1.168 +} my_cquantizer; 1.169 + 1.170 +typedef my_cquantizer * my_cquantize_ptr; 1.171 + 1.172 + 1.173 +/* 1.174 + * Policy-making subroutines for create_colormap and create_colorindex. 1.175 + * These routines determine the colormap to be used. The rest of the module 1.176 + * only assumes that the colormap is orthogonal. 1.177 + * 1.178 + * * select_ncolors decides how to divvy up the available colors 1.179 + * among the components. 1.180 + * * output_value defines the set of representative values for a component. 1.181 + * * largest_input_value defines the mapping from input values to 1.182 + * representative values for a component. 1.183 + * Note that the latter two routines may impose different policies for 1.184 + * different components, though this is not currently done. 1.185 + */ 1.186 + 1.187 + 1.188 +LOCAL(int) 1.189 +select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) 1.190 +/* Determine allocation of desired colors to components, */ 1.191 +/* and fill in Ncolors[] array to indicate choice. */ 1.192 +/* Return value is total number of colors (product of Ncolors[] values). */ 1.193 +{ 1.194 + int nc = cinfo->out_color_components; /* number of color components */ 1.195 + int max_colors = cinfo->desired_number_of_colors; 1.196 + int total_colors, iroot, i, j; 1.197 + boolean changed; 1.198 + long temp; 1.199 + static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; 1.200 + 1.201 + /* We can allocate at least the nc'th root of max_colors per component. */ 1.202 + /* Compute floor(nc'th root of max_colors). */ 1.203 + iroot = 1; 1.204 + do { 1.205 + iroot++; 1.206 + temp = iroot; /* set temp = iroot ** nc */ 1.207 + for (i = 1; i < nc; i++) 1.208 + temp *= iroot; 1.209 + } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ 1.210 + iroot--; /* now iroot = floor(root) */ 1.211 + 1.212 + /* Must have at least 2 color values per component */ 1.213 + if (iroot < 2) 1.214 + ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); 1.215 + 1.216 + /* Initialize to iroot color values for each component */ 1.217 + total_colors = 1; 1.218 + for (i = 0; i < nc; i++) { 1.219 + Ncolors[i] = iroot; 1.220 + total_colors *= iroot; 1.221 + } 1.222 + /* We may be able to increment the count for one or more components without 1.223 + * exceeding max_colors, though we know not all can be incremented. 1.224 + * Sometimes, the first component can be incremented more than once! 1.225 + * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) 1.226 + * In RGB colorspace, try to increment G first, then R, then B. 1.227 + */ 1.228 + do { 1.229 + changed = FALSE; 1.230 + for (i = 0; i < nc; i++) { 1.231 + j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); 1.232 + /* calculate new total_colors if Ncolors[j] is incremented */ 1.233 + temp = total_colors / Ncolors[j]; 1.234 + temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ 1.235 + if (temp > (long) max_colors) 1.236 + break; /* won't fit, done with this pass */ 1.237 + Ncolors[j]++; /* OK, apply the increment */ 1.238 + total_colors = (int) temp; 1.239 + changed = TRUE; 1.240 + } 1.241 + } while (changed); 1.242 + 1.243 + return total_colors; 1.244 +} 1.245 + 1.246 + 1.247 +LOCAL(int) 1.248 +output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) 1.249 +/* Return j'th output value, where j will range from 0 to maxj */ 1.250 +/* The output values must fall in 0..MAXJSAMPLE in increasing order */ 1.251 +{ 1.252 + /* We always provide values 0 and MAXJSAMPLE for each component; 1.253 + * any additional values are equally spaced between these limits. 1.254 + * (Forcing the upper and lower values to the limits ensures that 1.255 + * dithering can't produce a color outside the selected gamut.) 1.256 + */ 1.257 + return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); 1.258 +} 1.259 + 1.260 + 1.261 +LOCAL(int) 1.262 +largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) 1.263 +/* Return largest input value that should map to j'th output value */ 1.264 +/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ 1.265 +{ 1.266 + /* Breakpoints are halfway between values returned by output_value */ 1.267 + return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); 1.268 +} 1.269 + 1.270 + 1.271 +/* 1.272 + * Create the colormap. 1.273 + */ 1.274 + 1.275 +LOCAL(void) 1.276 +create_colormap (j_decompress_ptr cinfo) 1.277 +{ 1.278 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.279 + JSAMPARRAY colormap; /* Created colormap */ 1.280 + int total_colors; /* Number of distinct output colors */ 1.281 + int i,j,k, nci, blksize, blkdist, ptr, val; 1.282 + 1.283 + /* Select number of colors for each component */ 1.284 + total_colors = select_ncolors(cinfo, cquantize->Ncolors); 1.285 + 1.286 + /* Report selected color counts */ 1.287 + if (cinfo->out_color_components == 3) 1.288 + TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, 1.289 + total_colors, cquantize->Ncolors[0], 1.290 + cquantize->Ncolors[1], cquantize->Ncolors[2]); 1.291 + else 1.292 + TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); 1.293 + 1.294 + /* Allocate and fill in the colormap. */ 1.295 + /* The colors are ordered in the map in standard row-major order, */ 1.296 + /* i.e. rightmost (highest-indexed) color changes most rapidly. */ 1.297 + 1.298 + colormap = (*cinfo->mem->alloc_sarray) 1.299 + ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.300 + (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); 1.301 + 1.302 + /* blksize is number of adjacent repeated entries for a component */ 1.303 + /* blkdist is distance between groups of identical entries for a component */ 1.304 + blkdist = total_colors; 1.305 + 1.306 + for (i = 0; i < cinfo->out_color_components; i++) { 1.307 + /* fill in colormap entries for i'th color component */ 1.308 + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ 1.309 + blksize = blkdist / nci; 1.310 + for (j = 0; j < nci; j++) { 1.311 + /* Compute j'th output value (out of nci) for component */ 1.312 + val = output_value(cinfo, i, j, nci-1); 1.313 + /* Fill in all colormap entries that have this value of this component */ 1.314 + for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { 1.315 + /* fill in blksize entries beginning at ptr */ 1.316 + for (k = 0; k < blksize; k++) 1.317 + colormap[i][ptr+k] = (JSAMPLE) val; 1.318 + } 1.319 + } 1.320 + blkdist = blksize; /* blksize of this color is blkdist of next */ 1.321 + } 1.322 + 1.323 + /* Save the colormap in private storage, 1.324 + * where it will survive color quantization mode changes. 1.325 + */ 1.326 + cquantize->sv_colormap = colormap; 1.327 + cquantize->sv_actual = total_colors; 1.328 +} 1.329 + 1.330 + 1.331 +/* 1.332 + * Create the color index table. 1.333 + */ 1.334 + 1.335 +LOCAL(void) 1.336 +create_colorindex (j_decompress_ptr cinfo) 1.337 +{ 1.338 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.339 + JSAMPROW indexptr; 1.340 + int i,j,k, nci, blksize, val, pad; 1.341 + 1.342 + /* For ordered dither, we pad the color index tables by MAXJSAMPLE in 1.343 + * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). 1.344 + * This is not necessary in the other dithering modes. However, we 1.345 + * flag whether it was done in case user changes dithering mode. 1.346 + */ 1.347 + if (cinfo->dither_mode == JDITHER_ORDERED) { 1.348 + pad = MAXJSAMPLE*2; 1.349 + cquantize->is_padded = TRUE; 1.350 + } else { 1.351 + pad = 0; 1.352 + cquantize->is_padded = FALSE; 1.353 + } 1.354 + 1.355 + cquantize->colorindex = (*cinfo->mem->alloc_sarray) 1.356 + ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.357 + (JDIMENSION) (MAXJSAMPLE+1 + pad), 1.358 + (JDIMENSION) cinfo->out_color_components); 1.359 + 1.360 + /* blksize is number of adjacent repeated entries for a component */ 1.361 + blksize = cquantize->sv_actual; 1.362 + 1.363 + for (i = 0; i < cinfo->out_color_components; i++) { 1.364 + /* fill in colorindex entries for i'th color component */ 1.365 + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ 1.366 + blksize = blksize / nci; 1.367 + 1.368 + /* adjust colorindex pointers to provide padding at negative indexes. */ 1.369 + if (pad) 1.370 + cquantize->colorindex[i] += MAXJSAMPLE; 1.371 + 1.372 + /* in loop, val = index of current output value, */ 1.373 + /* and k = largest j that maps to current val */ 1.374 + indexptr = cquantize->colorindex[i]; 1.375 + val = 0; 1.376 + k = largest_input_value(cinfo, i, 0, nci-1); 1.377 + for (j = 0; j <= MAXJSAMPLE; j++) { 1.378 + while (j > k) /* advance val if past boundary */ 1.379 + k = largest_input_value(cinfo, i, ++val, nci-1); 1.380 + /* premultiply so that no multiplication needed in main processing */ 1.381 + indexptr[j] = (JSAMPLE) (val * blksize); 1.382 + } 1.383 + /* Pad at both ends if necessary */ 1.384 + if (pad) 1.385 + for (j = 1; j <= MAXJSAMPLE; j++) { 1.386 + indexptr[-j] = indexptr[0]; 1.387 + indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; 1.388 + } 1.389 + } 1.390 +} 1.391 + 1.392 + 1.393 +/* 1.394 + * Create an ordered-dither array for a component having ncolors 1.395 + * distinct output values. 1.396 + */ 1.397 + 1.398 +LOCAL(ODITHER_MATRIX_PTR) 1.399 +make_odither_array (j_decompress_ptr cinfo, int ncolors) 1.400 +{ 1.401 + ODITHER_MATRIX_PTR odither; 1.402 + int j,k; 1.403 + INT32 num,den; 1.404 + 1.405 + odither = (ODITHER_MATRIX_PTR) 1.406 + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.407 + SIZEOF(ODITHER_MATRIX)); 1.408 + /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). 1.409 + * Hence the dither value for the matrix cell with fill order f 1.410 + * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). 1.411 + * On 16-bit-int machine, be careful to avoid overflow. 1.412 + */ 1.413 + den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); 1.414 + for (j = 0; j < ODITHER_SIZE; j++) { 1.415 + for (k = 0; k < ODITHER_SIZE; k++) { 1.416 + num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) 1.417 + * MAXJSAMPLE; 1.418 + /* Ensure round towards zero despite C's lack of consistency 1.419 + * about rounding negative values in integer division... 1.420 + */ 1.421 + odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); 1.422 + } 1.423 + } 1.424 + return odither; 1.425 +} 1.426 + 1.427 + 1.428 +/* 1.429 + * Create the ordered-dither tables. 1.430 + * Components having the same number of representative colors may 1.431 + * share a dither table. 1.432 + */ 1.433 + 1.434 +LOCAL(void) 1.435 +create_odither_tables (j_decompress_ptr cinfo) 1.436 +{ 1.437 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.438 + ODITHER_MATRIX_PTR odither; 1.439 + int i, j, nci; 1.440 + 1.441 + for (i = 0; i < cinfo->out_color_components; i++) { 1.442 + nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ 1.443 + odither = NULL; /* search for matching prior component */ 1.444 + for (j = 0; j < i; j++) { 1.445 + if (nci == cquantize->Ncolors[j]) { 1.446 + odither = cquantize->odither[j]; 1.447 + break; 1.448 + } 1.449 + } 1.450 + if (odither == NULL) /* need a new table? */ 1.451 + odither = make_odither_array(cinfo, nci); 1.452 + cquantize->odither[i] = odither; 1.453 + } 1.454 +} 1.455 + 1.456 + 1.457 +/* 1.458 + * Map some rows of pixels to the output colormapped representation. 1.459 + */ 1.460 + 1.461 +METHODDEF(void) 1.462 +color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 1.463 + JSAMPARRAY output_buf, int num_rows) 1.464 +/* General case, no dithering */ 1.465 +{ 1.466 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.467 + JSAMPARRAY colorindex = cquantize->colorindex; 1.468 + register int pixcode, ci; 1.469 + register JSAMPROW ptrin, ptrout; 1.470 + int row; 1.471 + JDIMENSION col; 1.472 + JDIMENSION width = cinfo->output_width; 1.473 + register int nc = cinfo->out_color_components; 1.474 + 1.475 + for (row = 0; row < num_rows; row++) { 1.476 + ptrin = input_buf[row]; 1.477 + ptrout = output_buf[row]; 1.478 + for (col = width; col > 0; col--) { 1.479 + pixcode = 0; 1.480 + for (ci = 0; ci < nc; ci++) { 1.481 + pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); 1.482 + } 1.483 + *ptrout++ = (JSAMPLE) pixcode; 1.484 + } 1.485 + } 1.486 +} 1.487 + 1.488 + 1.489 +METHODDEF(void) 1.490 +color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 1.491 + JSAMPARRAY output_buf, int num_rows) 1.492 +/* Fast path for out_color_components==3, no dithering */ 1.493 +{ 1.494 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.495 + register int pixcode; 1.496 + register JSAMPROW ptrin, ptrout; 1.497 + JSAMPROW colorindex0 = cquantize->colorindex[0]; 1.498 + JSAMPROW colorindex1 = cquantize->colorindex[1]; 1.499 + JSAMPROW colorindex2 = cquantize->colorindex[2]; 1.500 + int row; 1.501 + JDIMENSION col; 1.502 + JDIMENSION width = cinfo->output_width; 1.503 + 1.504 + for (row = 0; row < num_rows; row++) { 1.505 + ptrin = input_buf[row]; 1.506 + ptrout = output_buf[row]; 1.507 + for (col = width; col > 0; col--) { 1.508 + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); 1.509 + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); 1.510 + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); 1.511 + *ptrout++ = (JSAMPLE) pixcode; 1.512 + } 1.513 + } 1.514 +} 1.515 + 1.516 + 1.517 +METHODDEF(void) 1.518 +quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 1.519 + JSAMPARRAY output_buf, int num_rows) 1.520 +/* General case, with ordered dithering */ 1.521 +{ 1.522 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.523 + register JSAMPROW input_ptr; 1.524 + register JSAMPROW output_ptr; 1.525 + JSAMPROW colorindex_ci; 1.526 + int * dither; /* points to active row of dither matrix */ 1.527 + int row_index, col_index; /* current indexes into dither matrix */ 1.528 + int nc = cinfo->out_color_components; 1.529 + int ci; 1.530 + int row; 1.531 + JDIMENSION col; 1.532 + JDIMENSION width = cinfo->output_width; 1.533 + 1.534 + for (row = 0; row < num_rows; row++) { 1.535 + /* Initialize output values to 0 so can process components separately */ 1.536 + jzero_far((void FAR *) output_buf[row], 1.537 + (size_t) (width * SIZEOF(JSAMPLE))); 1.538 + row_index = cquantize->row_index; 1.539 + for (ci = 0; ci < nc; ci++) { 1.540 + input_ptr = input_buf[row] + ci; 1.541 + output_ptr = output_buf[row]; 1.542 + colorindex_ci = cquantize->colorindex[ci]; 1.543 + dither = cquantize->odither[ci][row_index]; 1.544 + col_index = 0; 1.545 + 1.546 + for (col = width; col > 0; col--) { 1.547 + /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, 1.548 + * select output value, accumulate into output code for this pixel. 1.549 + * Range-limiting need not be done explicitly, as we have extended 1.550 + * the colorindex table to produce the right answers for out-of-range 1.551 + * inputs. The maximum dither is +- MAXJSAMPLE; this sets the 1.552 + * required amount of padding. 1.553 + */ 1.554 + *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; 1.555 + input_ptr += nc; 1.556 + output_ptr++; 1.557 + col_index = (col_index + 1) & ODITHER_MASK; 1.558 + } 1.559 + } 1.560 + /* Advance row index for next row */ 1.561 + row_index = (row_index + 1) & ODITHER_MASK; 1.562 + cquantize->row_index = row_index; 1.563 + } 1.564 +} 1.565 + 1.566 + 1.567 +METHODDEF(void) 1.568 +quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 1.569 + JSAMPARRAY output_buf, int num_rows) 1.570 +/* Fast path for out_color_components==3, with ordered dithering */ 1.571 +{ 1.572 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.573 + register int pixcode; 1.574 + register JSAMPROW input_ptr; 1.575 + register JSAMPROW output_ptr; 1.576 + JSAMPROW colorindex0 = cquantize->colorindex[0]; 1.577 + JSAMPROW colorindex1 = cquantize->colorindex[1]; 1.578 + JSAMPROW colorindex2 = cquantize->colorindex[2]; 1.579 + int * dither0; /* points to active row of dither matrix */ 1.580 + int * dither1; 1.581 + int * dither2; 1.582 + int row_index, col_index; /* current indexes into dither matrix */ 1.583 + int row; 1.584 + JDIMENSION col; 1.585 + JDIMENSION width = cinfo->output_width; 1.586 + 1.587 + for (row = 0; row < num_rows; row++) { 1.588 + row_index = cquantize->row_index; 1.589 + input_ptr = input_buf[row]; 1.590 + output_ptr = output_buf[row]; 1.591 + dither0 = cquantize->odither[0][row_index]; 1.592 + dither1 = cquantize->odither[1][row_index]; 1.593 + dither2 = cquantize->odither[2][row_index]; 1.594 + col_index = 0; 1.595 + 1.596 + for (col = width; col > 0; col--) { 1.597 + pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + 1.598 + dither0[col_index]]); 1.599 + pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + 1.600 + dither1[col_index]]); 1.601 + pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + 1.602 + dither2[col_index]]); 1.603 + *output_ptr++ = (JSAMPLE) pixcode; 1.604 + col_index = (col_index + 1) & ODITHER_MASK; 1.605 + } 1.606 + row_index = (row_index + 1) & ODITHER_MASK; 1.607 + cquantize->row_index = row_index; 1.608 + } 1.609 +} 1.610 + 1.611 + 1.612 +METHODDEF(void) 1.613 +quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, 1.614 + JSAMPARRAY output_buf, int num_rows) 1.615 +/* General case, with Floyd-Steinberg dithering */ 1.616 +{ 1.617 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.618 + register LOCFSERROR cur; /* current error or pixel value */ 1.619 + LOCFSERROR belowerr; /* error for pixel below cur */ 1.620 + LOCFSERROR bpreverr; /* error for below/prev col */ 1.621 + LOCFSERROR bnexterr; /* error for below/next col */ 1.622 + LOCFSERROR delta; 1.623 + register FSERRPTR errorptr; /* => fserrors[] at column before current */ 1.624 + register JSAMPROW input_ptr; 1.625 + register JSAMPROW output_ptr; 1.626 + JSAMPROW colorindex_ci; 1.627 + JSAMPROW colormap_ci; 1.628 + int pixcode; 1.629 + int nc = cinfo->out_color_components; 1.630 + int dir; /* 1 for left-to-right, -1 for right-to-left */ 1.631 + int dirnc; /* dir * nc */ 1.632 + int ci; 1.633 + int row; 1.634 + JDIMENSION col; 1.635 + JDIMENSION width = cinfo->output_width; 1.636 + JSAMPLE *range_limit = cinfo->sample_range_limit; 1.637 + SHIFT_TEMPS 1.638 + 1.639 + for (row = 0; row < num_rows; row++) { 1.640 + /* Initialize output values to 0 so can process components separately */ 1.641 + jzero_far((void FAR *) output_buf[row], 1.642 + (size_t) (width * SIZEOF(JSAMPLE))); 1.643 + for (ci = 0; ci < nc; ci++) { 1.644 + input_ptr = input_buf[row] + ci; 1.645 + output_ptr = output_buf[row]; 1.646 + if (cquantize->on_odd_row) { 1.647 + /* work right to left in this row */ 1.648 + input_ptr += (width-1) * nc; /* so point to rightmost pixel */ 1.649 + output_ptr += width-1; 1.650 + dir = -1; 1.651 + dirnc = -nc; 1.652 + errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ 1.653 + } else { 1.654 + /* work left to right in this row */ 1.655 + dir = 1; 1.656 + dirnc = nc; 1.657 + errorptr = cquantize->fserrors[ci]; /* => entry before first column */ 1.658 + } 1.659 + colorindex_ci = cquantize->colorindex[ci]; 1.660 + colormap_ci = cquantize->sv_colormap[ci]; 1.661 + /* Preset error values: no error propagated to first pixel from left */ 1.662 + cur = 0; 1.663 + /* and no error propagated to row below yet */ 1.664 + belowerr = bpreverr = 0; 1.665 + 1.666 + for (col = width; col > 0; col--) { 1.667 + /* cur holds the error propagated from the previous pixel on the 1.668 + * current line. Add the error propagated from the previous line 1.669 + * to form the complete error correction term for this pixel, and 1.670 + * round the error term (which is expressed * 16) to an integer. 1.671 + * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct 1.672 + * for either sign of the error value. 1.673 + * Note: errorptr points to *previous* column's array entry. 1.674 + */ 1.675 + cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); 1.676 + /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. 1.677 + * The maximum error is +- MAXJSAMPLE; this sets the required size 1.678 + * of the range_limit array. 1.679 + */ 1.680 + cur += GETJSAMPLE(*input_ptr); 1.681 + cur = GETJSAMPLE(range_limit[cur]); 1.682 + /* Select output value, accumulate into output code for this pixel */ 1.683 + pixcode = GETJSAMPLE(colorindex_ci[cur]); 1.684 + *output_ptr += (JSAMPLE) pixcode; 1.685 + /* Compute actual representation error at this pixel */ 1.686 + /* Note: we can do this even though we don't have the final */ 1.687 + /* pixel code, because the colormap is orthogonal. */ 1.688 + cur -= GETJSAMPLE(colormap_ci[pixcode]); 1.689 + /* Compute error fractions to be propagated to adjacent pixels. 1.690 + * Add these into the running sums, and simultaneously shift the 1.691 + * next-line error sums left by 1 column. 1.692 + */ 1.693 + bnexterr = cur; 1.694 + delta = cur * 2; 1.695 + cur += delta; /* form error * 3 */ 1.696 + errorptr[0] = (FSERROR) (bpreverr + cur); 1.697 + cur += delta; /* form error * 5 */ 1.698 + bpreverr = belowerr + cur; 1.699 + belowerr = bnexterr; 1.700 + cur += delta; /* form error * 7 */ 1.701 + /* At this point cur contains the 7/16 error value to be propagated 1.702 + * to the next pixel on the current line, and all the errors for the 1.703 + * next line have been shifted over. We are therefore ready to move on. 1.704 + */ 1.705 + input_ptr += dirnc; /* advance input ptr to next column */ 1.706 + output_ptr += dir; /* advance output ptr to next column */ 1.707 + errorptr += dir; /* advance errorptr to current column */ 1.708 + } 1.709 + /* Post-loop cleanup: we must unload the final error value into the 1.710 + * final fserrors[] entry. Note we need not unload belowerr because 1.711 + * it is for the dummy column before or after the actual array. 1.712 + */ 1.713 + errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ 1.714 + } 1.715 + cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); 1.716 + } 1.717 +} 1.718 + 1.719 + 1.720 +/* 1.721 + * Allocate workspace for Floyd-Steinberg errors. 1.722 + */ 1.723 + 1.724 +LOCAL(void) 1.725 +alloc_fs_workspace (j_decompress_ptr cinfo) 1.726 +{ 1.727 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.728 + size_t arraysize; 1.729 + int i; 1.730 + 1.731 + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); 1.732 + for (i = 0; i < cinfo->out_color_components; i++) { 1.733 + cquantize->fserrors[i] = (FSERRPTR) 1.734 + (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); 1.735 + } 1.736 +} 1.737 + 1.738 + 1.739 +/* 1.740 + * Initialize for one-pass color quantization. 1.741 + */ 1.742 + 1.743 +METHODDEF(void) 1.744 +start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) 1.745 +{ 1.746 + my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; 1.747 + size_t arraysize; 1.748 + int i; 1.749 + 1.750 + /* Install my colormap. */ 1.751 + cinfo->colormap = cquantize->sv_colormap; 1.752 + cinfo->actual_number_of_colors = cquantize->sv_actual; 1.753 + 1.754 + /* Initialize for desired dithering mode. */ 1.755 + switch (cinfo->dither_mode) { 1.756 + case JDITHER_NONE: 1.757 + if (cinfo->out_color_components == 3) 1.758 + cquantize->pub.color_quantize = color_quantize3; 1.759 + else 1.760 + cquantize->pub.color_quantize = color_quantize; 1.761 + break; 1.762 + case JDITHER_ORDERED: 1.763 + if (cinfo->out_color_components == 3) 1.764 + cquantize->pub.color_quantize = quantize3_ord_dither; 1.765 + else 1.766 + cquantize->pub.color_quantize = quantize_ord_dither; 1.767 + cquantize->row_index = 0; /* initialize state for ordered dither */ 1.768 + /* If user changed to ordered dither from another mode, 1.769 + * we must recreate the color index table with padding. 1.770 + * This will cost extra space, but probably isn't very likely. 1.771 + */ 1.772 + if (! cquantize->is_padded) 1.773 + create_colorindex(cinfo); 1.774 + /* Create ordered-dither tables if we didn't already. */ 1.775 + if (cquantize->odither[0] == NULL) 1.776 + create_odither_tables(cinfo); 1.777 + break; 1.778 + case JDITHER_FS: 1.779 + cquantize->pub.color_quantize = quantize_fs_dither; 1.780 + cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ 1.781 + /* Allocate Floyd-Steinberg workspace if didn't already. */ 1.782 + if (cquantize->fserrors[0] == NULL) 1.783 + alloc_fs_workspace(cinfo); 1.784 + /* Initialize the propagated errors to zero. */ 1.785 + arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); 1.786 + for (i = 0; i < cinfo->out_color_components; i++) 1.787 + jzero_far((void FAR *) cquantize->fserrors[i], arraysize); 1.788 + break; 1.789 + default: 1.790 + ERREXIT(cinfo, JERR_NOT_COMPILED); 1.791 + break; 1.792 + } 1.793 +} 1.794 + 1.795 + 1.796 +/* 1.797 + * Finish up at the end of the pass. 1.798 + */ 1.799 + 1.800 +METHODDEF(void) 1.801 +finish_pass_1_quant (j_decompress_ptr cinfo) 1.802 +{ 1.803 + /* no work in 1-pass case */ 1.804 +} 1.805 + 1.806 + 1.807 +/* 1.808 + * Switch to a new external colormap between output passes. 1.809 + * Shouldn't get to this module! 1.810 + */ 1.811 + 1.812 +METHODDEF(void) 1.813 +new_color_map_1_quant (j_decompress_ptr cinfo) 1.814 +{ 1.815 + ERREXIT(cinfo, JERR_MODE_CHANGE); 1.816 +} 1.817 + 1.818 + 1.819 +/* 1.820 + * Module initialization routine for 1-pass color quantization. 1.821 + */ 1.822 + 1.823 +GLOBAL(void) 1.824 +jinit_1pass_quantizer (j_decompress_ptr cinfo) 1.825 +{ 1.826 + my_cquantize_ptr cquantize; 1.827 + 1.828 + cquantize = (my_cquantize_ptr) 1.829 + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.830 + SIZEOF(my_cquantizer)); 1.831 + cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; 1.832 + cquantize->pub.start_pass = start_pass_1_quant; 1.833 + cquantize->pub.finish_pass = finish_pass_1_quant; 1.834 + cquantize->pub.new_color_map = new_color_map_1_quant; 1.835 + cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ 1.836 + cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ 1.837 + 1.838 + /* Make sure my internal arrays won't overflow */ 1.839 + if (cinfo->out_color_components > MAX_Q_COMPS) 1.840 + ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); 1.841 + /* Make sure colormap indexes can be represented by JSAMPLEs */ 1.842 + if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) 1.843 + ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); 1.844 + 1.845 + /* Create the colormap and color index table. */ 1.846 + create_colormap(cinfo); 1.847 + create_colorindex(cinfo); 1.848 + 1.849 + /* Allocate Floyd-Steinberg workspace now if requested. 1.850 + * We do this now since it is FAR storage and may affect the memory 1.851 + * manager's space calculations. If the user changes to FS dither 1.852 + * mode in a later pass, we will allocate the space then, and will 1.853 + * possibly overrun the max_memory_to_use setting. 1.854 + */ 1.855 + if (cinfo->dither_mode == JDITHER_FS) 1.856 + alloc_fs_workspace(cinfo); 1.857 +} 1.858 + 1.859 +#endif /* QUANT_1PASS_SUPPORTED */