Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
Data Structures | Macros | Typedefs | Functions | Variables
mcut.c File Reference
#include <stdio.h>
#include "rle.h"
Include dependency graph for mcut.c:

Go to the source code of this file.

Data Structures

struct  _color
 
struct  _histogram
 
struct  _bounds
 
struct  _color_box
 

Macros

#define MAX(i, j)    ( (i) > (j) ? (i) : (j) )
 
#define MIN(i, j)    ( (i) < (j) ? (i) : (j) )
 
#define TLISTLINKS(type)    type * next, * prev
 
#define P(node)   ((node)->prev)
 
#define N(node)   ((node)->next)
 
#define TRACE(t_var, ini)    for((t_var)=(ini);(t_var)!=NULL;(t_var)=N(t_var))
 
#define ADD(new, first)
 
#define INSERT(new, after)
 
#define BLUEMASK(x)   ((x) & 0x1f)
 
#define GREENMASK(x)   (((x)>>5) & 0x1f)
 
#define REDMASK(x)   (((x)>>10) & 0x1f)
 
#define TO_5_BITS(x)   (((x)>>3) & 0x1f)
 
#define FROM_5_BITS(x)   (((x)<<3) & 0xff)
 
#define PACK_15(r, g, b)   (TO_5_BITS(r)<<10 | TO_5_BITS(g)<<5 | TO_5_BITS(b))
 
#define FAST_PACK(r, g, b)   (((r)&0xf8)<<7 | ((g)&0xf8)<<2 | (TO_5_BITS(b)))
 
#define DISTANCE(x, y)
 

Typedefs

typedef struct _color color_t
 
typedef struct _color_box color_box_t
 
typedef struct _histogram histogram_t
 
typedef struct _bounds bounds_t
 

Functions

void subdivide ()
 
void sum_hist ()
 
void average_colors ()
 
void calc_inverse_map ()
 
void make_rle_map ()
 
void re_expand_map ()
 
void quantize_dither_rle ()
 
void quantize_rle ()
 
void free_hist ()
 
void bound_rgb ()
 
void set_size_axis ()
 
int break_box ()
 
void radix_sort ()
 
void main (int argc, char **argv)
 
color_box_tsplit_box (color_box_t *box)
 
void quantize_rle (rle_pixel **scan)
 
void quantize_dither_rle (rle_pixel **scan)
 
int resort_compare (histogram_t **c1, histogram_t **c2)
 
void set_size_axis (color_box_t *cb)
 
void bound_rgb (color_box_t *box)
 
void radix_sort (color_box_t *bbox, int start_bit, int num_bits)
 
int cmp_radices (histogram_t **h1, histogram_t **h2)
 
color_box_tinsert_elt (color_box_t *list, color_box_t *elt)
 

Variables

color_box_tcb_list
 
color_box_tcb
 
int cb_list_size
 
static unsigned mask
 
short out_map [3][256]
 
rle_hdr in_hdr
 
rle_hdr out_hdr
 
int max_colors = 200
 
histogram_thist [32768]
 
int hist_size
 
char * cmd_nm
 

Macro Definition Documentation

#define ADD (   new,
  first 
)
Value:
( P(new) = NULL ,N(new) = (first),\
( ((first)!=NULL) ? (P(first)=(new), 0) :0 ),\
first = (new) )
#define P(node)
Definition: mcut.c:44
#define N(node)
Definition: mcut.c:45

Definition at line 60 of file mcut.c.

#define BLUEMASK (   x)    ((x) & 0x1f)

Definition at line 72 of file mcut.c.

#define DISTANCE (   x,
  y 
)
Value:
(((x).r-(y).r) * ((x).r-(y).r) + \
((x).g-(y).g) * ((x).g-(y).g) + \
((x).b-(y).b) * ((x).b-(y).b))
static unsigned char g
Definition: getami.c:692
static unsigned char r
Definition: getami.c:692
static int y
Definition: getami.c:691
static unsigned char b
Definition: getami.c:692
static int x
Definition: getami.c:691

