ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcomb.c
Revision: 2.18
Committed: Tue Sep 3 11:30:37 1996 UTC (27 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.17: +58 -48 lines
Log Message:
fixed S(n) function and added T(n) function and pa(n) and WE constants

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 17 /* scanline window size */
25 #define MIDSCN ((WINSIZ-1)/2+1)
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 float pa; /* pixel aspect ratio */
33 COLOR *scan[WINSIZ]; /* input scanline window */
34 COLOR coef; /* coefficient */
35 COLOR expos; /* recorded exposure */
36 } input[MAXINP]; /* input pictures */
37
38 int nfiles; /* number of input files */
39
40 char ourfmt[LPICFMT+1] = PICFMT; /* input picture format */
41
42 char Command[] = "<Command>";
43 char vcolin[3][4] = {"ri", "gi", "bi"};
44 char vcolout[3][4] = {"ro", "go", "bo"};
45 char vbrtin[] = "li";
46 char vbrtout[] = "lo";
47 char vcolexp[3][4] = {"re", "ge", "be"};
48 char vbrtexp[] = "le";
49 char vpixaspect[] = "pa";
50
51 char vray[7][4] = {"Ox", "Oy", "Oz", "Dx", "Dy", "Dz", "T"};
52
53 char vpsize[] = "S";
54
55 char vnfiles[] = "nfiles";
56 char vwhteff[] = "WE";
57 char vxmax[] = "xmax";
58 char vymax[] = "ymax";
59 char vxres[] = "xres";
60 char vyres[] = "yres";
61 char vxpos[] = "x";
62 char vypos[] = "y";
63
64 int nowarn = 0; /* no warning messages? */
65
66 int xmax = 0, ymax = 0; /* input resolution */
67
68 int xscan, yscan; /* input position */
69
70 int xres, yres; /* output resolution */
71
72 int xpos, ypos; /* output position */
73
74 char *progname; /* global argv[0] */
75
76 int wrongformat = 0;
77 int gotview;
78
79 FILE *popen();
80
81 extern char *emalloc();
82
83
84 main(argc, argv)
85 int argc;
86 char *argv[];
87 {
88 int original;
89 double f;
90 int a, i;
91 #ifdef MSDOS
92 extern int _fmode;
93 _fmode = O_BINARY;
94 setmode(fileno(stdin), O_BINARY);
95 setmode(fileno(stdout), O_BINARY);
96 #endif
97 progname = argv[0];
98 /* scan options */
99 for (a = 1; a < argc; a++) {
100 if (argv[a][0] == '-')
101 switch (argv[a][1]) {
102 case 'x':
103 case 'y':
104 a++;
105 continue;
106 case 'w':
107 nowarn = !nowarn;
108 continue;
109 case 'f':
110 case 'e':
111 a++;
112 continue;
113 }
114 break;
115 }
116 newheader("RADIANCE", stdout); /* start header */
117 /* process files */
118 for (nfiles = 0; nfiles < MAXINP; nfiles++) {
119 setcolor(input[nfiles].coef, 1.0, 1.0, 1.0);
120 setcolor(input[nfiles].expos, 1.0, 1.0, 1.0);
121 copystruct(&input[nfiles].vw, &stdview);
122 input[nfiles].pa = 1.0;
123 }
124 nfiles = 0;
125 original = 0;
126 for ( ; a < argc; a++) {
127 if (nfiles >= MAXINP) {
128 eputs(argv[0]);
129 eputs(": too many picture files\n");
130 quit(1);
131 }
132 if (argv[a][0] == '-')
133 switch (argv[a][1]) {
134 case '\0':
135 input[nfiles].name = "<stdin>";
136 input[nfiles].fp = stdin;
137 break;
138 case 'o':
139 original++;
140 continue;
141 case 's':
142 f = atof(argv[++a]);
143 scalecolor(input[nfiles].coef, f);
144 continue;
145 case 'c':
146 colval(input[nfiles].coef,RED)*=atof(argv[++a]);
147 colval(input[nfiles].coef,GRN)*=atof(argv[++a]);
148 colval(input[nfiles].coef,BLU)*=atof(argv[++a]);
149 continue;
150 default:
151 goto usage;
152 }
153 else {
154 if (argv[a][0] == '!') {
155 input[nfiles].name = Command;
156 input[nfiles].fp = popen(argv[a]+1, "r");
157 } else {
158 input[nfiles].name = argv[a];
159 input[nfiles].fp = fopen(argv[a], "r");
160 }
161 if (input[nfiles].fp == NULL) {
162 perror(argv[a]);
163 quit(1);
164 }
165 }
166 checkfile();
167 if (original) {
168 colval(input[nfiles].coef,RED) /=
169 colval(input[nfiles].expos,RED);
170 colval(input[nfiles].coef,GRN) /=
171 colval(input[nfiles].expos,GRN);
172 colval(input[nfiles].coef,BLU) /=
173 colval(input[nfiles].expos,BLU);
174 }
175 nfiles++;
176 original = 0;
177 }
178 init(); /* set constants */
179 /* go back and get expressions */
180 for (a = 1; a < argc; a++) {
181 if (argv[a][0] == '-')
182 switch (argv[a][1]) {
183 case 'x':
184 varset(vxres, ':', eval(argv[++a]));
185 continue;
186 case 'y':
187 varset(vyres, ':', eval(argv[++a]));
188 continue;
189 case 'w':
190 continue;
191 case 'f':
192 fcompile(argv[++a]);
193 continue;
194 case 'e':
195 scompile(argv[++a], NULL, 0);
196 continue;
197 }
198 break;
199 }
200 /* set/get output resolution */
201 if (!vardefined(vxres))
202 varset(vxres, ':', (double)xmax);
203 if (!vardefined(vyres))
204 varset(vyres, ':', (double)ymax);
205 xres = varvalue(vxres) + .5;
206 yres = varvalue(vyres) + .5;
207 if (xres <= 0 || yres <= 0) {
208 eputs(argv[0]);
209 eputs(": illegal output resolution\n");
210 quit(1);
211 }
212 /* complete header */
213 printargs(argc, argv, stdout);
214 if (strcmp(ourfmt, PICFMT))
215 fputformat(ourfmt, stdout); /* print format if known */
216 putchar('\n');
217 fprtresolu(xres, yres, stdout);
218 /* combine pictures */
219 combine();
220 quit(0);
221 usage:
222 eputs("Usage: ");
223 eputs(argv[0]);
224 eputs(
225 " [-w][-x xr][-y yr][-e expr][-f file] [ [-o][-s f][-c r g b] pic ..]\n");
226 quit(1);
227 }
228
229
230 tputs(s) /* put out string preceded by a tab */
231 char *s;
232 {
233 char fmt[32];
234 double d;
235 COLOR ctmp;
236
237 if (isheadid(s)) /* header id */
238 return; /* don't echo */
239 if (formatval(fmt, s)) { /* check format */
240 if (globmatch(ourfmt, fmt)) {
241 wrongformat = 0;
242 strcpy(ourfmt, fmt);
243 } else
244 wrongformat = 1;
245 return; /* don't echo */
246 }
247 if (isexpos(s)) { /* exposure */
248 d = exposval(s);
249 scalecolor(input[nfiles].expos, d);
250 } else if (iscolcor(s)) { /* color correction */
251 colcorval(ctmp, s);
252 multcolor(input[nfiles].expos, ctmp);
253 } else if (isaspect(s))
254 input[nfiles].pa *= aspectval(s);
255 else if (isview(s) && sscanview(&input[nfiles].vw, s) > 0)
256 gotview++;
257 /* echo line */
258 putchar('\t');
259 fputs(s, stdout);
260 }
261
262
263 checkfile() /* ready a file */
264 {
265 register int i;
266 /* process header */
267 gotview = 0;
268 fputs(input[nfiles].name, stdout);
269 fputs(":\n", stdout);
270 getheader(input[nfiles].fp, tputs, NULL);
271 if (wrongformat) {
272 eputs(input[nfiles].name);
273 eputs(": not in Radiance picture format\n");
274 quit(1);
275 }
276 if (!gotview || setview(&input[nfiles].vw) != NULL)
277 input[nfiles].vw.type = 0;
278 if (!fgetsresolu(&input[nfiles].rs, input[nfiles].fp)) {
279 eputs(input[nfiles].name);
280 eputs(": bad picture size\n");
281 quit(1);
282 }
283 if (xmax == 0 && ymax == 0) {
284 xmax = scanlen(&input[nfiles].rs);
285 ymax = numscans(&input[nfiles].rs);
286 } else if (scanlen(&input[nfiles].rs) != xmax ||
287 numscans(&input[nfiles].rs) != ymax) {
288 eputs(input[nfiles].name);
289 eputs(": resolution mismatch\n");
290 quit(1);
291 }
292 /* allocate scanlines */
293 for (i = 0; i < WINSIZ; i++)
294 input[nfiles].scan[i] = (COLOR *)emalloc(xmax*sizeof(COLOR));
295 }
296
297
298 double
299 rgb_bright(clr)
300 COLOR clr;
301 {
302 return(bright(clr));
303 }
304
305
306 double
307 xyz_bright(clr)
308 COLOR clr;
309 {
310 return(clr[CIEY]);
311 }
312
313
314 double (*ourbright)() = rgb_bright;
315
316
317 init() /* perform final setup */
318 {
319 double l_colin(), l_expos(), l_pixaspect(), l_ray(), l_psize();
320 register int i;
321 /* define constants */
322 varset(vnfiles, ':', (double)nfiles);
323 varset(vxmax, ':', (double)xmax);
324 varset(vymax, ':', (double)ymax);
325 /* set functions */
326 for (i = 0; i < 3; i++) {
327 funset(vcolexp[i], 1, ':', l_expos);
328 funset(vcolin[i], 1, '=', l_colin);
329 }
330 funset(vbrtexp, 1, ':', l_expos);
331 funset(vbrtin, 1, '=', l_colin);
332 funset(vpixaspect, 1, ':', l_pixaspect);
333 for (i = 0; i < 7; i++)
334 funset(vray[i], 1, '=', l_ray);
335 funset(vpsize, 1, '=', l_psize);
336 /* set brightness function */
337 if (!strcmp(ourfmt, CIEFMT)) {
338 varset(vwhteff, ':', 1.0);
339 ourbright = xyz_bright;
340 } else
341 varset(vwhteff, ':', WHTEFFICACY);
342 }
343
344
345 combine() /* combine pictures */
346 {
347 EPNODE *coldef[3], *brtdef;
348 COLOR *scanout;
349 double d;
350 register int i, j;
351 /* check defined variables */
352 for (j = 0; j < 3; j++) {
353 if (vardefined(vcolout[j]))
354 coldef[j] = eparse(vcolout[j]);
355 else
356 coldef[j] = NULL;
357 }
358 if (vardefined(vbrtout))
359 brtdef = eparse(vbrtout);
360 else
361 brtdef = NULL;
362 /* allocate scanline */
363 scanout = (COLOR *)emalloc(xres*sizeof(COLOR));
364 /* set input position */
365 yscan = ymax+MIDSCN;
366 /* combine files */
367 for (ypos = yres-1; ypos >= 0; ypos--) {
368 advance();
369 varset(vypos, '=', (double)ypos);
370 for (xpos = 0; xpos < xres; xpos++) {
371 xscan = (long)xpos*xmax/xres;
372 varset(vxpos, '=', (double)xpos);
373 eclock++;
374 if (brtdef != NULL) {
375 d = evalue(brtdef);
376 if (d < 0.0)
377 d = 0.0;
378 setcolor(scanout[xpos], d, d, d);
379 } else {
380 for (j = 0; j < 3; j++) {
381 if (coldef[j] != NULL) {
382 d = evalue(coldef[j]);
383 } else {
384 d = 0.0;
385 for (i = 0; i < nfiles; i++)
386 d += colval(input[i].scan[MIDSCN][xscan],j);
387 }
388 if (d < 0.0)
389 d = 0.0;
390 colval(scanout[xpos],j) = d;
391 }
392 }
393 }
394 if (fwritescan(scanout, xres, stdout) < 0) {
395 perror("write error");
396 quit(1);
397 }
398 }
399 efree(scanout);
400 }
401
402
403 advance() /* read in data for next scanline */
404 {
405 int ytarget;
406 register COLOR *st;
407 register int i, j;
408
409 for (ytarget = (long)ypos*ymax/yres; yscan > ytarget; yscan--)
410 for (i = 0; i < nfiles; i++) {
411 st = input[i].scan[WINSIZ-1];
412 for (j = WINSIZ-1; j > 0; j--) /* rotate window */
413 input[i].scan[j] = input[i].scan[j-1];
414 input[i].scan[0] = st;
415 if (yscan <= MIDSCN) /* hit bottom? */
416 continue;
417 if (freadscan(st, xmax, input[i].fp) < 0) { /* read */
418 eputs(input[i].name);
419 eputs(": read error\n");
420 quit(1);
421 }
422 if (fabs(colval(input[i].coef,RED)-1.0) > 1e-3 ||
423 fabs(colval(input[i].coef,GRN)-1.0) > 1e-3 ||
424 fabs(colval(input[i].coef,BLU)-1.0) > 1e-3)
425 for (j = 0; j < xmax; j++) /* adjust color */
426 multcolor(st[j], input[i].coef);
427 }
428 }
429
430
431 double
432 l_expos(nam) /* return picture exposure */
433 register char *nam;
434 {
435 register int fn, n;
436
437 fn = argument(1) - .5;
438 if (fn < 0 || fn >= nfiles)
439 return(1.0);
440 if (nam == vbrtexp)
441 return((*ourbright)(input[fn].expos));
442 n = 3;
443 while (n--)
444 if (nam == vcolexp[n])
445 return(colval(input[fn].expos,n));
446 eputs("Bad call to l_expos()!\n");
447 quit(1);
448 }
449
450
451 double
452 l_pixaspect() /* return pixel aspect ratio */
453 {
454 register int fn;
455
456 fn = argument(1) - .5;
457 if (fn < 0 || fn >= nfiles)
458 return(1.0);
459 return(input[fn].pa);
460 }
461
462
463 double
464 l_colin(nam) /* return color value for picture */
465 register char *nam;
466 {
467 int fn;
468 register int n, xoff, yoff;
469 double d;
470
471 fn = argument(1) - .5;
472 if (fn < 0 || fn >= nfiles) {
473 errno = EDOM;
474 return(0.0);
475 }
476 xoff = yoff = 0;
477 n = nargum();
478 if (n >= 2) {
479 d = argument(2);
480 if (d < 0.0) {
481 xoff = d-.5;
482 if (xscan+xoff < 0)
483 xoff = -xscan;
484 } else {
485 xoff = d+.5;
486 if (xscan+xoff >= xmax)
487 xoff = xmax-1-xscan;
488 }
489 }
490 if (n >= 3) {
491 d = argument(3);
492 if (d < 0.0) {
493 yoff = d-.5;
494 if (yoff+MIDSCN < 0)
495 yoff = -MIDSCN;
496 if (yscan+yoff < 0)
497 yoff = -yscan;
498 } else {
499 yoff = d+.5;
500 if (yoff+MIDSCN >= WINSIZ)
501 yoff = WINSIZ-1-MIDSCN;
502 if (yscan+yoff >= ymax)
503 yoff = ymax-1-yscan;
504 }
505 }
506 if (nam == vbrtin)
507 return((*ourbright)(input[fn].scan[MIDSCN+yoff][xscan+xoff]));
508 n = 3;
509 while (n--)
510 if (nam == vcolin[n])
511 return(colval(input[fn].scan[MIDSCN+yoff][xscan+xoff],n));
512 eputs("Bad call to l_colin()!\n");
513 quit(1);
514 }
515
516
517 double
518 l_ray(nam) /* return ray origin or direction */
519 register char *nam;
520 {
521 static unsigned long ltick[MAXINP];
522 static FVECT lorg[MAXINP], ldir[MAXINP];
523 static double ldist[MAXINP];
524 FLOAT loc[2];
525 int fn;
526 register int i;
527
528 fn = argument(1) - .5;
529 if (fn < 0 || fn >= nfiles) {
530 errno = EDOM;
531 return(0.0);
532 }
533 if (ltick[fn] < eclock) { /* need to compute? */
534 lorg[fn][0] = lorg[fn][1] = lorg[fn][2] = 0.0;
535 ldir[fn][0] = ldir[fn][1] = ldir[fn][2] = 0.0;
536 if (input[fn].vw.type == 0)
537 errno = EDOM;
538 else {
539 pix2loc(loc, &input[fn].rs, xscan, ymax-1-yscan);
540 ldist[fn] = viewray(lorg[fn], ldir[fn],
541 &input[fn].vw, loc[0], loc[1]);
542 }
543 ltick[fn] = eclock;
544 }
545 if (nam == vray[i=6])
546 return(ldist[fn]);
547 while (i--)
548 if (nam == vray[i])
549 return(i < 3 ? lorg[fn][i] : ldir[fn][i-3]);
550 eputs("Bad call to l_ray()!\n");
551 quit(1);
552 }
553
554
555 double
556 l_psize() /* compute pixel size in steradians */
557 {
558 static unsigned long ltick[MAXINP];
559 static double psize[MAXINP];
560 FVECT dir0, org, dirx, diry;
561 FLOAT locx[2], locy[2];
562 double d;
563 int fn;
564 register int i;
565
566 d = argument(1);
567 if (d < .5 || d >= nfiles+.5) {
568 errno = EDOM;
569 return(0.0);
570 }
571 fn = d - .5;
572 if (ltick[fn] < eclock) { /* need to compute? */
573 psize[fn] = 0.0;
574 if (input[fn].vw.type == 0)
575 errno = EDOM;
576 else if (input[fn].vw.type != VT_PAR &&
577 funvalue(vray[6], 1, &d) >= 0) {
578 for (i = 0; i < 3; i++)
579 dir0[i] = funvalue(vray[3+i], 1, &d);
580 pix2loc(locx, &input[fn].rs, xscan+1, ymax-1-yscan);
581 pix2loc(locy, &input[fn].rs, xscan, ymax-yscan);
582 if (viewray(org, dirx, &input[fn].vw,
583 locx[0], locx[1]) >= 0 &&
584 viewray(org, diry, &input[fn].vw,
585 locy[0], locy[1]) >= 0) {
586 /* approximate solid angle */
587 for (i = 0; i < 3; i++) {
588 dirx[i] -= dir0[i];
589 diry[i] -= dir0[i];
590 }
591 fcross(dir0, dirx, diry);
592 psize[fn] = 0.5 * sqrt(DOT(dir0,dir0));
593 }
594 }
595 ltick[fn] = eclock;
596 }
597 return(psize[fn]);
598 }
599
600
601 wputs(msg)
602 char *msg;
603 {
604 if (!nowarn)
605 eputs(msg);
606 }
607
608
609 eputs(msg)
610 char *msg;
611 {
612 fputs(msg, stderr);
613 }
614
615
616 quit(code) /* exit gracefully */
617 int code;
618 {
619 register int i;
620 /* close input files */
621 for (i = 0; i < nfiles; i++)
622 if (input[i].name == Command)
623 pclose(input[i].fp);
624 else
625 fclose(input[i].fp);
626 exit(code);
627 }