ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcomb.c
Revision: 1.17
Committed: Fri May 24 17:14:49 1991 UTC (32 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.16: +36 -26 lines
Log Message:
changed operation of -o option

File Contents

# Content
1 /* Copyright (c) 1991 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 #include <errno.h>
16
17 #include "color.h"
18
19 #include "calcomp.h"
20
21 #define MAXINP 32 /* maximum number of input files */
22 #define WINSIZ 9 /* scanline window size */
23 #define MIDSCN 4 /* current scan position */
24
25 #define BRT (-1) /* special index for brightness */
26
27 struct {
28 char *name; /* file name */
29 FILE *fp; /* stream pointer */
30 COLOR *scan[WINSIZ]; /* input scanline window */
31 COLOR coef; /* coefficient */
32 COLOR expos; /* recorded exposure */
33 } input[MAXINP]; /* input pictures */
34
35 int nfiles; /* number of input files */
36
37 char *vcolin[3] = {"ri", "gi", "bi"};
38 char *vcolout[3] = {"ro", "go", "bo"};
39 char vbrtin[] = "li";
40 char vbrtout[] = "lo";
41 char *vcolexp[3] = {"re", "ge", "be"};
42 char vbrtexp[] = "le";
43
44 #define vnfiles "nfiles"
45 #define vxres "xres"
46 #define vyres "yres"
47 #define vxpos "x"
48 #define vypos "y"
49
50 int nowarn = 0; /* no warning messages? */
51
52 int original = 0; /* origninal values? */
53
54 int xres=0, yres=0; /* picture resolution */
55
56 int xpos, ypos; /* picture position */
57
58 int wrongformat = 0;
59
60
61 main(argc, argv)
62 int argc;
63 char *argv[];
64 {
65 double f;
66 int a, i;
67 /* scan options */
68 for (a = 1; a < argc; a++) {
69 if (argv[a][0] == '-')
70 switch (argv[a][1]) {
71 case 'x':
72 xres = atoi(argv[++a]);
73 continue;
74 case 'y':
75 yres = atoi(argv[++a]);
76 continue;
77 case 'w':
78 nowarn = !nowarn;
79 continue;
80 case 'f':
81 case 'e':
82 a++;
83 continue;
84 }
85 break;
86 }
87 /* process files */
88 for (nfiles = 0; nfiles < MAXINP; nfiles++) {
89 setcolor(input[nfiles].coef, 1.0, 1.0, 1.0);
90 setcolor(input[nfiles].expos, 1.0, 1.0, 1.0);
91 }
92 nfiles = 0;
93 for ( ; a < argc; a++) {
94 if (nfiles >= MAXINP) {
95 eputs(argv[0]);
96 eputs(": too many picture files\n");
97 quit(1);
98 }
99 if (argv[a][0] == '-')
100 switch (argv[a][1]) {
101 case '\0':
102 input[nfiles].name = "<stdin>";
103 input[nfiles].fp = stdin;
104 break;
105 case 'o':
106 original++;
107 break;
108 case 's':
109 f = atof(argv[++a]);
110 scalecolor(input[nfiles].coef, f);
111 continue;
112 case 'c':
113 colval(input[nfiles].coef,RED)*=atof(argv[++a]);
114 colval(input[nfiles].coef,GRN)*=atof(argv[++a]);
115 colval(input[nfiles].coef,BLU)*=atof(argv[++a]);
116 continue;
117 default:
118 goto usage;
119 }
120 else {
121 input[nfiles].name = argv[a];
122 input[nfiles].fp = fopen(argv[a], "r");
123 if (input[nfiles].fp == NULL) {
124 perror(argv[a]);
125 quit(1);
126 }
127 }
128 checkfile();
129 original = 0;
130 nfiles++;
131 }
132 init(); /* set constant expressions */
133 /* go back and get expressions */
134 for (a = 1; a < argc; a++) {
135 if (argv[a][0] == '-')
136 switch (argv[a][1]) {
137 case 'x':
138 case 'y':
139 a++;
140 continue;
141 case 'w':
142 continue;
143 case 'f':
144 fcompile(argv[++a]);
145 continue;
146 case 'e':
147 scompile(argv[++a], NULL, 0);
148 continue;
149 }
150 break;
151 }
152 /* complete header */
153 printargs(argc, argv, stdout);
154 fputformat(COLRFMT, stdout);
155 putchar('\n');
156 fputresolu(YMAJOR|YDECR, xres, yres, stdout);
157 /* combine pictures */
158 combine();
159 quit(0);
160 usage:
161 eputs("Usage: ");
162 eputs(argv[0]);
163 eputs(
164 " [-w][-h][-x xr][-y yr][-e expr][-f file] [ [-s f][-c r g b] pic ..]\n");
165 quit(1);
166 }
167
168
169 tputs(s) /* put out string preceded by a tab */
170 char *s;
171 {
172 char fmt[32];
173 double d;
174 COLOR ctmp;
175
176 if (isformat(s)) { /* check format */
177 formatval(fmt, s);
178 wrongformat = strcmp(fmt, COLRFMT);
179 return; /* don't echo */
180 }
181 if (isexpos(s)) { /* exposure */
182 d = exposval(s);
183 scalecolor(input[nfiles].expos, d);
184 if (original)
185 scalecolor(input[nfiles].coef, 1.0/d);
186 } else if (iscolcor(s)) { /* color correction */
187 colcorval(ctmp, s);
188 multcolor(input[nfiles].expos, ctmp);
189 if (original) {
190 colval(input[nfiles].coef,RED) /= colval(ctmp,RED);
191 colval(input[nfiles].coef,GRN) /= colval(ctmp,GRN);
192 colval(input[nfiles].coef,BLU) /= colval(ctmp,BLU);
193 }
194 }
195 /* echo line */
196 putchar('\t');
197 fputs(s, stdout);
198 }
199
200
201 checkfile() /* ready a file */
202 {
203 register int i;
204 /* process header */
205 fputs(input[nfiles].name, stdout);
206 fputs(":\n", stdout);
207 getheader(input[nfiles].fp, tputs, NULL);
208 if (wrongformat) {
209 eputs(input[nfiles].name);
210 eputs(": not in Radiance picture format\n");
211 quit(1);
212 }
213 if (fgetresolu(&xpos, &ypos, input[nfiles].fp) != (YMAJOR|YDECR)) {
214 eputs(input[nfiles].name);
215 eputs(": bad picture size\n");
216 quit(1);
217 }
218 if (xres == 0 && yres == 0) {
219 xres = xpos;
220 yres = ypos;
221 } else if (xpos != xres || ypos != yres) {
222 eputs(input[nfiles].name);
223 eputs(": resolution mismatch\n");
224 quit(1);
225 }
226 /* allocate scanlines */
227 for (i = 0; i < WINSIZ; i++)
228 input[nfiles].scan[i] = (COLOR *)emalloc(xres*sizeof(COLOR));
229 }
230
231
232 init() /* perform final setup */
233 {
234 double l_colin(), l_expos();
235 register int i;
236 /* prime input */
237 for (ypos = yres+(MIDSCN-1); ypos >= yres; ypos--)
238 advance();
239 /* define constants */
240 varset(vnfiles, ':', (double)nfiles);
241 varset(vxres, ':', (double)xres);
242 varset(vyres, ':', (double)yres);
243 /* set functions */
244 for (i = 0; i < 3; i++) {
245 funset(vcolexp[i], 1, ':', l_expos);
246 funset(vcolin[i], 1, '=', l_colin);
247 }
248 funset(vbrtexp, 1, ':', l_expos);
249 funset(vbrtin, 1, '=', l_colin);
250 }
251
252
253 combine() /* combine pictures */
254 {
255 EPNODE *coldef[3], *brtdef;
256 COLOR *scanout;
257 double d;
258 register int i, j;
259 /* check defined variables */
260 for (j = 0; j < 3; j++) {
261 if (vardefined(vcolout[j]))
262 coldef[j] = eparse(vcolout[j]);
263 else
264 coldef[j] = NULL;
265 }
266 if (vardefined(vbrtout))
267 brtdef = eparse(vbrtout);
268 else
269 brtdef = NULL;
270 /* allocate scanline */
271 scanout = (COLOR *)emalloc(xres*sizeof(COLOR));
272 /* combine files */
273 for (ypos = yres-1; ypos >= 0; ypos--) {
274 advance();
275 varset(vypos, '=', (double)ypos);
276 for (xpos = 0; xpos < xres; xpos++) {
277 varset(vxpos, '=', (double)xpos);
278 eclock++;
279 if (brtdef != NULL) {
280 d = evalue(brtdef);
281 if (d < 0.0)
282 d = 0.0;
283 setcolor(scanout[xpos], d, d, d);
284 } else {
285 for (j = 0; j < 3; j++) {
286 if (coldef[j] != NULL) {
287 d = evalue(coldef[j]);
288 } else {
289 d = 0.0;
290 for (i = 0; i < nfiles; i++)
291 d += colval(input[i].scan[MIDSCN][xpos],j);
292 }
293 if (d < 0.0)
294 d = 0.0;
295 colval(scanout[xpos],j) = d;
296 }
297 }
298 }
299 if (fwritescan(scanout, xres, stdout) < 0) {
300 perror("write error");
301 quit(1);
302 }
303 }
304 efree(scanout);
305 }
306
307
308 advance() /* read in next scanline */
309 {
310 register COLOR *st;
311 register int i, j;
312
313 for (i = 0; i < nfiles; i++) {
314 st = input[i].scan[WINSIZ-1];
315 for (j = WINSIZ-1; j > 0; j--) /* rotate window */
316 input[i].scan[j] = input[i].scan[j-1];
317 input[i].scan[0] = st;
318 if (ypos < MIDSCN) /* hit bottom */
319 continue;
320 if (freadscan(st, xres, input[i].fp) < 0) {
321 eputs(input[i].name);
322 eputs(": read error\n");
323 quit(1);
324 }
325 for (j = 0; j < xres; j++) /* adjust color */
326 multcolor(st[j], input[i].coef);
327 }
328 }
329
330
331 double
332 l_expos(nam) /* return picture exposure */
333 register char *nam;
334 {
335 register int fn, n;
336 double d;
337
338 d = argument(1);
339 if (d > -.5 && d < .5)
340 return((double)nfiles);
341 fn = d - .5;
342 if (fn < 0 || fn >= nfiles) {
343 errno = EDOM;
344 return(0.0);
345 }
346 if (nam == vbrtexp)
347 return(bright(input[fn].expos));
348 n = 3;
349 while (n--)
350 if (nam == vcolexp[n])
351 return(colval(input[fn].expos,n));
352 eputs("Bad call to l_expos()!\n");
353 quit(1);
354 }
355
356
357 double
358 l_colin(nam) /* return color value for picture */
359 register char *nam;
360 {
361 int fn;
362 register int n, xoff, yoff;
363 double d;
364
365 d = argument(1);
366 if (d > -.5 && d < .5)
367 return((double)nfiles);
368 fn = d - .5;
369 if (fn < 0 || fn >= nfiles) {
370 errno = EDOM;
371 return(0.0);
372 }
373 xoff = yoff = 0;
374 n = nargum();
375 if (n >= 2) {
376 d = argument(2);
377 if (d < 0.0) {
378 xoff = d-.5;
379 if (xpos+xoff < 0)
380 xoff = -xpos;
381 } else {
382 xoff = d+.5;
383 if (xpos+xoff >= xres)
384 xoff = xres-1-xpos;
385 }
386 }
387 if (n >= 3) {
388 d = argument(3);
389 if (d < 0.0) {
390 yoff = d-.5;
391 if (yoff+MIDSCN < 0)
392 yoff = -MIDSCN;
393 if (ypos+yoff < 0)
394 yoff = -ypos;
395 } else {
396 yoff = d+.5;
397 if (yoff+MIDSCN >= WINSIZ)
398 yoff = WINSIZ-1-MIDSCN;
399 if (ypos+yoff >= yres)
400 yoff = yres-1-ypos;
401 }
402 }
403 if (nam == vbrtin)
404 return(bright(input[fn].scan[MIDSCN+yoff][xpos+xoff]));
405 n = 3;
406 while (n--)
407 if (nam == vcolin[n])
408 return(colval(input[fn].scan[MIDSCN+yoff][xpos+xoff],n));
409 eputs("Bad call to l_colin()!\n");
410 quit(1);
411 }
412
413
414 wputs(msg)
415 char *msg;
416 {
417 if (!nowarn)
418 eputs(msg);
419 }
420
421
422 eputs(msg)
423 char *msg;
424 {
425 fputs(msg, stderr);
426 }
427
428
429 quit(code)
430 int code;
431 {
432 exit(code);
433 }