Definition at line 81 of file mcut.c.

#define FAST_PACK (   r,
  g,
  b 
)    (((r)&0xf8)<<7 | ((g)&0xf8)<<2 | (TO_5_BITS(b)))

Definition at line 79 of file mcut.c.

#define FROM_5_BITS (   x)    (((x)<<3) & 0xff)

Definition at line 77 of file mcut.c.

#define GREENMASK (   x)    (((x)>>5) & 0x1f)

Definition at line 73 of file mcut.c.

#define INSERT (   new,
  after 
)
Value:
( P(new) = (after),N(new) = N(after),\
( (N(after)!=NULL) ? (P(N(after))=(new), 0) :0),\
N(after) = (new) )
#define P(node)
Definition: mcut.c:44
#define N(node)
Definition: mcut.c:45

Definition at line 64 of file mcut.c.

#define MAX (   i,
 
)    ( (i) > (j) ? (i) : (j) )

Definition at line 32 of file mcut.c.

#define MIN (   i,
 
)    ( (i) < (j) ? (i) : (j) )

Definition at line 33 of file mcut.c.

#define N (   node)    ((node)->next)

Definition at line 45 of file mcut.c.

#define P (   node)    ((node)->prev)

Definition at line 44 of file mcut.c.

#define PACK_15 (   r,
  g,
  b 
)    (TO_5_BITS(r)<<10 | TO_5_BITS(g)<<5 | TO_5_BITS(b))

Definition at line 78 of file mcut.c.

#define REDMASK (   x)    (((x)>>10) & 0x1f)

Definition at line 74 of file mcut.c.

#define TLISTLINKS (   type)    type * next, * prev

Definition at line 39 of file mcut.c.

#define TO_5_BITS (   x)    (((x)>>3) & 0x1f)

Definition at line 76 of file mcut.c.

#define TRACE (   t_var,
  ini 
)    for((t_var)=(ini);(t_var)!=NULL;(t_var)=N(t_var))

Definition at line 50 of file mcut.c.

Typedef Documentation

typedef struct _bounds bounds_t

Definition at line 119 of file mcut.c.

typedef struct _color_box color_box_t

Definition at line 98 of file mcut.c.

typedef struct _color color_t

Definition at line 91 of file mcut.c.

typedef struct _histogram histogram_t

Definition at line 105 of file mcut.c.

Function Documentation

void average_colors ( )

Definition at line 527 of file mcut.c.

References _color::b, cb_list, _histogram::color, _color_box::color, _color::g, _color_box::hist, _color_box::hsize, _histogram::nsamples, and _color::r.

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 }
#define GREENMASK(x)
Definition: mcut.c:73
int hsize
Definition: mcut.c:139
int nsamples
Definition: mcut.c:108
#define TRACE(t_var, ini)
Definition: mcut.c:50
#define BLUEMASK(x)
Definition: mcut.c:72
int
Definition: getami.c:848
int i
Definition: rletorla.c:82
color_t color
Definition: mcut.c:142
#define REDMASK(x)
Definition: mcut.c:74
int color
Definition: mcut.c:108
color_box_t * cb_list
Definition: mcut.c:159
static unsigned char red[256]
Definition: rastorle.c:71
histogram_t ** hist
Definition: mcut.c:138
void bound_rgb ( )
void bound_rgb ( color_box_t box)

Definition at line 910 of file mcut.c.

Referenced by sum_hist().

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 }
#define GREENMASK(x)
Definition: mcut.c:73
int max
Definition: mcut.c:122
bounds_t r
Definition: mcut.c:141
int hsize
Definition: mcut.c:139
bounds_t b
Definition: mcut.c:141
bounds_t g
Definition: mcut.c:141
#define BLUEMASK(x)
Definition: mcut.c:72
#define MAX(i, j)
Definition: mcut.c:32
int min
Definition: mcut.c:122
int i
Definition: rletorla.c:82
#define MIN(i, j)
Definition: mcut.c:33
#define REDMASK(x)
Definition: mcut.c:74
histogram_t ** hist
Definition: mcut.c:138

Here is the caller graph for this function:

int break_box ( )

Definition at line 433 of file mcut.c.

References _color_box::axis, cb_list, cb_list_size, insert_elt(), radix_sort(), and split_box().

Referenced by subdivide().

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 );
456  cb_list = insert_elt( cb_list, 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 }
#define P(node)
Definition: mcut.c:44
color_box_t * insert_elt(color_box_t *list, color_box_t *elt)
Definition: mcut.c:983
void radix_sort()
#define RLE_GREEN
Definition: rle.h:63
int axis
Definition: mcut.c:137
#define RLE_BLUE
Definition: rle.h:64
color_box_t * split_box(color_box_t *box)
Definition: mcut.c:480
#define N(node)
Definition: mcut.c:45
#define RLE_RED
Definition: rle.h:62
int cb_list_size
Definition: mcut.c:161
color_box_t * cb_list
Definition: mcut.c:159

Here is the call graph for this function:

Here is the caller graph for this function:

void calc_inverse_map ( )

Definition at line 565 of file mcut.c.

References _color::b, cb_list, _histogram::color, _color_box::color, _histogram::color_ptr, _color::g, _color_box::hist, _color_box::hsize, and _color::r.

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 }
#define GREENMASK(x)
Definition: mcut.c:73
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
#define BLUEMASK(x)
Definition: mcut.c:72
if(tfd)
Definition: getami.c:852
int i
Definition: rletorla.c:82
color_t color
Definition: mcut.c:142
#define REDMASK(x)
Definition: mcut.c:74
int color
Definition: mcut.c:108
color_box_t * cb_list
Definition: mcut.c:159
histogram_t ** hist
Definition: mcut.c:138
#define DISTANCE(x, y)
Definition: mcut.c:81
int cmp_radices ( histogram_t **  h1,
histogram_t **  h2 
)

Definition at line 963 of file mcut.c.

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 }
static unsigned mask
Definition: mcut.c:162
void free_hist ( )

Definition at line 1035 of file mcut.c.

References cb_list, cb_list_size, and hist.

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 }
#define N(node)
Definition: mcut.c:45
histogram_t * hist[32768]
Definition: mcut.c:167
int i
Definition: rletorla.c:82
int cb_list_size
Definition: mcut.c:161
color_box_t * cb_list
Definition: mcut.c:159
color_box_t* insert_elt ( color_box_t list,
color_box_t elt 
)

Definition at line 983 of file mcut.c.

Referenced by break_box().

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 }
#define P(node)
Definition: mcut.c:44
int size
Definition: mcut.c:136
#define N(node)
Definition: mcut.c:45
#define ADD(new, first)
Definition: mcut.c:60
#define INSERT(new, after)
Definition: mcut.c:64

Here is the caller graph for this function:

void main ( int  argc,
char **  argv 
)

Definition at line 236 of file mcut.c.

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 );
258  in_hdr.rle_file = rle_open_f(cmd_nm, infname, "r");
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 */
291  out_hdr.cmap = (rle_map *) out_map;
292 
293  if ( rle_cnt == 0 )
294  outfile = rle_open_f( cmd_name( argv ), out_fname, "w" );
296 
297  /* getrow and putrow have different origins, this makes them the same */
298  in_hdr.xmax -= in_hdr.xmin;
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();
330  average_colors();
332 
333  make_rle_map();
334  sprintf( cmap_comment, "color_map_length=%d", cb_list_size );
335  rle_putcom( cmap_comment, &out_hdr );
336  rle_addhist( argv, &in_hdr, &out_hdr );
338 
339  re_expand_map();
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 );
345  rle_get_setup_ok( &in_hdr, cmd_nm, infname );
346  in_hdr.xmax -= in_hdr.xmin; /* Spencer trick */
347  in_hdr.xmin = 0;
348 
349  if (dither)
350  quantize_dither_rle(scan);
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 }
void sum_hist()
Definition: mcut.c:376
void rle_row_free(rle_hdr *the_hdr, rle_pixel **scanp)
Definition: rle_row_alc.c:114
int xmin
Definition: rle.h:100
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
void quantize_rle()
FILE * outfile
Definition: giftorle.c:61
void quantize_dither_rle()
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
#define RLE_EMPTY
Definition: rle.h:73
const char * rle_putcom(const char *value, rle_hdr *the_hdr)
rle_map * cmap
Definition: rle.h:112
#define RLE_GREEN
Definition: rle.h:63
short out_map[3][256]
Definition: mcut.c:163
void rle_addhist(char *argv[], rle_hdr *in_hdr, rle_hdr *out_hdr)
#define RLE_SUCCESS
Definition: rle.h:70
void free_hist()
Definition: mcut.c:1035
void average_colors()
Definition: mcut.c:527
#define RLE_BLUE
Definition: rle.h:64
unsigned char ** scan
Definition: rle.c:26
int max_colors
Definition: mcut.c:166
void calc_inverse_map()
Definition: mcut.c:565
string infname
Definition: getbob.c:68
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
int nsamples
Definition: mcut.c:108
const char * cmd
Definition: rle.h:133
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
#define RLE_RED
Definition: rle.h:62
int xmax
Definition: rle.h:100
histogram_t * hist[32768]
Definition: mcut.c:167
int rle_get_error(int code, const char *pgmname, const char *fname)
#define RLE_EOF
Definition: rle.h:74
rle_hdr in_hdr
Definition: mcut.c:164
#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 re_expand_map()
Definition: mcut.c:626
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
void * malloc()
int cmaplen
Definition: rle.h:100
int i
Definition: rletorla.c:82
FILE * rle_open_f(const char *prog_name, const char *f_name, const char *mode)
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
unsigned short rle_map
Definition: rle.h:57
#define FAST_PACK(r, g, b)
Definition: mcut.c:79
char * cmd_name(char **argv)
Definition: cmd_name.c:31
int color
Definition: mcut.c:108
int cb_list_size
Definition: mcut.c:161
void subdivide()
Definition: mcut.c:416
int oflag
Definition: painttorle.c:45
void rle_get_setup_ok(rle_hdr *the_hdr, const char *prog_name, const char *file_name)
int rle_getrow(rle_hdr *the_hdr, rle_pixel *scanline[])
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
rle_hdr out_hdr
Definition: mcut.c:164
void make_rle_map ( )

Definition at line 602 of file mcut.c.

References _color::b, cb_list, _color_box::cindex, _color_box::color, _color::g, out_map, and _color::r.

603 {
604  register int index;
605  color_box_t * cp;
606 
607  index = 0;
608  TRACE( cp, cb_list )
609  {
610  out_map[RLE_RED][index] = FROM_5_BITS(cp->color.r) << 8;
611  out_map[RLE_GREEN][index] = FROM_5_BITS(cp->color.g) << 8;
612  out_map[RLE_BLUE][index] = FROM_5_BITS(cp->color.b) << 8;
613  cp->cindex = index++;
614  }
615 }
#define RLE_GREEN
Definition: rle.h:63
short out_map[3][256]
Definition: mcut.c:163
#define RLE_BLUE
Definition: rle.h:64
#define RLE_RED
Definition: rle.h:62
#define index
Definition: rle_config.h:96
#define TRACE(t_var, ini)
Definition: mcut.c:50
#define FROM_5_BITS(x)
Definition: mcut.c:77
color_t color
Definition: mcut.c:142
int cindex
Definition: mcut.c:143
color_box_t * cb_list
Definition: mcut.c:159
void quantize_dither_rle ( )
void quantize_dither_rle ( rle_pixel **  scan)

