ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pfilt.c
Revision: 2.3
Committed: Tue Sep 8 15:33:08 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +2 -3 lines
Log Message:
used TEMPLATE defined in paths.h for pfilt.c

File Contents

# User Rev Content
1 greg 1.18 /* Copyright (c) 1991 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * pfilt.c - program to post-process picture file.
9     *
10     * 9/26/85
11     */
12    
13     #include <stdio.h>
14    
15     #include <signal.h>
16    
17     #include "color.h"
18    
19 greg 1.19 #include "resolu.h"
20    
21 greg 2.3 #include "paths.h"
22    
23 greg 1.1 extern char *malloc();
24 greg 1.13 extern float *matchlamp();
25 greg 1.1
26 greg 1.15 #define FEQ(a,b) ((a) >= .98*(b) && (a) <= 1.02*(b))
27    
28 greg 1.1 #define CHECKRAD 1.5 /* radius to check for filtering */
29    
30     COLOR exposure = WHTCOLOR; /* exposure for the frame */
31    
32     double rad = 0.0; /* output pixel radius for filtering */
33    
34     int nrows = 0; /* number of rows for output */
35     int ncols = 0; /* number of columns for output */
36    
37 greg 1.4 double x_c = 1.0; /* ratio of output x size to input */
38     double y_r = 1.0; /* ratio of output y size to input */
39 greg 1.2
40 greg 1.1 int singlepass = 0; /* true means skip first pass */
41    
42     int avghot = 0; /* true means average in bright spots */
43    
44     double hotlvl = 1000.0; /* level considered "hot" */
45    
46     int npts = 0; /* (half) number of points for stars */
47    
48     double spread = 1e-4; /* spread for star points */
49    
50     char *tfname = NULL;
51    
52 greg 1.13 char *lampdat = "lamp.tab"; /* lamp data file */
53    
54 greg 1.19 int order; /* scanline ordering of input */
55 greg 1.1 int xres, yres; /* resolution of input */
56 greg 1.9 double inpaspect = 1.0; /* pixel aspect ratio of input */
57 greg 1.12 int correctaspect = 0; /* aspect ratio correction? */
58 greg 1.1
59 greg 1.16 int wrongformat = 0;
60    
61 greg 1.1 int xrad; /* x window size */
62     int yrad; /* y window size */
63    
64     int barsize; /* size of input scan bar */
65     COLOR **scanin; /* input scan bar */
66     COLOR *scanout; /* output scan line */
67    
68     char *progname;
69    
70    
71     main(argc, argv)
72     int argc;
73     char **argv;
74     {
75 greg 2.2 extern double pow();
76 greg 1.1 extern long ftell();
77 greg 1.9 extern int quit(), headline();
78 greg 1.1 FILE *fin;
79 greg 1.13 float *lampcolor;
80     char *lamptype = NULL;
81 greg 1.1 long fpos;
82 greg 1.9 double outaspect = 0.0;
83 greg 1.1 double d;
84 greg 1.18 int i, j;
85 greg 1.1
86     if (signal(SIGINT, quit) == SIG_IGN)
87     signal(SIGINT, SIG_IGN);
88     if (signal(SIGHUP, quit) == SIG_IGN)
89     signal(SIGINT, SIG_IGN);
90     signal(SIGTERM, quit);
91     signal(SIGPIPE, quit);
92     #ifdef SIGXCPU
93     signal(SIGXCPU, quit);
94     signal(SIGXFSZ, quit);
95     #endif
96    
97     progname = argv[0];
98    
99     for (i = 1; i < argc; i++)
100     if (argv[i][0] == '-')
101     switch (argv[i][1]) {
102     case 'x':
103 greg 1.3 i++;
104 greg 1.5 if (argv[i][0] == '/') {
105 greg 1.4 x_c = 1.0/atof(argv[i]+1);
106 greg 1.5 ncols = 0;
107     } else
108 greg 1.3 ncols = atoi(argv[i]);
109 greg 1.1 break;
110     case 'y':
111 greg 1.3 i++;
112 greg 1.5 if (argv[i][0] == '/') {
113 greg 1.4 y_r = 1.0/atof(argv[i]+1);
114 greg 1.5 nrows = 0;
115     } else
116 greg 1.3 nrows = atoi(argv[i]);
117 greg 1.1 break;
118 greg 1.12 case 'c':
119     correctaspect = !correctaspect;
120     break;
121 greg 1.9 case 'p':
122     i++;
123     outaspect = atof(argv[i]);
124     break;
125 greg 1.1 case 'e':
126     if (argv[i+1][0] == '+' || argv[i+1][0] == '-')
127     d = pow(2.0, atof(argv[i+1]));
128     else
129     d = atof(argv[i+1]);
130 greg 1.15 if (d < 1e-20 || d > 1e20) {
131     fprintf(stderr,
132     "%s: exposure out of range\n",
133     argv[0]);
134     exit(1);
135     }
136 greg 1.1 switch (argv[i][2]) {
137     case '\0':
138     scalecolor(exposure, d);
139     break;
140     case 'r':
141     colval(exposure,RED) *= d;
142     break;
143     case 'g':
144     colval(exposure,GRN) *= d;
145     break;
146     case 'b':
147     colval(exposure,BLU) *= d;
148     break;
149     default:
150     goto badopt;
151     }
152     i++;
153     break;
154 greg 1.13 case 'f':
155     lampdat = argv[++i];
156     break;
157     case 't':
158     lamptype = argv[++i];
159     break;
160 greg 1.1 case '1':
161     singlepass = 1;
162     break;
163 greg 1.6 case '2':
164     singlepass = 0;
165     break;
166 greg 1.9 case 'n':
167 greg 1.1 npts = atoi(argv[++i]) / 2;
168     break;
169     case 's':
170     spread = atof(argv[++i]);
171     break;
172     case 'a':
173     avghot = !avghot;
174     break;
175     case 'h':
176     hotlvl = atof(argv[++i]);
177     break;
178     case 'r':
179     rad = atof(argv[++i]);
180     break;
181     case 'b':
182     rad = 0.0;
183     break;
184     default:;
185     badopt:
186     fprintf(stderr, "%s: unknown option: %s\n",
187     progname, argv[i]);
188     quit(1);
189     break;
190     }
191     else
192     break;
193 greg 1.14 /* get lamp data (if necessary) */
194     if (lamptype != NULL) {
195     if (loadlamps(lampdat) < 0)
196     quit(1);
197     if ((lampcolor = matchlamp(lamptype)) == NULL) {
198     fprintf(stderr, "%s: unknown lamp type\n", lamptype);
199     quit(1);
200     }
201 greg 1.18 for (i = 0; i < 3; i++)
202     if (lampcolor[i] > 1e-4)
203     colval(exposure,i) /= lampcolor[i];
204 greg 1.14 freelamps();
205     }
206     /* open input file */
207 greg 1.1 if (i == argc) {
208     if (singlepass)
209     fin = stdin;
210     else {
211     tfname = mktemp(TEMPLATE);
212     if ((fin = fopen(tfname, "w+")) == NULL) {
213     fprintf(stderr, "%s: can't create ", progname);
214     fprintf(stderr, "temp file \"%s\"\n", tfname);
215     quit(1);
216     }
217     copyfile(stdin, fin);
218     if (fseek(fin, 0L, 0) == -1) {
219     fprintf(stderr, "%s: seek fail\n", progname);
220     quit(1);
221     }
222     }
223     } else if (i == argc-1) {
224     if ((fin = fopen(argv[i], "r")) == NULL) {
225     fprintf(stderr, "%s: can't open file \"%s\"\n",
226     progname, argv[i]);
227     quit(1);
228     }
229     } else {
230     fprintf(stderr, "%s: bad # file arguments\n", progname);
231     quit(1);
232     }
233 greg 1.9 /* get header */
234 greg 1.16 getheader(fin, headline, NULL);
235     if (wrongformat) {
236     fprintf(stderr, "%s: input must be a Radiance picture\n",
237     progname);
238     quit(1);
239     }
240 greg 1.1 /* add new header info. */
241     printargs(i, argv, stdout);
242     /* get picture size */
243 greg 1.19 if ((order = fgetresolu(&xres, &yres, fin)) < 0) {
244 greg 1.1 fprintf(stderr, "%s: bad picture size\n", progname);
245     quit(1);
246     }
247 greg 1.19 if (!(order & YMAJOR))
248     inpaspect = 1.0/inpaspect;
249 greg 1.9 /* compute output resolution */
250     if (ncols <= 0)
251 greg 1.4 ncols = x_c*xres + .5;
252 greg 1.9 if (nrows <= 0)
253 greg 1.4 nrows = y_r*yres + .5;
254 greg 1.9 if (outaspect > .01) {
255     d = inpaspect * yres/xres / outaspect;
256     if (d * ncols > nrows)
257     ncols = nrows / d;
258     else
259     nrows = ncols * d;
260     }
261     x_c = (double)ncols/xres;
262     y_r = (double)nrows/yres;
263 greg 1.1
264 greg 1.9 if (singlepass) { /* skip exposure, etc. */
265 greg 1.1 pass1default();
266     pass2(fin);
267     quit(0);
268     }
269    
270     fpos = ftell(fin); /* save input file position */
271    
272     pass1(fin);
273    
274     if (fseek(fin, fpos, 0) == -1) {
275     fprintf(stderr, "%s: seek fail\n", progname);
276     quit(1);
277     }
278     pass2(fin);
279    
280     quit(0);
281     }
282    
283    
284 greg 1.9 headline(s) /* process line from header */
285     char *s;
286     {
287 greg 1.16 char fmt[32];
288    
289 greg 1.9 fputs(s, stdout); /* copy to output */
290     if (isaspect(s)) /* get aspect ratio */
291     inpaspect *= aspectval(s);
292 greg 1.16 else if (isformat(s)) {
293     formatval(fmt, s);
294     wrongformat = strcmp(fmt, COLRFMT);
295     }
296 greg 1.9 }
297    
298    
299 greg 1.1 copyfile(in, out) /* copy a file */
300     register FILE *in, *out;
301     {
302     register int c;
303    
304     while ((c = getc(in)) != EOF)
305     putc(c, out);
306    
307     if (ferror(out)) {
308     fprintf(stderr, "%s: write error in copyfile\n", progname);
309     quit(1);
310     }
311     }
312    
313    
314     pass1(in) /* first pass of picture file */
315     FILE *in;
316     {
317     int i;
318     COLOR *scan;
319    
320     pass1init();
321    
322     scan = (COLOR *)malloc(xres*sizeof(COLOR));
323     if (scan == NULL) {
324     fprintf(stderr, "%s: out of memory\n", progname);
325     quit(1);
326     }
327     for (i = 0; i < yres; i++) {
328     if (freadscan(scan, xres, in) < 0) {
329     nrows = nrows * i / yres; /* adjust frame */
330     if (nrows <= 0) {
331     fprintf(stderr, "%s: empty frame\n", progname);
332     quit(1);
333     }
334     fprintf(stderr, "%s: warning - partial frame (%d%%)\n",
335     progname, 100*i/yres);
336     yres = i;
337 greg 1.11 y_r = (double)nrows/yres;
338 greg 1.1 break;
339     }
340     pass1scan(scan, i);
341     }
342     free((char *)scan);
343     }
344    
345    
346     pass2(in) /* last pass on file, write to stdout */
347     FILE *in;
348     {
349     int yread;
350     int ycent, xcent;
351     int r, c;
352    
353     pass2init();
354     scan2init();
355     yread = 0;
356     for (r = 0; r < nrows; r++) {
357     ycent = (long)r*yres/nrows;
358     while (yread <= ycent+yrad) {
359     if (yread < yres) {
360     if (freadscan(scanin[yread%barsize],
361     xres, in) < 0) {
362     fprintf(stderr,
363     "%s: bad read (y=%d)\n",
364     progname, yres-1-yread);
365     quit(1);
366     }
367     pass2scan(scanin[yread%barsize], yread);
368     }
369     yread++;
370     }
371     for (c = 0; c < ncols; c++) {
372     xcent = (long)c*xres/ncols;
373     if (rad <= 0.0)
374     dobox(scanout[c], xcent, ycent, c, r);
375     else
376     dogauss(scanout[c], xcent, ycent, c, r);
377     }
378     if (fwritescan(scanout, ncols, stdout) < 0) {
379     fprintf(stderr, "%s: write error in pass2\n", progname);
380     quit(1);
381     }
382     }
383 greg 1.10 /* skip leftovers */
384     while (yread < yres) {
385     if (freadscan(scanin[0], xres, in) < 0)
386     break;
387     yread++;
388     }
389 greg 1.1 }
390    
391    
392     scan2init() /* prepare scanline arrays */
393     {
394 greg 1.15 COLOR ctmp;
395 greg 1.9 double d;
396 greg 1.1 register int i;
397    
398     if (rad <= 0.0) {
399     xrad = xres/ncols/2 + 1;
400     yrad = yres/nrows/2 + 1;
401     } else {
402     if (nrows >= yres && ncols >= xres)
403     rad *= (y_r + x_c)/2.0;
404    
405     xrad = CHECKRAD*rad/x_c + 1;
406     yrad = CHECKRAD*rad/y_r + 1;
407    
408     initmask(); /* initialize filter table */
409     }
410 greg 1.17 barsize = 2*yrad + 1;
411 greg 1.1 scanin = (COLOR **)malloc(barsize*sizeof(COLOR *));
412     for (i = 0; i < barsize; i++) {
413     scanin[i] = (COLOR *)malloc(xres*sizeof(COLOR));
414     if (scanin[i] == NULL) {
415     fprintf(stderr, "%s: out of memory\n", progname);
416     quit(1);
417     }
418     }
419     scanout = (COLOR *)malloc(ncols*sizeof(COLOR));
420     if (scanout == NULL) {
421     fprintf(stderr, "%s: out of memory\n", progname);
422     quit(1);
423     }
424 greg 1.15 /* record pixel aspect ratio */
425 greg 1.12 if (!correctaspect) {
426 greg 1.19 d = order & YMAJOR ? x_c/y_r : y_r/x_c ;
427 greg 1.15 if (!FEQ(d,1.0))
428 greg 1.12 fputaspect(d, stdout);
429     }
430 greg 1.15 /* record exposure */
431 greg 1.9 d = bright(exposure);
432 greg 1.15 if (!FEQ(d,1.0))
433 greg 1.9 fputexpos(d, stdout);
434 greg 1.15 /* record color correction */
435     copycolor(ctmp, exposure);
436     scalecolor(ctmp, 1.0/d);
437     if (!FEQ(colval(ctmp,RED),colval(ctmp,GRN)) ||
438     !FEQ(colval(ctmp,GRN),colval(ctmp,BLU)))
439     fputcolcor(ctmp, stdout);
440 greg 1.1 printf("\n");
441 greg 1.15 /* write out resolution */
442 greg 1.19 fputresolu(order, ncols, nrows, stdout);
443 greg 1.1 }
444    
445    
446     quit(code) /* remove temporary file and exit */
447     int code;
448     {
449     if (tfname != NULL)
450     unlink(tfname);
451     exit(code);
452     }