ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcomb.c
Revision: 2.15
Committed: Fri Feb 17 18:37:20 1995 UTC (29 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.14: +1 -1 lines
Log Message:
fixed potential bug in eclock tracking

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 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 newheader("RADIANCE", stdout); /* start header */
110 /* process files */
111 for (nfiles = 0; nfiles < MAXINP; nfiles++) {
112 setcolor(input[nfiles].coef, 1.0, 1.0, 1.0);
113 setcolor(input[nfiles].expos, 1.0, 1.0, 1.0);
114 copystruct(&input[nfiles].vw, &stdview);
115 }
116 nfiles = 0;
117 original = 0;
118 for ( ; a < argc; a++) {
119 if (nfiles >= MAXINP) {
120 eputs(argv[0]);
121 eputs(": too many picture files\n");
122 quit(1);
123 }
124 if (argv[a][0] == '-')
125 switch (argv[a][1]) {
126 case '\0':
127 input[nfiles].name = "<stdin>";
128 input[nfiles].fp = stdin;
129 break;
130 case 'o':
131 original++;
132 continue;
133 case 's':
134 f = atof(argv[++a]);
135 scalecolor(input[nfiles].coef, f);
136 continue;
137 case 'c':
138 colval(input[nfiles].coef,RED)*=atof(argv[++a]);
139 colval(input[nfiles].coef,GRN)*=atof(argv[++a]);
140 colval(input[nfiles].coef,BLU)*=atof(argv[++a]);
141 continue;
142 default:
143 goto usage;
144 }
145 else {
146 if (argv[a][0] == '!') {
147 input[nfiles].name = Command;
148 input[nfiles].fp = popen(argv[a]+1, "r");
149 } else {
150 input[nfiles].name = argv[a];
151 input[nfiles].fp = fopen(argv[a], "r");
152 }
153 if (input[nfiles].fp == NULL) {
154 perror(argv[a]);
155 quit(1);
156 }
157 }
158 checkfile();
159 if (original) {
160 colval(input[nfiles].coef,RED) /=
161 colval(input[nfiles].expos,RED);
162 colval(input[nfiles].coef,GRN) /=
163 colval(input[nfiles].expos,GRN);
164 colval(input[nfiles].coef,BLU) /=
165 colval(input[nfiles].expos,BLU);
166 }
167 nfiles++;
168 original = 0;
169 }
170 init(); /* set constants */
171 /* go back and get expressions */
172 for (a = 1; a < argc; a++) {
173 if (argv[a][0] == '-')
174 switch (argv[a][1]) {
175 case 'x':
176 varset(vxres, ':', eval(argv[++a]));
177 continue;
178 case 'y':
179 varset(vyres, ':', eval(argv[++a]));
180 continue;
181 case 'w':
182 continue;
183 case 'f':
184 fcompile(argv[++a]);
185 continue;
186 case 'e':
187 scompile(argv[++a], NULL, 0);
188 continue;
189 }
190 break;
191 }
192 /* set/get output resolution */
193 if (!vardefined(vxres))
194 varset(vxres, ':', (double)xmax);
195 if (!vardefined(vyres))
196 varset(vyres, ':', (double)ymax);
197 xres = varvalue(vxres) + .5;
198 yres = varvalue(vyres) + .5;
199 if (xres <= 0 || yres <= 0) {
200 eputs(argv[0]);
201 eputs(": illegal output resolution\n");
202 quit(1);
203 }
204 /* complete header */
205 printargs(argc, argv, stdout);
206 fputformat(COLRFMT, stdout);
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 tputs(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; /* don't echo */
230 if (formatval(fmt, s)) { /* check format */
231 wrongformat = strcmp(fmt, COLRFMT);
232 return; /* don't echo */
233 }
234 if (isexpos(s)) { /* exposure */
235 d = exposval(s);
236 scalecolor(input[nfiles].expos, d);
237 } else if (iscolcor(s)) { /* color correction */
238 colcorval(ctmp, s);
239 multcolor(input[nfiles].expos, ctmp);
240 } else if (isview(s) && sscanview(&input[nfiles].vw, s) > 0)
241 gotview++;
242 /* echo line */
243 putchar('\t');
244 fputs(s, stdout);
245 }
246
247
248 checkfile() /* ready a file */
249 {
250 register int i;
251 /* process header */
252 gotview = 0;
253 fputs(input[nfiles].name, stdout);
254 fputs(":\n", stdout);
255 getheader(input[nfiles].fp, tputs, NULL);
256 if (wrongformat) {
257 eputs(input[nfiles].name);
258 eputs(": not in Radiance picture format\n");
259 quit(1);
260 }
261 if (!gotview || setview(&input[nfiles].vw) != NULL)
262 input[nfiles].vw.type = 0;
263 if (!fgetsresolu(&input[nfiles].rs, input[nfiles].fp)) {
264 eputs(input[nfiles].name);
265 eputs(": bad picture size\n");
266 quit(1);
267 }
268 if (xmax == 0 && ymax == 0) {
269 xmax = scanlen(&input[nfiles].rs);
270 ymax = numscans(&input[nfiles].rs);
271 } else if (scanlen(&input[nfiles].rs) != xmax ||
272 numscans(&input[nfiles].rs) != ymax) {
273 eputs(input[nfiles].name);
274 eputs(": resolution mismatch\n");
275 quit(1);
276 }
277 /* allocate scanlines */
278 for (i = 0; i < WINSIZ; i++)
279 input[nfiles].scan[i] = (COLOR *)emalloc(xmax*sizeof(COLOR));
280 }
281
282
283 init() /* perform final setup */
284 {
285 double l_colin(), l_expos(), l_ray();
286 register int i;
287 /* define constants */
288 varset(vnfiles, ':', (double)nfiles);
289 varset(vxmax, ':', (double)xmax);
290 varset(vymax, ':', (double)ymax);
291 /* set functions */
292 for (i = 0; i < 3; i++) {
293 funset(vcolexp[i], 1, ':', l_expos);
294 funset(vcolin[i], 1, '=', l_colin);
295 }
296 funset(vbrtexp, 1, ':', l_expos);
297 funset(vbrtin, 1, '=', l_colin);
298 for (i = 0; i < 6; i++)
299 funset(vray[i], 1, '=', l_ray);
300 }
301
302
303 combine() /* combine pictures */
304 {
305 EPNODE *coldef[3], *brtdef;
306 COLOR *scanout;
307 double d;
308 register int i, j;
309 /* check defined variables */
310 for (j = 0; j < 3; j++) {
311 if (vardefined(vcolout[j]))
312 coldef[j] = eparse(vcolout[j]);
313 else
314 coldef[j] = NULL;
315 }
316 if (vardefined(vbrtout))
317 brtdef = eparse(vbrtout);
318 else
319 brtdef = NULL;
320 /* allocate scanline */
321 scanout = (COLOR *)emalloc(xres*sizeof(COLOR));
322 /* set input position */
323 yscan = ymax+MIDSCN;
324 /* combine files */
325 for (ypos = yres-1; ypos >= 0; ypos--) {
326 advance();
327 varset(vypos, '=', (double)ypos);
328 for (xpos = 0; xpos < xres; xpos++) {
329 xscan = (long)xpos*xmax/xres;
330 varset(vxpos, '=', (double)xpos);
331 eclock++;
332 if (brtdef != NULL) {
333 d = evalue(brtdef);
334 if (d < 0.0)
335 d = 0.0;
336 setcolor(scanout[xpos], d, d, d);
337 } else {
338 for (j = 0; j < 3; j++) {
339 if (coldef[j] != NULL) {
340 d = evalue(coldef[j]);
341 } else {
342 d = 0.0;
343 for (i = 0; i < nfiles; i++)
344 d += colval(input[i].scan[MIDSCN][xscan],j);
345 }
346 if (d < 0.0)
347 d = 0.0;
348 colval(scanout[xpos],j) = d;
349 }
350 }
351 }
352 if (fwritescan(scanout, xres, stdout) < 0) {
353 perror("write error");
354 quit(1);
355 }
356 }
357 efree(scanout);
358 }
359
360
361 advance() /* read in data for next scanline */
362 {
363 int ytarget;
364 register COLOR *st;
365 register int i, j;
366
367 for (ytarget = (long)ypos*ymax/yres; yscan > ytarget; yscan--)
368 for (i = 0; i < nfiles; i++) {
369 st = input[i].scan[WINSIZ-1];
370 for (j = WINSIZ-1; j > 0; j--) /* rotate window */
371 input[i].scan[j] = input[i].scan[j-1];
372 input[i].scan[0] = st;
373 if (yscan <= MIDSCN) /* hit bottom? */
374 continue;
375 if (freadscan(st, xmax, input[i].fp) < 0) { /* read */
376 eputs(input[i].name);
377 eputs(": read error\n");
378 quit(1);
379 }
380 if (fabs(colval(input[i].coef,RED)-1.0) > 1e-3 ||
381 fabs(colval(input[i].coef,GRN)-1.0) > 1e-3 ||
382 fabs(colval(input[i].coef,BLU)-1.0) > 1e-3)
383 for (j = 0; j < xmax; j++) /* adjust color */
384 multcolor(st[j], input[i].coef);
385 }
386 }
387
388
389 double
390 l_expos(nam) /* return picture exposure */
391 register char *nam;
392 {
393 register int fn, n;
394
395 fn = argument(1) - .5;
396 if (fn < 0 || fn >= nfiles)
397 return(1.0);
398 if (nam == vbrtexp)
399 return(bright(input[fn].expos));
400 n = 3;
401 while (n--)
402 if (nam == vcolexp[n])
403 return(colval(input[fn].expos,n));
404 eputs("Bad call to l_expos()!\n");
405 quit(1);
406 }
407
408
409 double
410 l_colin(nam) /* return color value for picture */
411 register char *nam;
412 {
413 int fn;
414 register int n, xoff, yoff;
415 double d;
416
417 d = argument(1);
418 if (d > -.5 && d < .5)
419 return((double)nfiles);
420 fn = d - .5;
421 if (fn < 0 || fn >= nfiles) {
422 errno = EDOM;
423 return(0.0);
424 }
425 xoff = yoff = 0;
426 n = nargum();
427 if (n >= 2) {
428 d = argument(2);
429 if (d < 0.0) {
430 xoff = d-.5;
431 if (xscan+xoff < 0)
432 xoff = -xscan;
433 } else {
434 xoff = d+.5;
435 if (xscan+xoff >= xmax)
436 xoff = xmax-1-xscan;
437 }
438 }
439 if (n >= 3) {
440 d = argument(3);
441 if (d < 0.0) {
442 yoff = d-.5;
443 if (yoff+MIDSCN < 0)
444 yoff = -MIDSCN;
445 if (yscan+yoff < 0)
446 yoff = -yscan;
447 } else {
448 yoff = d+.5;
449 if (yoff+MIDSCN >= WINSIZ)
450 yoff = WINSIZ-1-MIDSCN;
451 if (yscan+yoff >= ymax)
452 yoff = ymax-1-yscan;
453 }
454 }
455 if (nam == vbrtin)
456 return(bright(input[fn].scan[MIDSCN+yoff][xscan+xoff]));
457 n = 3;
458 while (n--)
459 if (nam == vcolin[n])
460 return(colval(input[fn].scan[MIDSCN+yoff][xscan+xoff],n));
461 eputs("Bad call to l_colin()!\n");
462 quit(1);
463 }
464
465
466 double
467 l_ray(nam) /* return ray origin or direction */
468 register char *nam;
469 {
470 static unsigned long ltick[MAXINP];
471 static FVECT lorg[MAXINP], ldir[MAXINP];
472 FLOAT loc[2];
473 double d;
474 int fn;
475 register int i;
476
477 d = argument(1);
478 if (d > -.5 && d < .5)
479 return((double)nfiles);
480 fn = d - .5;
481 if (fn < 0 || fn >= nfiles) {
482 errno = EDOM;
483 return(0.0);
484 }
485 if (ltick[fn] < eclock) { /* need to compute? */
486 lorg[fn][0] = lorg[fn][1] = lorg[fn][2] = 0.0;
487 ldir[fn][0] = ldir[fn][1] = ldir[fn][2] = 0.0;
488 if (input[fn].vw.type == 0)
489 errno = EDOM;
490 else {
491 pix2loc(loc, &input[fn].rs, xscan, ymax-1-yscan);
492 if (viewray(lorg[fn], ldir[fn],
493 &input[fn].vw, loc[0], loc[1]) < 0)
494 errno = ERANGE;
495 }
496 ltick[fn] = eclock;
497 }
498 i = 6;
499 while (i--)
500 if (nam == vray[i])
501 return(i < 3 ? lorg[fn][i] : ldir[fn][i-3]);
502 eputs("Bad call to l_ray()!\n");
503 quit(1);
504 }
505
506
507 wputs(msg)
508 char *msg;
509 {
510 if (!nowarn)
511 eputs(msg);
512 }
513
514
515 eputs(msg)
516 char *msg;
517 {
518 fputs(msg, stderr);
519 }
520
521
522 quit(code) /* exit gracefully */
523 int code;
524 {
525 register int i;
526 /* close input files */
527 for (i = 0; i < nfiles; i++)
528 if (input[i].name == Command)
529 pclose(input[i].fp);
530 else
531 fclose(input[i].fp);
532 exit(code);
533 }