ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcomb.c
Revision: 2.7
Committed: Mon Sep 21 12:13:48 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.6: +12 -0 lines
Log Message:
Changes for PC port

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 <stdio.h>
14
15 #ifdef MSDOS
16 #include <fcntl.h>
17 #endif
18
19 #include <errno.h>
20
21 #include "color.h"
22
23 #include "resolu.h"
24
25 #include "calcomp.h"
26
27 #define MAXINP 32 /* maximum number of input files */
28 #define WINSIZ 9 /* scanline window size */
29 #define MIDSCN 4 /* current scan position */
30
31 struct {
32 char *name; /* file or command name */
33 FILE *fp; /* stream pointer */
34 COLOR *scan[WINSIZ]; /* input scanline window */
35 COLOR coef; /* coefficient */
36 COLOR expos; /* recorded exposure */
37 } input[MAXINP]; /* input pictures */
38
39 int nfiles; /* number of input files */
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 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 int wrongformat = 0;
68
69 FILE *popen();
70
71 extern char *emalloc();
72
73
74 main(argc, argv)
75 int argc;
76 char *argv[];
77 {
78 int original;
79 double f;
80 int a, i;
81 #ifdef MSDOS
82 extern int _fmode;
83 _fmode = O_BINARY;
84 setmode(fileno(stdin), O_BINARY);
85 setmode(fileno(stdout), O_BINARY);
86 #endif
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 /* process files */
106 for (nfiles = 0; nfiles < MAXINP; nfiles++) {
107 setcolor(input[nfiles].coef, 1.0, 1.0, 1.0);
108 setcolor(input[nfiles].expos, 1.0, 1.0, 1.0);
109 }
110 nfiles = 0;
111 original = 0;
112 for ( ; a < argc; a++) {
113 if (nfiles >= MAXINP) {
114 eputs(argv[0]);
115 eputs(": too many picture files\n");
116 quit(1);
117 }
118 if (argv[a][0] == '-')
119 switch (argv[a][1]) {
120 case '\0':
121 input[nfiles].name = "<stdin>";
122 input[nfiles].fp = stdin;
123 break;
124 case 'o':
125 original++;
126 continue;
127 case 's':
128 f = atof(argv[++a]);
129 scalecolor(input[nfiles].coef, f);
130 continue;
131 case 'c':
132 colval(input[nfiles].coef,RED)*=atof(argv[++a]);
133 colval(input[nfiles].coef,GRN)*=atof(argv[++a]);
134 colval(input[nfiles].coef,BLU)*=atof(argv[++a]);
135 continue;
136 default:
137 goto usage;
138 }
139 else {
140 if (argv[a][0] == '!') {
141 input[nfiles].name = Command;
142 input[nfiles].fp = popen(argv[a]+1, "r");
143 } else {
144 input[nfiles].name = argv[a];
145 input[nfiles].fp = fopen(argv[a], "r");
146 }
147 if (input[nfiles].fp == NULL) {
148 perror(argv[a]);
149 quit(1);
150 }
151 }
152 checkfile();
153 if (original) {
154 colval(input[nfiles].coef,RED) /=
155 colval(input[nfiles].expos,RED);
156 colval(input[nfiles].coef,GRN) /=
157 colval(input[nfiles].expos,GRN);
158 colval(input[nfiles].coef,BLU) /=
159 colval(input[nfiles].expos,BLU);
160 }
161 nfiles++;
162 original = 0;
163 }
164 init(); /* set constants */
165 /* go back and get expressions */
166 for (a = 1; a < argc; a++) {
167 if (argv[a][0] == '-')
168 switch (argv[a][1]) {
169 case 'x':
170 varset(vxres, ':', eval(argv[++a]));
171 continue;
172 case 'y':
173 varset(vyres, ':', eval(argv[++a]));
174 continue;
175 case 'w':
176 continue;
177 case 'f':
178 fcompile(argv[++a]);
179 continue;
180 case 'e':
181 scompile(argv[++a], NULL, 0);
182 continue;
183 }
184 break;
185 }
186 /* set/get output resolution */
187 if (!vardefined(vxres))
188 varset(vxres, ':', (double)xmax);
189 if (!vardefined(vyres))
190 varset(vyres, ':', (double)ymax);
191 xres = varvalue(vxres) + .5;
192 yres = varvalue(vyres) + .5;
193 if (xres <= 0 || yres <= 0) {
194 eputs(argv[0]);
195 eputs(": illegal output resolution\n");
196 quit(1);
197 }
198 /* complete header */
199 printargs(argc, argv, stdout);
200 fputformat(COLRFMT, stdout);
201 putchar('\n');
202 fprtresolu(xres, yres, stdout);
203 /* combine pictures */
204 combine();
205 quit(0);
206 usage:
207 eputs("Usage: ");
208 eputs(argv[0]);
209 eputs(
210 " [-w][-x xr][-y yr][-e expr][-f file] [ [-s f][-c r g b] pic ..]\n");
211 quit(1);
212 }
213
214
215 tputs(s) /* put out string preceded by a tab */
216 char *s;
217 {
218 char fmt[32];
219 double d;
220 COLOR ctmp;
221
222 if (isformat(s)) { /* check format */
223 formatval(fmt, s);
224 wrongformat = strcmp(fmt, COLRFMT);
225 return; /* don't echo */
226 }
227 if (isexpos(s)) { /* exposure */
228 d = exposval(s);
229 scalecolor(input[nfiles].expos, d);
230 } else if (iscolcor(s)) { /* color correction */
231 colcorval(ctmp, s);
232 multcolor(input[nfiles].expos, ctmp);
233 }
234 /* echo line */
235 putchar('\t');
236 fputs(s, stdout);
237 }
238
239
240 checkfile() /* ready a file */
241 {
242 int xinp, yinp;
243 register int i;
244 /* process header */
245 fputs(input[nfiles].name, stdout);
246 fputs(":\n", stdout);
247 getheader(input[nfiles].fp, tputs, NULL);
248 if (wrongformat) {
249 eputs(input[nfiles].name);
250 eputs(": not in Radiance picture format\n");
251 quit(1);
252 }
253 if (fgetresolu(&xinp, &yinp, input[nfiles].fp) < 0) {
254 eputs(input[nfiles].name);
255 eputs(": bad picture size\n");
256 quit(1);
257 }
258 if (xmax == 0 && ymax == 0) {
259 xmax = xinp;
260 ymax = yinp;
261 } else if (xinp != xmax || yinp != ymax) {
262 eputs(input[nfiles].name);
263 eputs(": resolution mismatch\n");
264 quit(1);
265 }
266 /* allocate scanlines */
267 for (i = 0; i < WINSIZ; i++)
268 input[nfiles].scan[i] = (COLOR *)emalloc(xmax*sizeof(COLOR));
269 }
270
271
272 init() /* perform final setup */
273 {
274 double l_colin(), l_expos();
275 register int i;
276 /* define constants */
277 varset(vnfiles, ':', (double)nfiles);
278 varset(vxmax, ':', (double)xmax);
279 varset(vymax, ':', (double)ymax);
280 /* set functions */
281 for (i = 0; i < 3; i++) {
282 funset(vcolexp[i], 1, ':', l_expos);
283 funset(vcolin[i], 1, '=', l_colin);
284 }
285 funset(vbrtexp, 1, ':', l_expos);
286 funset(vbrtin, 1, '=', l_colin);
287 }
288
289
290 combine() /* combine pictures */
291 {
292 EPNODE *coldef[3], *brtdef;
293 COLOR *scanout;
294 double d;
295 register int i, j;
296 /* check defined variables */
297 for (j = 0; j < 3; j++) {
298 if (vardefined(vcolout[j]))
299 coldef[j] = eparse(vcolout[j]);
300 else
301 coldef[j] = NULL;
302 }
303 if (vardefined(vbrtout))
304 brtdef = eparse(vbrtout);
305 else
306 brtdef = NULL;
307 /* allocate scanline */
308 scanout = (COLOR *)emalloc(xres*sizeof(COLOR));
309 /* set input position */
310 yscan = ymax+MIDSCN;
311 /* combine files */
312 for (ypos = yres-1; ypos >= 0; ypos--) {
313 advance();
314 varset(vypos, '=', (double)ypos);
315 for (xpos = 0; xpos < xres; xpos++) {
316 xscan = (long)xpos*xmax/xres;
317 varset(vxpos, '=', (double)xpos);
318 eclock++;
319 if (brtdef != NULL) {
320 d = evalue(brtdef);
321 if (d < 0.0)
322 d = 0.0;
323 setcolor(scanout[xpos], d, d, d);
324 } else {
325 for (j = 0; j < 3; j++) {
326 if (coldef[j] != NULL) {
327 d = evalue(coldef[j]);
328 } else {
329 d = 0.0;
330 for (i = 0; i < nfiles; i++)
331 d += colval(input[i].scan[MIDSCN][xscan],j);
332 }
333 if (d < 0.0)
334 d = 0.0;
335 colval(scanout[xpos],j) = d;
336 }
337 }
338 }
339 if (fwritescan(scanout, xres, stdout) < 0) {
340 perror("write error");
341 quit(1);
342 }
343 }
344 efree(scanout);
345 }
346
347
348 advance() /* read in data for next scanline */
349 {
350 extern double fabs();
351 int ytarget;
352 register COLOR *st;
353 register int i, j;
354
355 for (ytarget = (long)ypos*ymax/yres; yscan > ytarget; yscan--)
356 for (i = 0; i < nfiles; i++) {
357 st = input[i].scan[WINSIZ-1];
358 for (j = WINSIZ-1; j > 0; j--) /* rotate window */
359 input[i].scan[j] = input[i].scan[j-1];
360 input[i].scan[0] = st;
361 if (yscan <= MIDSCN) /* hit bottom? */
362 continue;
363 if (freadscan(st, xmax, input[i].fp) < 0) { /* read */
364 eputs(input[i].name);
365 eputs(": read error\n");
366 quit(1);
367 }
368 if (fabs(colval(input[i].coef,RED)-1.0) > 1e-3 ||
369 fabs(colval(input[i].coef,GRN)-1.0) > 1e-3 ||
370 fabs(colval(input[i].coef,BLU)-1.0) > 1e-3)
371 for (j = 0; j < xmax; j++) /* adjust color */
372 multcolor(st[j], input[i].coef);
373 }
374 }
375
376
377 double
378 l_expos(nam) /* return picture exposure */
379 register char *nam;
380 {
381 register int fn, n;
382
383 fn = argument(1) - .5;
384 if (fn < 0 || fn >= nfiles)
385 return(1.0);
386 if (nam == vbrtexp)
387 return(bright(input[fn].expos));
388 n = 3;
389 while (n--)
390 if (nam == vcolexp[n])
391 return(colval(input[fn].expos,n));
392 eputs("Bad call to l_expos()!\n");
393 quit(1);
394 }
395
396
397 double
398 l_colin(nam) /* return color value for picture */
399 register char *nam;
400 {
401 int fn;
402 register int n, xoff, yoff;
403 double d;
404
405 d = argument(1);
406 if (d > -.5 && d < .5)
407 return((double)nfiles);
408 fn = d - .5;
409 if (fn < 0 || fn >= nfiles) {
410 errno = EDOM;
411 return(0.0);
412 }
413 xoff = yoff = 0;
414 n = nargum();
415 if (n >= 2) {
416 d = argument(2);
417 if (d < 0.0) {
418 xoff = d-.5;
419 if (xscan+xoff < 0)
420 xoff = -xscan;
421 } else {
422 xoff = d+.5;
423 if (xscan+xoff >= xmax)
424 xoff = xmax-1-xscan;
425 }
426 }
427 if (n >= 3) {
428 d = argument(3);
429 if (d < 0.0) {
430 yoff = d-.5;
431 if (yoff+MIDSCN < 0)
432 yoff = -MIDSCN;
433 if (yscan+yoff < 0)
434 yoff = -yscan;
435 } else {
436 yoff = d+.5;
437 if (yoff+MIDSCN >= WINSIZ)
438 yoff = WINSIZ-1-MIDSCN;
439 if (yscan+yoff >= ymax)
440 yoff = ymax-1-yscan;
441 }
442 }
443 if (nam == vbrtin)
444 return(bright(input[fn].scan[MIDSCN+yoff][xscan+xoff]));
445 n = 3;
446 while (n--)
447 if (nam == vcolin[n])
448 return(colval(input[fn].scan[MIDSCN+yoff][xscan+xoff],n));
449 eputs("Bad call to l_colin()!\n");
450 quit(1);
451 }
452
453
454 wputs(msg)
455 char *msg;
456 {
457 if (!nowarn)
458 eputs(msg);
459 }
460
461
462 eputs(msg)
463 char *msg;
464 {
465 fputs(msg, stderr);
466 }
467
468
469 quit(code) /* exit gracefully */
470 int code;
471 {
472 register int i;
473 /* close input files */
474 for (i = 0; i < nfiles; i++)
475 if (input[i].name == Command)
476 pclose(input[i].fp);
477 else
478 fclose(input[i].fp);
479 exit(code);
480 }