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.8 by greg, Fri Jan 31 12:58:39 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 >        c2[0] = mat[0][0]*c1[0] + mat[0][1]*c1[1] + mat[0][2]*c1[2];
174 >        c2[1] = mat[1][0]*c1[0] + mat[1][1]*c1[1] + mat[1][2]*c1[2];
175 >        c2[2] = mat[2][0]*c1[0] + mat[2][1]*c1[1] + mat[2][2]*c1[2];
176 > }
177  
178 +
179 + multcolormat(m3, m2, m1)        /* multiply m1 by m2 and put into m3 */
180 + COLORMAT  m1, m2, m3;           /* m3 can be either m1 or m2 w/o harm */
181 + {
182 +        COLORMAT  mt;
183 +        register int  i, j;
184 +
185          for (i = 0; i < 3; i++)
186 <                ciecolor[i] =   rgb2xyzmat[i][0]*rgbcolor[0] +
187 <                                rgb2xyzmat[i][1]*rgbcolor[1] +
188 <                                rgb2xyzmat[i][2]*rgbcolor[2] ;
186 >                for (j = 0; j < 3; j++)
187 >                        mt[i][j] =      m1[i][0]*m2[0][j] +
188 >                                        m1[i][1]*m2[1][j] +
189 >                                        m1[i][2]*m2[2][j] ;
190 >        cpcolormat(m3, mt);
191 > }
192 >
193 >
194 > compxyz2rgbmat(mat, pr)         /* compute conversion from CIE to RGB space */
195 > COLORMAT  mat;
196 > register RGBPRIMS  pr;
197 > {
198 >        double  C_rD, C_gD, C_bD;
199 >
200 >        if (pr == stdprims) {   /* can use xyz2rgbmat */
201 >                cpcolormat(mat, xyz2rgbmat);
202 >                return;
203 >        }
204 >        C_rD = (1./pr[WHT][CIEY]) *
205 >                        ( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) -
206 >                          pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) +
207 >                  pr[GRN][CIEX]*pr[BLU][CIEY] - pr[BLU][CIEX]*pr[GRN][CIEY] ) ;
208 >        C_gD = (1./pr[WHT][CIEY]) *
209 >                        ( pr[WHT][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) -
210 >                          pr[WHT][CIEY]*(pr[BLU][CIEX] - pr[RED][CIEX]) -
211 >                  pr[RED][CIEX]*pr[BLU][CIEY] + pr[BLU][CIEX]*pr[RED][CIEY] ) ;
212 >        C_bD = (1./pr[WHT][CIEY]) *
213 >                        ( pr[WHT][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) -
214 >                          pr[WHT][CIEY]*(pr[RED][CIEX] - pr[GRN][CIEX]) +
215 >                  pr[RED][CIEX]*pr[GRN][CIEY] - pr[GRN][CIEX]*pr[RED][CIEY] ) ;
216 >
217 >        mat[0][0] = (pr[GRN][CIEY] - pr[BLU][CIEY] -
218 >                        pr[BLU][CIEX]*pr[GRN][CIEY] +
219 >                        pr[BLU][CIEY]*pr[GRN][CIEX])/C_rD ;
220 >        mat[0][1] = (pr[BLU][CIEX] - pr[GRN][CIEX] -
221 >                        pr[BLU][CIEX]*pr[GRN][CIEY] +
222 >                        pr[GRN][CIEX]*pr[BLU][CIEY])/C_rD ;
223 >        mat[0][2] = (pr[GRN][CIEX]*pr[BLU][CIEY] -
224 >                        pr[BLU][CIEX]*pr[GRN][CIEY])/C_rD ;
225 >        mat[1][0] = (pr[BLU][CIEY] - pr[RED][CIEY] -
226 >                        pr[BLU][CIEY]*pr[RED][CIEX] +
227 >                        pr[RED][CIEY]*pr[BLU][CIEX])/C_gD ;
228 >        mat[1][1] = (pr[RED][CIEX] - pr[BLU][CIEX] -
229 >                        pr[RED][CIEX]*pr[BLU][CIEY] +
230 >                        pr[BLU][CIEX]*pr[RED][CIEY])/C_gD ;
231 >        mat[1][2] = (pr[BLU][CIEX]*pr[RED][CIEY] -
232 >                        pr[RED][CIEX]*pr[BLU][CIEY])/C_gD ;
233 >        mat[2][0] = (pr[RED][CIEY] - pr[GRN][CIEY] -
234 >                        pr[RED][CIEY]*pr[GRN][CIEX] +
235 >                        pr[GRN][CIEY]*pr[RED][CIEX])/C_bD ;
236 >        mat[2][1] = (pr[GRN][CIEX] - pr[RED][CIEX] -
237 >                        pr[GRN][CIEX]*pr[RED][CIEY] +
238 >                        pr[RED][CIEX]*pr[GRN][CIEY])/C_bD ;
239 >        mat[2][2] = (pr[RED][CIEX]*pr[GRN][CIEY] -
240 >                        pr[GRN][CIEX]*pr[RED][CIEY])/C_bD ;
241 > }
242 >
243 >
244 > comprgb2xyzmat(mat, pr)         /* compute conversion from RGB to CIE space */
245 > COLORMAT  mat;
246 > register RGBPRIMS  pr;
247 > {
248 >        double  C_rD, C_gD, C_bD, D;
249 >
250 >        if (pr == stdprims) {   /* can use rgb2xyzmat */
251 >                cpcolormat(mat, rgb2xyzmat);
252 >                return;
253 >        }
254 >        C_rD = (1./pr[WHT][CIEY]) *
255 >                        ( pr[WHT][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) -
256 >                          pr[WHT][CIEY]*(pr[GRN][CIEX] - pr[BLU][CIEX]) +
257 >                  pr[GRN][CIEX]*pr[BLU][CIEY] - pr[BLU][CIEX]*pr[GRN][CIEY] ) ;
258 >        C_gD = (1./pr[WHT][CIEY]) *
259 >                        ( pr[WHT][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) -
260 >                          pr[WHT][CIEY]*(pr[BLU][CIEX] - pr[RED][CIEX]) -
261 >                  pr[RED][CIEX]*pr[BLU][CIEY] + pr[BLU][CIEX]*pr[RED][CIEY] ) ;
262 >        C_bD = (1./pr[WHT][CIEY]) *
263 >                        ( pr[WHT][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) -
264 >                          pr[WHT][CIEY]*(pr[RED][CIEX] - pr[GRN][CIEX]) +
265 >                  pr[RED][CIEX]*pr[GRN][CIEY] - pr[GRN][CIEX]*pr[RED][CIEY] ) ;
266 >        D = pr[RED][CIEX]*(pr[GRN][CIEY] - pr[BLU][CIEY]) +
267 >                        pr[GRN][CIEX]*(pr[BLU][CIEY] - pr[RED][CIEY]) +
268 >                        pr[BLU][CIEX]*(pr[RED][CIEY] - pr[GRN][CIEY]) ;
269 >        mat[0][0] = pr[RED][CIEX]*C_rD/D;
270 >        mat[0][1] = pr[GRN][CIEX]*C_gD/D;
271 >        mat[0][2] = pr[BLU][CIEX]*C_bD/D;
272 >        mat[1][0] = pr[RED][CIEY]*C_rD/D;
273 >        mat[1][1] = pr[GRN][CIEY]*C_gD/D;
274 >        mat[1][2] = pr[BLU][CIEY]*C_bD/D;
275 >        mat[2][0] = (1.-pr[RED][CIEX]-pr[RED][CIEY])*C_rD/D;
276 >        mat[2][1] = (1.-pr[GRN][CIEX]-pr[GRN][CIEY])*C_gD/D;
277 >        mat[2][2] = (1.-pr[BLU][CIEX]-pr[BLU][CIEY])*C_bD/D;
278 > }
279 >
280 >
281 > comprgb2rgbmat(mat, pr1, pr2)   /* compute conversion from RGB1 to RGB2 */
282 > COLORMAT  mat;
283 > RGBPRIMS  pr1, pr2;
284 > {
285 >        COLORMAT  pr1toxyz, xyztopr2;
286 >
287 >        if (pr1 == pr2) {
288 >                mat[0][0] = mat[1][1] = mat[2][2] = 1.0;
289 >                mat[0][1] = mat[0][2] = mat[1][0] =
290 >                mat[1][2] = mat[2][0] = mat[2][1] = 0.0;
291 >                return;
292 >        }
293 >        comprgb2xyzmat(pr1toxyz, pr1);
294 >        compxyz2rgbmat(xyztopr2, pr2);
295 >                                /* combine transforms */
296 >        multcolormat(mat, pr1toxyz, xyztopr2);
297   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines