--- ray/src/rt/colortab.c 1989/10/04 09:23:38 1.6 +++ ray/src/rt/colortab.c 2004/03/30 16:13:01 2.9 @@ -1,9 +1,6 @@ -/* Copyright (c) 1989 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: colortab.c,v 2.9 2004/03/30 16:13:01 schorsch Exp $"; #endif - /* * colortab.c - allocate and control dynamic color table. * @@ -14,11 +11,18 @@ static char SCCSid[] = "$SunId$ LBL"; * histogram is cleared. This algorithm * performs only as well as the next drawing's color * distribution is correlated to the last. + * + * External symbols declared in drvier.h */ +#include "copyright.h" + +#include + +#include "standard.h" #include "color.h" +#include "driver.h" -#define NULL 0 /* histogram resolution */ #define NRED 24 #define NGRN 32 @@ -28,15 +32,14 @@ static char SCCSid[] = "$SunId$ LBL"; #define MINSAMP 7 /* maximum distance^2 before color reassign */ #define MAXDST2 12 - /* maximum frame buffer depth */ -#define FBDEPTH 8 /* map a color */ #define map_col(c,p) clrmap[p][ colval(c,p)<1. ? \ (int)(colval(c,p)*256.) : 255 ] /* color partition tree */ #define CNODE short -#define set_branch(p,c) ((c)<<2|(p)) +#define set_branch(p,c) ((c)<<2|(p)) #define set_pval(pv) ((pv)<<2|3) +#define is_branch(cn) (((cn)&3)!=3) #define is_pval(cn) (((cn)&3)==3) #define part(cn) ((cn)>>2) #define prim(cn) ((cn)&3) @@ -44,46 +47,61 @@ static char SCCSid[] = "$SunId$ LBL"; /* our color table */ static struct tabent { long sum[3]; /* sum of colors using this entry */ - long n; /* number of colors */ - short ent[3]; /* current table value */ -} clrtab[1< 1< 0; h--) { - if (is_pval(*p.t)) - break; - if (cv[prim(*p.t)] < part(*p.t)) - p.t++; /* left branch */ + for (tp = ctree, h = 0; is_branch(*tp); h++) + if (cv[prim(*tp)] < part(*tp)) + tp += 1<sum[RED] += r; - p.e->sum[GRN] += g; - p.e->sum[BLU] += b; - p.e->n++; + clrtab[h].sum[RED] += r; + clrtab[h].sum[GRN] += g; + clrtab[h].sum[BLU] += b; + clrtab[h].n++; /* recompute average */ - r = p.e->sum[RED] / p.e->n; - g = p.e->sum[GRN] / p.e->n; - b = p.e->sum[BLU] / p.e->n; + r = clrtab[h].sum[RED] / clrtab[h].n; + g = clrtab[h].sum[GRN] / clrtab[h].n; + b = clrtab[h].sum[BLU] / clrtab[h].n; /* check for movement */ - if (p.e->n == 1 || - (r-p.e->ent[RED])*(r-p.e->ent[RED]) + - (g-p.e->ent[GRN])*(g-p.e->ent[GRN]) + - (b-p.e->ent[BLU])*(b-p.e->ent[BLU]) > MAXDST2) { - p.e->ent[RED] = r; - p.e->ent[GRN] = g; /* reassign pixel */ - p.e->ent[BLU] = b; -#ifdef notdef - printf("pixel %d = (%d,%d,%d) (%d refs)\n", - h, r, g, b, p.e->n); + if (clrtab[h].n == 1 || + (r-clrtab[h].ent[RED])*(r-clrtab[h].ent[RED]) + + (g-clrtab[h].ent[GRN])*(g-clrtab[h].ent[GRN]) + + (b-clrtab[h].ent[BLU])*(b-clrtab[h].ent[BLU]) > MAXDST2) { + clrtab[h].ent[RED] = r; + clrtab[h].ent[GRN] = g; /* reassign pixel */ + clrtab[h].ent[BLU] = b; +#ifdef DEBUG + sprintf(errmsg, "pixel %d = (%d,%d,%d) (%d refs)\n", + h, r, g, b, clrtab[h].n); + eputs(errmsg); #endif - (*set_pixel)(h, r, g, b); + (*newcolr)(h, r, g, b); } return(h); /* return pixel value */ } +void make_gmap(gam) /* make gamma correction map */ -double gam; +double gam; { - extern double pow(); register int i; for (i = 0; i < 256; i++) clrmap[RED][i] = clrmap[GRN][i] = - clrmap[BLU][i] = 256.0 * pow(i/256.0, 1.0/gam); + clrmap[BLU][i] = 256.0 * pow((i+0.5)/256.0, 1.0/gam); } +void set_cmap(rmap, gmap, bmap) /* set custom color correction map */ BYTE *rmap, *gmap, *bmap; { - bcopy(rmap, clrmap[RED], 256); - bcopy(gmap, clrmap[GRN], 256); - bcopy(bmap, clrmap[BLU], 256); + memcpy((void *)clrmap[RED], (void *)rmap, 256); + memcpy((void *)clrmap[GRN], (void *)gmap, 256); + memcpy((void *)clrmap[BLU], (void *)bmap, 256); } -static -cut(tree, height, box, c0, c1) /* partition color space */ +void +map_color(rgb, col) /* map a color to a byte triplet */ +BYTE rgb[3]; +COLOR col; +{ + rgb[RED] = map_col(col,RED); + rgb[GRN] = map_col(col,GRN); + rgb[BLU] = map_col(col,BLU); +} + + +static void +cut(tree, level, box, c0, c1) /* partition color space */ register CNODE *tree; -int height; +int level; register int box[3][2]; int c0, c1; { @@ -172,14 +197,14 @@ int c0, c1; } /* split box */ *tree = split(box); - bcopy(box, kb, sizeof(kb)); + memcpy((void *)kb, (void *)box, sizeof(kb)); /* do left (lesser) branch */ kb[prim(*tree)][1] = part(*tree); - cut(tree+1, height-1, kb, c0, (c0+c1)>>1); + cut(tree+(1<>1); /* do right branch */ kb[prim(*tree)][0] = part(*tree); kb[prim(*tree)][1] = box[prim(*tree)][1]; - cut(tree+(1<>1, c1); + cut(tree+(1<<(level+1)), level+1, kb, (c0+c1)>>1, c1); } @@ -190,7 +215,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])