ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pfilt.c
Revision: 2.8
Committed: Fri Jun 18 16:20:16 1993 UTC (30 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +3 -1 lines
Log Message:
changed default setting of hotlvl and made it absolute

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