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