--- ray/src/common/color.c 1989/03/15 13:48:37 1.2 +++ ray/src/common/color.c 1990/09/22 10:45:42 1.12 @@ -14,99 +14,7 @@ static char SCCSid[] = "$SunId$ LBL"; #include "color.h" -#ifdef SPEC_RGB -/* - * The following table contains the CIE tristimulus integrals - * for X, Y, and Z. The table is cumulative, so that - * each color coordinate integrates to 1. - */ -#define STARTWL 380 /* starting wavelength (nanometers) */ -#define INCWL 10 /* wavelength increment */ -#define NINC 40 /* # of values */ - -static BYTE chroma[3][NINC] = { - { /* X */ - 0, 0, 0, 2, 6, 13, 22, 30, 36, 41, - 42, 43, 43, 44, 46, 52, 60, 71, 87, 106, - 128, 153, 178, 200, 219, 233, 243, 249, 252, 254, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - }, { /* Y */ - 0, 0, 0, 0, 0, 1, 2, 4, 7, 11, - 17, 24, 34, 48, 64, 84, 105, 127, 148, 169, - 188, 205, 220, 232, 240, 246, 250, 253, 254, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - }, { /* Z */ - 0, 0, 2, 10, 32, 66, 118, 153, 191, 220, - 237, 246, 251, 253, 254, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 - } -}; - - -spec_rgb(col, s, e) /* comput RGB color from spectral range */ -COLOR col; -int s, e; -{ - COLOR ciecolor; - - spec_cie(ciecolor, s, e); - cie_rgb(col, ciecolor); -} - - -spec_cie(col, s, e) /* compute a color from a spectral range */ -COLOR col; /* returned color */ -int s, e; /* starting and ending wavelengths */ -{ - register int i, d, r; - - s -= STARTWL; - if (s < 0) - s = 0; - - e -= STARTWL; - if (e >= INCWL*(NINC - 1)) - e = INCWL*(NINC - 1) - 1; - - d = e / INCWL; /* interpolate values */ - r = e % INCWL; - for (i = 0; i < 3; i++) - col[i] = chroma[i][d]*(INCWL - r) + chroma[i][d + 1]*r; - - d = s / INCWL; - r = s % INCWL; - for (i = 0; i < 3; i++) - col[i] -= chroma[i][d]*(INCWL - r) - chroma[i][d + 1]*r; - - col[RED] = (col[RED] + 0.5) / (256*INCWL); - col[GRN] = (col[GRN] + 0.5) / (256*INCWL); - col[BLU] = (col[BLU] + 0.5) / (256*INCWL); -} - - -cie_rgb(rgbcolor, ciecolor) /* convert CIE to RGB (NTSC) */ -register COLOR rgbcolor, ciecolor; -{ - static float cmat[3][3] = { - 1.73, -.48, -.26, - -.81, 1.65, -.02, - .08, -.17, 1.28, - }; - register int i; - - for (i = 0; i < 3; i++) { - rgbcolor[i] = cmat[i][0]*ciecolor[0] + - cmat[i][1]*ciecolor[1] + - cmat[i][2]*ciecolor[2] ; - if (rgbcolor[i] < 0.0) - rgbcolor[i] = 0.0; - } -} -#endif - - fwritecolrs(scanline, len, fp) /* write out a colr scanline */ register COLR *scanline; int len; @@ -289,7 +197,7 @@ double r, g, b; d = r > g ? r : g; if (b > d) d = b; - if (d <= 0.0) { + if (d <= 1e-32) { clr[RED] = clr[GRN] = clr[BLU] = 0; clr[EXP] = 0; return; @@ -308,7 +216,7 @@ colr_color(col, clr) /* convert short to float color register COLOR col; register COLR clr; { - double ldexp(), f; + double f; if (clr[EXP] == 0) col[RED] = col[GRN] = col[BLU] = 0.0; @@ -321,31 +229,57 @@ register COLR clr; } -#ifdef FREXP -double -frexp(x, ip) /* call it paranoia, I've seen the lib version */ -register double x; -int *ip; +normcolrs(scan, len, adjust) /* normalize a scanline of colrs */ +register COLR *scan; +int len; +int adjust; { - int neg; - register int i; + register int c; + register int shift; - if (neg = (x < 0.0)) - x = -x; - else if (x == 0.0) { - *ip = 0; - return(0.0); + while (len-- > 0) { + shift = scan[0][EXP] + adjust - COLXS; + if (shift > 0) { + if (shift > 8) { + scan[0][RED] = + scan[0][GRN] = + scan[0][BLU] = 255; + } else { + shift--; + c = (scan[0][RED]<<1 | 1) << shift; + scan[0][RED] = c > 255 ? 255 : c; + c = (scan[0][GRN]<<1 | 1) << shift; + scan[0][GRN] = c > 255 ? 255 : c; + c = (scan[0][BLU]<<1 | 1) << shift; + scan[0][BLU] = c > 255 ? 255 : c; + } + } else if (shift < 0) { + if (shift < -8) { + scan[0][RED] = + scan[0][GRN] = + scan[0][BLU] = 0; + } else { + shift = -1-shift; + scan[0][RED] = ((scan[0][RED]>>shift)+1)>>1; + scan[0][GRN] = ((scan[0][GRN]>>shift)+1)>>1; + scan[0][BLU] = ((scan[0][BLU]>>shift)+1)>>1; + } + } + scan[0][EXP] = COLXS - adjust; + scan++; } - if (x < 0.5) - for (i = 0; x < 0.5; i--) - x *= 2.0; - else - for (i = 0; x >= 1.0; i++) - x /= 2.0; - *ip = i; - if (neg) - return(-x); - else - return(x); } -#endif + + +bigdiff(c1, c2, md) /* c1 delta c2 > md? */ +register COLOR c1, c2; +double md; +{ + register int i; + + for (i = 0; i < 3; i++) + if (colval(c1,i)-colval(c2,i) > md*colval(c2,i) || + colval(c2,i)-colval(c1,i) > md*colval(c1,i)) + return(1); + return(0); +}