ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/spec_rgb.c
Revision: 2.4
Committed: Thu Jul 7 15:21:25 1994 UTC (29 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.3: +20 -0 lines
Log Message:
added rgb_cie() routine

File Contents

# User Rev Content
1 greg 1.2 /* Copyright (c) 1990 Regents of the University of California */
2    
3 greg 1.1 #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * Convert colors and spectral ranges.
9     */
10    
11     #include "color.h"
12    
13     /*
14     * The following table contains the CIE tristimulus integrals
15     * for X, Y, and Z. The table is cumulative, so that
16     * each color coordinate integrates to 1.
17     */
18    
19     #define STARTWL 380 /* starting wavelength (nanometers) */
20     #define INCWL 10 /* wavelength increment */
21     #define NINC 40 /* # of values */
22    
23     static BYTE chroma[3][NINC] = {
24     { /* X */
25     0, 0, 0, 2, 6, 13, 22, 30, 36, 41,
26     42, 43, 43, 44, 46, 52, 60, 71, 87, 106,
27     128, 153, 178, 200, 219, 233, 243, 249, 252, 254,
28     255, 255, 255, 255, 255, 255, 255, 255, 255, 255
29     }, { /* Y */
30     0, 0, 0, 0, 0, 1, 2, 4, 7, 11,
31     17, 24, 34, 48, 64, 84, 105, 127, 148, 169,
32     188, 205, 220, 232, 240, 246, 250, 253, 254, 255,
33     255, 255, 255, 255, 255, 255, 255, 255, 255, 255
34     }, { /* Z */
35     0, 0, 2, 10, 32, 66, 118, 153, 191, 220,
36     237, 246, 251, 253, 254, 255, 255, 255, 255, 255,
37     255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38     255, 255, 255, 255, 255, 255, 255, 255, 255, 255
39     }
40     };
41    
42 greg 2.3 static float xyz2rgbmat[3][3] = { /* XYZ to RGB */
43     {(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g)/CIE_C_rD,
44     (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b)/CIE_C_rD,
45     (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g)/CIE_C_rD},
46     {(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b)/CIE_C_gD,
47     (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r)/CIE_C_gD,
48     (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b)/CIE_C_gD},
49     {(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r)/CIE_C_bD,
50     (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g)/CIE_C_bD,
51     (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r)/CIE_C_bD}
52 greg 1.2 };
53 greg 1.1
54 greg 2.4 static float rgb2xyzmat[3][3] = { /* RGB to XYZ */
55     {CIE_x_r*CIE_C_rD/CIE_D,CIE_x_g*CIE_C_gD/CIE_D,CIE_x_b*CIE_C_bD/CIE_D},
56     {CIE_y_r*CIE_C_rD/CIE_D,CIE_y_g*CIE_C_gD/CIE_D,CIE_y_b*CIE_C_bD/CIE_D},
57     {(1.-CIE_x_r-CIE_y_r)*CIE_C_rD/CIE_D,
58     (1.-CIE_x_g-CIE_y_g)*CIE_C_gD/CIE_D,
59     (1.-CIE_x_b-CIE_y_b)*CIE_C_bD/CIE_D}
60     };
61 greg 1.2
62    
63 greg 2.4
64 greg 1.1 spec_rgb(col, s, e) /* compute RGB color from spectral range */
65     COLOR col;
66     int s, e;
67     {
68     COLOR ciecolor;
69    
70     spec_cie(ciecolor, s, e);
71     cie_rgb(col, ciecolor);
72     }
73    
74    
75     spec_cie(col, s, e) /* compute a color from a spectral range */
76     COLOR col; /* returned color */
77     int s, e; /* starting and ending wavelengths */
78     {
79     register int i, d, r;
80    
81     s -= STARTWL;
82     if (s < 0)
83     s = 0;
84    
85     e -= STARTWL;
86 greg 1.2 if (e <= s) {
87     col[RED] = col[GRN] = col[BLU] = 0.0;
88     return;
89     }
90 greg 1.1 if (e >= INCWL*(NINC - 1))
91     e = INCWL*(NINC - 1) - 1;
92    
93     d = e / INCWL; /* interpolate values */
94     r = e % INCWL;
95     for (i = 0; i < 3; i++)
96     col[i] = chroma[i][d]*(INCWL - r) + chroma[i][d + 1]*r;
97    
98     d = s / INCWL;
99     r = s % INCWL;
100     for (i = 0; i < 3; i++)
101     col[i] -= chroma[i][d]*(INCWL - r) - chroma[i][d + 1]*r;
102    
103     col[RED] = (col[RED] + 0.5) / (256*INCWL);
104     col[GRN] = (col[GRN] + 0.5) / (256*INCWL);
105     col[BLU] = (col[BLU] + 0.5) / (256*INCWL);
106     }
107    
108    
109 greg 1.3 cie_rgb(rgbcolor, ciecolor) /* convert CIE to RGB */
110 greg 1.1 register COLOR rgbcolor, ciecolor;
111     {
112     register int i;
113    
114     for (i = 0; i < 3; i++) {
115 greg 1.2 rgbcolor[i] = xyz2rgbmat[i][0]*ciecolor[0] +
116     xyz2rgbmat[i][1]*ciecolor[1] +
117     xyz2rgbmat[i][2]*ciecolor[2] ;
118 greg 1.1 if (rgbcolor[i] < 0.0)
119     rgbcolor[i] = 0.0;
120     }
121 greg 2.4 }
122    
123    
124     rgb_cie(ciecolor, rgbcolor) /* convert RGB to CIE */
125     register COLOR ciecolor, rgbcolor;
126     {
127     register int i;
128    
129     for (i = 0; i < 3; i++)
130     ciecolor[i] = rgb2xyzmat[i][0]*rgbcolor[0] +
131     rgb2xyzmat[i][1]*rgbcolor[1] +
132     rgb2xyzmat[i][2]*rgbcolor[2] ;
133 greg 1.1 }