Definition at line 686 of file mcut.c.

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 
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  {
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;
789  hist[tmp]->cmap_index = cb_list->cindex;
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 
810  red -= FROM_5_BITS(hist[tmp]->color_ptr->color.r);
811  green -= FROM_5_BITS(hist[tmp]->color_ptr->color.g);
812  blue -= FROM_5_BITS(hist[tmp]->color_ptr->color.b);
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 
841  rle_putrow( scan, in_hdr.xmax + 1, &out_hdr );
842  }
843  rle_puteof( &out_hdr );
844 
845  free( thisline );
846  free( nextline );
847 }
int cmap_index
Definition: mcut.c:110
static unsigned char blue[256]
Definition: rastorle.c:71
void rle_putrow(rle_pixel *rows[], int rowlen, rle_hdr *the_hdr)
#define RLE_GREEN
Definition: rle.h:63
int ymin
Definition: rle.h:100
#define RLE_BLUE
Definition: rle.h:64
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
unsigned char ** scan
Definition: rle.c:26
#define RLE_RED
Definition: rle.h:62
int xmax
Definition: rle.h:100
static unsigned char green[256]
Definition: rastorle.c:71
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
rle_hdr in_hdr
Definition: mcut.c:164
#define FROM_5_BITS(x)
Definition: mcut.c:77
char * cmd_nm
Definition: mcut.c:169
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
void * malloc()
int i
Definition: rletorla.c:82
color_t color
Definition: mcut.c:142
#define FAST_PACK(r, g, b)
Definition: mcut.c:79
int cindex
Definition: mcut.c:143
int color
Definition: mcut.c:108
color_box_t * cb_list
Definition: mcut.c:159
static unsigned char red[256]
Definition: rastorle.c:71
int rle_getrow(rle_hdr *the_hdr, rle_pixel *scanline[])
#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
rle_hdr out_hdr
Definition: mcut.c:164
void quantize_rle ( )
void quantize_rle ( rle_pixel **  scan)

Definition at line 653 of file mcut.c.

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 
674  rle_putrow( scan, in_hdr.xmax + 1, &out_hdr );
675  }
676  rle_puteof( &out_hdr );
677 }
int cmap_index
Definition: mcut.c:110
void rle_putrow(rle_pixel *rows[], int rowlen, rle_hdr *the_hdr)
#define RLE_GREEN
Definition: rle.h:63
#define RLE_BLUE
Definition: rle.h:64
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
unsigned char ** scan
Definition: rle.c:26
#define RLE_RED
Definition: rle.h:62
int xmax
Definition: rle.h:100
histogram_t * hist[32768]
Definition: mcut.c:167
rle_hdr in_hdr
Definition: mcut.c:164
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
int i
Definition: rletorla.c:82
#define FAST_PACK(r, g, b)
Definition: mcut.c:79
int rle_getrow(rle_hdr *the_hdr, rle_pixel *scanline[])
rle_hdr out_hdr
Definition: mcut.c:164
void radix_sort ( )
void radix_sort ( color_box_t bbox,
int  start_bit,
int  num_bits 
)

Definition at line 944 of file mcut.c.

Referenced by break_box().

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 }
static unsigned mask
Definition: mcut.c:162
int hsize
Definition: mcut.c:139
int cmp_radices(histogram_t **h1, histogram_t **h2)
Definition: mcut.c:963
histogram_t ** hist
Definition: mcut.c:138

Here is the caller graph for this function:

void re_expand_map ( )

Definition at line 626 of file mcut.c.

References _color_box::cindex, _histogram::cmap_index, _histogram::color, _histogram::color_ptr, hist, hist_size, and resort_compare().

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 }
int cmap_index
Definition: mcut.c:110
int hist_size
Definition: mcut.c:168
histogram_t * hist[32768]
Definition: mcut.c:167
int i
Definition: rletorla.c:82
int color
Definition: mcut.c:108
int resort_compare(histogram_t **c1, histogram_t **c2)
Definition: mcut.c:855

Here is the call graph for this function:

int resort_compare ( histogram_t **  c1,
histogram_t **  c2 
)

Definition at line 855 of file mcut.c.

Referenced by re_expand_map().

857 {
858  return ( (*c1)->color > (*c2)->color );
859 }

Here is the caller graph for this function:

void set_size_axis ( )
void set_size_axis ( color_box_t cb)

Definition at line 868 of file mcut.c.

Referenced by sum_hist().

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 }
int max
Definition: mcut.c:122
bounds_t r
Definition: mcut.c:141
int size
Definition: mcut.c:136
#define RLE_GREEN
Definition: rle.h:63
int axis
Definition: mcut.c:137
#define RLE_BLUE
Definition: rle.h:64
#define RLE_RED
Definition: rle.h:62
bounds_t b
Definition: mcut.c:141
bounds_t g
Definition: mcut.c:141
int min
Definition: mcut.c:122

Here is the caller graph for this function:

color_box_t* split_box ( color_box_t box)

Definition at line 480 of file mcut.c.

Referenced by break_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 }
void set_size_axis()
int size
Definition: mcut.c:136
int hsize
Definition: mcut.c:139
int nsamples
Definition: mcut.c:108
char * cmd_nm
Definition: mcut.c:169
void * malloc()
int i
Definition: rletorla.c:82
int nsamples
Definition: mcut.c:140
histogram_t ** hist
Definition: mcut.c:138
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86
void bound_rgb()

Here is the caller graph for this function:

void subdivide ( )

Definition at line 416 of file mcut.c.

References break_box(), cb_list_size, and max_colors.

417 {
418  while ( cb_list_size < max_colors )
419  if ( break_box() )
420  return;
421 }
int max_colors
Definition: mcut.c:166
int break_box()
Definition: mcut.c:433
int cb_list_size
Definition: mcut.c:161

Here is the call graph for this function:

void sum_hist ( )

Definition at line 376 of file mcut.c.

References bound_rgb(), cb, cb_list, cb_list_size, cmd_nm, _color_box::hist, hist, hist_size, _color_box::hsize, _histogram::nsamples, _color_box::nsamples, and set_size_axis().

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 );
403  set_size_axis( cb );
404 
405  cb_list = cb;
406  cb_list_size = 1;
407 }
int hist_size
Definition: mcut.c:168
void set_size_axis()
int hsize
Definition: mcut.c:139
int nsamples
Definition: mcut.c:108
histogram_t * hist[32768]
Definition: mcut.c:167
char * cmd_nm
Definition: mcut.c:169
void * malloc()
int i
Definition: rletorla.c:82
int nsamples
Definition: mcut.c:140
int cb_list_size
Definition: mcut.c:161
color_box_t * cb_list
Definition: mcut.c:159
histogram_t ** hist
Definition: mcut.c:138
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86
void bound_rgb()
color_box_t * cb
Definition: mcut.c:159

Here is the call graph for this function:

Variable Documentation

Definition at line 159 of file mcut.c.

Referenced by sum_hist().

color_box_t* cb_list

Definition at line 159 of file mcut.c.

Referenced by average_colors(), break_box(), calc_inverse_map(), free_hist(), make_rle_map(), and sum_hist().

int cb_list_size

Definition at line 161 of file mcut.c.

Referenced by break_box(), free_hist(), subdivide(), and sum_hist().

char* cmd_nm

Definition at line 169 of file mcut.c.

Referenced by sum_hist().

histogram_t* hist[32768]

Definition at line 167 of file mcut.c.

Referenced by free_hist(), re_expand_map(), and sum_hist().

int hist_size

Definition at line 168 of file mcut.c.

Referenced by re_expand_map(), and sum_hist().

rle_hdr in_hdr

Definition at line 164 of file mcut.c.

unsigned mask
static

Definition at line 162 of file mcut.c.

int max_colors = 200

Definition at line 166 of file mcut.c.

Referenced by subdivide().

rle_hdr out_hdr

Definition at line 164 of file mcut.c.

short out_map[3][256]

Definition at line 163 of file mcut.c.

Referenced by make_rle_map().