Back to index

radiance  4R0+20100331
Defines | Functions | Variables
pfilt.c File Reference
#include "copyright.h"
#include <signal.h>
#include <string.h>
#include "platform.h"
#include "standard.h"
#include "rtio.h"
#include "color.h"
#include "view.h"
#include "paths.h"
#include "pfilt.h"

Go to the source code of this file.

Defines

#define FEQ(a, b)   ((a) >= .98*(b) && (a) <= 1.02*(b))
#define THRESHRAD   5.0 /* maximum sample spread in output */

Functions

static void copyfile (FILE *in, FILE *out)
static void pass1 (FILE *in)
static void pass2 (FILE *in)
static void scan2init (void)
static void scan2sync (int r)
static void scan2flush (void)
int main (int argc, char **argv)
static double rgb_bright (COLOR clr)
static double xyz_bright (COLOR clr)
static int headline (char *s, void *p)
static void copyfile (register FILE *in, register FILE *out)
void quit (int code)

Variables

static const char RCSid [] = "$Id: pfilt.c,v 2.30 2004/03/29 00:34:23 schorsch Exp $"
double CHECKRAD = 2.0
COLOR exposure = WHTCOLOR
double rad = 0.0
double thresh = 0.0
int nrows = 0
int ncols = 0
double x_c = 1.0
double y_r = 1.0
int singlepass = 0
int avghot = 0
double hotlvl = 100.0
int npts = 0
double spread = 1e-4
char * tfname = NULL
char template [] = TEMPLATE
char * lampdat = "lamp.tab"
int order
int xres
int yres
double inpaspect = 1.0
int correctaspect = 0
int wrongformat = 0
VIEW ourview = STDVIEW
int gotview = 0
int wrapfilt = 0
int estatus = 0
int xrad
int yrad
int xbrad
int ybrad
int barsize
COLOR ** scanin
COLORscanout
COLOR ** scoutbar
float ** greybar
int obarsize = 0
int orad = 0
char * progname
static gethfunc headline
static brightfunc_t rgb_bright
static brightfunc_t xyz_bright
brightfunc_tourbright = rgb_bright

Define Documentation

#define FEQ (   a,
 
)    ((a) >= .98*(b) && (a) <= 1.02*(b))

Definition at line 25 of file pfilt.c.

#define THRESHRAD   5.0 /* maximum sample spread in output */

Definition at line 29 of file pfilt.c.


Function Documentation

static void copyfile ( FILE *  in,
FILE *  out 
) [static]

Here is the caller graph for this function:

static void copyfile ( register FILE *  in,
register FILE *  out 
) [static]

Definition at line 375 of file pfilt.c.

{
       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);
       }
}

Here is the call graph for this function:

static int headline ( char *  s,
void *  p 
) [static]

Definition at line 348 of file pfilt.c.

{
       char  fmt[32];

       fputs(s, stdout);           /* copy to output */
       if (isaspect(s))            /* get aspect ratio */
              inpaspect *= aspectval(s);
       else if (isexpos(s))        /* get exposure */
              hotlvl *= exposval(s);
       else if (formatval(fmt, s)) {      /* get format */
              wrongformat = 0;
              if (!strcmp(COLRFMT, fmt))
                     ourbright = rgb_bright;
              else if (!strcmp(CIEFMT, fmt))
                     ourbright = xyz_bright;
              else
                     wrongformat = !globmatch(PICFMT, fmt);
       } else if (isview(s) && sscanview(&ourview, s) > 0)
              gotview++;
       return(0);
}

Here is the call graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 101 of file pfilt.c.

{
       FILE  *fin;
       float  *lampcolor;
       char  *lamptype = NULL;
       long  fpos;
       double outaspect = 0.0;
       double d;
       int  i, j;
       SET_DEFAULT_BINARY();
       SET_FILE_BINARY(stdin);
       SET_FILE_BINARY(stdout);
       if (signal(SIGINT, quit) == SIG_IGN)
              signal(SIGINT, SIG_IGN);
#ifdef SIGHUP
       if (signal(SIGHUP, quit) == SIG_IGN)
              signal(SIGHUP, SIG_IGN);
#endif
       signal(SIGTERM, quit);
#ifdef SIGPIPE
       signal(SIGPIPE, quit);
#endif
#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]);
                                   quit(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 'm':
                            thresh = atof(argv[++i]);
                            if (rad <= FTINY)
                                   rad = 0.6;
                            break;
                     case 'b':
                            rad = thresh = 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 (j = 0; j < 3; j++)
                     if (lampcolor[j] > 1e-4)
                            colval(exposure,j) /= lampcolor[j];
              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;
                                   /* wrap around for cylindrical view? */
       wrapfilt = gotview && ourview.type == VT_CYL &&
                     ourview.horiz >= 360.-FTINY && order & YMAJOR;
                                   /* 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(estatus);
       return estatus; /* pro forma return */
}

Here is the call graph for this function:

static void pass1 ( FILE *  in) [static]

Definition at line 393 of file pfilt.c.

{
       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 = (long)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, (int)(100L*i/yres));
                     yres = i;
                     y_r = (double)nrows/yres;
                     estatus++;
                     break;
              }
              pass1scan(scan, i);
       }
       free((void *)scan);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pass2 ( FILE *  in) [static]

