hist *histogram(read_info *input_image, int reqcolors, int speed_tradeoff) { hist *hist; int ignorebits=0; const rgb_pixel *const *input_pixels = (const rgb_pixel *const *)input_image->row_pointers; int cols = input_image->width, rows = input_image->height; double gamma = input_image->gamma; assert(gamma > 0); /* ** Step 2: attempt to make a histogram of the colors, unclustered. ** If at first we don't succeed, increase ignorebits to increase color ** coherence and try again. */ if (speed_tradeoff > 7) ignorebits++; int maxcolors = (1<<17) + (1<<18)*(10-speed_tradeoff); verbose_printf(" making histogram..."); for (; ;) { hist = pam_computeacolorhist(input_pixels, cols, rows, gamma, maxcolors, ignorebits, speed_tradeoff < 9); if (hist) break; ignorebits++; verbose_printf("too many colors!\n scaling colors to improve clustering..."); } verbose_printf("%d colors found\n", hist->size); return hist; }
int msQuantizeRasterBuffer(rgbaPixel *pixelsIn,int height,int width, unsigned int *reqcolors, rgbaPixel *palette, unsigned int *palette_scaling_maxval) { register rgbaPixel *pP; register int col; unsigned char newmaxval; acolorhist_vector achv, acolormap=NULL; int row; int colors; int newcolors = 0; int x; *palette_scaling_maxval = 255; int row_step = width*4; rgbaPixel **apixels=(rgbaPixel**)malloc(height*sizeof(rgbaPixel**)); for(row=0;row<height;row++) { apixels[row]=(rgbaPixel*)(&(pixelsIn[row*width])); } /* ** Step 2: attempt to make a histogram of the colors, unclustered. ** If at first we don't succeed, lower maxval to increase color ** coherence and try again. This will eventually terminate, with ** maxval at worst 15, since 32^3 is approximately MAXCOLORS. [GRR POSSIBLE BUG: what about 32^4 ?] */ for ( ; ; ) { achv = pam_computeacolorhist( apixels, width, height, MAXCOLORS, &colors ); if ( achv != (acolorhist_vector) 0 ) break; newmaxval = *palette_scaling_maxval / 2; for ( row = 0; row < height; ++row ) for ( col = 0, pP = apixels[row]; col < width; ++col, ++pP ) PAM_DEPTH( *pP, *pP, *palette_scaling_maxval, newmaxval ); *palette_scaling_maxval = newmaxval; } newcolors = MS_MIN(colors, *reqcolors); acolormap = mediancut(achv, colors, width*height, *palette_scaling_maxval, newcolors); pam_freeacolorhist(achv); *reqcolors = newcolors; for (x = 0; x < newcolors; ++x) { palette[x].r = acolormap[x].acolor.r; palette[x].g = acolormap[x].acolor.g; palette[x].b = acolormap[x].acolor.b; palette[x].a = acolormap[x].acolor.a; } free(acolormap); free(apixels); return MS_SUCCESS; }
/** * 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 contained in "force_palette". if 0, * "force_palette" can be NULL * - palette_scaling_maxval: the quantization process may have to reduce the image depth * by iteratively dividing the pixels by 2. In case palette_scaling_maxval is set to * something different than 255, the returned palette colors have to be scaled back up to * 255, and rb's pixels will have been scaled down to maxsize (see bug #3848) */ int msQuantizeRasterBuffer(rasterBufferObj *rb, unsigned int *reqcolors, rgbaPixel *palette, rgbaPixel *forced_palette, int num_forced_palette_entries, unsigned int *palette_scaling_maxval) { rgbaPixel **apixels=NULL; /* pointer to the start rows of truecolor pixels */ register rgbaPixel *pP; register int col; unsigned char newmaxval; acolorhist_vector achv, acolormap=NULL; int row; int colors; int newcolors = 0; int x; /* int channels; */ assert(rb->type == MS_BUFFER_BYTE_RGBA); *palette_scaling_maxval = 255; apixels=(rgbaPixel**)msSmallMalloc(rb->height*sizeof(rgbaPixel*)); for(row=0; row<rb->height; row++) { apixels[row]=(rgbaPixel*)(&(rb->data.rgba.pixels[row * rb->data.rgba.row_step])); } /* ** Step 2: attempt to make a histogram of the colors, unclustered. ** If at first we don't succeed, lower maxval to increase color ** coherence and try again. This will eventually terminate, with ** maxval at worst 15, since 32^3 is approximately MAXCOLORS. [GRR POSSIBLE BUG: what about 32^4 ?] */ for ( ; ; ) { achv = pam_computeacolorhist( apixels, rb->width, rb->height, MAXCOLORS, &colors ); if ( achv != (acolorhist_vector) 0 ) break; newmaxval = *palette_scaling_maxval / 2; for ( row = 0; row < rb->height; ++row ) for ( col = 0, pP = apixels[row]; col < rb->width; ++col, ++pP ) PAM_DEPTH( *pP, *pP, *palette_scaling_maxval, newmaxval ); *palette_scaling_maxval = newmaxval; } newcolors = MS_MIN(colors, *reqcolors); acolormap = mediancut(achv, colors, rb->width*rb->height, *palette_scaling_maxval, newcolors); pam_freeacolorhist(achv); *reqcolors = newcolors; for (x = 0; x < newcolors; ++x) { palette[x].r = acolormap[x].acolor.r; palette[x].g = acolormap[x].acolor.g; palette[x].b = acolormap[x].acolor.b; palette[x].a = acolormap[x].acolor.a; } free(acolormap); free(apixels); return MS_SUCCESS; }
/** * 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 * - palette: preallocated array of palette entries that will be populated by the * function * - maxval: max value of pixel intensity. In some cases, the input data has to * be rescaled to compute the quantization. if the returned value of maxscale is * less than 255, this means that the input pixels have been rescaled, and that * the returned palette must be upscaled before being written to the png file * - forced_palette: entries that should appear in the computed palette * - num_forced_palette_entries: number of entries contained in "force_palette". if 0, * "force_palette" can be NULL */ int _mapcache_imageio_quantize_image(mapcache_image *rb, unsigned int *reqcolors, rgbaPixel *palette, unsigned int *maxval, rgbaPixel *forced_palette, int num_forced_palette_entries) { rgbaPixel **apixels=NULL; /* pointer to the start rows of truecolor pixels */ register rgbaPixel *pP; register int col; unsigned char newmaxval; acolorhist_vector achv, acolormap=NULL; int row; int colors; int newcolors = 0; int x; /* int channels; */ *maxval = 255; apixels=(rgbaPixel**)malloc(rb->h*sizeof(rgbaPixel**)); if(!apixels) return MAPCACHE_FAILURE; for(row=0;row<rb->h;row++) { apixels[row]=(rgbaPixel*)(&(rb->data[row * rb->stride])); } /* ** Step 2: attempt to make a histogram of the colors, unclustered. ** If at first we don't succeed, lower maxval to increase color ** coherence and try again. This will eventually terminate, with ** maxval at worst 15, since 32^3 is approximately MAXCOLORS. [GRR POSSIBLE BUG: what about 32^4 ?] */ for ( ; ; ) { achv = pam_computeacolorhist( apixels, rb->w, rb->h, MAXCOLORS, &colors ); if ( achv != (acolorhist_vector) 0 ) break; newmaxval = *maxval / 2; for ( row = 0; row < rb->h; ++row ) for ( col = 0, pP = apixels[row]; col < rb->w; ++col, ++pP ) PAM_DEPTH( *pP, *pP, *maxval, newmaxval ); *maxval = newmaxval; } newcolors = MAPCACHE_MIN(colors, *reqcolors); acolormap = mediancut(achv, colors, rb->w*rb->h, *maxval, newcolors); pam_freeacolorhist(achv); *reqcolors = newcolors; for (x = 0; x < newcolors; ++x) { palette[x].r = acolormap[x].acolor.r; palette[x].g = acolormap[x].acolor.g; palette[x].b = acolormap[x].acolor.b; palette[x].a = acolormap[x].acolor.a; } free(acolormap); free(apixels); return MAPCACHE_SUCCESS; }