--- ray/src/px/closest.c 1989/02/02 14:10:34 1.2 +++ ray/src/px/closest.c 2004/03/28 20:33:13 2.4 @@ -1,9 +1,6 @@ -/* Copyright 1988 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: closest.c,v 2.4 2004/03/28 20:33:13 schorsch Exp $"; #endif - /* CLOSEST - nearest-color lookup by locally ordered search we use distance in rgb space as color metric @@ -15,40 +12,54 @@ About 6 times faster than exhaustive. Paul Heckbert */ +#include + #include "ciq.h" #define inf 3*256*256 -#define key ((r&0xe0)<<1|(g&0xe0)>>2|(b&0xe0)>>5) /* hash key: rrrgggbbb */ +#define key(r,g,b) (((r)&0xe0)<<1|((g)&0xe0)>>2|((b)&0xe0)>>5) + /* 9-bit hash key: rrrgggbbb */ -static struct thing {int mindist,pv;} space[512*257],*next=space,*bucket[512]; +static struct thing {int mindist,pv;} space[512*257],*next,*bucket[512]; /* sorted lists of colors */ -static int nfill=0,tests=0,calls=0; +static int nfill,tests,calls; static char filled[512]; /* has bucket[key] been filled yet? */ static int sq[511]; -initialize() { /* reset the buckets */ +static int compare(const void *a, const void *b); +static void fillbucket(int k); + + +void +initializeclosest(void) { /* reset the buckets */ int k; nfill = tests = calls = 0; for (k=0; k<512; k++) filled[k] = 0; next = space; } -closest(r,g,b) /* find pv of colormap color closest to (r,g,b) */ -int r,g,b; +int +closest( /* find pv of colormap color closest to (r,g,b) */ + int r, + int g, + int b +) { register struct thing *p; - register int *rsq,*gsq,*bsq,dist,min,best; + register int *rsq,*gsq,*bsq,dist,min; + int best,k; struct thing *p0; - if (!filled[key]) fillbucket(key); + k = key(r,g,b); + if (!filled[k]) fillbucket(k); min = inf; rsq = sq+255-r; gsq = sq+255-g; bsq = sq+255-b; /* stop looking when best is closer than next could be */ - for (p0=p=bucket[key]; min>p->mindist; p++) { + for (p0=p=bucket[k]; min>p->mindist; p++) { dist = rsq[color[0][p->pv]] + gsq[color[1][p->pv]] + bsq[color[2][p->pv]]; if (distmindist-b->mindist; + return ((struct thing*)a)->mindist - ((struct thing*)b)->mindist; } -fillbucket(k) /* make list of colormap colors which could be closest */ -int k; /* matches for colors in bucket #k */ +static void +fillbucket( /* make list of colormap colors which could be closest */ + int k /* matches for colors in bucket #k */ +) { register int r,g,b,j,dist,*rsq,*gsq,*bsq,min,best; struct thing *p,*q; if (!sq[0]) for (j= -255; j<256; j++) sq[j+255] = j*j; - r = k>>1&0xe0|H; /* center of 32x32x32 cubical bucket */ - g = k<<2&0xe0|H; - b = k<<5&0xe0|H; + r = (k>>1&0xe0)|H; /* center of 32x32x32 cubical bucket */ + g = (k<<2&0xe0)|H; + b = (k<<5&0xe0)|H; rsq = sq+255-r; gsq = sq+255-g; bsq = sq+255-b;