ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcomb.c
Revision: 2.12
Committed: Mon May 3 12:13:03 1993 UTC (31 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +1 -1 lines
Log Message:
changed a range error to a domain error in l_ray()

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Combine picture files according to calcomp functions.
9 *
10 * 1/4/89
11 */
12
13 #include "standard.h"
14
15 #include "color.h"
16
17 #include "resolu.h"
18
19 #include "calcomp.h"
20
21 #include "view.h"
22
23 #define MAXINP 32 /* maximum number of input files */
24 #define WINSIZ 9 /* scanline window size */
25 #define MIDSCN 4 /* current scan position */
26
27 struct {
28 char *name; /* file or command name */
29 FILE *fp; /* stream pointer */
30 VIEW vw; /* view for picture */
31 RESOLU rs; /* image resolution and orientation */
32 COLOR *scan[WINSIZ]; /* input scanline window */
33 COLOR coef; /* coefficient */
34 COLOR expos; /* recorded exposure */
35 } input[MAXINP]; /* input pictures */
36
37 int nfiles; /* number of input files */
38
39 char Command[] = "<Command>";
40 char vcolin[3][4] = {"ri", "gi", "bi"};
41 char vcolout[3][4] = {"ro", "go", "bo"};
42 char vbrtin[] = "li";
43 char vbrtout[] = "lo";
44 char vcolexp[3][4] = {"re", "ge", "be"};
45 char vbrtexp[] = "le";
46
47 char vray[6][4] = {"Ox", "Oy", "Oz", "Dx", "Dy", "Dz"};
48
49 char vnfiles[] = "nfiles";
50 char vxmax[] = "xmax";
51 char vymax[] = "ymax";
52 char vxres[] = "xres";
53 char vyres[] = "yres";
54 char vxpos[] = "x";
55 char vypos[] = "y";
56
57 int nowarn = 0; /* no warning messages? */
58
59 int xmax = 0, ymax = 0; /* input resolution */
60
61 int xscan, yscan; /* input position */
62
63 int xres, yres; /* output resolution */
64
65 int xpos, ypos; /* output position */
66
67 char *progname; /* global argv[0] */
68
69 int wrongformat = 0;
70 int gotview;
71
72 FILE *popen();
73
74 extern char *emalloc();
75
76
77 main(argc, argv)
78 int argc;
79 char *argv[];
80 {
81 int original;
82 double f;
83 int a, i;
84 #ifdef MSDOS
85 extern int _fmode;
86 _fmode = O_BINARY;
87 setmode(fileno(stdin), O_BINARY);
88 setmode(fileno(stdout), O_BINARY);
89 #endif
90 progname = argv[0];
91 /* scan options */
92 for (a = 1; a < argc; a++) {
93 if (argv[a][0] == '-')
94 switch (argv[a][1]) {
95 case 'x':
96 case 'y':
97 a++;
98 continue;
99 case 'w':
100 nowarn = !nowarn;
101 continue;
102 case 'f':
103 case 'e':
104 a++;
105 continue;
106 }
107 break;
108 }
109 /* process files */
110 for (nfiles = 0; nfiles < MAXINP; nfiles++) {
111 setcolor(input[nfiles].coef, 1.0, 1.0, 1.0);
112 setcolor(input[nfiles].expos, 1.0, 1.0, 1.0);
113 copystruct(&input[nfiles].vw, &stdview);
114 }
115 nfiles = 0;
116 original = 0;
117 for ( ; a < argc; a++) {
118 if (nfiles >= MAXINP) {
119 eputs(argv[0]);
120 eputs(": too many picture files\n");
121 quit(1);
122 }
123 if (argv[a][0] == '-')
124 switch (argv[a][1]) {
125 case '\0':
126 input[nfiles].name = "<stdin>";
127 input[nfiles].fp = stdin;
128 break;
129 case 'o':
130 original++;
131 continue;
132 case 's':
133 f = atof(argv[++a]);
134 scalecolor(input[nfiles].coef, f);
135 continue;
136 case 'c':
137 colval(input[nfiles].coef,RED)*=atof(argv[++a]);
138 colval(input[nfiles].coef,GRN)*=atof(argv[++a]);
139 colval(input[nfiles].coef,BLU)*=atof(argv[++a]);
140 continue;
141 default:
142 goto usage;
143 }
144 else {
145 if (argv[a][0] == '!') {
146 input[nfiles].name = Command;
147 input[nfiles].fp = popen(argv[a]+1, "r");
148 } else {
149 input[nfiles].name = argv[a];
150 input[nfiles].fp = fopen(argv[a], "r");
151 }
152 if (input[nfiles].fp == NULL) {
153 perror(argv[a]);
154 quit(1);
155 }
156 }
157 checkfile();
158 if (original) {
159 colval(input[nfiles].coef,RED) /=
160 colval(input[nfiles].expos,RED);
161 colval(input[nfiles].coef,GRN) /=
162 colval(input[nfiles].expos,GRN);
163 colval(input[nfiles].coef,BLU) /=
164 colval(input[nfiles].expos,BLU);
165 }
166 nfiles++;
167 original = 0;
168 }
169 init(); /* set constants */
170 /* go back and get expressions */
171 for (a = 1; a < argc; a++) {
172 if (argv[a][0] == '-')
173 switch (argv[a][1]) {
174 case 'x':
175 varset(vxres, ':', eval(argv[++a]));
176 continue;
177 case 'y':
178 varset(vyres, ':', eval(argv[++a]));
179 continue;
180 case 'w':
181 continue;
182 case 'f':
183 fcompile(argv[++a]);
184 continue;
185 case 'e':
186 scompile(argv[++a], NULL, 0);
187 continue;
188 }
189 break;
190 }
191 /* set/get output resolution */
192 if (!vardefined(vxres))
193 varset(vxres, ':', (double)xmax);
194 if (!vardefined(vyres))
195 varset(vyres, ':', (double)ymax);
196 xres = varvalue(vxres) + .5;
197 yres = varvalue(vyres) + .5;
198 if (xres <= 0 || yres <= 0) {
199 eputs(argv[0]);
200 eputs(": illegal output resolution\n");
201 quit(1);
202 }
203 /* complete header */
204 printargs(argc, argv, stdout);
205 fputformat(COLRFMT, stdout);
206 putchar('\n');
207 fprtresolu(xres, yres, stdout);
208 /* combine pictures */
209 combine();
210 quit(0);
211 usage:
212 eputs("Usage: ");
213 eputs(argv[0]);
214 eputs(
215 " [-w][-x xr][-y yr][-e expr][-f file] [ [-o][-s f][-c r g b] pic ..]\n");
216 quit(1);
217 }
218
219
220 tputs(s) /* put out string preceded by a tab */
221 char *s;
222 {
223 char fmt[32];
224 double d;
225 COLOR ctmp;
226
227 if (isformat(s)) { /* check format */
228 formatval(fmt, s);
229 wrongformat = strcmp(fmt, COLRFMT);
230 return; /* don't echo */
231 }
232 if (isexpos(s)) { /* exposure */
233 d = exposval(s);
234 scalecolor(input[nfiles].expos, d);
235 } else if (iscolcor(s)) { /* color correction */
236 colcorval(ctmp, s);
237 multcolor(input[nfiles].expos, ctmp);
238 } else if (isview(s) && sscanview(&input[nfiles].vw, s) > 0)
239 gotview++;
240 /* echo line */
241 putchar('\t');
242 fputs(s, stdout);
243 }
244
245
246 checkfile() /* ready a file */
247 {
248 register int i;
249 /* process header */
250 gotview = 0;
251 fputs(input[nfiles].name, stdout);
252 fputs(":\n", stdout);
253 getheader(input[nfiles].fp, tputs, NULL);
254 if (wrongformat) {
255 eputs(input[nfiles].name);
256 eputs(": not in Radiance picture format\n");
257 quit(1);
258 }
259 if (!gotview || setview(&input[nfiles].vw) != NULL)
260 input[nfiles].vw.type = 0;
261 if (!fgetsresolu(&input[nfiles].rs, input[nfiles].fp)) {
262 eputs(input[nfiles].name);
263 eputs(": bad picture size\n");
264 quit(1);
265 }
266 if (xmax == 0 && ymax == 0) {
267 xmax = scanlen(&input[nfiles].rs);
268 ymax = numscans(&input[nfiles].rs);
269 } else if (scanlen(&input[nfiles].rs) != xmax ||
270 numscans(&input[nfiles].rs) != ymax) {
271 eputs(input[nfiles].name);
272 eputs(": resolution mismatch\n");
273 quit(1);
274 }
275 /* allocate scanlines */
276 for (i = 0; i < WINSIZ; i++)
277 input[nfiles].scan[i] = (COLOR *)emalloc(xmax*sizeof(COLOR));
278 }
279
280
281 init() /* perform final setup */
282 {
283 double l_colin(), l_expos(), l_ray();
284 register int i;
285 /* define constants */
286 varset(vnfiles, ':', (double)nfiles);
287 varset(vxmax, ':', (double)xmax);
288 varset(vymax, ':', (double)ymax);
289 /* set functions */
290 for (i = 0; i < 3; i++) {
291 funset(vcolexp[i], 1, ':', l_expos);
292 funset(vcolin[i], 1, '=', l_colin);
293 }
294 funset(vbrtexp, 1, ':', l_expos);
295 funset(vbrtin, 1, '=', l_colin);
296 for (i = 0; i < 6; i++)
297 funset(vray[i], 1, '=', l_ray);
298 }
299
300
301 combine() /* combine pictures */
302 {
303 EPNODE *coldef[3], *brtdef;
304 COLOR *scanout;
305 double d;
306 register int i, j;
307 /* check defined variables */
308 for (j = 0; j < 3; j++) {
309 if (vardefined(vcolout[j]))
310 coldef[j] = eparse(vcolout[j]);
311 else
312 coldef[j] = NULL;
313 }
314 if (vardefined(vbrtout))
315 brtdef = eparse(vbrtout);
316 else
317 brtdef = NULL;
318 /* allocate scanline */
319 scanout = (COLOR *)emalloc(xres*sizeof(COLOR));
320 /* set input position */
321 yscan = ymax+MIDSCN;
322 /* combine files */
323 for (ypos = yres-1; ypos >= 0; ypos--) {
324 advance();
325 varset(vypos, '=', (double)ypos);
326 for (xpos = 0; xpos < xres; xpos++) {
327 xscan = (long)xpos*xmax/xres;
328 varset(vxpos, '=', (double)xpos);
329 eclock++;
330 if (brtdef != NULL) {
331 d = evalue(brtdef);
332 if (d < 0.0)
333 d = 0.0;
334 setcolor(scanout[xpos], d, d, d);
335 } else {
336 for (j = 0; j < 3; j++) {
337 if (coldef[j] != NULL) {
338 d = evalue(coldef[j]);
339 } else {
340 d = 0.0;
341 for (i = 0; i < nfiles; i++)
342 d += colval(input[i].scan[MIDSCN][xscan],j);
343 }
344 if (d < 0.0)
345 d = 0.0;
346 colval(scanout[xpos],j) = d;
347 }
348 }
349 }
350 if (fwritescan(scanout, xres, stdout) < 0) {
351 perror("write error");
352 quit(1);
353 }
354 }
355 efree(scanout);
356 }
357
358
359 advance() /* read in data for next scanline */
360 {
361 int ytarget;
362 register COLOR *st;
363 register int i, j;
364
365 for (ytarget = (long)ypos*ymax/yres; yscan > ytarget; yscan--)
366 for (i = 0; i < nfiles; i++) {
367 st = input[i].scan[WINSIZ-1];
368 for (j = WINSIZ-1; j > 0; j--) /* rotate window */
369 input[i].scan[j] = input[i].scan[j-1];
370 input[i].scan[0] = st;
371 if (yscan <= MIDSCN) /* hit bottom? */
372 continue;
373 if (freadscan(st, xmax, input[i].fp) < 0) { /* read */
374 eputs(input[i].name);
375 eputs(": read error\n");
376 quit(1);
377 }
378 if (fabs(colval(input[i].coef,RED)-1.0) > 1e-3 ||
379 fabs(colval(input[i].coef,GRN)-1.0) > 1e-3 ||
380 fabs(colval(input[i].coef,BLU)-1.0) > 1e-3)
381 for (j = 0; j < xmax; j++) /* adjust color */
382 multcolor(st[j], input[i].coef);
383 }
384 }
385
386
387 double
388 l_expos(nam) /* return picture exposure */
389 register char *nam;
390 {
391 register int fn, n;
392
393 fn = argument(1) - .5;
394 if (fn < 0 || fn >= nfiles)
395 return(1.0);
396 if (nam == vbrtexp)
397 return(bright(input[fn].expos));
398 n = 3;
399 while (n--)
400 if (nam == vcolexp[n])
401 return(colval(input[fn].expos,n));
402 eputs("Bad call to l_expos()!\n");
403 quit(1);
404 }
405
406
407 double
408 l_colin(nam) /* return color value for picture */
409 register char *nam;
410 {
411 int fn;
412 register int n, xoff, yoff;
413 double d;
414
415 d = argument(1);
416 if (d > -.5 && d < .5)
417 return((double)nfiles);
418 fn = d - .5;
419 if (fn < 0 || fn >= nfiles) {
420 errno = EDOM;
421 return(0.0);
422 }
423 xoff = yoff = 0;
424 n = nargum();
425 if (n >= 2) {
426 d = argument(2);
427 if (d < 0.0) {
428 xoff = d-.5;
429 if (xscan+xoff < 0)
430 xoff = -xscan;
431 } else {
432 xoff = d+.5;
433 if (xscan+xoff >= xmax)
434 xoff = xmax-1-xscan;
435 }
436 }
437 if (n >= 3) {
438 d = argument(3);
439 if (d < 0.0) {
440 yoff = d-.5;
441 if (yoff+MIDSCN < 0)
442 yoff = -MIDSCN;
443 if (yscan+yoff < 0)
444 yoff = -yscan;
445 } else {
446 yoff = d+.5;
447 if (yoff+MIDSCN >= WINSIZ)
448 yoff = WINSIZ-1-MIDSCN;
449 if (yscan+yoff >= ymax)
450 yoff = ymax-1-yscan;
451 }
452 }
453 if (nam == vbrtin)
454 return(bright(input[fn].scan[MIDSCN+yoff][xscan+xoff]));
455 n = 3;
456 while (n--)
457 if (nam == vcolin[n])
458 return(colval(input[fn].scan[MIDSCN+yoff][xscan+xoff],n));
459 eputs("Bad call to l_colin()!\n");
460 quit(1);
461 }
462
463
464 double
465 l_ray(nam) /* return ray origin or direction */
466 register char *nam;
467 {
468 static long ltick[MAXINP];
469 static FVECT lorg[MAXINP], ldir[MAXINP];
470 FLOAT loc[2];
471 double d;
472 int fn;
473 register int i;
474
475 d = argument(1);
476 if (d > -.5 && d < .5)
477 return((double)nfiles);
478 fn = d - .5;
479 if (fn < 0 || fn >= nfiles) {
480 errno = EDOM;
481 return(0.0);
482 }
483 if (ltick[fn] < eclock) { /* need to compute? */
484 lorg[fn][0] = lorg[fn][1] = lorg[fn][2] = 0.0;
485 ldir[fn][0] = ldir[fn][1] = ldir[fn][2] = 0.0;
486 if (input[fn].vw.type == 0)
487 errno = EDOM;
488 else {
489 pix2loc(loc, &input[fn].rs, xscan, ymax-1-yscan);
490 if (viewray(lorg[fn], ldir[fn],
491 &input[fn].vw, loc[0], loc[1]) < 0)
492 errno = ERANGE;
493 }
494 ltick[fn] = eclock;
495 }
496 i = 6;
497 while (i--)
498 if (nam == vray[i])
499 return(i < 3 ? lorg[fn][i] : ldir[fn][i-3]);
500 eputs("Bad call to l_ray()!\n");
501 quit(1);
502 }
503
504
505 wputs(msg)
506 char *msg;
507 {
508 if (!nowarn)
509 eputs(msg);
510 }
511
512
513 eputs(msg)
514 char *msg;
515 {
516 fputs(msg, stderr);
517 }
518
519
520 quit(code) /* exit gracefully */
521 int code;
522 {
523 register int i;
524 /* close input files */
525 for (i = 0; i < nfiles; i++)
526 if (input[i].name == Command)
527 pclose(input[i].fp);
528 else
529 fclose(input[i].fp);
530 exit(code);
531 }