| 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 |