Example #1
0
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;
}
Example #2
0
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;
}
Example #4
0
/**
 * 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;
}