ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/spec_rgb.c
(Generate patch)

Comparing ray/src/common/spec_rgb.c (file contents):
Revision 1.1 by greg, Sat Sep 22 10:44:56 1990 UTC vs.
Revision 2.9 by greg, Thu Apr 17 15:42:02 1997 UTC

# Line 1 | Line 1
1 + /* Copyright (c) 1997 Regents of the University of California */
2 +
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
5   #endif
# Line 8 | Line 10 | static char SCCSid[] = "$SunId$ LBL";
10  
11   #include "color.h"
12  
13 +
14 + RGBPRIMS  stdprims = STDPRIMS;          /* standard primary chromaticities */
15 +
16 + COLOR  cblack = BLKCOLOR;               /* global black color */
17 + COLOR  cwhite = WHTCOLOR;               /* global white color */
18 +
19   /*
20   *      The following table contains the CIE tristimulus integrals
21   *  for X, Y, and Z.  The table is cumulative, so that
# Line 37 | Line 45 | static BYTE  chroma[3][NINC] = {
45          }
46   };
47  
48 + COLORMAT  xyz2rgbmat = {                /* XYZ to RGB */
49 +        {(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g)/CIE_C_rD,
50 +         (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b)/CIE_C_rD,
51 +         (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g)/CIE_C_rD},
52 +        {(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b)/CIE_C_gD,
53 +         (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r)/CIE_C_gD,
54 +         (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b)/CIE_C_gD},
55 +        {(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r)/CIE_C_bD,
56 +         (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g)/CIE_C_bD,
57 +         (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r)/CIE_C_bD}
58 + };
59  
60 + COLORMAT  rgb2xyzmat = {                /* RGB to XYZ */
61 +        {CIE_x_r*CIE_C_rD/CIE_D,CIE_x_g*CIE_C_gD/CIE_D,CIE_x_b*CIE_C_bD/CIE_D},
62 +        {CIE_y_r*CIE_C_rD/CIE_D,CIE_y_g*CIE_C_gD/CIE_D,CIE_y_b*CIE_C_bD/CIE_D},
63 +        {(1.-CIE_x_r-CIE_y_r)*CIE_C_rD/CIE_D,
64 +         (1.-CIE_x_g-CIE_y_g)*CIE_C_gD/CIE_D,
65 +         (1.-CIE_x_b-CIE_y_b)*CIE_C_bD/CIE_D}
66 + };
67 +
68 +
69 +
70   spec_rgb(col, s, e)             /* compute RGB color from spectral range */
71   COLOR  col;
72   int  s, e;
# Line 60 | Line 89 | int  s, e;             /* starting and ending wavelengths */
89                  s = 0;
90  
91          e -= STARTWL;
92 +        if (e <= s) {
93 +                col[CIEX] = col[CIEY] = col[CIEZ] = 0.0;
94 +                return;
95 +        }
96          if (e >= INCWL*(NINC - 1))
97                  e = INCWL*(NINC - 1) - 1;
98  
# Line 73 | Line 106 | int  s, e;             /* starting and ending wavelengths */
106          for (i = 0; i < 3; i++)
107                  col[i] -= chroma[i][d]*(INCWL - r) - chroma[i][d + 1]*r;
108  
109 <        col[RED] = (col[RED] + 0.5) / (256*INCWL);
110 <        col[GRN] = (col[GRN] + 0.5) / (256*INCWL);
111 <        col[BLU] = (col[BLU] + 0.5) / (256*INCWL);
109 >        col[CIEX] = (col[CIEX] + 0.5) * (1./(256*INCWL));
110 >        col[CIEY] = (col[CIEY] + 0.5) * (1./(256*INCWL));
111 >        col[CIEZ] = (col[CIEZ] + 0.5) * (1./(256*INCWL));
112   }
113  
114  
115 < cie_rgb(rgbcolor, ciecolor)             /* convert CIE to RGB (NTSC) */
116 < register COLOR  rgbcolor, ciecolor;
115 > cie_rgb(rgb, xyz)               /* convert CIE color to standard RGB */
116 > COLOR   rgb, xyz;
117   {
118 <        static float  cmat[3][3] = {
119 <                1.73, -.48, -.26,
120 <                -.81, 1.65, -.02,
121 <                 .08, -.17, 1.28,
122 <        };
118 >        colortrans(rgb, xyz2rgbmat, xyz);
119 >        clipgamut(rgb, xyz[CIEY], CGAMUT_LOWER, cblack, cwhite);
120 > }
121 >
122 >
123 > int
124 > clipgamut(col, brt, gamut, lower, upper)        /* clip to gamut cube */
125 > COLOR  col;
126 > double  brt;
127 > int  gamut;
128 > COLOR  lower, upper;
129 > {
130 >        int  rflags = 0;
131 >        double  brtmin, brtmax, v, vv;
132 >        COLOR  cgry;
133          register int  i;
134 +                                        /* check for no check */
135 +        if (gamut == 0) return(0);
136 +                                        /* check brightness limits */
137 +        brtmin = 1./3.*(lower[0]+lower[1]+lower[2]);
138 +        if (gamut & CGAMUT_LOWER && brt < brtmin) {
139 +                copycolor(col, lower);
140 +                return(CGAMUT_LOWER);
141 +        }
142 +        brtmax = 1./3.*(upper[0]+upper[1]+upper[2]);
143 +        if (gamut & CGAMUT_UPPER && brt > brtmax) {
144 +                copycolor(col, upper);
145 +                return(CGAMUT_UPPER);
146 +        }
147 +                                        /* compute equivalent grey */
148 +        v = (brt - brtmin)/(brtmax - brtmin);
149 +        for (i = 0; i < 3; i++)
150 +                cgry[i] = v*upper[i] + (1.-v)*lower[i];
151 +        vv = 1.;                        /* check each limit */
152 +        for (i = 0; i < 3; i++)
153 +                if (gamut & CGAMUT_LOWER && col[i] < lower[i]) {
154 +                        v = (lower[i] - cgry[i])/(col[i] - cgry[i]);
155 +                        if (v < vv) vv = v;
156 +                        rflags |= CGAMUT_LOWER;
157 +                } else if (gamut & CGAMUT_UPPER && col[i] > upper[i]) {
158 +                        v = (upper[i] - cgry[i])/(col[i] - cgry[i]);
159 +                        if (v < vv) vv = v;
160 +                        rflags |= CGAMUT_UPPER;
161 +                }
162 +        if (rflags)                     /* desaturate to cube face */
163 +                for (i = 0; i < 3; i++)
164 +                        col[i] = vv*col[i] + (1.-vv)*cgry[i];
165 +        return(rflags);
166 + }
167  
168 <        for (i = 0; i < 3; i++) {
169 <                rgbcolor[i] =   cmat[i][0]*ciecolor[0] +
170 <                                cmat[i][1]*ciecolor[1] +
171 <                                cmat[i][2]*ciecolor[2] ;
172 <                if (rgbcolor[i] < 0.0)
173 <                        rgbcolor[i] = 0.0;
168 >
169 > colortrans(c2, mat, c1)         /* convert c1 by mat and put into c2 */
170 > register COLORMAT  mat;
171 > register COLOR  c1, c2;
172 > {
173 >        COLOR   cout;
174 >
175 >        cout[0] = mat[0][0]*c1[0] + mat[0][1]*c1[1] + mat[0][2]*c1[2];
176 >        cout[1] = mat[1][0]*c1[0] + mat[1][1]*c1[1] + mat[1][2]*c1[2];
177 >        cout[2] = mat[2][0]*c1[0] + mat[2][1]*c1[1] + mat[2][2]*c1[2];
178 >
179 >        copycolor(c2, cout);
180 > }
181 >
182 >
183 > multcolormat(m3, m2, m1)        /* multiply m1 by m2 and put into m3 */
184 > COLORMAT  m1, m2, m3;           /* m3 can be either m1 or m2 w/o harm */
185 > {
186 >        COLORMAT  mt;
187 >        register int  i, j;
188 >
189 >        for (i = 0; i < 3; i++)
190 >                for (j = 0; j < 3; j++)
191 >                        mt[i][j] =      m1[i][0]*m2[0][j] +
192 >                                        m1[i][1]*m2[1][j] +
193 >                                        m1[i][2]*m2[2][j] ;
194 >        cpcolormat(m3, mt);
195 > }
196 >
197 >
198 > compxyz2rgbmat(mat, pr)         /* compute conversion from CIE to RGB space */
199 > COLORMAT  mat;
200 > register RGBPRIMS  pr;
201 > {
202 >        double  C_rD, C_gD, C_bD;
203 >
204 >        if (pr == stdprims) {   /* can use xyz2rgbmat */
205 >                cpcolormat(mat, xyz2rgbmat);
206 >                return;
207          }
208 +        C_rD = (1./pr[WHT][CIEY]) *
209 +                        ( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) -
210 +                          pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) +
211 +                  pr[GRN][CIEX]*pr[BLU][CIEY] - pr[BLU][CIEX]*pr[GRN][CIEY] ) ;
212 +        C_gD = (1./pr[WHT][CIEY]) *
213 +                        ( pr[WHT][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) -
214 +                          pr[WHT][CIEY]*(pr[BLU][CIEX] - pr[RED][CIEX]) -
215 +                  pr[RED][CIEX]*pr[BLU][CIEY] + pr[BLU][CIEX]*pr[RED][CIEY] ) ;
216 +        C_bD = (1./pr[WHT][CIEY]) *
217 +                        ( pr[WHT][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) -
218 +                          pr[WHT][CIEY]*(pr[RED][CIEX] - pr[GRN][CIEX]) +
219 +                  pr[RED][CIEX]*pr[GRN][CIEY] - pr[GRN][CIEX]*pr[RED][CIEY] ) ;
220 +
221 +        mat[0][0] = (pr[GRN][CIEY] - pr[BLU][CIEY] -
222 +                        pr[BLU][CIEX]*pr[GRN][CIEY] +
223 +                        pr[BLU][CIEY]*pr[GRN][CIEX])/C_rD ;
224 +        mat[0][1] = (pr[BLU][CIEX] - pr[GRN][CIEX] -
225 +                        pr[BLU][CIEX]*pr[GRN][CIEY] +
226 +                        pr[GRN][CIEX]*pr[BLU][CIEY])/C_rD ;
227 +        mat[0][2] = (pr[GRN][CIEX]*pr[BLU][CIEY] -
228 +                        pr[BLU][CIEX]*pr[GRN][CIEY])/C_rD ;
229 +        mat[1][0] = (pr[BLU][CIEY] - pr[RED][CIEY] -
230 +                        pr[BLU][CIEY]*pr[RED][CIEX] +
231 +                        pr[RED][CIEY]*pr[BLU][CIEX])/C_gD ;
232 +        mat[1][1] = (pr[RED][CIEX] - pr[BLU][CIEX] -
233 +                        pr[RED][CIEX]*pr[BLU][CIEY] +
234 +                        pr[BLU][CIEX]*pr[RED][CIEY])/C_gD ;
235 +        mat[1][2] = (pr[BLU][CIEX]*pr[RED][CIEY] -
236 +                        pr[RED][CIEX]*pr[BLU][CIEY])/C_gD ;
237 +        mat[2][0] = (pr[RED][CIEY] - pr[GRN][CIEY] -
238 +                        pr[RED][CIEY]*pr[GRN][CIEX] +
239 +                        pr[GRN][CIEY]*pr[RED][CIEX])/C_bD ;
240 +        mat[2][1] = (pr[GRN][CIEX] - pr[RED][CIEX] -
241 +                        pr[GRN][CIEX]*pr[RED][CIEY] +
242 +                        pr[RED][CIEX]*pr[GRN][CIEY])/C_bD ;
243 +        mat[2][2] = (pr[RED][CIEX]*pr[GRN][CIEY] -
244 +                        pr[GRN][CIEX]*pr[RED][CIEY])/C_bD ;
245 + }
246 +
247 +
248 + comprgb2xyzmat(mat, pr)         /* compute conversion from RGB to CIE space */
249 + COLORMAT  mat;
250 + register RGBPRIMS  pr;
251 + {
252 +        double  C_rD, C_gD, C_bD, D;
253 +
254 +        if (pr == stdprims) {   /* can use rgb2xyzmat */
255 +                cpcolormat(mat, rgb2xyzmat);
256 +                return;
257 +        }
258 +        C_rD = (1./pr[WHT][CIEY]) *
259 +                        ( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) -
260 +                          pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) +
261 +                  pr[GRN][CIEX]*pr[BLU][CIEY] - pr[BLU][CIEX]*pr[GRN][CIEY] ) ;
262 +        C_gD = (1./pr[WHT][CIEY]) *
263 +                        ( pr[WHT][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) -
264 +                          pr[WHT][CIEY]*(pr[BLU][CIEX] - pr[RED][CIEX]) -
265 +                  pr[RED][CIEX]*pr[BLU][CIEY] + pr[BLU][CIEX]*pr[RED][CIEY] ) ;
266 +        C_bD = (1./pr[WHT][CIEY]) *
267 +                        ( pr[WHT][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) -
268 +                          pr[WHT][CIEY]*(pr[RED][CIEX] - pr[GRN][CIEX]) +
269 +                  pr[RED][CIEX]*pr[GRN][CIEY] - pr[GRN][CIEX]*pr[RED][CIEY] ) ;
270 +        D = pr[RED][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) +
271 +                        pr[GRN][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) +
272 +                        pr[BLU][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) ;
273 +        mat[0][0] = pr[RED][CIEX]*C_rD/D;
274 +        mat[0][1] = pr[GRN][CIEX]*C_gD/D;
275 +        mat[0][2] = pr[BLU][CIEX]*C_bD/D;
276 +        mat[1][0] = pr[RED][CIEY]*C_rD/D;
277 +        mat[1][1] = pr[GRN][CIEY]*C_gD/D;
278 +        mat[1][2] = pr[BLU][CIEY]*C_bD/D;
279 +        mat[2][0] = (1.-pr[RED][CIEX]-pr[RED][CIEY])*C_rD/D;
280 +        mat[2][1] = (1.-pr[GRN][CIEX]-pr[GRN][CIEY])*C_gD/D;
281 +        mat[2][2] = (1.-pr[BLU][CIEX]-pr[BLU][CIEY])*C_bD/D;
282 + }
283 +
284 +
285 + comprgb2rgbmat(mat, pr1, pr2)   /* compute conversion from RGB1 to RGB2 */
286 + COLORMAT  mat;
287 + RGBPRIMS  pr1, pr2;
288 + {
289 +        COLORMAT  pr1toxyz, xyztopr2;
290 +
291 +        if (pr1 == pr2) {
292 +                mat[0][0] = mat[1][1] = mat[2][2] = 1.0;
293 +                mat[0][1] = mat[0][2] = mat[1][0] =
294 +                mat[1][2] = mat[2][0] = mat[2][1] = 0.0;
295 +                return;
296 +        }
297 +        comprgb2xyzmat(pr1toxyz, pr1);
298 +        compxyz2rgbmat(xyztopr2, pr2);
299 +                                /* combine transforms */
300 +        multcolormat(mat, pr1toxyz, xyztopr2);
301   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines