Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
mcut.c
Go to the documentation of this file.
1 /*
2  * mcut.c - Generate a "median cut" color map for an image.
3  *
4  * Producer: Robert Mecklenburg
5  * Director: John W. Peterson
6  * Computer Science Dept.
7  * University of Utah
8  *
9  * Based on the novel by Paul Heckbert
10  * (See "Color Image Quantization for Frame Buffer Display",
11  * Proc. SIGGRAPH '82)
12  *
13  * Date: Sun Sep 27 1987
14  * Copyright (c) 1987, University of Utah
15  */
16 
17 /*
18  * Still left to do:
19  *
20  * The five bits used for initial quantization should be generalized
21  * with a #define. It would not be a good idea to make this a
22  * run-time option, since the arithmatic required to compute the bit
23  * shifting and masking on the fly would way slow down critical loops.
24  */
25 
26 #include <stdio.h>
27 #include "rle.h"
28 
29 /*
30  * Standard max min functions.
31  */
32 #define MAX(i,j) ( (i) > (j) ? (i) : (j) )
33 #define MIN(i,j) ( (i) < (j) ? (i) : (j) )
34 
35 /*
36  * A TLISTLINKS at the front of an object struct definition provides for
37  * linking together a list of that type of objects.
38  */
39 #define TLISTLINKS(type) type * next, * prev
40 
41 /*
42  * Access for List pointer manipulations. (Previous and Next.)
43  */
44 #define P(node) ((node)->prev)
45 #define N(node) ((node)->next)
46 
47 /*
48  * Trace a linear linked list.
49  */
50 #define TRACE(t_var,ini) for((t_var)=(ini);(t_var)!=NULL;(t_var)=N(t_var))
51 
52 /*
53  * ADD links new members into a list, given a pointer to the new member, and
54  * a pointer to the first (left) element of the list.
55  *
56  * INSERT links members into the middle of a list, given a pointer to the new
57  * member, and a pointer to the list element to insert after.
58  *
59  */
60 #define ADD(new,first) ( P(new) = NULL ,N(new) = (first),
61  ( ((first)!=NULL) ? (P(first)=(new), 0) :0 ),
62  first = (new) )
63 
64 #define INSERT(new,after) ( P(new) = (after),N(new) = N(after),
65  ( (N(after)!=NULL) ? (P(N(after))=(new), 0) :0),
66  N(after) = (new) )
67 
68 
69 /*
70  * Macros for dealing with the "hashed" colors.
71  */
72 #define BLUEMASK(x) ((x) & 0x1f)
73 #define GREENMASK(x) (((x)>>5) & 0x1f)
74 #define REDMASK(x) (((x)>>10) & 0x1f)
75 
76 #define TO_5_BITS(x) (((x)>>3) & 0x1f)
77 #define FROM_5_BITS(x) (((x)<<3) & 0xff)
78 #define PACK_15(r,g,b) (TO_5_BITS(r)<<10 | TO_5_BITS(g)<<5 | TO_5_BITS(b))
79 #define FAST_PACK(r,g,b) (((r)&0xf8)<<7 | ((g)&0xf8)<<2 | (TO_5_BITS(b)))
80 
81 #define DISTANCE(x,y) (((x).r-(y).r) * ((x).r-(y).r) +
82  ((x).g-(y).g) * ((x).g-(y).g) +
83  ((x).b-(y).b) * ((x).b-(y).b))
84 
85 
86 /*****************************************************************
87  * TAG( color_t )
88  *
89  * An rgb structure.
90  */
91 typedef struct _color color_t;
92 struct _color
93 {
94  int r, g, b;
95 };
96 
97 /* Forward declaration */
98 typedef struct _color_box color_box_t;
99 
100 /*****************************************************************
101  * TAG( histogram_t )
102  *
103  * The histogram structure recording color frequency.
104  */
105 typedef struct _histogram histogram_t;
107 {
111 };
112 
113 
114 /*****************************************************************
115  * TAG( bounds_t )
116  *
117  * A bounding box structure.
118  */
119 typedef struct _bounds bounds_t;
120 struct _bounds
121 {
122  int max, min;
123 };
124 
125 
126 /*****************************************************************
127  * TAG( color_box_t )
128  *
129  * A color bounding box structure which contains the size of the
130  * largest dimension, a histogram of the points in the box, and the
131  * number of samples in the histogram.
132  */
134 {
135  TLISTLINKS( color_box_t ); /* Linked list header. */
136  int size; /* Longest dimension for sorting. */
137  int axis; /* Which color axis is longest. */
138  histogram_t **hist; /* The histogram of enclosed points. */
139  int hsize; /* The size of the histogram. */
140  int nsamples; /* Number of values in histogram. */
141  bounds_t r, g, b; /* The bounds of the box. */
142  color_t color; /* New 24 bit RGB value */
143  int cindex; /* RLE cmap index of this color value */
144 };
145 
146 /*
147  * Forward decls.
148  */
152 int break_box();
153 void radix_sort();
154 
155 /*
156  * Globals
157  */
158 
159 color_box_t *cb_list, /* List of subdivided colors. */
160  *cb; /* Scratch ptr to hold first value. */
161 int cb_list_size; /* Number of el's in cb_list. */
162 static unsigned mask;
163 short out_map[3][256]; /* Output color map constructed */
164 rle_hdr in_hdr, /* For RLE routines. */
165  out_hdr;
166 int max_colors = 200; /* Number of colors allowed. */
169 char *cmd_nm; /* Command name for error messages */
170 
171 
172 /*****************************************************************
173  * TAG( mcut )
174  *
175  * Theory
176  *
177  * This program accepts a color image of 24 bit RGB and tries to find
178  * N representative colors which best fit the image. Its main purpose
179  * is to display reasonable color pictures on shallow (8 bits or less)
180  * frame buffers.
181  *
182  * The basic algorithm is to first bash a 24 bit color down to a 15
183  * bit color and histogram the results. Next we calculate a color
184  * space bounding box for the image and begin subdividing. A box is
185  * subdivided at the median of its longest dimension. These new boxes
186  * are then candidates for subdividing. We continue to subdivide
187  * until we have N boxes. We then walk the color box list calculating
188  * an average color for each box. Finally, we take the original 15
189  * bit colors from the histogram and map them onto the averaged colors
190  * from the bounding box list. The new image is constructed by
191  * rereading the old image, mapping 24 bit colors to 15 bits and
192  * looking up the 15 bit color in the histogram.
193  *
194  * Implementation
195  *
196  * The key data structures for the program are histogram_t and
197  * color_box_t. A histogram contains a 15 bit color value, count of
198  * the number of occurrences of that color, a pointer into an
199  * associated color_box_t structure, and an 8 bit color map index. An
200  * array of 32768 histogram_t's is allocated to initially build the
201  * color map. The first part of the algorithm fills in the entry's
202  * color value and counts the occurrences. Then the histogram is
203  * compacted forcing all non-empty histogram slots to the front. This
204  * constitutes the set of subdivideable colors. A single color_box_t
205  * structure (cb) is initialized to bound this color space and the
206  * color_box_t is inserted into the cb_list. The color_box_t
207  * structure contains a bounding box for r, g, and b, an indicator of
208  * which dimension is longest, the length of the longest dimension, a
209  * pointer to a histogram of the elements within the bounding box, the
210  * number of histogram entries, and the total number of pixels in the
211  * histogram. Two other structure members are the new 24 bit color,
212  * and the color map index of this color.
213  *
214  * The subdivision process proceeds by removing the first element on
215  * the cb_list and subdividing it along its longest dimension.
216  * Subdivision occurs at the median pixel count, except a single
217  * histogram entry is never subdivided. The two new color_box_t
218  * structures are added to the cb_list with an insertion sort so the
219  * first element is always the next to be subdivided.
220  *
221  * Finally, the cb_list is traversed and an average color is
222  * calculated for each color_box_t. These are converted to 24 bit
223  * colors with a simple left shift. Next the histogram is scanned and
224  * for each 15 bit color entry in the histogram the nearest new color
225  * (from the new list of 24 bit colors) is calculated and a back
226  * pointer from the histogram entry to the color_box_t structure for
227  * the color is saved. This is done because we need to be able to
228  * translate quickly from a 15 bit color to its new color map index
229  * which we don't yet know! So the color map index is then calculated
230  * and saved in the color_box_t structure and can be accessed quickly
231  * through the back pointer. In fact, the histogram_t structure also
232  * has a slot for a color map index, so the back pointer it followed
233  * only once.
234  */
235 void
237 int argc;
238 char ** argv;
239 {
240  register rle_pixel *rptr, *gptr, *bptr;
241  int tmp, dither = 0, oflag = 0;
242  register int i;
243  rle_pixel **scan;
244  char * infname = NULL, *out_fname = NULL;
245  FILE *outfile = stdout;
246  char cmap_comment[80];
247  int rle_err, rle_cnt;
248  long start;
249 
250  if ( ! scanargs( argc, argv, "% n%-colors!d d%- o%-outfile!s infile!s",
251  &tmp, &max_colors, &dither, &oflag, &out_fname, &infname ))
252  exit( 1 );
253 
254  cmd_nm = cmd_name( argv );
255 
256  in_hdr = *rle_hdr_init( NULL );
257  out_hdr = *rle_hdr_init( NULL );
259  rle_names( &in_hdr, cmd_nm, infname, 0 );
260  rle_names( &out_hdr, in_hdr.cmd, out_fname, 0 );
261 
262  for ( rle_cnt = 0; ; rle_cnt++ )
263  {
264  start = ftell( in_hdr.rle_file );
265  if ( start < 0 )
266  {
267  fprintf( stderr, "%s: Sorry, can't accept piped input.\n",
268  cmd_nm );
269  exit( -1 );
270  }
271  if ( (rle_err = rle_get_setup( &in_hdr )) != RLE_SUCCESS )
272  break;
273  /*
274  * Setup rle buffers.
275  */
276 
277  if (in_hdr.ncolors != 3)
278  {
279  fprintf(stderr,
280  "%s: input file must be three channel (RGB) image.\n",
281  cmd_nm);
282  exit(-5);
283  }
284 
285  (void)rle_hdr_cp( &in_hdr, &out_hdr );
286  out_hdr.ncolors = 1; /* Just one chan, the cmap index */
287  for (i = 1; i < in_hdr.ncolors; i++)
288  RLE_CLR_BIT( out_hdr, i ); /* Kill extra output channels */
289  out_hdr.ncmap = 3;
290  out_hdr.cmaplen = 8; /* == 256 entries */
292 
293  if ( rle_cnt == 0 )
294  outfile = rle_open_f( cmd_name( argv ), out_fname, "w" );
295  out_hdr.rle_file = outfile;
296 
297  /* getrow and putrow have different origins, this makes them the same */
299  in_hdr.xmin = 0;
300 
301  if ( rle_row_alloc( &in_hdr, &scan ) < 0 )
302  RLE_CHECK_ALLOC( cmd_nm, 0, "input image data" );
303 
304  /*
305  * Build histogram.
306  */
307  while ( rle_getrow(&in_hdr,scan) <= in_hdr.ymax )
308  {
309  rptr = scan[RLE_RED];
310  gptr = scan[RLE_GREEN];
311  bptr = scan[RLE_BLUE];
312 
313  for ( i=0; i <= in_hdr.xmax; i++ )
314  {
315  register int tmp = FAST_PACK( *rptr++, *gptr++, *bptr++ );
316  register histogram_t *hp = hist[tmp];
317 
318  if ( hp == NULL )
319  {
320  hist[tmp] = hp = (histogram_t *) malloc( sizeof(histogram_t) );
321  RLE_CHECK_ALLOC( cmd_nm, hp, "histogram" );
322  }
323  hp->color = tmp;
324  hp->nsamples++;
325  }
326  }
327 
328  sum_hist();
329  subdivide();
332 
334  sprintf( cmap_comment, "color_map_length=%d", cb_list_size );
335  rle_putcom( cmap_comment, &out_hdr );
338 
340 
341  /*
342  * Now rewind the input and convert the pixels from RGB to the index.
343  */
344  fseek( in_hdr.rle_file, start, 0 );
346  in_hdr.xmax -= in_hdr.xmin; /* Spencer trick */
347  in_hdr.xmin = 0;
348 
349  if (dither)
351  else
352  quantize_rle(scan);
353 
354  rle_row_free( &in_hdr, scan );
355  free_hist();
356  }
357 
358  /* Check for an error. EOF or EMPTY is ok if at least one image
359  * has been read. Otherwise, print an error message.
360  */
361  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
362  rle_get_error( rle_err, cmd_nm, infname );
363 
364 
365  exit( 0 );
366 }
367 
368 
369 /*****************************************************************
370  * TAG( sum_hist )
371  *
372  * Build the first bounding box from the histogram. This also
373  * compacts the histogram.
374  */
375 void
377 {
378  register int oldh, newh, i, total;
379 
380  /* Get a color box. */
381  cb = (color_box_t *) malloc( sizeof( color_box_t ) );
382  RLE_CHECK_ALLOC( cmd_nm, cb, 0 );
383  bzero( cb, sizeof( color_box_t ) );
384 
385  /* Compact histogram. */
386  for ( oldh = newh = 0; oldh < 32768; oldh++ )
387  if ( hist[oldh] )
388  {
389  hist[newh] = hist[oldh];
390  if ( oldh != newh ) hist[oldh] = NULL;
391  newh++;
392  }
393  hist_size = cb->hsize = newh;
394 
395  /* Calculate total pixels. */
396  for ( total = i = 0; i<cb->hsize; i++ )
397  if ( hist[i] )
398  total += hist[i]->nsamples;
399 
400  cb->hist = hist;
401  cb->nsamples = total;
402  bound_rgb( cb );
404 
405  cb_list = cb;
406  cb_list_size = 1;
407 }
408 
409 
410 /*****************************************************************
411  * TAG( subdivide )
412  *
413  * Break up bounding boxes until the desired number of colors is reached.
414  */
415 void
417 {
418  while ( cb_list_size < max_colors )
419  if ( break_box() )
420  return;
421 }
422 
423 
424 /*****************************************************************
425  * TAG( break_box )
426  *
427  * Break a bounding box along its largest axis. Grab the first box
428  * off the color box list (this will be the largest box) and sort it
429  * according to the largest dimension color. This is so we can split
430  * the box into two boxes with "contiguous" colors.
431  */
432 int
434 {
435  color_box_t *newb, *box = cb_list, *split_box(), *insert_elt();
436 
437  cb_list = N(cb_list);
438  if ( cb_list ) P(cb_list) = NULL;
439  N(box) = P(box) = NULL;
440 
441  switch ( box->axis )
442  {
443  case RLE_RED:
444  radix_sort( box, 0, 5 );
445  break;
446 
447  case RLE_GREEN:
448  radix_sort( box, 5, 5 );
449  break;
450 
451  case RLE_BLUE:
452  radix_sort( box, 10, 5 );
453  }
454 
455  newb = split_box( box );
457 
458  if ( newb == NULL )
459  return 1;
460 
461  cb_list = insert_elt( cb_list, newb );
462  cb_list_size++;
463  return 0;
464 }
465 
466 
467 /*****************************************************************
468  * TAG( split_box )
469  *
470  * Given a box which needs to be split, split it. Split a color box
471  * at it median. The granularity of the split is a historgram entry,
472  * so we never have the same color in two boxes. Recalculate the
473  * bounding boxes for each new color_box_t. We play some nifty games
474  * here with pointers. There is only one histogram, but each
475  * color_box_t structure has a pointer into this histogram along with
476  * the number of entries it "owns". Those entries are re-arranged
477  * (sorted) whenever the color_box_t is split.
478  */
479 color_box_t *
481 color_box_t *box;
482 {
483  int t, i;
484  color_box_t *newbox;
485 
486  if ( box->size <= 0 )
487  return NULL;
488 
489  /* Calculate median of the box. */
490  for ( t = 0, i = 0; i < box->hsize; i++ )
491  if ( box->hist[i] )
492  {
493  if ( t+box->hist[i]->nsamples > box->nsamples/2 && t > 0 )
494  break;
495  t += box->hist[i]->nsamples;
496  }
497 
498  /*
499  * Allocate a new box and set the bounding box and histogram
500  * stuff. Note the new box gets the second half of the old box.
501  */
502  newbox = (color_box_t *) malloc( sizeof(color_box_t) );
503  RLE_CHECK_ALLOC( cmd_nm, newbox, 0 );
504  bzero( newbox, sizeof( color_box_t ) );
505 
506  newbox->hist = &box->hist[i];
507  newbox->hsize = box->hsize - i;
508  newbox->nsamples = box->nsamples - t;
509  bound_rgb( newbox );
510  set_size_axis( newbox );
511 
512  box->hsize = box->hsize - newbox->hsize;
513  box->nsamples = box->nsamples - newbox->nsamples;
514  bound_rgb( box );
515  set_size_axis( box );
516 
517  return newbox;
518 }
519 
520 
521 /*****************************************************************
522  * TAG( average_colors )
523  *
524  * Walk the list of bounding boxes calculating the average colors.
525  */
526 void
528 {
529  color_box_t *cp;
530  int i;
531  float red, grn, blu, nsamp;
532 
533  TRACE( cp, cb_list )
534  {
535  red = grn = blu = nsamp = 0;
536  for ( i=0; i<cp->hsize; i++ )
537  if ( cp->hist[i] )
538  {
539  float samp = cp->hist[i]->nsamples * cp->hist[i]->nsamples;
540  red += REDMASK(cp->hist[i]->color) * samp;
541  grn += GREENMASK(cp->hist[i]->color) * samp;
542  blu += BLUEMASK(cp->hist[i]->color) * samp;
543  nsamp += samp;
544  }
545  cp->color.r = (int)(red / nsamp);
546  cp->color.g = (int)(grn / nsamp);
547  cp->color.b = (int)(blu / nsamp);
548  }
549 }
550 
551 
552 /*****************************************************************
553  * TAG( calc_inverse_map )
554  *
555  * Calculate the inverse mapping from original colors to new (averaged
556  * colors). This is a simple linear exhaustive search. For each
557  * color box in cb_list, walk the color box's histogram. For each
558  * histogram entry calculate the distance from the histogram color to
559  * the color box's color, then check that against all other colors in
560  * the cb_list. Choose the color_box_t color which is nearest the
561  * histogram_t's color. When you find the nearest color_box_t set a
562  * back pointer from the histogram entry to the color_box_t.
563  */
564 void
566 {
567  register color_box_t *cp, *tmp;
568  int i, dist;
569  color_t ref_col;
570 
571  TRACE( cp, cb_list )
572  for ( i=0; i<cp->hsize; i++ )
573  if ( cp->hist[i] )
574  {
575  ref_col.r = REDMASK( cp->hist[i]->color );
576  ref_col.g = GREENMASK( cp->hist[i]->color );
577  ref_col.b = BLUEMASK( cp->hist[i]->color );
578  dist = DISTANCE( ref_col, cp->color );
579 
580  TRACE( tmp, cb_list )
581  {
582  register color_t *newcol = &tmp->color;
583  register int newdist = DISTANCE( ref_col, *newcol );
584 
585  if ( newdist < dist )
586  {
587  dist = newdist;
588  }
589  }
590  /* Back pointer to 24 bit value */
591  cp->hist[i]->color_ptr = cp;
592  }
593 }
594 
595 
596 /*****************************************************************
597  * TAG( make_rle_map )
598  *
599  * Generate the RLE color map entries from the color box list.
600  */
601 void
603 {
604  register int index;
605  color_box_t * cp;
606 
607  index = 0;
608  TRACE( cp, cb_list )
609  {
613  cp->cindex = index++;
614  }
615 }
616 
617 
618 /*****************************************************************
619  * TAG( re_expand_map )
620  *
621  * In order to convert RGB pixel values into final color map indices,
622  * we need to "re-hash" the values into their original slots. The table
623  * is first sorted, so we can walk backwards without trashing anything.
624  */
625 void
627 {
628  register int i;
629  int resort_compare();
630  histogram_t *tmp, **hist_ptr;
631 
632  qsort( hist, hist_size, sizeof( histogram_t * ), resort_compare );
633  hist_ptr = &(hist[hist_size-1]);
634  for ( i = hist_size-1; i >= 0; i-- )
635  {
636  (*hist_ptr)->cmap_index = (*hist_ptr)->color_ptr->cindex;
637  tmp = *hist_ptr;
638  if (tmp->color != i) /* Don't stomp existing slot. */
639  {
640  hist[tmp->color] = tmp;
641  *hist_ptr = NULL;
642  }
643  hist_ptr--;
644  }
645 }
646 
647 /*****************************************************************
648  * TAG( quantize_rle )
649  *
650  * Read the RLE file and quantize to the reduced color set.
651  */
652 void
654 rle_pixel **scan;
655 {
656  register rle_pixel *rptr, *gptr, *bptr, *optr;
657  register int i;
658  int tmp;
659 
660  while ( rle_getrow(&in_hdr,scan) <= in_hdr.ymax )
661  {
662  optr = rptr = scan[RLE_RED];
663  gptr = scan[RLE_GREEN];
664  bptr = scan[RLE_BLUE];
665 
666  for ( i=0; i<=in_hdr.xmax; i++ )
667  {
668  tmp = FAST_PACK( *rptr++, *gptr++, *bptr++ );
669  if (hist[tmp] == NULL)
670  fprintf(stderr, "bogus hash: %d\n", tmp);
671  *optr++ = hist[tmp]->cmap_index;
672  }
673 
675  }
677 }
678 
679 /*****************************************************************
680  * TAG( quantize_dither_rle )
681  *
682  * Read the RLE file and quantize to the reduced color set.
683  * Use Floyd/Steinberg dither to hide contouring.
684  */
685 void
687 rle_pixel **scan;
688 {
689  register rle_pixel *rptr, *gptr, *bptr, *optr;
690  register int i, j;
691  short *thisline, *nextline, *tmpptr ;
692  register short *thisptr, *nextptr ;
693  int tmp;
694  int lastline, lastpixel ;
695 
696  thisline = (short *) malloc( (in_hdr.xmax + 1) * 3 * sizeof(short));
697  RLE_CHECK_ALLOC( cmd_nm, thisline, 0 );
698  nextline = (short *) malloc( (in_hdr.xmax + 1) * 3 * sizeof(short));
699  RLE_CHECK_ALLOC( cmd_nm, nextline, 0 );
700 
701  /* Store the first scanline into nextline */
702 
703  rle_getrow(&in_hdr,scan);
704  rptr = scan[RLE_RED];
705  gptr = scan[RLE_GREEN];
706  bptr = scan[RLE_BLUE];
707  nextptr = nextline;
708  for (j=0; j <= in_hdr.xmax; j++)
709  {
710  *nextptr++ = *bptr++ ;
711  *nextptr++ = *gptr++ ;
712  *nextptr++ = *rptr++ ;
713  }
714 
715  for (i=in_hdr.ymin; i <= in_hdr.ymax; i++)
716  {
717  /* swap nextline into thisline and read new nextline */
718  tmpptr = thisline ;
719  thisline = nextline ;
720  nextline = tmpptr ;
721  lastline = (i == in_hdr.ymax) ;
722  if (!lastline)
723  {
724  rle_getrow(&in_hdr,scan);
725  rptr = scan[RLE_RED];
726  gptr = scan[RLE_GREEN];
727  bptr = scan[RLE_BLUE];
728  nextptr = nextline;
729  for (j=0; j <= in_hdr.xmax; j++)
730  {
731  *nextptr++ = *bptr++ ;
732  *nextptr++ = *gptr++ ;
733  *nextptr++ = *rptr++ ;
734  }
735  }
736 
737  optr = scan[RLE_RED];
738  thisptr = thisline ;
739  nextptr = nextline ;
740 
741  for(j=0; j <= in_hdr.xmax ; j++)
742  {
743  int red,green,blue ;
744  rle_pixel r2,g2,b2 ;
745 
746  lastpixel = (j == in_hdr.xmax) ;
747 
748  blue = *thisptr++ ;
749  green = *thisptr++ ;
750  red = *thisptr++ ;
751 
752  /* Current pixel has been accumulating error, it could be
753  * out of range.
754  */
755  if( red < 0 ) red = 0 ;
756  else if( red > 255 ) red = 255 ;
757  if( green < 0 ) green = 0 ;
758  else if( green > 255 ) green = 255 ;
759  if( blue < 0 ) blue = 0 ;
760  else if( blue > 255 ) blue = 255 ;
761 
762  r2 = red;
763  g2 = green;
764  b2 = blue;
765 
766  tmp = FAST_PACK( r2, g2, b2 );
767  if (hist[tmp] == NULL)
768  {
769  register color_box_t *tmp_cb;
770  color_t ref_col;
771  int dist;
772 
773  hist[tmp] = (histogram_t *) malloc( sizeof(histogram_t) );
774  RLE_CHECK_ALLOC( cmd_nm, hist[tmp], 0 );
775  hist[tmp]->color = tmp;
776 
777  /* The error propagation has produced a color that was
778  * not in the original image (its not in the histogram!).
779  * So, we need to find the closest color.
780  */
781  ref_col.r = TO_5_BITS( r2 );
782  ref_col.g = TO_5_BITS( g2 );
783  ref_col.b = TO_5_BITS( b2 );
784 
785  if ( cb_list )
786  {
787  dist = DISTANCE( ref_col, cb_list->color );
788  hist[tmp]->color_ptr = cb_list;
790 
791  TRACE( tmp_cb, cb_list )
792  {
793  register color_t *newcol = &tmp_cb->color;
794  register newdist = DISTANCE( ref_col, *newcol );
795 
796  if ( newdist < dist )
797  {
798  dist = newdist;
799  hist[tmp]->color_ptr = tmp_cb;
800  hist[tmp]->cmap_index = tmp_cb->cindex;
801  }
802  }
803  }
804  else
805  fprintf( stderr, "Color box list is empty.\n" );
806  }
807 
808  *optr++ = hist[tmp]->cmap_index;
809 
811  green -= FROM_5_BITS(hist[tmp]->color_ptr->color.g);
813 
814  if( !lastpixel )
815  {
816  thisptr[0] += blue * 7 / 16 ;
817  thisptr[1] += green * 7 / 16 ;
818  thisptr[2] += red * 7 / 16 ;
819  }
820  if( !lastline )
821  {
822  if( j != 0 )
823  {
824  nextptr[-3] += blue * 3 / 16 ;
825  nextptr[-2] += green * 3 / 16 ;
826  nextptr[-1] += red * 3 / 16 ;
827  }
828  nextptr[0] += blue * 5 / 16 ;
829  nextptr[1] += green * 5 / 16 ;
830  nextptr[2] += red * 5 / 16 ;
831  if( !lastpixel )
832  {
833  nextptr[3] += blue / 16 ;
834  nextptr[4] += green / 16 ;
835  nextptr[5] += red / 16 ;
836  }
837  nextptr += 3 ;
838  }
839  }
840 
842  }
844 
845  free( thisline );
846  free( nextline );
847 }
848 
849 /*****************************************************************
850  * TAG( resort_compare )
851  *
852  * Extract the color for resorting the structure of the histogram.
853  */
854 int
856 histogram_t **c1, **c2;
857 {
858  return ( (*c1)->color > (*c2)->color );
859 }
860 
861 
862 /*****************************************************************
863  * TAG( set_size_axis )
864  *
865  * Determine the largest axis and its dimension.
866  */
867 void
869 color_box_t *cb;
870 {
871  int rsize = cb->r.max - cb->r.min,
872  gsize = cb->g.max - cb->g.min,
873  bsize = cb->b.max - cb->b.min;
874 
875  if ( rsize > gsize )
876  {
877  if ( rsize > bsize )
878  {
879  cb->axis = RLE_RED;
880  cb->size = rsize;
881  }
882  else
883  {
884  cb->axis = RLE_BLUE;
885  cb->size = bsize;
886  }
887  }
888  else
889  {
890  if ( gsize > bsize )
891  {
892  cb->axis = RLE_GREEN;
893  cb->size = gsize;
894  }
895  else
896  {
897  cb->axis = RLE_BLUE;
898  cb->size = bsize;
899  }
900  }
901 }
902 
903 
904 /*****************************************************************
905  * TAG( bound_rgb )
906  *
907  * Calcluate the rgb bounding box for the color_box_t.
908  */
909 void
911 register color_box_t *box;
912 {
913  register int i;
914  register histogram_t **hp = box->hist;
915  int first_time = 1;
916 
917  for ( i=0; i<box->hsize; i++, hp++ )
918  if ( *hp )
919  {
920  if ( first_time )
921  {
922  box->r.min = box->r.max = REDMASK( (*hp)->color );
923  box->g.min = box->g.max = GREENMASK( (*hp)->color );
924  box->b.min = box->b.max = BLUEMASK( (*hp)->color );
925  first_time = 0;
926  }
927 
928  box->r.min = MIN( box->r.min, REDMASK((*hp)->color) );
929  box->r.max = MAX( box->r.max, REDMASK((*hp)->color) );
930  box->g.min = MIN( box->g.min, GREENMASK((*hp)->color) );
931  box->g.max = MAX( box->g.max, GREENMASK((*hp)->color) );
932  box->b.min = MIN( box->b.min, BLUEMASK((*hp)->color) );
933  box->b.max = MAX( box->b.max, BLUEMASK((*hp)->color) );
934  }
935 }
936 
937 
938 /*****************************************************************
939  * TAG( radix_sort )
940  *
941  * Simulate a radix sort with qsort.
942  */
943 void
945 color_box_t *bbox;
946 int start_bit, num_bits;
947 {
948  int cmp_radices();
949 
950  mask = ~(~0 << num_bits) << start_bit;
951 
952  qsort( (char *)bbox->hist, bbox->hsize,
953  sizeof(histogram_t *), cmp_radices );
954 }
955 
956 
957 /*****************************************************************
958  * TAG( cmp_radices )
959  *
960  * The comparison function for qsort.
961  */
962 int
964 histogram_t **h1, **h2;
965 {
966  register c1 = -1, c2 = -1;
967 
968  if ( *h1 )
969  c1 = (*h1)->color & mask;
970  if ( *h2 )
971  c2 = (*h2)->color & mask;
972 
973  return c1>c2 ? 1 : ( c2>c1 ? -1 : 0 );
974 }
975 
976 
977 /*****************************************************************
978  * TAG( insert_elt )
979  *
980  * Insert an element into a linked list decreasing order.
981  */
982 color_box_t *
984 color_box_t *list, *elt;
985 {
986  color_box_t *lp, *ll;
987 
988  /* Special cases: NULL list and one element list. */
989  if ( list == NULL )
990  list = elt;
991  else if ( P(list) == NULL && N(list) == NULL )
992  if ( list->size <= elt->size )
993  ADD( elt, list );
994  else
995  {
996  ADD( list, elt );
997  list = elt;
998  }
999  else
1000  {
1001  /* Search a multi-element list for proper spot to insert. */
1002  for ( lp = list; N(lp); lp = N(lp) )
1003  if ( lp->size <= elt->size )
1004  break;
1005 
1006  /*
1007  * Special cases: insert before beginning, insert after end,
1008  * insert in middle.
1009  */
1010  if ( P(lp) == NULL )
1011  ADD( elt, list );
1012  else
1013  if ( N(lp) == NULL && elt->size < lp->size )
1014  {
1015  /* Append elt to lp */
1016  for (ll = lp; N(ll) != NULL; ll = N(ll)) ;
1017  N(ll) = elt;
1018  P(elt) = ll;
1019  }
1020  else
1021  {
1022  lp = P(lp);
1023  INSERT( elt, lp );
1024  }
1025  }
1026 
1027  return list;
1028 }
1029 
1030 
1031 /*****************************************************************
1032  * free_hist -- free all histogram and color box storage.
1033  */
1034 void
1036 {
1037  register color_box_t *tmp_cb, *next_cb;
1038  register int i;
1039 
1040  for( tmp_cb = cb_list; tmp_cb; tmp_cb = next_cb )
1041  {
1042  next_cb = N(tmp_cb);
1043  free( tmp_cb );
1044  }
1045  cb_list = NULL;
1046  cb_list_size = 0;
1047 
1048  for ( i = 0; i < 32768; i++ )
1049  {
1050  if ( hist[i] )
1051  free( hist[i] );
1052  hist[i] = NULL;
1053  }
1054 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
static unsigned mask
Definition: mcut.c:162
int cmap_index
Definition: mcut.c:110
#define MIN(x, y)
Definition: rletopaint.c:53
void sum_hist()
Definition: mcut.c:376
#define GREENMASK(x)
Definition: mcut.c:73
int xmin
Definition: rle.h:100
int max
Definition: mcut.c:122
int b
Definition: mcut.c:94
bounds_t r
Definition: mcut.c:141
#define P(node)
Definition: mcut.c:44
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
int hist_size
Definition: mcut.c:168
void quantize_rle(rle_pixel **scan)
Definition: mcut.c:653
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
int size
Definition: mcut.c:136
struct _color color_t
Definition: mcut.c:91
void rle_row_free(rle_hdr *the_hdr, rle_pixel **scanp)
Definition: rle_row_alc.c:114
#define RLE_EMPTY
Definition: rle.h:73
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void quantize_dither_rle(rle_pixel **scan)
Definition: mcut.c:686
void main(int argc, char **argv)
Definition: aliastorle.c:121
int g
Definition: mcut.c:94
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
int hsize
Definition: mcut.c:139
color_box_t * insert_elt(color_box_t *list, color_box_t *elt)
Definition: mcut.c:983
rle_map * cmap
Definition: rle.h:112
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
struct _histogram histogram_t
Definition: mcut.c:105
#define RLE_GREEN
Definition: rle.h:63
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
int axis
Definition: mcut.c:137
short out_map[3][256]
Definition: mcut.c:163
#define RLE_SUCCESS
Definition: rle.h:70
void free_hist()
Definition: mcut.c:1035
void average_colors()
Definition: mcut.c:527
int ymin
Definition: rle.h:100
int rle_get_error(int code, const char *pgmname, const char *fname)
Definition: rle_error.c:76
#define RLE_BLUE
Definition: rle.h:64
int max_colors
Definition: mcut.c:166
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
color_box_t * split_box(color_box_t *box)
Definition: mcut.c:480
void calc_inverse_map()
Definition: mcut.c:565
#define N(node)
Definition: mcut.c:45
#define ADD(new, first)
Definition: mcut.c:60
int nsamples
Definition: mcut.c:108
const char * cmd
Definition: rle.h:133
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
#define RLE_RED
Definition: rle.h:62
bounds_t b
Definition: mcut.c:141
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
#define index
Definition: rle_config.h:96
rle_hdr out_hdr
Definition: unslice.c:34
histogram_t * hist[32768]
Definition: mcut.c:167
#define TRACE(t_var, ini)
Definition: mcut.c:50
color_box_t * color_ptr
Definition: mcut.c:109
bounds_t g
Definition: mcut.c:141
#define RLE_EOF
Definition: rle.h:74
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
Definition: mcut.c:120
struct _bounds bounds_t
Definition: mcut.c:119
#define INSERT(new, after)
Definition: mcut.c:64
int break_box()
Definition: mcut.c:433
void rle_get_setup_ok(rle_hdr *the_hdr, const char *prog_name, const char *file_name)
Definition: rle_getrow.c:254
#define MAX(i, j)
Definition: get4d.c:23
#define FROM_5_BITS(x)
Definition: mcut.c:77
#define BLUEMASK(x)
Definition: mcut.c:72
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
char * cmd_nm
Definition: mcut.c:169
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
void make_rle_map()
Definition: mcut.c:602
unsigned char rle_pixel
Definition: rle.h:56
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
void bound_rgb(color_box_t *box)
Definition: mcut.c:910
int min
Definition: mcut.c:122
void re_expand_map()
Definition: mcut.c:626
const char * rle_putcom(char *value, rle_hdr *the_hdr) const
Definition: rle_putcom.c:82
int cmaplen
Definition: rle.h:100
int nsamples
Definition: mcut.c:140
struct _color_box color_box_t
Definition: mcut.c:98
#define TLISTLINKS(type)
Definition: mcut.c:39
color_t color
Definition: mcut.c:142
unsigned short rle_map
Definition: rle.h:57
#define FAST_PACK(r, g, b)
Definition: mcut.c:79
rle_hdr in_hdr
Definition: unslice.c:34
int cmp_radices(histogram_t **h1, histogram_t **h2)
Definition: mcut.c:963
void set_size_axis(color_box_t *cb)
Definition: mcut.c:868
int cindex
Definition: mcut.c:143
#define REDMASK(x)
Definition: mcut.c:74
int color
Definition: mcut.c:108
int cb_list_size
Definition: mcut.c:161
int r
Definition: mcut.c:94
void subdivide()
Definition: mcut.c:416
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
Definition: mcut.c:92
color_box_t * cb_list
Definition: mcut.c:159
int resort_compare(histogram_t **c1, histogram_t **c2)
Definition: mcut.c:855
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
void radix_sort(color_box_t *bbox, int start_bit, int num_bits)
Definition: mcut.c:944
histogram_t ** hist
Definition: mcut.c:138
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86
#define TO_5_BITS(x)
Definition: mcut.c:76
#define DISTANCE(x, y)
Definition: mcut.c:81
color_box_t * cb
Definition: mcut.c:159