ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pcompos.c
Revision: 2.29
Committed: Sun Mar 28 20:33:14 2004 UTC (20 years ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6, rad3R6P1
Changes since 2.28: +25 -14 lines
Log Message:
Continued ANSIfication, and other fixes and clarifications.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: pcompos.c,v 2.28 2004/03/15 21:16:54 greg Exp $";
3 #endif
4 /*
5 * pcompos.c - program to composite pictures.
6 *
7 * 6/30/87
8 */
9
10 #include <stdio.h>
11 #include <math.h>
12 #include <time.h>
13 #include <string.h>
14
15 #include "copyright.h"
16
17 #include "platform.h"
18 #include "rtprocess.h"
19 #include "rterror.h"
20 #include "color.h"
21 #include "resolu.h"
22
23 #define MAXFILE 64
24
25 #define HASMIN 1
26 #define HASMAX 2
27
28 /* output picture size */
29 int xsiz = 0;
30 int ysiz = 0;
31 /* input dimensions */
32 int xmin = 0;
33 int ymin = 0;
34 int xmax = 0;
35 int ymax = 0;
36
37 COLR bgcolr = BLKCOLR; /* background color */
38
39 int labelht = 24; /* label height */
40
41 int checkthresh = 0; /* check threshold value */
42
43 char StandardInput[] = "<stdin>";
44 char Command[] = "<Command>";
45 char Label[] = "<Label>";
46
47 char *progname;
48
49 struct {
50 char *name; /* file or command name */
51 FILE *fp; /* stream pointer */
52 int xres, yres; /* picture size */
53 int xloc, yloc; /* anchor point */
54 int flags; /* HASMIN, HASMAX */
55 COLR thmin, thmax; /* thresholds */
56 } input[MAXFILE]; /* our input files */
57
58 int nfile; /* number of files */
59
60 char ourfmt[LPICFMT+1] = PICFMT;
61 int wrongformat = 0;
62
63
64 static gethfunc tabputs;
65 static void compos(void);
66 static int cmpcolr(COLR c1, COLR c2);
67 static FILE * lblopen(char *s, int *xp, int *yp);
68
69
70
71 static int
72 tabputs( /* print line preceded by a tab */
73 char *s,
74 void *p
75 )
76 {
77 char fmt[32];
78
79 if (isheadid(s))
80 return(0);
81 if (formatval(fmt, s)) {
82 if (globmatch(ourfmt, fmt)) {
83 wrongformat = 0;
84 strcpy(ourfmt, fmt);
85 } else
86 wrongformat = 1;
87 } else {
88 putc('\t', stdout);
89 fputs(s, stdout);
90 }
91 return(0);
92 }
93
94
95 int
96 main(
97 int argc,
98 char *argv[]
99 )
100 {
101 int ncolumns = 0;
102 int autolabel = 0;
103 int curcol = 0, x0 = 0, curx = 0, cury = 0, spacing = 0;
104 int xsgn, ysgn;
105 char *thislabel;
106 int an;
107 SET_DEFAULT_BINARY();
108 SET_FILE_BINARY(stdin);
109 SET_FILE_BINARY(stdout);
110 progname = argv[0];
111
112 for (an = 1; an < argc && argv[an][0] == '-'; an++)
113 switch (argv[an][1]) {
114 case 'x':
115 xsiz = atoi(argv[++an]);
116 break;
117 case 'y':
118 ysiz = atoi(argv[++an]);
119 break;
120 case 'b':
121 setcolr(bgcolr, atof(argv[an+1]),
122 atof(argv[an+2]),
123 atof(argv[an+3]));
124 an += 3;
125 break;
126 case 'a':
127 ncolumns = atoi(argv[++an]);
128 break;
129 case 's':
130 spacing = atoi(argv[++an]);
131 break;
132 case 'o':
133 curx = x0 = atoi(argv[++an]);
134 cury = atoi(argv[++an]);
135 break;
136 case 'l':
137 switch (argv[an][2]) {
138 case 'a':
139 autolabel++;
140 break;
141 case 'h':
142 labelht = atoi(argv[++an]);
143 break;
144 case '\0':
145 goto dofiles;
146 default:
147 goto userr;
148 }
149 break;
150 case '\0':
151 case 't':
152 goto dofiles;
153 default:
154 goto userr;
155 }
156 dofiles:
157 newheader("RADIANCE", stdout);
158 fputnow(stdout);
159 for (nfile = 0; an < argc; nfile++) {
160 if (nfile >= MAXFILE)
161 goto toomany;
162 thislabel = NULL;
163 input[nfile].flags = 0;
164 xsgn = ysgn = '-';
165 while (an < argc && (argv[an][0] == '-' || argv[an][0] == '+'
166 || argv[an][0] == '=')) {
167 switch (argv[an][1]) {
168 case 't':
169 checkthresh = 1;
170 if (argv[an][0] == '-') {
171 input[nfile].flags |= HASMIN;
172 setcolr(input[nfile].thmin,
173 atof(argv[an+1]),
174 atof(argv[an+1]),
175 atof(argv[an+1]));
176 } else if (argv[an][0] == '+') {
177 input[nfile].flags |= HASMAX;
178 setcolr(input[nfile].thmax,
179 atof(argv[an+1]),
180 atof(argv[an+1]),
181 atof(argv[an+1]));
182 } else
183 goto userr;
184 an++;
185 break;
186 case 'l':
187 if (strcmp(argv[an], "-l"))
188 goto userr;
189 thislabel = argv[++an];
190 break;
191 case '+':
192 case '-':
193 case '0':
194 if (argv[an][0] != '=')
195 goto userr;
196 xsgn = argv[an][1];
197 ysgn = argv[an][2];
198 if (ysgn != '+' && ysgn != '-' && ysgn != '0')
199 goto userr;
200 break;
201 case '\0':
202 if (argv[an][0] == '-')
203 goto getfile;
204 goto userr;
205 default:
206 goto userr;
207 }
208 an++;
209 }
210 getfile:
211 if (argc-an < (ncolumns ? 1 : 3))
212 goto userr;
213 if (autolabel && thislabel == NULL)
214 thislabel = argv[an];
215 if (!strcmp(argv[an], "-")) {
216 input[nfile].name = StandardInput;
217 input[nfile].fp = stdin;
218 } else {
219 if (argv[an][0] == '!') {
220 input[nfile].name = Command;
221 input[nfile].fp = popen(argv[an]+1, "r");
222 } else {
223 input[nfile].name = argv[an];
224 input[nfile].fp = fopen(argv[an], "r");
225 }
226 if (input[nfile].fp == NULL) {
227 perror(argv[an]);
228 quit(1);
229 }
230 }
231 an++;
232 /* get header */
233 printf("%s:\n", input[nfile].name);
234 getheader(input[nfile].fp, tabputs, NULL);
235 if (wrongformat) {
236 fprintf(stderr, "%s: incompatible input format\n",
237 input[nfile].name);
238 quit(1);
239 }
240 /* get picture size */
241 if (fgetresolu(&input[nfile].xres, &input[nfile].yres,
242 input[nfile].fp) < 0) {
243 fprintf(stderr, "%s: bad picture size\n",
244 input[nfile].name);
245 quit(1);
246 }
247 if (ncolumns > 0) {
248 if (curcol >= ncolumns) {
249 cury = ymax + spacing;
250 curx = x0;
251 curcol = 0;
252 }
253 input[nfile].xloc = curx;
254 input[nfile].yloc = cury;
255 curx += input[nfile].xres + spacing;
256 curcol++;
257 } else {
258 input[nfile].xloc = atoi(argv[an++]);
259 if (xsgn == '+')
260 input[nfile].xloc -= input[nfile].xres;
261 else if (xsgn == '0')
262 input[nfile].xloc -= input[nfile].xres/2;
263 input[nfile].yloc = atoi(argv[an++]);
264 if (ysgn == '+')
265 input[nfile].yloc -= input[nfile].yres;
266 else if (ysgn == '0')
267 input[nfile].yloc -= input[nfile].yres/2;
268 }
269 if (input[nfile].xloc < xmin)
270 xmin = input[nfile].xloc;
271 if (input[nfile].yloc < ymin)
272 ymin = input[nfile].yloc;
273 if (input[nfile].xloc+input[nfile].xres > xmax)
274 xmax = input[nfile].xloc+input[nfile].xres;
275 if (input[nfile].yloc+input[nfile].yres > ymax)
276 ymax = input[nfile].yloc+input[nfile].yres;
277 if (thislabel != NULL) {
278 if (++nfile >= MAXFILE)
279 goto toomany;
280 input[nfile].name = Label;
281 input[nfile].flags = 0;
282 input[nfile].xres = input[nfile-1].xres;
283 input[nfile].yres = labelht;
284 if ((input[nfile].fp = lblopen(thislabel,
285 &input[nfile].xres,
286 &input[nfile].yres)) == NULL)
287 goto labelerr;
288 input[nfile].xloc = input[nfile-1].xloc;
289 input[nfile].yloc = input[nfile-1].yloc +
290 input[nfile-1].yres-input[nfile].yres;
291 }
292 }
293 if (xsiz <= 0)
294 xsiz = xmax;
295 else if (xsiz > xmax)
296 xmax = xsiz;
297 if (ysiz <= 0)
298 ysiz = ymax;
299 else if (ysiz > ymax)
300 ymax = ysiz;
301 /* add new header info. */
302 printargs(argc, argv, stdout);
303 if (strcmp(ourfmt, PICFMT))
304 fputformat(ourfmt, stdout); /* print format if known */
305 putchar('\n');
306 fprtresolu(xsiz, ysiz, stdout);
307
308 compos();
309
310 quit(0);
311 userr:
312 fprintf(stderr,
313 "Usage: %s [-x xr][-y yr][-b r g b][-a n][-s p][-o x0 y0][-la][-lh h] ",
314 progname);
315 fprintf(stderr, "[-t min1][+t max1][-l lab][=SS] pic1 x1 y1 ..\n");
316 quit(1);
317 toomany:
318 fprintf(stderr, "%s: only %d files and labels allowed\n",
319 progname, MAXFILE);
320 quit(1);
321 labelerr:
322 fprintf(stderr, "%s: error opening label\n", progname);
323 quit(1);
324 return 1; /* pro forma return */
325 }
326
327
328 static void
329 compos(void) /* composite pictures */
330 {
331 COLR *scanin, *scanout;
332 int y;
333 register int x, i;
334
335 scanin = (COLR *)malloc((xmax-xmin)*sizeof(COLR));
336 if (scanin == NULL)
337 goto memerr;
338 scanin -= xmin;
339 if (checkthresh) {
340 scanout = (COLR *)malloc(xsiz*sizeof(COLR));
341 if (scanout == NULL)
342 goto memerr;
343 } else
344 scanout = scanin;
345 for (y = ymax-1; y >= 0; y--) {
346 for (x = 0; x < xsiz; x++)
347 copycolr(scanout[x], bgcolr);
348 for (i = 0; i < nfile; i++) {
349 if (input[i].yloc > y ||
350 input[i].yloc+input[i].yres <= y)
351 continue;
352 if (freadcolrs(scanin+input[i].xloc,
353 input[i].xres, input[i].fp) < 0) {
354 fprintf(stderr, "%s: read error (y==%d)\n",
355 input[i].name,
356 y-input[i].yloc);
357 quit(1);
358 }
359 if (y >= ysiz)
360 continue;
361 if (checkthresh) {
362 x = input[i].xloc+input[i].xres;
363 if (x > xsiz)
364 x = xsiz;
365 for (x--; x >= 0 && x >= input[i].xloc; x--) {
366 if (input[i].flags & HASMIN &&
367 cmpcolr(scanin[x], input[i].thmin) <= 0)
368 continue;
369 if (input[i].flags & HASMAX &&
370 cmpcolr(scanin[x], input[i].thmax) >= 0)
371 continue;
372 copycolr(scanout[x], scanin[x]);
373 }
374 }
375 }
376 if (y >= ysiz)
377 continue;
378 if (fwritecolrs(scanout, xsiz, stdout) < 0) {
379 perror(progname);
380 quit(1);
381 }
382 }
383 /* read remainders from streams */
384 for (i = 0; i < nfile; i++)
385 if (input[i].name[0] == '<')
386 while (getc(input[i].fp) != EOF)
387 ;
388 return;
389 memerr:
390 perror(progname);
391 quit(1);
392 }
393
394
395 static int
396 cmpcolr( /* compare two colr's (improvisation) */
397 register COLR c1,
398 register COLR c2
399 )
400 {
401 register int i, j;
402
403 j = 4; /* check exponents first! */
404 while (j--)
405 if ( (i = c1[j] - c2[j]) )
406 return(i);
407 return(0);
408 }
409
410
411 static FILE *
412 lblopen( /* open pipe to label generator */
413 char *s,
414 int *xp,
415 int *yp
416 )
417 {
418 char com[PATH_MAX];
419 FILE *fp;
420
421 sprintf(com, "psign -s -.15 -a 2 -x %d -y %d '%.90s'", *xp, *yp, s);
422 if ((fp = popen(com, "r")) == NULL)
423 return(NULL);
424 if (checkheader(fp, COLRFMT, NULL) < 0)
425 goto err;
426 if (fgetresolu(xp, yp, fp) < 0)
427 goto err;
428 return(fp);
429 err:
430 pclose(fp);
431 return(NULL);
432 }
433
434
435 void
436 quit(code) /* exit gracefully */
437 int code;
438 {
439 register int i;
440 /* close input files */
441 for (i = 0; i < nfile; i++)
442 if (input[i].name == Command || input[i].name == Label)
443 pclose(input[i].fp);
444 else
445 fclose(input[i].fp);
446 exit(code);
447 }