home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / segal / quant.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-25  |  4.7 KB  |  226 lines

  1. /*
  2.  *    quant.c - quantizing routines to handle color images in Segal3d
  3.  *
  4.  *    Bryan Skene, LBL
  5.  *    November, 1992
  6.  */
  7. #include "common.h"
  8.  
  9. /*****************************************/
  10. void
  11. sort_frame_lex(buf, size)
  12. COLOR_TYPE *buf; /* one frame of rgb */
  13. int size;
  14. {
  15. /* Sorts the triples in buf in lexicographic order: r, g, b */
  16.     int compare_colors();
  17.  
  18.     qsort((u_char *) buf, size, sizeof(COLOR_TYPE), compare_colors);
  19. }
  20.  
  21. /*****************************************/
  22. int
  23. compare_colors(c1, c2)
  24. COLOR_TYPE *c1, *c2;
  25. {
  26.     unsigned long x1, x2;
  27.  
  28.     /* build  24 bit words describing each color */
  29.     x1 = (c1->r * 1000000) + (c1->g * 1000) + c1->b;
  30.     x2 = (c2->r * 1000000) + (c2->g * 1000) + c2->b;
  31.  
  32.     if(x1 < x2) return(-1);
  33.     else if(x1 > x2) return(1);
  34.     else return(0); /* the two colors are equal */
  35. }
  36.  
  37. /*****************************************/
  38. void
  39. build_rgb_histo(buf, size)
  40. COLOR_TYPE *buf;
  41. int size;
  42. {
  43. /* Main quantizing routine */
  44.     int compare_count();
  45.  
  46.     COLOR_TYPE mark;
  47.     int i, p, count;
  48.  
  49.     /* 1st pass - determine number of distinct colors */
  50.     rgb.num_histo = 0;
  51.     p = 0;
  52.     while(p < size) {
  53.         mark.r = buf[p].r;
  54.         mark.g = buf[p].g;
  55.         mark.b = buf[p].b;
  56.  
  57.         /* count the repeats */
  58.         count = 1;
  59.         while(p + count < size
  60.             && mark.r == buf[p + count].r
  61.             && mark.g == buf[p + count].g
  62.             && mark.b == buf[p + count].b)
  63.             count++;
  64.  
  65.         p += count;
  66.         rgb.num_histo++;
  67.     }
  68.  
  69.     /* 2nd pass - fill in rgb.histo[] */
  70.  
  71.     rgb.histo = (RGB_HISTO *) calloc(rgb.num_histo, sizeof(RGB_HISTO));
  72.  
  73.     i = 0;
  74.     p = 0;
  75.     while(p < size) {
  76.         mark.r = buf[p].r;
  77.         mark.g = buf[p].g;
  78.         mark.b = buf[p].b;
  79.  
  80.         /* count the repeats */
  81.         count = 1;
  82.         while(p + count < size
  83.             && mark.r == buf[p + count].r
  84.             && mark.g == buf[p + count].g
  85.             && mark.b == buf[p + count].b)
  86.             count++;
  87.  
  88.         p += count;
  89.  
  90.         rgb.histo[i].r = mark.r;
  91.         rgb.histo[i].g = mark.g;
  92.         rgb.histo[i].b = mark.b;
  93.         rgb.histo[i].count = count;
  94.         i++;
  95.     }
  96.  
  97.     /* now sort the rgb_histo by count: highest first */
  98.     qsort((char *) rgb.histo, rgb.num_histo, sizeof(RGB_HISTO),
  99.         compare_count);
  100. }
  101.  
  102. /*****************************************/
  103. int
  104. compare_count(c1, c2)
  105. RGB_HISTO *c1, *c2;
  106. {
  107.     /* sort by count in descending order */
  108.     if(c1->count > c2->count) return(-1);
  109.     else if(c1->count < c2->count) return(1);
  110.     else return(0);
  111. }
  112.  
  113. /*****************************************/
  114. void
  115. get_quant_colors(image, rows, cols)
  116. u_char ***image;
  117. int rows, cols;
  118. {
  119.     void set_quant_vals();
  120.     void sort_frame_lex();
  121.     void build_rgb_histo();
  122.  
  123.     COLOR_TYPE *buf;
  124.     register int r, c, i;
  125.     int size, step;
  126.  
  127.     set_watch_cursor();
  128.  
  129.     set_quant_vals();
  130.     if(rgb.quant.num_from_histo == 0) return; /* why bother? */
  131.  
  132.     /* max number of samples from the image */
  133.     step = rows * cols / rgb.quant.max_samples;
  134.  
  135.     buf = Calloc(rgb.quant.max_samples, COLOR_TYPE);
  136.     
  137.     /* build list of triples from RGB SEP-PLANE image */
  138.     for(i = 0, r = 0; r < rows; r += step)
  139.     for(c = 0; c < cols; c += step, i++) {
  140.         buf[i].r = image[RP][c][r];
  141.         buf[i].g = image[GP][c][r];
  142.         buf[i].b = image[BP][c][r];
  143.     }
  144.  
  145.     sort_frame_lex(buf, rgb.quant.max_samples);
  146.  
  147.     build_rgb_histo(buf, rgb.quant.max_samples);
  148.  
  149. #ifdef DEBUG
  150.     for(i = 0; i < 25; i++)
  151.         vprint"rgb.histo[%2d]: %3d, %3d, %3d  count = %d\n",
  152.             i, rgb.histo[i].r, rgb.histo[i].g, rgb.histo[i].b,
  153.             rgb.histo[i].count);
  154. #endif
  155.  
  156.     free(buf);
  157.  
  158.     unset_watch_cursor();
  159. }
  160.  
  161. /*****************************************/
  162. void
  163. set_quant_vals()
  164. {
  165.     switch(rgb.quant.quality) {
  166.     case Q_BEST :
  167.         rgb.quant.num_from_histo = 100;
  168.         rgb.quant.auto_r = 0;
  169.         rgb.quant.auto_g = 0;
  170.         rgb.quant.auto_b = 0;
  171.         rgb.quant.max_samples = win[rgb.quant.win].img_size / 16;
  172.         rgb.map_r = 32;
  173.         rgb.map_g = 32;
  174.         rgb.map_b = 32;
  175.         break;
  176.     case Q_MEDIUM :
  177.         rgb.quant.num_from_histo = 64;
  178.         rgb.quant.auto_r = 4; /* 36 colors */
  179.         rgb.quant.auto_g = 3;
  180.         rgb.quant.auto_b = 3;
  181.         rgb.quant.max_samples = win[rgb.quant.win].img_size / 32;
  182.         rgb.map_r = 32;
  183.         rgb.map_g = 32;
  184.         rgb.map_b = 32;
  185.         break;
  186.     case Q_WORST :
  187.         rgb.quant.num_from_histo = 0;
  188.         rgb.quant.auto_r = 5; /* 100 colors */
  189.         rgb.quant.auto_g = 5;
  190.         rgb.quant.auto_b = 4;
  191.         rgb.quant.max_samples = UNDEFINED;
  192.         rgb.map_r = 32;
  193.         rgb.map_g = 24;
  194.         rgb.map_b = 20;
  195.         break;
  196.     default :
  197.         break;
  198.  
  199.     }
  200.     /* hopefully this makes the alloc'd colors spread out as far as the
  201.      * lattice of rgb.map does.  This cuts out never even using the colors
  202.      * that got allocated because the resolution of the lattice is much
  203.      * worse than the resolution of the rgb.map.
  204.      */
  205.     rgb.quant.min_rgb_dist = 256 / rgb.map_r; 
  206. }
  207.  
  208. /*****************************************/
  209. void
  210. quantize()
  211. {
  212.     void get_quant_colors();
  213.     void cmap_init();
  214.     void FreeAllColors();
  215.     void build_cmap();
  216.     void redisplay_all();
  217.  
  218.     vprint"ReQuant routine\n");
  219.     get_quant_colors(win[rgb.quant.win].i_data, win[rgb.quant.win].img_r,
  220.         win[rgb.quant.win].img_c);
  221.     cmap_init();
  222.     FreeAllColors();
  223.     build_cmap();
  224.     redisplay_all();
  225. }
  226.