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

# User Rev Content
1 greg 1.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 greg 1.13 extern float *matchlamp();
21 greg 1.1
22 greg 1.15 #define FEQ(a,b) ((a) >= .98*(b) && (a) <= 1.02*(b))
23    
24 greg 1.1 #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 greg 1.4 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 greg 1.2
36 greg 1.1 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 greg 1.13 char *lampdat = "lamp.tab"; /* lamp data file */
51    
52 greg 1.1 int xres, yres; /* resolution of input */
53 greg 1.9 double inpaspect = 1.0; /* pixel aspect ratio of input */
54 greg 1.12 int correctaspect = 0; /* aspect ratio correction? */
55 greg 1.1
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 greg 1.9 extern int quit(), headline();
74 greg 1.1 FILE *fin;
75 greg 1.13 float *lampcolor;
76     char *lamptype = NULL;
77 greg 1.1 long fpos;
78 greg 1.9 double outaspect = 0.0;
79 greg 1.1 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 greg 1.3 i++;
100 greg 1.5 if (argv[i][0] == '/') {
101 greg 1.4 x_c = 1.0/atof(argv[i]+1);
102 greg 1.5 ncols = 0;
103     } else
104 greg 1.3 ncols = atoi(argv[i]);
105 greg 1.1 break;
106     case 'y':
107 greg 1.3 i++;
108 greg 1.5 if (argv[i][0] == '/') {
109 greg 1.4 y_r = 1.0/atof(argv[i]+1);
110 greg 1.5 nrows = 0;
111     } else
112 greg 1.3 nrows = atoi(argv[i]);
113 greg 1.1 break;
114 greg 1.12 case 'c':
115     correctaspect = !correctaspect;
116     break;
117 greg 1.9 case 'p':
118     i++;
119     outaspect = atof(argv[i]);
120     break;
121 greg 1.1 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 greg 1.15 if (d < 1e-20 || d > 1e20) {
127     fprintf(stderr,
128     "%s: exposure out of range\n",
129     argv[0]);
130     exit(1);
131     }
132 greg 1.1 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 greg 1.13 case 'f':
151     lampdat = argv[++i];
152     break;
153     case 't':
154     lamptype = argv[++i];
155     break;
156 greg 1.1 case '1':
157     singlepass = 1;
158     break;
159 greg 1.6 case '2':
160     singlepass = 0;
161     break;
162 greg 1.9 case 'n':
163 greg 1.1 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 greg 1.14 /* 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 greg 1.1 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 greg 1.9 /* get header */
230     getheader(fin, headline);
231 greg 1.1 /* add new header info. */
232     printargs(i, argv, stdout);
233     /* get picture size */
234 greg 1.7 if (fgetresolu(&xres, &yres, fin) != (YMAJOR|YDECR)) {
235 greg 1.1 fprintf(stderr, "%s: bad picture size\n", progname);
236     quit(1);
237     }
238 greg 1.9 /* compute output resolution */
239     if (ncols <= 0)
240 greg 1.4 ncols = x_c*xres + .5;
241 greg 1.9 if (nrows <= 0)
242 greg 1.4 nrows = y_r*yres + .5;
243 greg 1.9 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 greg 1.1
253 greg 1.9 if (singlepass) { /* skip exposure, etc. */
254 greg 1.1 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 greg 1.9 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 greg 1.1 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 greg 1.11 y_r = (double)nrows/yres;
321 greg 1.1 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 greg 1.10 /* skip leftovers */
367     while (yread < yres) {
368     if (freadscan(scanin[0], xres, in) < 0)
369     break;
370     yread++;
371     }
372 greg 1.1 }
373    
374    
375     scan2init() /* prepare scanline arrays */
376     {
377 greg 1.15 COLOR ctmp;
378 greg 1.9 double d;
379 greg 1.1 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 greg 1.15 /* record pixel aspect ratio */
408 greg 1.12 if (!correctaspect) {
409     d = x_c / y_r;
410 greg 1.15 if (!FEQ(d,1.0))
411 greg 1.12 fputaspect(d, stdout);
412     }
413 greg 1.15 /* record exposure */
414 greg 1.9 d = bright(exposure);
415 greg 1.15 if (!FEQ(d,1.0))
416 greg 1.9 fputexpos(d, stdout);
417 greg 1.15 /* 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 greg 1.1 printf("\n");
424 greg 1.15 /* write out resolution */
425     fputresolu(YMAJOR|YDECR, ncols, nrows, stdout);
426 greg 1.1 }
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     }