OLD | NEW |
1 /* | 1 /* |
2 * jquant1.c | 2 * jquant1.c |
3 * | 3 * |
4 * This file was part of the Independent JPEG Group's software: | 4 * This file was part of the Independent JPEG Group's software: |
5 * Copyright (C) 1991-1996, Thomas G. Lane. | 5 * Copyright (C) 1991-1996, Thomas G. Lane. |
6 * libjpeg-turbo Modifications: | 6 * libjpeg-turbo Modifications: |
7 * Copyright (C) 2009, D. R. Commander | 7 * Copyright (C) 2009, 2015, D. R. Commander. |
8 * For conditions of distribution and use, see the accompanying README file. | 8 * For conditions of distribution and use, see the accompanying README.ijg |
| 9 * file. |
9 * | 10 * |
10 * This file contains 1-pass color quantization (color mapping) routines. | 11 * This file contains 1-pass color quantization (color mapping) routines. |
11 * These routines provide mapping to a fixed color map using equally spaced | 12 * These routines provide mapping to a fixed color map using equally spaced |
12 * color values. Optional Floyd-Steinberg or ordered dithering is available. | 13 * color values. Optional Floyd-Steinberg or ordered dithering is available. |
13 */ | 14 */ |
14 | 15 |
15 #define JPEG_INTERNALS | 16 #define JPEG_INTERNALS |
16 #include "jinclude.h" | 17 #include "jinclude.h" |
17 #include "jpeglib.h" | 18 #include "jpeglib.h" |
18 | 19 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 * the distance between output values. For ordered dithering, we assume that | 64 * the distance between output values. For ordered dithering, we assume that |
64 * the output colors are equally spaced; if not, results will probably be | 65 * the output colors are equally spaced; if not, results will probably be |
65 * worse, since the dither may be too much or too little at a given point. | 66 * worse, since the dither may be too much or too little at a given point. |
66 * | 67 * |
67 * The normal calculation would be to form pixel value + dither, range-limit | 68 * The normal calculation would be to form pixel value + dither, range-limit |
68 * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. | 69 * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. |
69 * We can skip the separate range-limiting step by extending the colorindex | 70 * We can skip the separate range-limiting step by extending the colorindex |
70 * table in both directions. | 71 * table in both directions. |
71 */ | 72 */ |
72 | 73 |
73 #define ODITHER_SIZE 16» /* dimension of dither matrix */ | 74 #define ODITHER_SIZE 16 /* dimension of dither matrix */ |
74 /* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ | 75 /* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ |
75 #define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE)» /* # cells in matrix */ | 76 #define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ |
76 #define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ | 77 #define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ |
77 | 78 |
78 typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; | 79 typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; |
79 typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; | 80 typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; |
80 | 81 |
81 static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { | 82 static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { |
82 /* Bayer's order-4 dither array. Generated by the code given in | 83 /* Bayer's order-4 dither array. Generated by the code given in |
83 * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. | 84 * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. |
84 * The values in this array must range from 0 to ODITHER_CELLS-1. | 85 * The values in this array must range from 0 to ODITHER_CELLS-1. |
85 */ | 86 */ |
(...skipping 14 matching lines...) Expand all Loading... |
100 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, | 101 { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, |
101 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } | 102 { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } |
102 }; | 103 }; |
103 | 104 |
104 | 105 |
105 /* Declarations for Floyd-Steinberg dithering. | 106 /* Declarations for Floyd-Steinberg dithering. |
106 * | 107 * |
107 * Errors are accumulated into the array fserrors[], at a resolution of | 108 * Errors are accumulated into the array fserrors[], at a resolution of |
108 * 1/16th of a pixel count. The error at a given pixel is propagated | 109 * 1/16th of a pixel count. The error at a given pixel is propagated |
109 * to its not-yet-processed neighbors using the standard F-S fractions, | 110 * to its not-yet-processed neighbors using the standard F-S fractions, |
110 *» » ...» (here)» 7/16 | 111 * ... (here) 7/16 |
111 *» » 3/16» 5/16» 1/16 | 112 * 3/16 5/16 1/16 |
112 * We work left-to-right on even rows, right-to-left on odd rows. | 113 * We work left-to-right on even rows, right-to-left on odd rows. |
113 * | 114 * |
114 * We can get away with a single array (holding one row's worth of errors) | 115 * We can get away with a single array (holding one row's worth of errors) |
115 * by using it to store the current row's errors at pixel columns not yet | 116 * by using it to store the current row's errors at pixel columns not yet |
116 * processed, but the next row's errors at columns already processed. We | 117 * processed, but the next row's errors at columns already processed. We |
117 * need only a few extra variables to hold the errors immediately around the | 118 * need only a few extra variables to hold the errors immediately around the |
118 * current column. (If we are lucky, those variables are in registers, but | 119 * current column. (If we are lucky, those variables are in registers, but |
119 * even if not, they're probably cheaper to access than array elements are.) | 120 * even if not, they're probably cheaper to access than array elements are.) |
120 * | 121 * |
121 * The fserrors[] array is indexed [component#][position]. | 122 * The fserrors[] array is indexed [component#][position]. |
122 * We provide (#columns + 2) entries per component; the extra entry at each | 123 * We provide (#columns + 2) entries per component; the extra entry at each |
123 * end saves us from special-casing the first and last pixels. | 124 * end saves us from special-casing the first and last pixels. |
124 * | |
125 * Note: on a wide image, we might not have enough room in a PC's near data | |
126 * segment to hold the error array; so it is allocated with alloc_large. | |
127 */ | 125 */ |
128 | 126 |
129 #if BITS_IN_JSAMPLE == 8 | 127 #if BITS_IN_JSAMPLE == 8 |
130 typedef INT16 FSERROR;» » /* 16 bits should be enough */ | 128 typedef INT16 FSERROR; /* 16 bits should be enough */ |
131 typedef int LOCFSERROR;»» /* use 'int' for calculation temps */ | 129 typedef int LOCFSERROR; /* use 'int' for calculation temps */ |
132 #else | 130 #else |
133 typedef INT32 FSERROR;» » /* may need more than 16 bits */ | 131 typedef JLONG FSERROR; /* may need more than 16 bits */ |
134 typedef INT32 LOCFSERROR;» /* be sure calculation temps are big enough */ | 132 typedef JLONG LOCFSERROR; /* be sure calculation temps are big enough */ |
135 #endif | 133 #endif |
136 | 134 |
137 typedef FSERROR FAR *FSERRPTR;» /* pointer to error array (in FAR storage!) */ | 135 typedef FSERROR *FSERRPTR; /* pointer to error array */ |
138 | 136 |
139 | 137 |
140 /* Private subobject */ | 138 /* Private subobject */ |
141 | 139 |
142 #define MAX_Q_COMPS 4» » /* max components I can handle */ | 140 #define MAX_Q_COMPS 4 /* max components I can handle */ |
143 | 141 |
144 typedef struct { | 142 typedef struct { |
145 struct jpeg_color_quantizer pub; /* public fields */ | 143 struct jpeg_color_quantizer pub; /* public fields */ |
146 | 144 |
147 /* Initially allocated colormap is saved here */ | 145 /* Initially allocated colormap is saved here */ |
148 JSAMPARRAY sv_colormap;» /* The color map as a 2-D pixel array */ | 146 JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ |
149 int sv_actual;» » /* number of entries in use */ | 147 int sv_actual; /* number of entries in use */ |
150 | 148 |
151 JSAMPARRAY colorindex;» /* Precomputed mapping for speed */ | 149 JSAMPARRAY colorindex; /* Precomputed mapping for speed */ |
152 /* colorindex[i][j] = index of color closest to pixel value j in component i, | 150 /* colorindex[i][j] = index of color closest to pixel value j in component i, |
153 * premultiplied as described above. Since colormap indexes must fit into | 151 * premultiplied as described above. Since colormap indexes must fit into |
154 * JSAMPLEs, the entries of this array will too. | 152 * JSAMPLEs, the entries of this array will too. |
155 */ | 153 */ |
156 boolean is_padded;» » /* is the colorindex padded for odither? */ | 154 boolean is_padded; /* is the colorindex padded for odither? */ |
157 | 155 |
158 int Ncolors[MAX_Q_COMPS];» /* # of values alloced to each component */ | 156 int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ |
159 | 157 |
160 /* Variables for ordered dithering */ | 158 /* Variables for ordered dithering */ |
161 int row_index;» » /* cur row's vertical index in dither matrix */ | 159 int row_index; /* cur row's vertical index in dither matrix */ |
162 ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ | 160 ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ |
163 | 161 |
164 /* Variables for Floyd-Steinberg dithering */ | 162 /* Variables for Floyd-Steinberg dithering */ |
165 FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ | 163 FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ |
166 boolean on_odd_row;» » /* flag to remember which row we are on */ | 164 boolean on_odd_row; /* flag to remember which row we are on */ |
167 } my_cquantizer; | 165 } my_cquantizer; |
168 | 166 |
169 typedef my_cquantizer * my_cquantize_ptr; | 167 typedef my_cquantizer *my_cquantize_ptr; |
170 | 168 |
171 | 169 |
172 /* | 170 /* |
173 * Policy-making subroutines for create_colormap and create_colorindex. | 171 * Policy-making subroutines for create_colormap and create_colorindex. |
174 * These routines determine the colormap to be used. The rest of the module | 172 * These routines determine the colormap to be used. The rest of the module |
175 * only assumes that the colormap is orthogonal. | 173 * only assumes that the colormap is orthogonal. |
176 * | 174 * |
177 * * select_ncolors decides how to divvy up the available colors | 175 * * select_ncolors decides how to divvy up the available colors |
178 * among the components. | 176 * among the components. |
179 * * output_value defines the set of representative values for a component. | 177 * * output_value defines the set of representative values for a component. |
(...skipping 18 matching lines...) Expand all Loading... |
198 int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; | 196 int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; |
199 RGB_order[0] = rgb_green[cinfo->out_color_space]; | 197 RGB_order[0] = rgb_green[cinfo->out_color_space]; |
200 RGB_order[1] = rgb_red[cinfo->out_color_space]; | 198 RGB_order[1] = rgb_red[cinfo->out_color_space]; |
201 RGB_order[2] = rgb_blue[cinfo->out_color_space]; | 199 RGB_order[2] = rgb_blue[cinfo->out_color_space]; |
202 | 200 |
203 /* We can allocate at least the nc'th root of max_colors per component. */ | 201 /* We can allocate at least the nc'th root of max_colors per component. */ |
204 /* Compute floor(nc'th root of max_colors). */ | 202 /* Compute floor(nc'th root of max_colors). */ |
205 iroot = 1; | 203 iroot = 1; |
206 do { | 204 do { |
207 iroot++; | 205 iroot++; |
208 temp = iroot;» » /* set temp = iroot ** nc */ | 206 temp = iroot; /* set temp = iroot ** nc */ |
209 for (i = 1; i < nc; i++) | 207 for (i = 1; i < nc; i++) |
210 temp *= iroot; | 208 temp *= iroot; |
211 } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ | 209 } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ |
212 iroot--;» » » /* now iroot = floor(root) */ | 210 iroot--; /* now iroot = floor(root) */ |
213 | 211 |
214 /* Must have at least 2 color values per component */ | 212 /* Must have at least 2 color values per component */ |
215 if (iroot < 2) | 213 if (iroot < 2) |
216 ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); | 214 ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); |
217 | 215 |
218 /* Initialize to iroot color values for each component */ | 216 /* Initialize to iroot color values for each component */ |
219 total_colors = 1; | 217 total_colors = 1; |
220 for (i = 0; i < nc; i++) { | 218 for (i = 0; i < nc; i++) { |
221 Ncolors[i] = iroot; | 219 Ncolors[i] = iroot; |
222 total_colors *= iroot; | 220 total_colors *= iroot; |
223 } | 221 } |
224 /* We may be able to increment the count for one or more components without | 222 /* We may be able to increment the count for one or more components without |
225 * exceeding max_colors, though we know not all can be incremented. | 223 * exceeding max_colors, though we know not all can be incremented. |
226 * Sometimes, the first component can be incremented more than once! | 224 * Sometimes, the first component can be incremented more than once! |
227 * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) | 225 * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) |
228 * In RGB colorspace, try to increment G first, then R, then B. | 226 * In RGB colorspace, try to increment G first, then R, then B. |
229 */ | 227 */ |
230 do { | 228 do { |
231 changed = FALSE; | 229 changed = FALSE; |
232 for (i = 0; i < nc; i++) { | 230 for (i = 0; i < nc; i++) { |
233 j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); | 231 j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); |
234 /* calculate new total_colors if Ncolors[j] is incremented */ | 232 /* calculate new total_colors if Ncolors[j] is incremented */ |
235 temp = total_colors / Ncolors[j]; | 233 temp = total_colors / Ncolors[j]; |
236 temp *= Ncolors[j]+1;» /* done in long arith to avoid oflo */ | 234 temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ |
237 if (temp > (long) max_colors) | 235 if (temp > (long) max_colors) |
238 » break;» » » /* won't fit, done with this pass */ | 236 break; /* won't fit, done with this pass */ |
239 Ncolors[j]++;» » /* OK, apply the increment */ | 237 Ncolors[j]++; /* OK, apply the increment */ |
240 total_colors = (int) temp; | 238 total_colors = (int) temp; |
241 changed = TRUE; | 239 changed = TRUE; |
242 } | 240 } |
243 } while (changed); | 241 } while (changed); |
244 | 242 |
245 return total_colors; | 243 return total_colors; |
246 } | 244 } |
247 | 245 |
248 | 246 |
249 LOCAL(int) | 247 LOCAL(int) |
250 output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) | 248 output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) |
251 /* Return j'th output value, where j will range from 0 to maxj */ | 249 /* Return j'th output value, where j will range from 0 to maxj */ |
252 /* The output values must fall in 0..MAXJSAMPLE in increasing order */ | 250 /* The output values must fall in 0..MAXJSAMPLE in increasing order */ |
253 { | 251 { |
254 /* We always provide values 0 and MAXJSAMPLE for each component; | 252 /* We always provide values 0 and MAXJSAMPLE for each component; |
255 * any additional values are equally spaced between these limits. | 253 * any additional values are equally spaced between these limits. |
256 * (Forcing the upper and lower values to the limits ensures that | 254 * (Forcing the upper and lower values to the limits ensures that |
257 * dithering can't produce a color outside the selected gamut.) | 255 * dithering can't produce a color outside the selected gamut.) |
258 */ | 256 */ |
259 return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); | 257 return (int) (((JLONG) j * MAXJSAMPLE + maxj/2) / maxj); |
260 } | 258 } |
261 | 259 |
262 | 260 |
263 LOCAL(int) | 261 LOCAL(int) |
264 largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) | 262 largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) |
265 /* Return largest input value that should map to j'th output value */ | 263 /* Return largest input value that should map to j'th output value */ |
266 /* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ | 264 /* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ |
267 { | 265 { |
268 /* Breakpoints are halfway between values returned by output_value */ | 266 /* Breakpoints are halfway between values returned by output_value */ |
269 return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); | 267 return (int) (((JLONG) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); |
270 } | 268 } |
271 | 269 |
272 | 270 |
273 /* | 271 /* |
274 * Create the colormap. | 272 * Create the colormap. |
275 */ | 273 */ |
276 | 274 |
277 LOCAL(void) | 275 LOCAL(void) |
278 create_colormap (j_decompress_ptr cinfo) | 276 create_colormap (j_decompress_ptr cinfo) |
279 { | 277 { |
280 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 278 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
281 JSAMPARRAY colormap;» » /* Created colormap */ | 279 JSAMPARRAY colormap; /* Created colormap */ |
282 int total_colors;» » /* Number of distinct output colors */ | 280 int total_colors; /* Number of distinct output colors */ |
283 int i,j,k, nci, blksize, blkdist, ptr, val; | 281 int i,j,k, nci, blksize, blkdist, ptr, val; |
284 | 282 |
285 /* Select number of colors for each component */ | 283 /* Select number of colors for each component */ |
286 total_colors = select_ncolors(cinfo, cquantize->Ncolors); | 284 total_colors = select_ncolors(cinfo, cquantize->Ncolors); |
287 | 285 |
288 /* Report selected color counts */ | 286 /* Report selected color counts */ |
289 if (cinfo->out_color_components == 3) | 287 if (cinfo->out_color_components == 3) |
290 TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, | 288 TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, |
291 » total_colors, cquantize->Ncolors[0], | 289 total_colors, cquantize->Ncolors[0], |
292 » cquantize->Ncolors[1], cquantize->Ncolors[2]); | 290 cquantize->Ncolors[1], cquantize->Ncolors[2]); |
293 else | 291 else |
294 TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); | 292 TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); |
295 | 293 |
296 /* Allocate and fill in the colormap. */ | 294 /* Allocate and fill in the colormap. */ |
297 /* The colors are ordered in the map in standard row-major order, */ | 295 /* The colors are ordered in the map in standard row-major order, */ |
298 /* i.e. rightmost (highest-indexed) color changes most rapidly. */ | 296 /* i.e. rightmost (highest-indexed) color changes most rapidly. */ |
299 | 297 |
300 colormap = (*cinfo->mem->alloc_sarray) | 298 colormap = (*cinfo->mem->alloc_sarray) |
301 ((j_common_ptr) cinfo, JPOOL_IMAGE, | 299 ((j_common_ptr) cinfo, JPOOL_IMAGE, |
302 (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); | 300 (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); |
303 | 301 |
304 /* blksize is number of adjacent repeated entries for a component */ | 302 /* blksize is number of adjacent repeated entries for a component */ |
305 /* blkdist is distance between groups of identical entries for a component */ | 303 /* blkdist is distance between groups of identical entries for a component */ |
306 blkdist = total_colors; | 304 blkdist = total_colors; |
307 | 305 |
308 for (i = 0; i < cinfo->out_color_components; i++) { | 306 for (i = 0; i < cinfo->out_color_components; i++) { |
309 /* fill in colormap entries for i'th color component */ | 307 /* fill in colormap entries for i'th color component */ |
310 nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ | 308 nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ |
311 blksize = blkdist / nci; | 309 blksize = blkdist / nci; |
312 for (j = 0; j < nci; j++) { | 310 for (j = 0; j < nci; j++) { |
313 /* Compute j'th output value (out of nci) for component */ | 311 /* Compute j'th output value (out of nci) for component */ |
314 val = output_value(cinfo, i, j, nci-1); | 312 val = output_value(cinfo, i, j, nci-1); |
315 /* Fill in all colormap entries that have this value of this component */ | 313 /* Fill in all colormap entries that have this value of this component */ |
316 for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { | 314 for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { |
317 » /* fill in blksize entries beginning at ptr */ | 315 /* fill in blksize entries beginning at ptr */ |
318 » for (k = 0; k < blksize; k++) | 316 for (k = 0; k < blksize; k++) |
319 » colormap[i][ptr+k] = (JSAMPLE) val; | 317 colormap[i][ptr+k] = (JSAMPLE) val; |
320 } | 318 } |
321 } | 319 } |
322 blkdist = blksize;» » /* blksize of this color is blkdist of next */ | 320 blkdist = blksize; /* blksize of this color is blkdist of next */ |
323 } | 321 } |
324 | 322 |
325 /* Save the colormap in private storage, | 323 /* Save the colormap in private storage, |
326 * where it will survive color quantization mode changes. | 324 * where it will survive color quantization mode changes. |
327 */ | 325 */ |
328 cquantize->sv_colormap = colormap; | 326 cquantize->sv_colormap = colormap; |
329 cquantize->sv_actual = total_colors; | 327 cquantize->sv_actual = total_colors; |
330 } | 328 } |
331 | 329 |
332 | 330 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 /* adjust colorindex pointers to provide padding at negative indexes. */ | 368 /* adjust colorindex pointers to provide padding at negative indexes. */ |
371 if (pad) | 369 if (pad) |
372 cquantize->colorindex[i] += MAXJSAMPLE; | 370 cquantize->colorindex[i] += MAXJSAMPLE; |
373 | 371 |
374 /* in loop, val = index of current output value, */ | 372 /* in loop, val = index of current output value, */ |
375 /* and k = largest j that maps to current val */ | 373 /* and k = largest j that maps to current val */ |
376 indexptr = cquantize->colorindex[i]; | 374 indexptr = cquantize->colorindex[i]; |
377 val = 0; | 375 val = 0; |
378 k = largest_input_value(cinfo, i, 0, nci-1); | 376 k = largest_input_value(cinfo, i, 0, nci-1); |
379 for (j = 0; j <= MAXJSAMPLE; j++) { | 377 for (j = 0; j <= MAXJSAMPLE; j++) { |
380 while (j > k)» » /* advance val if past boundary */ | 378 while (j > k) /* advance val if past boundary */ |
381 » k = largest_input_value(cinfo, i, ++val, nci-1); | 379 k = largest_input_value(cinfo, i, ++val, nci-1); |
382 /* premultiply so that no multiplication needed in main processing */ | 380 /* premultiply so that no multiplication needed in main processing */ |
383 indexptr[j] = (JSAMPLE) (val * blksize); | 381 indexptr[j] = (JSAMPLE) (val * blksize); |
384 } | 382 } |
385 /* Pad at both ends if necessary */ | 383 /* Pad at both ends if necessary */ |
386 if (pad) | 384 if (pad) |
387 for (j = 1; j <= MAXJSAMPLE; j++) { | 385 for (j = 1; j <= MAXJSAMPLE; j++) { |
388 » indexptr[-j] = indexptr[0]; | 386 indexptr[-j] = indexptr[0]; |
389 » indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; | 387 indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; |
390 } | 388 } |
391 } | 389 } |
392 } | 390 } |
393 | 391 |
394 | 392 |
395 /* | 393 /* |
396 * Create an ordered-dither array for a component having ncolors | 394 * Create an ordered-dither array for a component having ncolors |
397 * distinct output values. | 395 * distinct output values. |
398 */ | 396 */ |
399 | 397 |
400 LOCAL(ODITHER_MATRIX_PTR) | 398 LOCAL(ODITHER_MATRIX_PTR) |
401 make_odither_array (j_decompress_ptr cinfo, int ncolors) | 399 make_odither_array (j_decompress_ptr cinfo, int ncolors) |
402 { | 400 { |
403 ODITHER_MATRIX_PTR odither; | 401 ODITHER_MATRIX_PTR odither; |
404 int j,k; | 402 int j,k; |
405 INT32 num,den; | 403 JLONG num,den; |
406 | 404 |
407 odither = (ODITHER_MATRIX_PTR) | 405 odither = (ODITHER_MATRIX_PTR) |
408 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, | 406 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
409 » » » » SIZEOF(ODITHER_MATRIX)); | 407 sizeof(ODITHER_MATRIX)); |
410 /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). | 408 /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). |
411 * Hence the dither value for the matrix cell with fill order f | 409 * Hence the dither value for the matrix cell with fill order f |
412 * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). | 410 * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). |
413 * On 16-bit-int machine, be careful to avoid overflow. | 411 * On 16-bit-int machine, be careful to avoid overflow. |
414 */ | 412 */ |
415 den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); | 413 den = 2 * ODITHER_CELLS * ((JLONG) (ncolors - 1)); |
416 for (j = 0; j < ODITHER_SIZE; j++) { | 414 for (j = 0; j < ODITHER_SIZE; j++) { |
417 for (k = 0; k < ODITHER_SIZE; k++) { | 415 for (k = 0; k < ODITHER_SIZE; k++) { |
418 num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) | 416 num = ((JLONG) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) |
419 » * MAXJSAMPLE; | 417 * MAXJSAMPLE; |
420 /* Ensure round towards zero despite C's lack of consistency | 418 /* Ensure round towards zero despite C's lack of consistency |
421 * about rounding negative values in integer division... | 419 * about rounding negative values in integer division... |
422 */ | 420 */ |
423 odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); | 421 odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); |
424 } | 422 } |
425 } | 423 } |
426 return odither; | 424 return odither; |
427 } | 425 } |
428 | 426 |
429 | 427 |
430 /* | 428 /* |
431 * Create the ordered-dither tables. | 429 * Create the ordered-dither tables. |
432 * Components having the same number of representative colors may | 430 * Components having the same number of representative colors may |
433 * share a dither table. | 431 * share a dither table. |
434 */ | 432 */ |
435 | 433 |
436 LOCAL(void) | 434 LOCAL(void) |
437 create_odither_tables (j_decompress_ptr cinfo) | 435 create_odither_tables (j_decompress_ptr cinfo) |
438 { | 436 { |
439 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 437 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
440 ODITHER_MATRIX_PTR odither; | 438 ODITHER_MATRIX_PTR odither; |
441 int i, j, nci; | 439 int i, j, nci; |
442 | 440 |
443 for (i = 0; i < cinfo->out_color_components; i++) { | 441 for (i = 0; i < cinfo->out_color_components; i++) { |
444 nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ | 442 nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ |
445 odither = NULL;» » /* search for matching prior component */ | 443 odither = NULL; /* search for matching prior component */ |
446 for (j = 0; j < i; j++) { | 444 for (j = 0; j < i; j++) { |
447 if (nci == cquantize->Ncolors[j]) { | 445 if (nci == cquantize->Ncolors[j]) { |
448 » odither = cquantize->odither[j]; | 446 odither = cquantize->odither[j]; |
449 » break; | 447 break; |
450 } | 448 } |
451 } | 449 } |
452 if (odither == NULL)» /* need a new table? */ | 450 if (odither == NULL) /* need a new table? */ |
453 odither = make_odither_array(cinfo, nci); | 451 odither = make_odither_array(cinfo, nci); |
454 cquantize->odither[i] = odither; | 452 cquantize->odither[i] = odither; |
455 } | 453 } |
456 } | 454 } |
457 | 455 |
458 | 456 |
459 /* | 457 /* |
460 * Map some rows of pixels to the output colormapped representation. | 458 * Map some rows of pixels to the output colormapped representation. |
461 */ | 459 */ |
462 | 460 |
463 METHODDEF(void) | 461 METHODDEF(void) |
464 color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | 462 color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, |
465 » » JSAMPARRAY output_buf, int num_rows) | 463 JSAMPARRAY output_buf, int num_rows) |
466 /* General case, no dithering */ | 464 /* General case, no dithering */ |
467 { | 465 { |
468 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 466 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
469 JSAMPARRAY colorindex = cquantize->colorindex; | 467 JSAMPARRAY colorindex = cquantize->colorindex; |
470 register int pixcode, ci; | 468 register int pixcode, ci; |
471 register JSAMPROW ptrin, ptrout; | 469 register JSAMPROW ptrin, ptrout; |
472 int row; | 470 int row; |
473 JDIMENSION col; | 471 JDIMENSION col; |
474 JDIMENSION width = cinfo->output_width; | 472 JDIMENSION width = cinfo->output_width; |
475 register int nc = cinfo->out_color_components; | 473 register int nc = cinfo->out_color_components; |
476 | 474 |
477 for (row = 0; row < num_rows; row++) { | 475 for (row = 0; row < num_rows; row++) { |
478 ptrin = input_buf[row]; | 476 ptrin = input_buf[row]; |
479 ptrout = output_buf[row]; | 477 ptrout = output_buf[row]; |
480 for (col = width; col > 0; col--) { | 478 for (col = width; col > 0; col--) { |
481 pixcode = 0; | 479 pixcode = 0; |
482 for (ci = 0; ci < nc; ci++) { | 480 for (ci = 0; ci < nc; ci++) { |
483 » pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); | 481 pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); |
484 } | 482 } |
485 *ptrout++ = (JSAMPLE) pixcode; | 483 *ptrout++ = (JSAMPLE) pixcode; |
486 } | 484 } |
487 } | 485 } |
488 } | 486 } |
489 | 487 |
490 | 488 |
491 METHODDEF(void) | 489 METHODDEF(void) |
492 color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | 490 color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, |
493 » » JSAMPARRAY output_buf, int num_rows) | 491 JSAMPARRAY output_buf, int num_rows) |
494 /* Fast path for out_color_components==3, no dithering */ | 492 /* Fast path for out_color_components==3, no dithering */ |
495 { | 493 { |
496 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 494 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
497 register int pixcode; | 495 register int pixcode; |
498 register JSAMPROW ptrin, ptrout; | 496 register JSAMPROW ptrin, ptrout; |
499 JSAMPROW colorindex0 = cquantize->colorindex[0]; | 497 JSAMPROW colorindex0 = cquantize->colorindex[0]; |
500 JSAMPROW colorindex1 = cquantize->colorindex[1]; | 498 JSAMPROW colorindex1 = cquantize->colorindex[1]; |
501 JSAMPROW colorindex2 = cquantize->colorindex[2]; | 499 JSAMPROW colorindex2 = cquantize->colorindex[2]; |
502 int row; | 500 int row; |
503 JDIMENSION col; | 501 JDIMENSION col; |
504 JDIMENSION width = cinfo->output_width; | 502 JDIMENSION width = cinfo->output_width; |
505 | 503 |
506 for (row = 0; row < num_rows; row++) { | 504 for (row = 0; row < num_rows; row++) { |
507 ptrin = input_buf[row]; | 505 ptrin = input_buf[row]; |
508 ptrout = output_buf[row]; | 506 ptrout = output_buf[row]; |
509 for (col = width; col > 0; col--) { | 507 for (col = width; col > 0; col--) { |
510 pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); | 508 pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); |
511 pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); | 509 pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); |
512 pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); | 510 pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); |
513 *ptrout++ = (JSAMPLE) pixcode; | 511 *ptrout++ = (JSAMPLE) pixcode; |
514 } | 512 } |
515 } | 513 } |
516 } | 514 } |
517 | 515 |
518 | 516 |
519 METHODDEF(void) | 517 METHODDEF(void) |
520 quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | 518 quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, |
521 » » JSAMPARRAY output_buf, int num_rows) | 519 JSAMPARRAY output_buf, int num_rows) |
522 /* General case, with ordered dithering */ | 520 /* General case, with ordered dithering */ |
523 { | 521 { |
524 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 522 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
525 register JSAMPROW input_ptr; | 523 register JSAMPROW input_ptr; |
526 register JSAMPROW output_ptr; | 524 register JSAMPROW output_ptr; |
527 JSAMPROW colorindex_ci; | 525 JSAMPROW colorindex_ci; |
528 int * dither;»» » /* points to active row of dither matrix */ | 526 int *dither; /* points to active row of dither matrix */ |
529 int row_index, col_index;» /* current indexes into dither matrix */ | 527 int row_index, col_index; /* current indexes into dither matrix */ |
530 int nc = cinfo->out_color_components; | 528 int nc = cinfo->out_color_components; |
531 int ci; | 529 int ci; |
532 int row; | 530 int row; |
533 JDIMENSION col; | 531 JDIMENSION col; |
534 JDIMENSION width = cinfo->output_width; | 532 JDIMENSION width = cinfo->output_width; |
535 | 533 |
536 for (row = 0; row < num_rows; row++) { | 534 for (row = 0; row < num_rows; row++) { |
537 /* Initialize output values to 0 so can process components separately */ | 535 /* Initialize output values to 0 so can process components separately */ |
538 jzero_far((void FAR *) output_buf[row], | 536 jzero_far((void *) output_buf[row], (size_t) (width * sizeof(JSAMPLE))); |
539 » (size_t) (width * SIZEOF(JSAMPLE))); | |
540 row_index = cquantize->row_index; | 537 row_index = cquantize->row_index; |
541 for (ci = 0; ci < nc; ci++) { | 538 for (ci = 0; ci < nc; ci++) { |
542 input_ptr = input_buf[row] + ci; | 539 input_ptr = input_buf[row] + ci; |
543 output_ptr = output_buf[row]; | 540 output_ptr = output_buf[row]; |
544 colorindex_ci = cquantize->colorindex[ci]; | 541 colorindex_ci = cquantize->colorindex[ci]; |
545 dither = cquantize->odither[ci][row_index]; | 542 dither = cquantize->odither[ci][row_index]; |
546 col_index = 0; | 543 col_index = 0; |
547 | 544 |
548 for (col = width; col > 0; col--) { | 545 for (col = width; col > 0; col--) { |
549 » /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, | 546 /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, |
550 » * select output value, accumulate into output code for this pixel. | 547 * select output value, accumulate into output code for this pixel. |
551 » * Range-limiting need not be done explicitly, as we have extended | 548 * Range-limiting need not be done explicitly, as we have extended |
552 » * the colorindex table to produce the right answers for out-of-range | 549 * the colorindex table to produce the right answers for out-of-range |
553 » * inputs. The maximum dither is +- MAXJSAMPLE; this sets the | 550 * inputs. The maximum dither is +- MAXJSAMPLE; this sets the |
554 » * required amount of padding. | 551 * required amount of padding. |
555 » */ | 552 */ |
556 » *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; | 553 *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; |
557 » input_ptr += nc; | 554 input_ptr += nc; |
558 » output_ptr++; | 555 output_ptr++; |
559 » col_index = (col_index + 1) & ODITHER_MASK; | 556 col_index = (col_index + 1) & ODITHER_MASK; |
560 } | 557 } |
561 } | 558 } |
562 /* Advance row index for next row */ | 559 /* Advance row index for next row */ |
563 row_index = (row_index + 1) & ODITHER_MASK; | 560 row_index = (row_index + 1) & ODITHER_MASK; |
564 cquantize->row_index = row_index; | 561 cquantize->row_index = row_index; |
565 } | 562 } |
566 } | 563 } |
567 | 564 |
568 | 565 |
569 METHODDEF(void) | 566 METHODDEF(void) |
570 quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | 567 quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, |
571 » » JSAMPARRAY output_buf, int num_rows) | 568 JSAMPARRAY output_buf, int num_rows) |
572 /* Fast path for out_color_components==3, with ordered dithering */ | 569 /* Fast path for out_color_components==3, with ordered dithering */ |
573 { | 570 { |
574 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 571 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
575 register int pixcode; | 572 register int pixcode; |
576 register JSAMPROW input_ptr; | 573 register JSAMPROW input_ptr; |
577 register JSAMPROW output_ptr; | 574 register JSAMPROW output_ptr; |
578 JSAMPROW colorindex0 = cquantize->colorindex[0]; | 575 JSAMPROW colorindex0 = cquantize->colorindex[0]; |
579 JSAMPROW colorindex1 = cquantize->colorindex[1]; | 576 JSAMPROW colorindex1 = cquantize->colorindex[1]; |
580 JSAMPROW colorindex2 = cquantize->colorindex[2]; | 577 JSAMPROW colorindex2 = cquantize->colorindex[2]; |
581 int * dither0;» » /* points to active row of dither matrix */ | 578 int *dither0; /* points to active row of dither matrix */ |
582 int * dither1; | 579 int *dither1; |
583 int * dither2; | 580 int *dither2; |
584 int row_index, col_index;» /* current indexes into dither matrix */ | 581 int row_index, col_index; /* current indexes into dither matrix */ |
585 int row; | 582 int row; |
586 JDIMENSION col; | 583 JDIMENSION col; |
587 JDIMENSION width = cinfo->output_width; | 584 JDIMENSION width = cinfo->output_width; |
588 | 585 |
589 for (row = 0; row < num_rows; row++) { | 586 for (row = 0; row < num_rows; row++) { |
590 row_index = cquantize->row_index; | 587 row_index = cquantize->row_index; |
591 input_ptr = input_buf[row]; | 588 input_ptr = input_buf[row]; |
592 output_ptr = output_buf[row]; | 589 output_ptr = output_buf[row]; |
593 dither0 = cquantize->odither[0][row_index]; | 590 dither0 = cquantize->odither[0][row_index]; |
594 dither1 = cquantize->odither[1][row_index]; | 591 dither1 = cquantize->odither[1][row_index]; |
595 dither2 = cquantize->odither[2][row_index]; | 592 dither2 = cquantize->odither[2][row_index]; |
596 col_index = 0; | 593 col_index = 0; |
597 | 594 |
598 for (col = width; col > 0; col--) { | 595 for (col = width; col > 0; col--) { |
599 pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + | 596 pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + |
600 » » » » » dither0[col_index]]); | 597 dither0[col_index]]); |
601 pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + | 598 pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + |
602 » » » » » dither1[col_index]]); | 599 dither1[col_index]]); |
603 pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + | 600 pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + |
604 » » » » » dither2[col_index]]); | 601 dither2[col_index]]); |
605 *output_ptr++ = (JSAMPLE) pixcode; | 602 *output_ptr++ = (JSAMPLE) pixcode; |
606 col_index = (col_index + 1) & ODITHER_MASK; | 603 col_index = (col_index + 1) & ODITHER_MASK; |
607 } | 604 } |
608 row_index = (row_index + 1) & ODITHER_MASK; | 605 row_index = (row_index + 1) & ODITHER_MASK; |
609 cquantize->row_index = row_index; | 606 cquantize->row_index = row_index; |
610 } | 607 } |
611 } | 608 } |
612 | 609 |
613 | 610 |
614 METHODDEF(void) | 611 METHODDEF(void) |
615 quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, | 612 quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, |
616 » » JSAMPARRAY output_buf, int num_rows) | 613 JSAMPARRAY output_buf, int num_rows) |
617 /* General case, with Floyd-Steinberg dithering */ | 614 /* General case, with Floyd-Steinberg dithering */ |
618 { | 615 { |
619 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 616 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
620 register LOCFSERROR cur;» /* current error or pixel value */ | 617 register LOCFSERROR cur; /* current error or pixel value */ |
621 LOCFSERROR belowerr;» » /* error for pixel below cur */ | 618 LOCFSERROR belowerr; /* error for pixel below cur */ |
622 LOCFSERROR bpreverr;» » /* error for below/prev col */ | 619 LOCFSERROR bpreverr; /* error for below/prev col */ |
623 LOCFSERROR bnexterr;» » /* error for below/next col */ | 620 LOCFSERROR bnexterr; /* error for below/next col */ |
624 LOCFSERROR delta; | 621 LOCFSERROR delta; |
625 register FSERRPTR errorptr;» /* => fserrors[] at column before current */ | 622 register FSERRPTR errorptr; /* => fserrors[] at column before current */ |
626 register JSAMPROW input_ptr; | 623 register JSAMPROW input_ptr; |
627 register JSAMPROW output_ptr; | 624 register JSAMPROW output_ptr; |
628 JSAMPROW colorindex_ci; | 625 JSAMPROW colorindex_ci; |
629 JSAMPROW colormap_ci; | 626 JSAMPROW colormap_ci; |
630 int pixcode; | 627 int pixcode; |
631 int nc = cinfo->out_color_components; | 628 int nc = cinfo->out_color_components; |
632 int dir;» » » /* 1 for left-to-right, -1 for right-to-left */ | 629 int dir; /* 1 for left-to-right, -1 for right-to-left */ |
633 int dirnc;» » » /* dir * nc */ | 630 int dirnc; /* dir * nc */ |
634 int ci; | 631 int ci; |
635 int row; | 632 int row; |
636 JDIMENSION col; | 633 JDIMENSION col; |
637 JDIMENSION width = cinfo->output_width; | 634 JDIMENSION width = cinfo->output_width; |
638 JSAMPLE *range_limit = cinfo->sample_range_limit; | 635 JSAMPLE *range_limit = cinfo->sample_range_limit; |
639 SHIFT_TEMPS | 636 SHIFT_TEMPS |
640 | 637 |
641 for (row = 0; row < num_rows; row++) { | 638 for (row = 0; row < num_rows; row++) { |
642 /* Initialize output values to 0 so can process components separately */ | 639 /* Initialize output values to 0 so can process components separately */ |
643 jzero_far((void FAR *) output_buf[row], | 640 jzero_far((void *) output_buf[row], (size_t) (width * sizeof(JSAMPLE))); |
644 » (size_t) (width * SIZEOF(JSAMPLE))); | |
645 for (ci = 0; ci < nc; ci++) { | 641 for (ci = 0; ci < nc; ci++) { |
646 input_ptr = input_buf[row] + ci; | 642 input_ptr = input_buf[row] + ci; |
647 output_ptr = output_buf[row]; | 643 output_ptr = output_buf[row]; |
648 if (cquantize->on_odd_row) { | 644 if (cquantize->on_odd_row) { |
649 » /* work right to left in this row */ | 645 /* work right to left in this row */ |
650 » input_ptr += (width-1) * nc; /* so point to rightmost pixel */ | 646 input_ptr += (width-1) * nc; /* so point to rightmost pixel */ |
651 » output_ptr += width-1; | 647 output_ptr += width-1; |
652 » dir = -1; | 648 dir = -1; |
653 » dirnc = -nc; | 649 dirnc = -nc; |
654 » errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last c
olumn */ | 650 errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last c
olumn */ |
655 } else { | 651 } else { |
656 » /* work left to right in this row */ | 652 /* work left to right in this row */ |
657 » dir = 1; | 653 dir = 1; |
658 » dirnc = nc; | 654 dirnc = nc; |
659 » errorptr = cquantize->fserrors[ci]; /* => entry before first column */ | 655 errorptr = cquantize->fserrors[ci]; /* => entry before first column */ |
660 } | 656 } |
661 colorindex_ci = cquantize->colorindex[ci]; | 657 colorindex_ci = cquantize->colorindex[ci]; |
662 colormap_ci = cquantize->sv_colormap[ci]; | 658 colormap_ci = cquantize->sv_colormap[ci]; |
663 /* Preset error values: no error propagated to first pixel from left */ | 659 /* Preset error values: no error propagated to first pixel from left */ |
664 cur = 0; | 660 cur = 0; |
665 /* and no error propagated to row below yet */ | 661 /* and no error propagated to row below yet */ |
666 belowerr = bpreverr = 0; | 662 belowerr = bpreverr = 0; |
667 | 663 |
668 for (col = width; col > 0; col--) { | 664 for (col = width; col > 0; col--) { |
669 » /* cur holds the error propagated from the previous pixel on the | 665 /* cur holds the error propagated from the previous pixel on the |
670 » * current line. Add the error propagated from the previous line | 666 * current line. Add the error propagated from the previous line |
671 » * to form the complete error correction term for this pixel, and | 667 * to form the complete error correction term for this pixel, and |
672 » * round the error term (which is expressed * 16) to an integer. | 668 * round the error term (which is expressed * 16) to an integer. |
673 » * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct | 669 * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct |
674 » * for either sign of the error value. | 670 * for either sign of the error value. |
675 » * Note: errorptr points to *previous* column's array entry. | 671 * Note: errorptr points to *previous* column's array entry. |
676 » */ | 672 */ |
677 » cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); | 673 cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); |
678 » /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. | 674 /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. |
679 » * The maximum error is +- MAXJSAMPLE; this sets the required size | 675 * The maximum error is +- MAXJSAMPLE; this sets the required size |
680 » * of the range_limit array. | 676 * of the range_limit array. |
681 » */ | 677 */ |
682 » cur += GETJSAMPLE(*input_ptr); | 678 cur += GETJSAMPLE(*input_ptr); |
683 » cur = GETJSAMPLE(range_limit[cur]); | 679 cur = GETJSAMPLE(range_limit[cur]); |
684 » /* Select output value, accumulate into output code for this pixel */ | 680 /* Select output value, accumulate into output code for this pixel */ |
685 » pixcode = GETJSAMPLE(colorindex_ci[cur]); | 681 pixcode = GETJSAMPLE(colorindex_ci[cur]); |
686 » *output_ptr += (JSAMPLE) pixcode; | 682 *output_ptr += (JSAMPLE) pixcode; |
687 » /* Compute actual representation error at this pixel */ | 683 /* Compute actual representation error at this pixel */ |
688 » /* Note: we can do this even though we don't have the final */ | 684 /* Note: we can do this even though we don't have the final */ |
689 » /* pixel code, because the colormap is orthogonal. */ | 685 /* pixel code, because the colormap is orthogonal. */ |
690 » cur -= GETJSAMPLE(colormap_ci[pixcode]); | 686 cur -= GETJSAMPLE(colormap_ci[pixcode]); |
691 » /* Compute error fractions to be propagated to adjacent pixels. | 687 /* Compute error fractions to be propagated to adjacent pixels. |
692 » * Add these into the running sums, and simultaneously shift the | 688 * Add these into the running sums, and simultaneously shift the |
693 » * next-line error sums left by 1 column. | 689 * next-line error sums left by 1 column. |
694 » */ | 690 */ |
695 » bnexterr = cur; | 691 bnexterr = cur; |
696 » delta = cur * 2; | 692 delta = cur * 2; |
697 » cur += delta;» » /* form error * 3 */ | 693 cur += delta; /* form error * 3 */ |
698 » errorptr[0] = (FSERROR) (bpreverr + cur); | 694 errorptr[0] = (FSERROR) (bpreverr + cur); |
699 » cur += delta;» » /* form error * 5 */ | 695 cur += delta; /* form error * 5 */ |
700 » bpreverr = belowerr + cur; | 696 bpreverr = belowerr + cur; |
701 » belowerr = bnexterr; | 697 belowerr = bnexterr; |
702 » cur += delta;» » /* form error * 7 */ | 698 cur += delta; /* form error * 7 */ |
703 » /* At this point cur contains the 7/16 error value to be propagated | 699 /* At this point cur contains the 7/16 error value to be propagated |
704 » * to the next pixel on the current line, and all the errors for the | 700 * to the next pixel on the current line, and all the errors for the |
705 » * next line have been shifted over. We are therefore ready to move on. | 701 * next line have been shifted over. We are therefore ready to move on. |
706 » */ | 702 */ |
707 » input_ptr += dirnc;» /* advance input ptr to next column */ | 703 input_ptr += dirnc; /* advance input ptr to next column */ |
708 » output_ptr += dir;» /* advance output ptr to next column */ | 704 output_ptr += dir; /* advance output ptr to next column */ |
709 » errorptr += dir;» /* advance errorptr to current column */ | 705 errorptr += dir; /* advance errorptr to current column */ |
710 } | 706 } |
711 /* Post-loop cleanup: we must unload the final error value into the | 707 /* Post-loop cleanup: we must unload the final error value into the |
712 * final fserrors[] entry. Note we need not unload belowerr because | 708 * final fserrors[] entry. Note we need not unload belowerr because |
713 * it is for the dummy column before or after the actual array. | 709 * it is for the dummy column before or after the actual array. |
714 */ | 710 */ |
715 errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ | 711 errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ |
716 } | 712 } |
717 cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); | 713 cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); |
718 } | 714 } |
719 } | 715 } |
720 | 716 |
721 | 717 |
722 /* | 718 /* |
723 * Allocate workspace for Floyd-Steinberg errors. | 719 * Allocate workspace for Floyd-Steinberg errors. |
724 */ | 720 */ |
725 | 721 |
726 LOCAL(void) | 722 LOCAL(void) |
727 alloc_fs_workspace (j_decompress_ptr cinfo) | 723 alloc_fs_workspace (j_decompress_ptr cinfo) |
728 { | 724 { |
729 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; | 725 my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; |
730 size_t arraysize; | 726 size_t arraysize; |
731 int i; | 727 int i; |
732 | 728 |
733 arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); | 729 arraysize = (size_t) ((cinfo->output_width + 2) * sizeof(FSERROR)); |
734 for (i = 0; i < cinfo->out_color_components; i++) { | 730 for (i = 0; i < cinfo->out_color_components; i++) { |
735 cquantize->fserrors[i] = (FSERRPTR) | 731 cquantize->fserrors[i] = (FSERRPTR) |
736 (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); | 732 (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); |
737 } | 733 } |
738 } | 734 } |
739 | 735 |
740 | 736 |
741 /* | 737 /* |
742 * Initialize for one-pass color quantization. | 738 * Initialize for one-pass color quantization. |
743 */ | 739 */ |
(...skipping 15 matching lines...) Expand all Loading... |
759 if (cinfo->out_color_components == 3) | 755 if (cinfo->out_color_components == 3) |
760 cquantize->pub.color_quantize = color_quantize3; | 756 cquantize->pub.color_quantize = color_quantize3; |
761 else | 757 else |
762 cquantize->pub.color_quantize = color_quantize; | 758 cquantize->pub.color_quantize = color_quantize; |
763 break; | 759 break; |
764 case JDITHER_ORDERED: | 760 case JDITHER_ORDERED: |
765 if (cinfo->out_color_components == 3) | 761 if (cinfo->out_color_components == 3) |
766 cquantize->pub.color_quantize = quantize3_ord_dither; | 762 cquantize->pub.color_quantize = quantize3_ord_dither; |
767 else | 763 else |
768 cquantize->pub.color_quantize = quantize_ord_dither; | 764 cquantize->pub.color_quantize = quantize_ord_dither; |
769 cquantize->row_index = 0;» /* initialize state for ordered dither */ | 765 cquantize->row_index = 0; /* initialize state for ordered dither */ |
770 /* If user changed to ordered dither from another mode, | 766 /* If user changed to ordered dither from another mode, |
771 * we must recreate the color index table with padding. | 767 * we must recreate the color index table with padding. |
772 * This will cost extra space, but probably isn't very likely. | 768 * This will cost extra space, but probably isn't very likely. |
773 */ | 769 */ |
774 if (! cquantize->is_padded) | 770 if (! cquantize->is_padded) |
775 create_colorindex(cinfo); | 771 create_colorindex(cinfo); |
776 /* Create ordered-dither tables if we didn't already. */ | 772 /* Create ordered-dither tables if we didn't already. */ |
777 if (cquantize->odither[0] == NULL) | 773 if (cquantize->odither[0] == NULL) |
778 create_odither_tables(cinfo); | 774 create_odither_tables(cinfo); |
779 break; | 775 break; |
780 case JDITHER_FS: | 776 case JDITHER_FS: |
781 cquantize->pub.color_quantize = quantize_fs_dither; | 777 cquantize->pub.color_quantize = quantize_fs_dither; |
782 cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ | 778 cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ |
783 /* Allocate Floyd-Steinberg workspace if didn't already. */ | 779 /* Allocate Floyd-Steinberg workspace if didn't already. */ |
784 if (cquantize->fserrors[0] == NULL) | 780 if (cquantize->fserrors[0] == NULL) |
785 alloc_fs_workspace(cinfo); | 781 alloc_fs_workspace(cinfo); |
786 /* Initialize the propagated errors to zero. */ | 782 /* Initialize the propagated errors to zero. */ |
787 arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); | 783 arraysize = (size_t) ((cinfo->output_width + 2) * sizeof(FSERROR)); |
788 for (i = 0; i < cinfo->out_color_components; i++) | 784 for (i = 0; i < cinfo->out_color_components; i++) |
789 jzero_far((void FAR *) cquantize->fserrors[i], arraysize); | 785 jzero_far((void *) cquantize->fserrors[i], arraysize); |
790 break; | 786 break; |
791 default: | 787 default: |
792 ERREXIT(cinfo, JERR_NOT_COMPILED); | 788 ERREXIT(cinfo, JERR_NOT_COMPILED); |
793 break; | 789 break; |
794 } | 790 } |
795 } | 791 } |
796 | 792 |
797 | 793 |
798 /* | 794 /* |
799 * Finish up at the end of the pass. | 795 * Finish up at the end of the pass. |
(...skipping 22 matching lines...) Expand all Loading... |
822 * Module initialization routine for 1-pass color quantization. | 818 * Module initialization routine for 1-pass color quantization. |
823 */ | 819 */ |
824 | 820 |
825 GLOBAL(void) | 821 GLOBAL(void) |
826 jinit_1pass_quantizer (j_decompress_ptr cinfo) | 822 jinit_1pass_quantizer (j_decompress_ptr cinfo) |
827 { | 823 { |
828 my_cquantize_ptr cquantize; | 824 my_cquantize_ptr cquantize; |
829 | 825 |
830 cquantize = (my_cquantize_ptr) | 826 cquantize = (my_cquantize_ptr) |
831 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, | 827 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
832 » » » » SIZEOF(my_cquantizer)); | 828 sizeof(my_cquantizer)); |
833 cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; | 829 cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; |
834 cquantize->pub.start_pass = start_pass_1_quant; | 830 cquantize->pub.start_pass = start_pass_1_quant; |
835 cquantize->pub.finish_pass = finish_pass_1_quant; | 831 cquantize->pub.finish_pass = finish_pass_1_quant; |
836 cquantize->pub.new_color_map = new_color_map_1_quant; | 832 cquantize->pub.new_color_map = new_color_map_1_quant; |
837 cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ | 833 cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ |
838 cquantize->odither[0] = NULL;»/* Also flag odither arrays not allocated */ | 834 cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ |
839 | 835 |
840 /* Make sure my internal arrays won't overflow */ | 836 /* Make sure my internal arrays won't overflow */ |
841 if (cinfo->out_color_components > MAX_Q_COMPS) | 837 if (cinfo->out_color_components > MAX_Q_COMPS) |
842 ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); | 838 ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); |
843 /* Make sure colormap indexes can be represented by JSAMPLEs */ | 839 /* Make sure colormap indexes can be represented by JSAMPLEs */ |
844 if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) | 840 if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) |
845 ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); | 841 ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); |
846 | 842 |
847 /* Create the colormap and color index table. */ | 843 /* Create the colormap and color index table. */ |
848 create_colormap(cinfo); | 844 create_colormap(cinfo); |
849 create_colorindex(cinfo); | 845 create_colorindex(cinfo); |
850 | 846 |
851 /* Allocate Floyd-Steinberg workspace now if requested. | 847 /* Allocate Floyd-Steinberg workspace now if requested. |
852 * We do this now since it is FAR storage and may affect the memory | 848 * We do this now since it may affect the memory manager's space |
853 * manager's space calculations. If the user changes to FS dither | 849 * calculations. If the user changes to FS dither mode in a later pass, we |
854 * mode in a later pass, we will allocate the space then, and will | 850 * will allocate the space then, and will possibly overrun the |
855 * possibly overrun the max_memory_to_use setting. | 851 * max_memory_to_use setting. |
856 */ | 852 */ |
857 if (cinfo->dither_mode == JDITHER_FS) | 853 if (cinfo->dither_mode == JDITHER_FS) |
858 alloc_fs_workspace(cinfo); | 854 alloc_fs_workspace(cinfo); |
859 } | 855 } |
860 | 856 |
861 #endif /* QUANT_1PASS_SUPPORTED */ | 857 #endif /* QUANT_1PASS_SUPPORTED */ |
OLD | NEW |