ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pfilt.c
Revision: 2.7
Committed: Thu Nov 12 09:05:17 1992 UTC (31 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.6: +2 -2 lines
Log Message:
bug fix for 16-bit integers (DOS)

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 = 1000.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 (isformat(s)) {
296 formatval(fmt, s);
297 wrongformat = strcmp(fmt, COLRFMT);
298 }
299 }
300
301
302 copyfile(in, out) /* copy a file */
303 register FILE *in, *out;
304 {
305 register int c;
306
307 while ((c = getc(in)) != EOF)
308 putc(c, out);
309
310 if (ferror(out)) {
311 fprintf(stderr, "%s: write error in copyfile\n", progname);
312 quit(1);
313 }
314 }
315
316
317 pass1(in) /* first pass of picture file */
318 FILE *in;
319 {
320 int i;
321 COLOR *scan;
322
323 pass1init();
324
325 scan = (COLOR *)malloc(xres*sizeof(COLOR));
326 if (scan == NULL) {
327 fprintf(stderr, "%s: out of memory\n", progname);
328 quit(1);
329 }
330 for (i = 0; i < yres; i++) {
331 if (freadscan(scan, xres, in) < 0) {
332 nrows = (long)nrows * i / yres; /* adjust frame */
333 if (nrows <= 0) {
334 fprintf(stderr, "%s: empty frame\n", progname);
335 quit(1);
336 }
337 fprintf(stderr, "%s: warning - partial frame (%d%%)\n",
338 progname, (int)(100L*i/yres));
339 yres = i;
340 y_r = (double)nrows/yres;
341 break;
342 }
343 pass1scan(scan, i);
344 }
345 free((char *)scan);
346 }
347
348
349 pass2(in) /* last pass on file, write to stdout */
350 FILE *in;
351 {
352 int yread;
353 int ycent, xcent;
354 int r, c;
355
356 pass2init();
357 scan2init();
358 yread = 0;
359 for (r = 0; r < nrows; r++) {
360 ycent = (long)r*yres/nrows;
361 while (yread <= ycent+yrad) {
362 if (yread < yres) {
363 if (freadscan(scanin[yread%barsize],
364 xres, in) < 0) {
365 fprintf(stderr,
366 "%s: bad read (y=%d)\n",
367 progname, yres-1-yread);
368 quit(1);
369 }
370 pass2scan(scanin[yread%barsize], yread);
371 }
372 yread++;
373 }
374 for (c = 0; c < ncols; c++) {
375 xcent = (long)c*xres/ncols;
376 if (rad <= 0.0)
377 dobox(scanout[c], xcent, ycent, c, r);
378 else
379 dogauss(scanout[c], xcent, ycent, c, r);
380 }
381 if (fwritescan(scanout, ncols, stdout) < 0) {
382 fprintf(stderr, "%s: write error in pass2\n", progname);
383 quit(1);
384 }
385 }
386 /* skip leftovers */
387 while (yread < yres) {
388 if (freadscan(scanin[0], xres, in) < 0)
389 break;
390 yread++;
391 }
392 }
393
394
395 scan2init() /* prepare scanline arrays */
396 {
397 COLOR ctmp;
398 double d;
399 register int i;
400
401 if (rad <= 0.0) {
402 xrad = xres/ncols/2 + 1;
403 yrad = yres/nrows/2 + 1;
404 } else {
405 if (nrows >= yres && ncols >= xres)
406 rad *= (y_r + x_c)/2.0;
407
408 xrad = CHECKRAD*rad/x_c + 1;
409 yrad = CHECKRAD*rad/y_r + 1;
410
411 initmask(); /* initialize filter table */
412 }
413 barsize = 2*yrad + 1;
414 scanin = (COLOR **)malloc(barsize*sizeof(COLOR *));
415 for (i = 0; i < barsize; i++) {
416 scanin[i] = (COLOR *)malloc(xres*sizeof(COLOR));
417 if (scanin[i] == NULL) {
418 fprintf(stderr, "%s: out of memory\n", progname);
419 quit(1);
420 }
421 }
422 scanout = (COLOR *)malloc(ncols*sizeof(COLOR));
423 if (scanout == NULL) {
424 fprintf(stderr, "%s: out of memory\n", progname);
425 quit(1);
426 }
427 /* record pixel aspect ratio */
428 if (!correctaspect) {
429 d = order & YMAJOR ? x_c/y_r : y_r/x_c ;
430 if (!FEQ(d,1.0))
431 fputaspect(d, stdout);
432 }
433 /* record exposure */
434 d = bright(exposure);
435 if (!FEQ(d,1.0))
436 fputexpos(d, stdout);
437 /* record color correction */
438 copycolor(ctmp, exposure);
439 scalecolor(ctmp, 1.0/d);
440 if (!FEQ(colval(ctmp,RED),colval(ctmp,GRN)) ||
441 !FEQ(colval(ctmp,GRN),colval(ctmp,BLU)))
442 fputcolcor(ctmp, stdout);
443 printf("\n");
444 /* write out resolution */
445 fputresolu(order, ncols, nrows, stdout);
446 }
447
448
449 quit(code) /* remove temporary file and exit */
450 int code;
451 {
452 if (tfname != NULL)
453 unlink(tfname);
454 exit(code);
455 }