ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pfilt.c
Revision: 1.15
Committed: Fri Dec 14 16:33:16 1990 UTC (33 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.14: +21 -4 lines
Log Message:
added use of COLORCORR header i/o

File Contents

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