Definition at line 428 of file pfilt.c.

{
       int  yread;
       int  ycent, xcent;
       int  r, c;
       
       pass2init();
       scan2init();
       yread = 0;
       for (r = 0; r < nrows; r++) {
              ycent = (r+.5)*yres/nrows;
              while (yread <= ycent+yrad) {
                     if (yread < yres) {
                            if (freadscan(scanin[yread%barsize],
                                          xres, in) < 0) {
                                   fprintf(stderr,
                                          "%s: truncated input (y=%d)\n",
                                          progname, yres-1-yread);
                                   quit(1);
                            }
                            pass2scan(scanin[yread%barsize], yread);
                     }
                     yread++;
              }
              if (obarsize > 0)
                     scan2sync(r);
              for (c = 0; c < ncols; c++) {
                     xcent = (c+.5)*xres/ncols;
                     if (thresh > FTINY)
                            dothresh(xcent, ycent, c, r);
                     else if (rad > FTINY)
                            dogauss(scanout[c], xcent, ycent, c, r);
                     else
                            dobox(scanout[c], xcent, ycent, c, r);
              }
              if (scanout != NULL && fwritescan(scanout, ncols, stdout) < 0) {
                     fprintf(stderr, "%s: write error in pass2\n", progname);
                     quit(1);
              }
       }
                                   /* skip leftover input */
       while (yread < yres) {
              if (freadscan(scanin[0], xres, in) < 0)
                     break;
              yread++;
       }
       scan2flush();               /* flush output */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void quit ( int  code)

Definition at line 602 of file pfilt.c.

{
       if (tfname != NULL)
              unlink(tfname);
       exit(code);
}
static double rgb_bright ( COLOR  clr) [static]

Definition at line 328 of file pfilt.c.

{
       return(bright(clr));
}
static void scan2flush ( void  ) [static]

Definition at line 587 of file pfilt.c.

{
       register int  r;

       for (r = nrows-orad; r < nrows; r++)
              if (fwritescan(scoutbar[r%obarsize], ncols, stdout) < 0)
                     break;
       if (fflush(stdout) < 0) {
              fprintf(stderr, "%s: write error at end of pass2\n", progname);
              quit(1);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void scan2init ( void  ) [static]

Definition at line 481 of file pfilt.c.

{
       COLOR  ctmp;
       double d;
       register int  i;

       xbrad = xres/ncols/2 + 1;
       ybrad = yres/nrows/2 + 1;
       if (rad > FTINY) {
              if (nrows >= yres && ncols >= xres)
                     rad *= (y_r + x_c)/2.0;

              if (thresh > FTINY) {
                     orad = CHECKRAD*THRESHRAD*rad + 1;
                     xrad = orad/x_c + xbrad;
                     yrad = orad/y_r + ybrad;
                     obarsize = 2*orad + 1;
              } else {
                     xrad = CHECKRAD*rad/x_c + 1;
                     yrad = CHECKRAD*rad/y_r + 1;
              }
              initmask();          /* initialize filter table */
       } else {
              xrad = xbrad;
              yrad = ybrad;
       }
       barsize = 2*yrad + 1;
       scanin = (COLOR **)malloc(barsize*sizeof(COLOR *));
       if (scanin == NULL)
              goto memerr;
       for (i = 0; i < barsize; i++) {
              scanin[i] = (COLOR *)malloc(xres*sizeof(COLOR));
              if (scanin[i] == NULL)
                     goto memerr;
       }
       if (obarsize > 0) {
              scoutbar = (COLOR **)malloc(obarsize*sizeof(COLOR *));
              greybar = (float **)malloc(obarsize*sizeof(float *));
              if ((scoutbar == NULL) | (greybar == NULL))
                     goto memerr;
              for (i = 0; i < obarsize; i++) {
                     scoutbar[i] = (COLOR *)malloc(ncols*sizeof(COLOR));
                     greybar[i] = (float *)malloc(ncols*sizeof(float));
                     if ((scoutbar[i] == NULL) | (greybar[i] == NULL))
                            goto memerr;
              }
       } else {
              scanout = (COLOR *)malloc(ncols*sizeof(COLOR));
              if (scanout == NULL)
                     goto memerr;
       }
                                   /* 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 = (*ourbright)(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);
       return;
memerr:
       fprintf(stderr, "%s: out of memory\n", progname);
       quit(1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void scan2sync ( int  r) [static]

Definition at line 559 of file pfilt.c.

{
       static int  nextrow = 0;
       COLOR  ctmp;
       int  ybot;
       register int  c;
                                   /* average input scanlines */
       while (nextrow <= r+orad && nextrow < nrows) {
              ybot = (nextrow+.5)*yres/nrows;
              for (c = 0; c < ncols; c++) {
                     dobox(ctmp, (int)((c+.5)*xres/ncols),ybot, c,nextrow);
                     greybar[nextrow%obarsize][c] = (*ourbright)(ctmp);
              }
                                   /* and zero output scanline */
              memset((char *)scoutbar[nextrow%obarsize], '\0', ncols*sizeof(COLOR));
              nextrow++;
       }
                                   /* point to top scanline for output */
       if (r-orad >= 0)
              scanout = scoutbar[(r-orad)%obarsize];
       else
              scanout = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double xyz_bright ( COLOR  clr) [static]

Definition at line 337 of file pfilt.c.

{
       return(clr[CIEY]);
}

Variable Documentation

int avghot = 0

Definition at line 45 of file pfilt.c.

int barsize

Definition at line 77 of file pfilt.c.

double CHECKRAD = 2.0

Definition at line 27 of file pfilt.c.

int correctaspect = 0

Definition at line 62 of file pfilt.c.

int estatus = 0

Definition at line 70 of file pfilt.c.

Definition at line 31 of file pfilt.c.

int gotview = 0

Definition at line 67 of file pfilt.c.

float** greybar

Definition at line 81 of file pfilt.c.

gethfunc headline [static]

Definition at line 87 of file pfilt.c.

double hotlvl = 100.0

Definition at line 47 of file pfilt.c.

double inpaspect = 1.0

Definition at line 61 of file pfilt.c.

char* lampdat = "lamp.tab"

Definition at line 57 of file pfilt.c.

int ncols = 0

Definition at line 38 of file pfilt.c.

int npts = 0

Definition at line 49 of file pfilt.c.

int nrows = 0

Definition at line 37 of file pfilt.c.

int obarsize = 0

Definition at line 82 of file pfilt.c.

int orad = 0

Definition at line 83 of file pfilt.c.

static void order

Definition at line 59 of file pfilt.c.

Definition at line 345 of file pfilt.c.

Definition at line 66 of file pfilt.c.

char* progname

Definition at line 85 of file pfilt.c.

double rad = 0.0

Definition at line 33 of file pfilt.c.

const char RCSid[] = "$Id: pfilt.c,v 2.30 2004/03/29 00:34:23 schorsch Exp $" [static]

Definition at line 2 of file pfilt.c.

Definition at line 88 of file pfilt.c.

Definition at line 78 of file pfilt.c.

Definition at line 79 of file pfilt.c.

Definition at line 80 of file pfilt.c.

int singlepass = 0

Definition at line 43 of file pfilt.c.

double spread = 1e-4

Definition at line 51 of file pfilt.c.

char template[] = TEMPLATE

Definition at line 55 of file pfilt.c.

static char * tfname = NULL

Definition at line 53 of file pfilt.c.

double thresh = 0.0

Definition at line 35 of file pfilt.c.

int wrapfilt = 0

Definition at line 68 of file pfilt.c.

int wrongformat = 0

Definition at line 64 of file pfilt.c.

double x_c = 1.0

Definition at line 40 of file pfilt.c.

int xbrad

Definition at line 74 of file pfilt.c.

int xrad

Definition at line 72 of file pfilt.c.

int xres

Definition at line 60 of file pfilt.c.

Definition at line 89 of file pfilt.c.

double y_r = 1.0

Definition at line 41 of file pfilt.c.

int ybrad

Definition at line 75 of file pfilt.c.

int yrad

Definition at line 73 of file pfilt.c.

int yres

Definition at line 60 of file pfilt.c.