home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)pfilt.c 2.6 11/3/92 LBL";
- #endif
-
- /*
- * pfilt.c - program to post-process picture file.
- *
- * 9/26/85
- */
-
- #include "standard.h"
-
- #include <signal.h>
-
- #include "color.h"
-
- #include "resolu.h"
-
- #include "paths.h"
-
- extern float *matchlamp();
-
- #define FEQ(a,b) ((a) >= .98*(b) && (a) <= 1.02*(b))
-
- #define CHECKRAD 1.5 /* radius to check for filtering */
-
- COLOR exposure = WHTCOLOR; /* exposure for the frame */
-
- double rad = 0.0; /* output pixel radius for filtering */
-
- int nrows = 0; /* number of rows for output */
- int ncols = 0; /* number of columns for output */
-
- double x_c = 1.0; /* ratio of output x size to input */
- double y_r = 1.0; /* ratio of output y size to input */
-
- int singlepass = 0; /* true means skip first pass */
-
- int avghot = 0; /* true means average in bright spots */
-
- double hotlvl = 1000.0; /* level considered "hot" */
-
- int npts = 0; /* (half) number of points for stars */
-
- double spread = 1e-4; /* spread for star points */
-
- char *tfname = NULL;
-
- char *lampdat = "lamp.tab"; /* lamp data file */
-
- int order; /* scanline ordering of input */
- int xres, yres; /* resolution of input */
- double inpaspect = 1.0; /* pixel aspect ratio of input */
- int correctaspect = 0; /* aspect ratio correction? */
-
- int wrongformat = 0;
-
- int xrad; /* x window size */
- int yrad; /* y window size */
-
- int barsize; /* size of input scan bar */
- COLOR **scanin; /* input scan bar */
- COLOR *scanout; /* output scan line */
-
- char *progname;
-
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- extern long ftell();
- extern int quit(), headline();
- FILE *fin;
- float *lampcolor;
- char *lamptype = NULL;
- long fpos;
- double outaspect = 0.0;
- double d;
- int i, j;
- #ifdef MSDOS
- extern int _fmode;
- _fmode = O_BINARY;
- setmode(fileno(stdin), O_BINARY);
- setmode(fileno(stdout), O_BINARY);
- #endif
- if (signal(SIGINT, quit) == SIG_IGN)
- signal(SIGINT, SIG_IGN);
- if (signal(SIGHUP, quit) == SIG_IGN)
- signal(SIGINT, SIG_IGN);
- signal(SIGTERM, quit);
- signal(SIGPIPE, quit);
- #ifdef SIGXCPU
- signal(SIGXCPU, quit);
- signal(SIGXFSZ, quit);
- #endif
-
- progname = argv[0] = fixargv0(argv[0]);
-
- for (i = 1; i < argc; i++)
- if (argv[i][0] == '-')
- switch (argv[i][1]) {
- case 'x':
- i++;
- if (argv[i][0] == '/') {
- x_c = 1.0/atof(argv[i]+1);
- ncols = 0;
- } else
- ncols = atoi(argv[i]);
- break;
- case 'y':
- i++;
- if (argv[i][0] == '/') {
- y_r = 1.0/atof(argv[i]+1);
- nrows = 0;
- } else
- nrows = atoi(argv[i]);
- break;
- case 'c':
- correctaspect = !correctaspect;
- break;
- case 'p':
- i++;
- outaspect = atof(argv[i]);
- break;
- case 'e':
- if (argv[i+1][0] == '+' || argv[i+1][0] == '-')
- d = pow(2.0, atof(argv[i+1]));
- else
- d = atof(argv[i+1]);
- if (d < 1e-20 || d > 1e20) {
- fprintf(stderr,
- "%s: exposure out of range\n",
- argv[0]);
- exit(1);
- }
- switch (argv[i][2]) {
- case '\0':
- scalecolor(exposure, d);
- break;
- case 'r':
- colval(exposure,RED) *= d;
- break;
- case 'g':
- colval(exposure,GRN) *= d;
- break;
- case 'b':
- colval(exposure,BLU) *= d;
- break;
- default:
- goto badopt;
- }
- i++;
- break;
- case 'f':
- lampdat = argv[++i];
- break;
- case 't':
- lamptype = argv[++i];
- break;
- case '1':
- singlepass = 1;
- break;
- case '2':
- singlepass = 0;
- break;
- case 'n':
- npts = atoi(argv[++i]) / 2;
- break;
- case 's':
- spread = atof(argv[++i]);
- break;
- case 'a':
- avghot = !avghot;
- break;
- case 'h':
- hotlvl = atof(argv[++i]);
- break;
- case 'r':
- rad = atof(argv[++i]);
- break;
- case 'b':
- rad = 0.0;
- break;
- default:;
- badopt:
- fprintf(stderr, "%s: unknown option: %s\n",
- progname, argv[i]);
- quit(1);
- break;
- }
- else
- break;
- /* get lamp data (if necessary) */
- if (lamptype != NULL) {
- if (loadlamps(lampdat) < 0)
- quit(1);
- if ((lampcolor = matchlamp(lamptype)) == NULL) {
- fprintf(stderr, "%s: unknown lamp type\n", lamptype);
- quit(1);
- }
- for (i = 0; i < 3; i++)
- if (lampcolor[i] > 1e-4)
- colval(exposure,i) /= lampcolor[i];
- freelamps();
- }
- /* open input file */
- if (i == argc) {
- if (singlepass)
- fin = stdin;
- else {
- tfname = mktemp(TEMPLATE);
- if ((fin = fopen(tfname, "w+")) == NULL) {
- fprintf(stderr, "%s: can't create ", progname);
- fprintf(stderr, "temp file \"%s\"\n", tfname);
- quit(1);
- }
- copyfile(stdin, fin);
- if (fseek(fin, 0L, 0) == -1) {
- fprintf(stderr, "%s: seek fail\n", progname);
- quit(1);
- }
- }
- } else if (i == argc-1) {
- if ((fin = fopen(argv[i], "r")) == NULL) {
- fprintf(stderr, "%s: can't open file \"%s\"\n",
- progname, argv[i]);
- quit(1);
- }
- } else {
- fprintf(stderr, "%s: bad # file arguments\n", progname);
- quit(1);
- }
- /* get header */
- getheader(fin, headline, NULL);
- if (wrongformat) {
- fprintf(stderr, "%s: input must be a Radiance picture\n",
- progname);
- quit(1);
- }
- /* add new header info. */
- printargs(i, argv, stdout);
- /* get picture size */
- if ((order = fgetresolu(&xres, &yres, fin)) < 0) {
- fprintf(stderr, "%s: bad picture size\n", progname);
- quit(1);
- }
- if (!(order & YMAJOR))
- inpaspect = 1.0/inpaspect;
- /* compute output resolution */
- if (ncols <= 0)
- ncols = x_c*xres + .5;
- if (nrows <= 0)
- nrows = y_r*yres + .5;
- if (outaspect > .01) {
- d = inpaspect * yres/xres / outaspect;
- if (d * ncols > nrows)
- ncols = nrows / d;
- else
- nrows = ncols * d;
- }
- x_c = (double)ncols/xres;
- y_r = (double)nrows/yres;
-
- if (singlepass) { /* skip exposure, etc. */
- pass1default();
- pass2(fin);
- quit(0);
- }
-
- fpos = ftell(fin); /* save input file position */
-
- pass1(fin);
-
- if (fseek(fin, fpos, 0) == -1) {
- fprintf(stderr, "%s: seek fail\n", progname);
- quit(1);
- }
- pass2(fin);
-
- quit(0);
- }
-
-
- headline(s) /* process line from header */
- char *s;
- {
- char fmt[32];
-
- fputs(s, stdout); /* copy to output */
- if (isaspect(s)) /* get aspect ratio */
- inpaspect *= aspectval(s);
- else if (isformat(s)) {
- formatval(fmt, s);
- wrongformat = strcmp(fmt, COLRFMT);
- }
- }
-
-
- copyfile(in, out) /* copy a file */
- register FILE *in, *out;
- {
- register int c;
-
- while ((c = getc(in)) != EOF)
- putc(c, out);
-
- if (ferror(out)) {
- fprintf(stderr, "%s: write error in copyfile\n", progname);
- quit(1);
- }
- }
-
-
- pass1(in) /* first pass of picture file */
- FILE *in;
- {
- int i;
- COLOR *scan;
-
- pass1init();
-
- scan = (COLOR *)malloc(xres*sizeof(COLOR));
- if (scan == NULL) {
- fprintf(stderr, "%s: out of memory\n", progname);
- quit(1);
- }
- for (i = 0; i < yres; i++) {
- if (freadscan(scan, xres, in) < 0) {
- nrows = nrows * i / yres; /* adjust frame */
- if (nrows <= 0) {
- fprintf(stderr, "%s: empty frame\n", progname);
- quit(1);
- }
- fprintf(stderr, "%s: warning - partial frame (%d%%)\n",
- progname, 100*i/yres);
- yres = i;
- y_r = (double)nrows/yres;
- break;
- }
- pass1scan(scan, i);
- }
- free((char *)scan);
- }
-
-
- pass2(in) /* last pass on file, write to stdout */
- FILE *in;
- {
- int yread;
- int ycent, xcent;
- int r, c;
-
- pass2init();
- scan2init();
- yread = 0;
- for (r = 0; r < nrows; r++) {
- ycent = (long)r*yres/nrows;
- while (yread <= ycent+yrad) {
- if (yread < yres) {
- if (freadscan(scanin[yread%barsize],
- xres, in) < 0) {
- fprintf(stderr,
- "%s: bad read (y=%d)\n",
- progname, yres-1-yread);
- quit(1);
- }
- pass2scan(scanin[yread%barsize], yread);
- }
- yread++;
- }
- for (c = 0; c < ncols; c++) {
- xcent = (long)c*xres/ncols;
- if (rad <= 0.0)
- dobox(scanout[c], xcent, ycent, c, r);
- else
- dogauss(scanout[c], xcent, ycent, c, r);
- }
- if (fwritescan(scanout, ncols, stdout) < 0) {
- fprintf(stderr, "%s: write error in pass2\n", progname);
- quit(1);
- }
- }
- /* skip leftovers */
- while (yread < yres) {
- if (freadscan(scanin[0], xres, in) < 0)
- break;
- yread++;
- }
- }
-
-
- scan2init() /* prepare scanline arrays */
- {
- COLOR ctmp;
- double d;
- register int i;
-
- if (rad <= 0.0) {
- xrad = xres/ncols/2 + 1;
- yrad = yres/nrows/2 + 1;
- } else {
- if (nrows >= yres && ncols >= xres)
- rad *= (y_r + x_c)/2.0;
-
- xrad = CHECKRAD*rad/x_c + 1;
- yrad = CHECKRAD*rad/y_r + 1;
-
- initmask(); /* initialize filter table */
- }
- barsize = 2*yrad + 1;
- scanin = (COLOR **)malloc(barsize*sizeof(COLOR *));
- for (i = 0; i < barsize; i++) {
- scanin[i] = (COLOR *)malloc(xres*sizeof(COLOR));
- if (scanin[i] == NULL) {
- fprintf(stderr, "%s: out of memory\n", progname);
- quit(1);
- }
- }
- scanout = (COLOR *)malloc(ncols*sizeof(COLOR));
- if (scanout == NULL) {
- fprintf(stderr, "%s: out of memory\n", progname);
- quit(1);
- }
- /* record pixel aspect ratio */
- if (!correctaspect) {
- d = order & YMAJOR ? x_c/y_r : y_r/x_c ;
- if (!FEQ(d,1.0))
- fputaspect(d, stdout);
- }
- /* record exposure */
- d = bright(exposure);
- if (!FEQ(d,1.0))
- fputexpos(d, stdout);
- /* record color correction */
- copycolor(ctmp, exposure);
- scalecolor(ctmp, 1.0/d);
- if (!FEQ(colval(ctmp,RED),colval(ctmp,GRN)) ||
- !FEQ(colval(ctmp,GRN),colval(ctmp,BLU)))
- fputcolcor(ctmp, stdout);
- printf("\n");
- /* write out resolution */
- fputresolu(order, ncols, nrows, stdout);
- }
-
-
- quit(code) /* remove temporary file and exit */
- int code;
- {
- if (tfname != NULL)
- unlink(tfname);
- exit(code);
- }
-