* Compute a palette for the given RGBA rasterBuffer using a median cut quantization. * - rb: the rasterBuffer to quantize * - reqcolors: the desired number of colors the palette should contain. will be set * with the actual number of entries in the computed palette * - forced_palette: entries that should appear in the computed palette * - num_forced_palette_entries: number of entries contai
| 127 | * 255, and rb's pixels will have been scaled down to maxsize (see bug #3848) |
| 128 | */ |
| 129 | int msQuantizeRasterBuffer(rasterBufferObj *rb, |
| 130 | unsigned int *reqcolors, rgbaPixel *palette, |
| 131 | rgbaPixel *forced_palette, int num_forced_palette_entries, |
| 132 | unsigned int *palette_scaling_maxval) { |
| 133 | rgbaPixel **apixels=NULL; /* pointer to the start rows of truecolor pixels */ |
| 134 | |
| 135 | register rgbaPixel *pP; |
| 136 | register int col; |
| 137 | |
| 138 | unsigned char newmaxval; |
| 139 | acolorhist_vector achv, acolormap=NULL; |
| 140 | |
| 141 | int row; |
| 142 | int colors; |
| 143 | int newcolors = 0; |
| 144 | |
| 145 | int x; |
| 146 | /* int channels; */ |
| 147 | |
| 148 | assert(rb->type == MS_BUFFER_BYTE_RGBA); |
| 149 | |
| 150 | *palette_scaling_maxval = 255; |
| 151 | |
| 152 | apixels=(rgbaPixel**)msSmallMalloc(rb->height*sizeof(rgbaPixel**)); |
| 153 | |
| 154 | for(row=0;row<rb->height;row++) { |
| 155 | apixels[row]=(rgbaPixel*)(&(rb->data.rgba.pixels[row * rb->data.rgba.row_step])); |
| 156 | } |
| 157 | |
| 158 | /* |
| 159 | ** Step 2: attempt to make a histogram of the colors, unclustered. |
| 160 | ** If at first we don't succeed, lower maxval to increase color |
| 161 | ** coherence and try again. This will eventually terminate, with |
| 162 | ** maxval at worst 15, since 32^3 is approximately MAXCOLORS. |
| 163 | [GRR POSSIBLE BUG: what about 32^4 ?] |
| 164 | */ |
| 165 | for ( ; ; ) { |
| 166 | achv = pam_computeacolorhist( |
| 167 | apixels, rb->width, rb->height, MAXCOLORS, &colors ); |
| 168 | if ( achv != (acolorhist_vector) 0 ) |
| 169 | break; |
| 170 | newmaxval = *palette_scaling_maxval / 2; |
| 171 | for ( row = 0; row < rb->height; ++row ) |
| 172 | for ( col = 0, pP = apixels[row]; col < rb->width; ++col, ++pP ) |
| 173 | PAM_DEPTH( *pP, *pP, *palette_scaling_maxval, newmaxval ); |
| 174 | *palette_scaling_maxval = newmaxval; |
| 175 | } |
| 176 | newcolors = MS_MIN(colors, *reqcolors); |
| 177 | acolormap = mediancut(achv, colors, rb->width*rb->height, *palette_scaling_maxval, newcolors); |
| 178 | pam_freeacolorhist(achv); |
| 179 | |
| 180 | |
| 181 | *reqcolors = newcolors; |
| 182 | |
| 183 | |
| 184 | for (x = 0; x < newcolors; ++x) { |
| 185 | palette[x].r = acolormap[x].acolor.r; |
| 186 | palette[x].g = acolormap[x].acolor.g; |
no test coverage detected