ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/color.c
Revision: 1.5
Committed: Wed Sep 13 16:35:14 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +46 -0 lines
Log Message:
Added routines for getting and putting picture resolution

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 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 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 if (d <= 1e-32) {
339 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 double ldexp(), f;
358
359 if (clr[EXP] == 0)
360 col[RED] = col[GRN] = col[BLU] = 0.0;
361 else {
362 f = ldexp(1.0, (int)clr[EXP]-(COLXS+8));
363 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 }