ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/color.c
Revision: 1.11
Committed: Thu Aug 30 09:13:21 1990 UTC (33 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.10: +1 -1 lines
Log Message:
fixed typo in comment (whew! -- I'll call it quits for today!)

File Contents

# User Rev Content
1 greg 1.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 greg 1.11 spec_rgb(col, s, e) /* compute RGB color from spectral range */
49 greg 1.1 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 greg 1.5 fputresolu(ord, xres, yres, fp) /* put x and y resolution */
111     register int ord;
112     int xres, yres;
113     FILE *fp;
114     {
115     if (ord&YMAJOR)
116     fprintf(fp, "%cY %d %cX %d\n",
117     ord&YDECR ? '-' : '+', yres,
118     ord&XDECR ? '-' : '+', xres);
119     else
120     fprintf(fp, "%cX %d %cY %d\n",
121     ord&XDECR ? '-' : '+', xres,
122     ord&YDECR ? '-' : '+', yres);
123     }
124    
125    
126     fgetresolu(xrp, yrp, fp) /* get x and y resolution */
127     int *xrp, *yrp;
128     FILE *fp;
129     {
130     char buf[64], *xndx, *yndx;
131     register char *cp;
132     register int ord;
133    
134     if (fgets(buf, sizeof(buf), fp) == NULL)
135     return(-1);
136     xndx = yndx = NULL;
137     for (cp = buf+1; *cp; cp++)
138     if (*cp == 'X')
139     xndx = cp;
140     else if (*cp == 'Y')
141     yndx = cp;
142     if (xndx == NULL || yndx == NULL)
143     return(-1);
144     ord = 0;
145     if (xndx > yndx) ord |= YMAJOR;
146     if (xndx[-1] == '-') ord |= XDECR;
147     if (yndx[-1] == '-') ord |= YDECR;
148     if ((*xrp = atoi(xndx+1)) <= 0)
149     return(-1);
150     if ((*yrp = atoi(yndx+1)) <= 0)
151     return(-1);
152     return(ord);
153     }
154    
155    
156 greg 1.1 fwritecolrs(scanline, len, fp) /* write out a colr scanline */
157     register COLR *scanline;
158     int len;
159     register FILE *fp;
160     {
161     COLR lastcolr;
162     int rept;
163    
164     lastcolr[RED] = lastcolr[GRN] = lastcolr[BLU] = 1;
165     lastcolr[EXP] = 0;
166     rept = 0;
167    
168     while (len > 0) {
169     if (scanline[0][EXP] == lastcolr[EXP] &&
170     scanline[0][RED] == lastcolr[RED] &&
171     scanline[0][GRN] == lastcolr[GRN] &&
172     scanline[0][BLU] == lastcolr[BLU])
173     rept++;
174     else {
175     while (rept) { /* write out count */
176     putc(1, fp);
177     putc(1, fp);
178     putc(1, fp);
179     putc(rept & 255, fp);
180     rept >>= 8;
181     }
182     putc(scanline[0][RED], fp); /* new color */
183     putc(scanline[0][GRN], fp);
184     putc(scanline[0][BLU], fp);
185     putc(scanline[0][EXP], fp);
186     copycolr(lastcolr, scanline[0]);
187     rept = 0;
188     }
189     scanline++;
190     len--;
191     }
192     while (rept) { /* write out count */
193     putc(1, fp);
194     putc(1, fp);
195     putc(1, fp);
196     putc(rept & 255, fp);
197     rept >>= 8;
198     }
199     return(ferror(fp) ? -1 : 0);
200     }
201    
202    
203     freadcolrs(scanline, len, fp) /* read in a colr scanline */
204     register COLR *scanline;
205     int len;
206     register FILE *fp;
207     {
208     int rshift;
209     register int i;
210    
211     rshift = 0;
212    
213     while (len > 0) {
214     scanline[0][RED] = getc(fp);
215     scanline[0][GRN] = getc(fp);
216     scanline[0][BLU] = getc(fp);
217     scanline[0][EXP] = getc(fp);
218     if (feof(fp) || ferror(fp))
219     return(-1);
220     if (scanline[0][RED] == 1 &&
221     scanline[0][GRN] == 1 &&
222     scanline[0][BLU] == 1) {
223     for (i = scanline[0][EXP] << rshift; i > 0; i--) {
224     copycolr(scanline[0], scanline[-1]);
225     scanline++;
226     len--;
227     }
228     rshift += 8;
229     } else {
230     scanline++;
231     len--;
232     rshift = 0;
233     }
234     }
235     return(0);
236     }
237    
238    
239     fwritescan(scanline, len, fp) /* write out a scanline */
240     register COLOR *scanline;
241     int len;
242     register FILE *fp;
243     {
244     COLR lastcolr, thiscolr;
245     int rept;
246    
247     lastcolr[RED] = lastcolr[GRN] = lastcolr[BLU] = 1;
248     lastcolr[EXP] = 0;
249     rept = 0;
250    
251     while (len > 0) {
252     setcolr(thiscolr, scanline[0][RED],
253     scanline[0][GRN],
254     scanline[0][BLU]);
255     if (thiscolr[EXP] == lastcolr[EXP] &&
256     thiscolr[RED] == lastcolr[RED] &&
257     thiscolr[GRN] == lastcolr[GRN] &&
258     thiscolr[BLU] == lastcolr[BLU])
259     rept++;
260     else {
261     while (rept) { /* write out count */
262     putc(1, fp);
263     putc(1, fp);
264     putc(1, fp);
265     putc(rept & 255, fp);
266     rept >>= 8;
267     }
268     putc(thiscolr[RED], fp); /* new color */
269     putc(thiscolr[GRN], fp);
270     putc(thiscolr[BLU], fp);
271     putc(thiscolr[EXP], fp);
272     copycolr(lastcolr, thiscolr);
273     rept = 0;
274     }
275     scanline++;
276     len--;
277     }
278     while (rept) { /* write out count */
279     putc(1, fp);
280     putc(1, fp);
281     putc(1, fp);
282     putc(rept & 255, fp);
283     rept >>= 8;
284     }
285     return(ferror(fp) ? -1 : 0);
286     }
287    
288    
289     freadscan(scanline, len, fp) /* read in a scanline */
290     register COLOR *scanline;
291     int len;
292     register FILE *fp;
293     {
294     COLR thiscolr;
295     int rshift;
296     register int i;
297    
298     rshift = 0;
299    
300     while (len > 0) {
301     thiscolr[RED] = getc(fp);
302     thiscolr[GRN] = getc(fp);
303     thiscolr[BLU] = getc(fp);
304     thiscolr[EXP] = getc(fp);
305     if (feof(fp) || ferror(fp))
306     return(-1);
307     if (thiscolr[RED] == 1 &&
308     thiscolr[GRN] == 1 &&
309     thiscolr[BLU] == 1) {
310     for (i = thiscolr[EXP] << rshift; i > 0; i--) {
311     copycolor(scanline[0], scanline[-1]);
312     scanline++;
313     len--;
314     }
315     rshift += 8;
316     } else {
317     colr_color(scanline[0], thiscolr);
318     scanline++;
319     len--;
320     rshift = 0;
321     }
322     }
323     return(0);
324     }
325    
326    
327     setcolr(clr, r, g, b) /* assign a short color value */
328     register COLR clr;
329     double r, g, b;
330     {
331     double frexp();
332     double d;
333     int e;
334    
335     d = r > g ? r : g;
336     if (b > d) d = b;
337    
338 greg 1.4 if (d <= 1e-32) {
339 greg 1.1 clr[RED] = clr[GRN] = clr[BLU] = 0;
340     clr[EXP] = 0;
341     return;
342     }
343    
344     d = frexp(d, &e) * 256.0 / d;
345    
346     clr[RED] = r * d;
347     clr[GRN] = g * d;
348     clr[BLU] = b * d;
349     clr[EXP] = e + COLXS;
350     }
351    
352    
353     colr_color(col, clr) /* convert short to float color */
354     register COLOR col;
355     register COLR clr;
356     {
357 greg 1.6 double f;
358 greg 1.1
359     if (clr[EXP] == 0)
360     col[RED] = col[GRN] = col[BLU] = 0.0;
361     else {
362 greg 1.2 f = ldexp(1.0, (int)clr[EXP]-(COLXS+8));
363 greg 1.1 col[RED] = (clr[RED] + 0.5)*f;
364     col[GRN] = (clr[GRN] + 0.5)*f;
365     col[BLU] = (clr[BLU] + 0.5)*f;
366     }
367 greg 1.6 }
368    
369    
370 greg 1.10 normcolrs(scan, len, adjust) /* normalize a scanline of colrs */
371 greg 1.8 register COLR *scan;
372     int len;
373 greg 1.10 int adjust;
374 greg 1.6 {
375     register int c;
376 greg 1.8 register int shift;
377 greg 1.6
378 greg 1.8 while (len-- > 0) {
379 greg 1.10 shift = scan[0][EXP] + adjust - COLXS;
380 greg 1.8 if (shift > 0) {
381 greg 1.9 if (shift > 8) {
382 greg 1.8 scan[0][RED] =
383     scan[0][GRN] =
384     scan[0][BLU] = 255;
385     } else {
386 greg 1.9 shift--;
387     c = (scan[0][RED]<<1 | 1) << shift;
388 greg 1.8 scan[0][RED] = c > 255 ? 255 : c;
389 greg 1.9 c = (scan[0][GRN]<<1 | 1) << shift;
390 greg 1.8 scan[0][GRN] = c > 255 ? 255 : c;
391 greg 1.9 c = (scan[0][BLU]<<1 | 1) << shift;
392 greg 1.8 scan[0][BLU] = c > 255 ? 255 : c;
393     }
394     } else if (shift < 0) {
395 greg 1.9 if (shift < -8) {
396 greg 1.8 scan[0][RED] =
397     scan[0][GRN] =
398     scan[0][BLU] = 0;
399     } else {
400 greg 1.9 shift = -1-shift;
401     scan[0][RED] = ((scan[0][RED]>>shift)+1)>>1;
402     scan[0][GRN] = ((scan[0][GRN]>>shift)+1)>>1;
403     scan[0][BLU] = ((scan[0][BLU]>>shift)+1)>>1;
404 greg 1.8 }
405 greg 1.6 }
406 greg 1.10 scan[0][EXP] = COLXS - adjust;
407 greg 1.8 scan++;
408 greg 1.6 }
409 greg 1.1 }
410 greg 1.7
411    
412     bigdiff(c1, c2, md) /* c1 delta c2 > md? */
413     register COLOR c1, c2;
414     double md;
415     {
416     register int i;
417    
418     for (i = 0; i < 3; i++)
419     if (colval(c1,i)-colval(c2,i) > md*colval(c2,i) ||
420     colval(c2,i)-colval(c1,i) > md*colval(c1,i))
421     return(1);
422     return(0);
423     }