--- ray/src/px/clrtab.c 1992/10/13 11:36:20 2.3 +++ ray/src/px/clrtab.c 2003/02/22 02:07:27 2.12 @@ -1,9 +1,6 @@ -/* Copyright (c) 1992 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: clrtab.c,v 2.12 2003/02/22 02:07:27 greg Exp $"; #endif - /* * Simple median-cut color quantization based on colortab.c */ @@ -23,7 +20,7 @@ static char SCCSid[] = "$SunId$ LBL"; #define part(cn) ((cn)>>2) #define prim(cn) ((cn)&3) /* our color table (global) */ -BYTE clrtab[256][3]; +extern BYTE clrtab[256][3]; /* histogram of colors / color assignments */ static unsigned histo[NRED][NGRN][NBLU]; #define cndx(c) histo[((c)[RED]*NRED)>>8][((c)[GRN]*NGRN)>>8][((c)[BLU]*NBLU)>>8] @@ -32,12 +29,24 @@ static int CLRCUBE[3][2] = {0,NRED,0,NGRN,0,NBLU}; /* maximum propagated error during dithering */ #define MAXERR 20 /* define CLOSEST to get closest colors */ -#define CLOSEST 1 +#ifndef CLOSEST +#ifdef SPEED +#if SPEED > 8 +#define CLOSEST 1 /* this step takes a little longer */ +#endif +#endif +#endif +static cut(), mktabent(), closest(), addneigh(), setclosest(); +static int split(); +static unsigned dist(); -new_histo() /* clear our histogram */ + +new_histo(n) /* clear our histogram */ +int n; { bzero((char *)histo, sizeof(histo)); + return(0); } @@ -71,6 +80,8 @@ int ncolors; #ifdef CLOSEST closest(ncolors); /* ensure colors picked are closest */ #endif + /* reset dithering function */ + dith_colrs((BYTE *)NULL, (COLR *)NULL, 0); /* return new color table size */ return(ncolors); } @@ -101,16 +112,17 @@ register BYTE *bs; register COLR *cs; int n; { - static short (*cerr)[3]; + static short (*cerr)[3] = NULL; static int N = 0; int err[3], errp[3]; register int x, i; if (n != N) { /* get error propogation array */ - if (N) - cerr = (short (*)[3])realloc((char *)cerr, - 3*n*sizeof(short)); - else + if (N) { + free((void *)cerr); + cerr = NULL; + } + if (n) cerr = (short (*)[3])malloc(3*n*sizeof(short)); if (cerr == NULL) { N = 0; @@ -175,7 +187,7 @@ register int box[3][2]; #define c0 r register int r, g, b; int pri; - int t[HMAX], med; + long t[HMAX], med; /* find dominant axis */ pri = RED; if (box[GRN][1]-box[GRN][0] > box[pri][1]-box[pri][0]) @@ -231,9 +243,10 @@ mktabent(p, box) /* compute average color for box and int p; register int box[3][2]; { - long sum[3]; - int r, g, n; - register int b, c; + unsigned long sum[3]; + unsigned r, g; + unsigned long n; + register unsigned b, c; /* sum pixels in box */ n = 0; sum[RED] = sum[GRN] = sum[BLU] = 0; @@ -248,6 +261,12 @@ register int box[3][2]; } histo[r][g][b] = p; /* assign pixel */ } + if (n >= (1L<<23)/HMAX) { /* avoid overflow */ + sum[RED] /= n; + sum[GRN] /= n; + sum[BLU] /= n; + n = 1; + } if (n) { /* compute average */ clrtab[p][RED] = sum[RED]*256/NRED/n; clrtab[p][GRN] = sum[GRN]*256/NGRN/n; @@ -335,7 +354,7 @@ dist(col, r, g, b) /* find distance from clrtab entry register BYTE col[3]; int r, g, b; { - register unsigned tmp; + register int tmp; register unsigned sum; tmp = col[RED]*NRED/256 - r;