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 2.4 by greg, Thu Jul 7 15:21:25 1994 UTC vs.
Revision 2.9 by greg, Thu Apr 17 15:42:02 1997 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1990 Regents of the University of California */
1 > /* Copyright (c) 1997 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 10 | 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 39 | Line 45 | static BYTE  chroma[3][NINC] = {
45          }
46   };
47  
48 < static float  xyz2rgbmat[3][3] = {      /* XYZ to RGB */
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},
# Line 51 | Line 57 | static float  xyz2rgbmat[3][3] = {     /* XYZ to RGB */
57           (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r)/CIE_C_bD}
58   };
59  
60 < static float  rgb2xyzmat[3][3] = {      /* RGB to XYZ */
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,
# Line 84 | Line 90 | int  s, e;             /* starting and ending wavelengths */
90  
91          e -= STARTWL;
92          if (e <= s) {
93 <                col[RED] = col[GRN] = col[BLU] = 0.0;
93 >                col[CIEX] = col[CIEY] = col[CIEZ] = 0.0;
94                  return;
95          }
96          if (e >= INCWL*(NINC - 1))
# Line 100 | 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 */
116 < register COLOR  rgbcolor, ciecolor;
115 > cie_rgb(rgb, xyz)               /* convert CIE color to standard RGB */
116 > COLOR   rgb, xyz;
117   {
118 <        register int  i;
118 >        colortrans(rgb, xyz2rgbmat, xyz);
119 >        clipgamut(rgb, xyz[CIEY], CGAMUT_LOWER, cblack, cwhite);
120 > }
121  
122 <        for (i = 0; i < 3; i++) {
123 <                rgbcolor[i] =   xyz2rgbmat[i][0]*ciecolor[0] +
124 <                                xyz2rgbmat[i][1]*ciecolor[1] +
125 <                                xyz2rgbmat[i][2]*ciecolor[2] ;
126 <                if (rgbcolor[i] < 0.0)
127 <                        rgbcolor[i] = 0.0;
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  
169 < rgb_cie(ciecolor, rgbcolor)             /* convert RGB to CIE */
170 < register COLOR  ciecolor, rgbcolor;
169 > colortrans(c2, mat, c1)         /* convert c1 by mat and put into c2 */
170 > register COLORMAT  mat;
171 > register COLOR  c1, c2;
172   {
173 <        register int  i;
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 <                ciecolor[i] =   rgb2xyzmat[i][0]*rgbcolor[0] +
191 <                                rgb2xyzmat[i][1]*rgbcolor[1] +
192 <                                rgb2xyzmat[i][2]*rgbcolor[2] ;
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