ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcomb.c
Revision: 2.23
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.22: +4 -10 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

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