ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcomb.c
Revision: 2.16
Committed: Mon Oct 16 12:04:33 1995 UTC (28 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.15: +33 -4 lines
Log Message:
added compatibility with Radiance XYZE picture format

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