ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/color.c
Revision: 1.1
Committed: Thu Feb 2 10:34:29 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * color.c - routines for color calculations.
9 *
10 * 10/10/85
11 */
12
13 #include <stdio.h>
14
15 #include "color.h"
16
17 #ifdef SPEC_RGB
18 /*
19 * The following table contains the CIE tristimulus integrals
20 * for X, Y, and Z. The table is cumulative, so that
21 * each color coordinate integrates to 1.
22 */
23
24 #define STARTWL 380 /* starting wavelength (nanometers) */
25 #define INCWL 10 /* wavelength increment */
26 #define NINC 40 /* # of values */
27
28 static BYTE chroma[3][NINC] = {
29 { /* X */
30 0, 0, 0, 2, 6, 13, 22, 30, 36, 41,
31 42, 43, 43, 44, 46, 52, 60, 71, 87, 106,
32 128, 153, 178, 200, 219, 233, 243, 249, 252, 254,
33 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
34 }, { /* Y */
35 0, 0, 0, 0, 0, 1, 2, 4, 7, 11,
36 17, 24, 34, 48, 64, 84, 105, 127, 148, 169,
37 188, 205, 220, 232, 240, 246, 250, 253, 254, 255,
38 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
39 }, { /* Z */
40 0, 0, 2, 10, 32, 66, 118, 153, 191, 220,
41 237, 246, 251, 253, 254, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
44 }
45 };
46
47
48 spec_rgb(col, s, e) /* comput RGB color from spectral range */
49 COLOR col;
50 int s, e;
51 {
52 COLOR ciecolor;
53
54 spec_cie(ciecolor, s, e);
55 cie_rgb(col, ciecolor);
56 }
57
58
59 spec_cie(col, s, e) /* compute a color from a spectral range */
60 COLOR col; /* returned color */
61 int s, e; /* starting and ending wavelengths */
62 {
63 register int i, d, r;
64
65 s -= STARTWL;
66 if (s < 0)
67 s = 0;
68
69 e -= STARTWL;
70 if (e >= INCWL*(NINC - 1))
71 e = INCWL*(NINC - 1) - 1;
72
73 d = e / INCWL; /* interpolate values */
74 r = e % INCWL;
75 for (i = 0; i < 3; i++)
76 col[i] = chroma[i][d]*(INCWL - r) + chroma[i][d + 1]*r;
77
78 d = s / INCWL;
79 r = s % INCWL;
80 for (i = 0; i < 3; i++)
81 col[i] -= chroma[i][d]*(INCWL - r) - chroma[i][d + 1]*r;
82
83 col[RED] = (col[RED] + 0.5) / (256*INCWL);
84 col[GRN] = (col[GRN] + 0.5) / (256*INCWL);
85 col[BLU] = (col[BLU] + 0.5) / (256*INCWL);
86 }
87
88
89 cie_rgb(rgbcolor, ciecolor) /* convert CIE to RGB (NTSC) */
90 register COLOR rgbcolor, ciecolor;
91 {
92 static float cmat[3][3] = {
93 1.73, -.48, -.26,
94 -.81, 1.65, -.02,
95 .08, -.17, 1.28,
96 };
97 register int i;
98
99 for (i = 0; i < 3; i++) {
100 rgbcolor[i] = cmat[i][0]*ciecolor[0] +
101 cmat[i][1]*ciecolor[1] +
102 cmat[i][2]*ciecolor[2] ;
103 if (rgbcolor[i] < 0.0)
104 rgbcolor[i] = 0.0;
105 }
106 }
107 #endif
108
109
110 fwritecolrs(scanline, len, fp) /* write out a colr scanline */
111 register COLR *scanline;
112 int len;
113 register FILE *fp;
114 {
115 COLR lastcolr;
116 int rept;
117
118 lastcolr[RED] = lastcolr[GRN] = lastcolr[BLU] = 1;
119 lastcolr[EXP] = 0;
120 rept = 0;
121
122 while (len > 0) {
123 if (scanline[0][EXP] == lastcolr[EXP] &&
124 scanline[0][RED] == lastcolr[RED] &&
125 scanline[0][GRN] == lastcolr[GRN] &&
126 scanline[0][BLU] == lastcolr[BLU])
127 rept++;
128 else {
129 while (rept) { /* write out count */
130 putc(1, fp);
131 putc(1, fp);
132 putc(1, fp);
133 putc(rept & 255, fp);
134 rept >>= 8;
135 }
136 putc(scanline[0][RED], fp); /* new color */
137 putc(scanline[0][GRN], fp);
138 putc(scanline[0][BLU], fp);
139 putc(scanline[0][EXP], fp);
140 copycolr(lastcolr, scanline[0]);
141 rept = 0;
142 }
143 scanline++;
144 len--;
145 }
146 while (rept) { /* write out count */
147 putc(1, fp);
148 putc(1, fp);
149 putc(1, fp);
150 putc(rept & 255, fp);
151 rept >>= 8;
152 }
153 return(ferror(fp) ? -1 : 0);
154 }
155
156
157 freadcolrs(scanline, len, fp) /* read in a colr scanline */
158 register COLR *scanline;
159 int len;
160 register FILE *fp;
161 {
162 int rshift;
163 register int i;
164
165 rshift = 0;
166
167 while (len > 0) {
168 scanline[0][RED] = getc(fp);
169 scanline[0][GRN] = getc(fp);
170 scanline[0][BLU] = getc(fp);
171 scanline[0][EXP] = getc(fp);
172 if (feof(fp) || ferror(fp))
173 return(-1);
174 if (scanline[0][RED] == 1 &&
175 scanline[0][GRN] == 1 &&
176 scanline[0][BLU] == 1) {
177 for (i = scanline[0][EXP] << rshift; i > 0; i--) {
178 copycolr(scanline[0], scanline[-1]);
179 scanline++;
180 len--;
181 }
182 rshift += 8;
183 } else {
184 scanline++;
185 len--;
186 rshift = 0;
187 }
188 }
189 return(0);
190 }
191
192
193 fwritescan(scanline, len, fp) /* write out a scanline */
194 register COLOR *scanline;
195 int len;
196 register FILE *fp;
197 {
198 COLR lastcolr, thiscolr;
199 int rept;
200
201 lastcolr[RED] = lastcolr[GRN] = lastcolr[BLU] = 1;
202 lastcolr[EXP] = 0;
203 rept = 0;
204
205 while (len > 0) {
206 setcolr(thiscolr, scanline[0][RED],
207 scanline[0][GRN],
208 scanline[0][BLU]);
209 if (thiscolr[EXP] == lastcolr[EXP] &&
210 thiscolr[RED] == lastcolr[RED] &&
211 thiscolr[GRN] == lastcolr[GRN] &&
212 thiscolr[BLU] == lastcolr[BLU])
213 rept++;
214 else {
215 while (rept) { /* write out count */
216 putc(1, fp);
217 putc(1, fp);
218 putc(1, fp);
219 putc(rept & 255, fp);
220 rept >>= 8;
221 }
222 putc(thiscolr[RED], fp); /* new color */
223 putc(thiscolr[GRN], fp);
224 putc(thiscolr[BLU], fp);
225 putc(thiscolr[EXP], fp);
226 copycolr(lastcolr, thiscolr);
227 rept = 0;
228 }
229 scanline++;
230 len--;
231 }
232 while (rept) { /* write out count */
233 putc(1, fp);
234 putc(1, fp);
235 putc(1, fp);
236 putc(rept & 255, fp);
237 rept >>= 8;
238 }
239 return(ferror(fp) ? -1 : 0);
240 }
241
242
243 freadscan(scanline, len, fp) /* read in a scanline */
244 register COLOR *scanline;
245 int len;
246 register FILE *fp;
247 {
248 COLR thiscolr;
249 int rshift;
250 register int i;
251
252 rshift = 0;
253
254 while (len > 0) {
255 thiscolr[RED] = getc(fp);
256 thiscolr[GRN] = getc(fp);
257 thiscolr[BLU] = getc(fp);
258 thiscolr[EXP] = getc(fp);
259 if (feof(fp) || ferror(fp))
260 return(-1);
261 if (thiscolr[RED] == 1 &&
262 thiscolr[GRN] == 1 &&
263 thiscolr[BLU] == 1) {
264 for (i = thiscolr[EXP] << rshift; i > 0; i--) {
265 copycolor(scanline[0], scanline[-1]);
266 scanline++;
267 len--;
268 }
269 rshift += 8;
270 } else {
271 colr_color(scanline[0], thiscolr);
272 scanline++;
273 len--;
274 rshift = 0;
275 }
276 }
277 return(0);
278 }
279
280
281 setcolr(clr, r, g, b) /* assign a short color value */
282 register COLR clr;
283 double r, g, b;
284 {
285 double frexp();
286 double d;
287 int e;
288
289 d = r > g ? r : g;
290 if (b > d) d = b;
291
292 if (d <= 0.0) {
293 clr[RED] = clr[GRN] = clr[BLU] = 0;
294 clr[EXP] = 0;
295 return;
296 }
297
298 d = frexp(d, &e) * 256.0 / d;
299
300 clr[RED] = r * d;
301 clr[GRN] = g * d;
302 clr[BLU] = b * d;
303 clr[EXP] = e + COLXS;
304 }
305
306
307 colr_color(col, clr) /* convert short to float color */
308 register COLOR col;
309 register COLR clr;
310 {
311 double ldexp(), f;
312
313 if (clr[EXP] == 0)
314 col[RED] = col[GRN] = col[BLU] = 0.0;
315 else {
316 f = ldexp(1.0, clr[EXP]-(COLXS+8));
317 col[RED] = (clr[RED] + 0.5)*f;
318 col[GRN] = (clr[GRN] + 0.5)*f;
319 col[BLU] = (clr[BLU] + 0.5)*f;
320 }
321 }
322
323
324 #ifdef FREXP
325 double
326 frexp(x, ip) /* call it paranoia, I've seen the lib version */
327 register double x;
328 int *ip;
329 {
330 int neg;
331 register int i;
332
333 if (neg = (x < 0.0))
334 x = -x;
335 else if (x == 0.0) {
336 *ip = 0;
337 return(0.0);
338 }
339 if (x < 0.5)
340 for (i = 0; x < 0.5; i--)
341 x *= 2.0;
342 else
343 for (i = 0; x >= 1.0; i++)
344 x /= 2.0;
345 *ip = i;
346 if (neg)
347 return(-x);
348 else
349 return(x);
350 }
351 #endif