--- ray/src/common/color.c 1989/10/20 20:35:22 1.8 +++ ray/src/common/color.c 1990/09/22 10:45:42 1.12 @@ -14,145 +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 - - -fputresolu(ord, xres, yres, fp) /* put x and y resolution */ -register int ord; -int xres, yres; -FILE *fp; -{ - if (ord&YMAJOR) - fprintf(fp, "%cY %d %cX %d\n", - ord&YDECR ? '-' : '+', yres, - ord&XDECR ? '-' : '+', xres); - else - fprintf(fp, "%cX %d %cY %d\n", - ord&XDECR ? '-' : '+', xres, - ord&YDECR ? '-' : '+', yres); -} - - -fgetresolu(xrp, yrp, fp) /* get x and y resolution */ -int *xrp, *yrp; -FILE *fp; -{ - char buf[64], *xndx, *yndx; - register char *cp; - register int ord; - - if (fgets(buf, sizeof(buf), fp) == NULL) - return(-1); - xndx = yndx = NULL; - for (cp = buf+1; *cp; cp++) - if (*cp == 'X') - xndx = cp; - else if (*cp == 'Y') - yndx = cp; - if (xndx == NULL || yndx == NULL) - return(-1); - ord = 0; - if (xndx > yndx) ord |= YMAJOR; - if (xndx[-1] == '-') ord |= XDECR; - if (yndx[-1] == '-') ord |= YDECR; - if ((*xrp = atoi(xndx+1)) <= 0) - return(-1); - if ((*yrp = atoi(yndx+1)) <= 0) - return(-1); - return(ord); -} - - fwritecolrs(scanline, len, fp) /* write out a colr scanline */ register COLR *scanline; int len; @@ -367,40 +229,43 @@ register COLR clr; } -normcolrs(scan, len) /* normalize a scanline of colrs */ +normcolrs(scan, len, adjust) /* normalize a scanline of colrs */ register COLR *scan; int len; +int adjust; { register int c; register int shift; while (len-- > 0) { - shift = scan[0][EXP] - COLXS; + shift = scan[0][EXP] + adjust - COLXS; if (shift > 0) { - if (shift >= 8) { + if (shift > 8) { scan[0][RED] = scan[0][GRN] = scan[0][BLU] = 255; } else { - c = scan[0][RED] << shift; + shift--; + c = (scan[0][RED]<<1 | 1) << shift; scan[0][RED] = c > 255 ? 255 : c; - c = scan[0][GRN] << shift; + c = (scan[0][GRN]<<1 | 1) << shift; scan[0][GRN] = c > 255 ? 255 : c; - c = scan[0][BLU] << shift; + c = (scan[0][BLU]<<1 | 1) << shift; scan[0][BLU] = c > 255 ? 255 : c; } } else if (shift < 0) { - if (shift <= -8) { + if (shift < -8) { scan[0][RED] = scan[0][GRN] = scan[0][BLU] = 0; } else { - scan[0][RED] = scan[0][RED] >> -shift; - scan[0][GRN] = scan[0][GRN] >> -shift; - scan[0][BLU] = scan[0][BLU] >> -shift; + 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; + scan[0][EXP] = COLXS - adjust; scan++; } }