--- ray/src/util/glareval.c 1991/04/05 14:57:28 1.11 +++ ray/src/util/glareval.c 1991/11/12 17:19:21 2.1 @@ -9,23 +9,15 @@ static char SCCSid[] = "$SunId$ LBL"; */ #include "glare.h" -#include - /* compute rtrace buffer size */ -#ifndef PIPE_BUF -#define PIPE_BUF 512 /* hyperconservative */ -#endif -#define MAXPIX (PIPE_BUF/(6*sizeof(float)) - 1) +#include "resolu.h" + /* maximum rtrace buffer size */ +#define MAXPIX (4096/(6*sizeof(float))) -#ifndef BSD -#define vfork fork -#endif - -#define MAXSBUF 524268 /* maximum total size of scanline buffer */ +#define MAXSBUF 786432 /* maximum total size of scanline buffer */ #define HSIZE 317 /* size of scanline hash table */ #define NRETIRE 16 /* number of scanlines to retire at once */ -int rt_pid = -1; /* process id for rtrace */ -int fd_tort, fd_fromrt; /* pipe descriptors */ +int rt_pd[3] = {-1,-1,-1}; /* process id & descriptors for rtrace */ FILE *pictfp = NULL; /* picture file pointer */ double exposure; /* picture exposure */ @@ -44,12 +36,17 @@ typedef struct scan { #define scandata(sl) ((COLR *)((sl)+1)) #define shash(y) ((y)%HSIZE) +static int maxpix; /* maximum number of pixels to buffer */ + static SCAN *freelist; /* scanline free list */ static SCAN *hashtab[HSIZE]; /* scanline hash table */ static long ncall = 0L; /* number of calls to getpictscan */ static long nread = 0L; /* number of scanlines read */ +static long nrecl = 0L; /* number of scanlines reclaimed */ +static int wrongformat = 0; + SCAN *scanretire(); extern long ftell(); @@ -75,12 +72,7 @@ int y; if (sl->y == y) { /* reclaim */ sl->next = hashtab[hi]; hashtab[hi] = sl; -#ifdef DEBUG - if (verbose) - fprintf(stderr, - "%s: scanline %d reclaimed\n", - progname, y); -#endif + nrecl++; } return(sl); } @@ -144,13 +136,15 @@ pict_stats() /* print out picture read statistics */ { static long lastcall = 0L; /* ncall at last report */ static long lastread = 0L; /* nread at last report */ + static long lastrecl = 0L; /* nrecl at last report */ if (ncall == lastcall) return; - fprintf(stderr, "%s: %ld scanlines read in %ld calls\n", - progname, nread-lastread, ncall-lastcall); + fprintf(stderr, "%s: %ld scanlines read (%ld reclaimed) in %ld calls\n", + progname, nread-lastread, nrecl-lastrecl, ncall-lastcall); lastcall = ncall; lastread = nread; + lastrecl = nrecl; } #endif @@ -160,7 +154,7 @@ pict_val(vd) /* find picture value for view directio FVECT vd; { FVECT pp; - double vpx, vpy, vpz; + FVECT ip; COLOR res; if (pictfp == NULL) @@ -168,10 +162,11 @@ FVECT vd; pp[0] = pictview.vp[0] + vd[0]; pp[1] = pictview.vp[1] + vd[1]; pp[2] = pictview.vp[2] + vd[2]; - viewpixel(&vpx, &vpy, &vpz, &pictview, pp); - if (vpz <= FTINY || vpx < 0. || vpx >= 1. || vpy < 0. || vpy >= 1.) + viewloc(ip, &pictview, pp); + if (ip[2] <= FTINY || ip[0] < 0. || ip[0] >= 1. || + ip[1] < 0. || ip[1] >= 1.) return(-1.0); - colr_color(res, getpictscan((int)(vpy*pysiz))[(int)(vpx*pxsiz)]); + colr_color(res, getpictscan((int)(ip[1]*pysiz))[(int)(ip[0]*pxsiz)]); return(luminance(res)/exposure); } @@ -181,7 +176,7 @@ getviewpix(vh, vv) /* compute single view pixel */ int vh, vv; { FVECT dir; - float rt_buf[6]; + float rt_buf[12]; double res; if (compdir(dir, vh, vv) < 0) @@ -189,7 +184,7 @@ int vh, vv; npixinvw++; if ((res = pict_val(dir)) >= 0.0) return(res); - if (rt_pid == -1) { + if (rt_pd[0] == -1) { npixmiss++; return(-1.0); } @@ -221,19 +216,19 @@ float *vb; #endif n = 0; for (vh = -hsize; vh <= hsize; vh++) { - if (compdir(dir, vh, vv) < 0) { /* off viewable region */ + if (compdir(dir, vh, vv) < 0) { /* not in view */ vb[vh+hsize] = -1.0; continue; } npixinvw++; if ((vb[vh+hsize] = pict_val(dir)) >= 0.0) continue; - if (rt_pid == -1) { /* missing information */ + if (rt_pd[0] == -1) { /* missing information */ npixmiss++; continue; } /* send to rtrace */ - if (n >= MAXPIX) { /* flush */ + if (n >= maxpix) { /* flush */ rt_compute(rt_buf, n); while (n-- > 0) vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n); @@ -262,49 +257,46 @@ rt_compute(pb, np) /* process buffer through rtrace * float *pb; int np; { - static float nbuf[6] = {0.,0.,0.,0.,0.,0.}; - #ifdef DEBUG if (verbose && np > 1) fprintf(stderr, "%s: sending %d samples to rtrace...\n", progname, np); #endif - if (writebuf(fd_tort,(char *)pb,6*sizeof(float)*np) < 6*sizeof(float)*np - || writebuf(fd_tort,(char *)nbuf,sizeof(nbuf)) < sizeof(nbuf)) { - fprintf(stderr, "%s: error writing to rtrace process\n", + bzero(pb+6*np, 6*sizeof(float)); + if (process(rt_pd, pb, pb, 3*sizeof(float)*np, + 6*sizeof(float)*(np+1)) < 3*sizeof(float)*np) { + fprintf(stderr, "%s: rtrace communication error\n", progname); exit(1); } - if (readbuf(fd_fromrt, (char *)pb, 3*sizeof(float)*np) - < 3*sizeof(float)*np) { - fprintf(stderr, "%s: error reading from rtrace process\n", - progname); - exit(1); - } } getexpos(s) /* get exposure from header line */ char *s; { + char fmt[32]; + if (isexpos(s)) exposure *= exposval(s); + else if (isformat(s)) { + formatval(fmt, s); + wrongformat = strcmp(fmt, COLRFMT); + } } open_pict(fn) /* open picture file */ char *fn; { - register int i; - if ((pictfp = fopen(fn, "r")) == NULL) { fprintf("%s: cannot open\n", fn); exit(1); } exposure = 1.0; - getheader(pictfp, getexpos); - if (fgetresolu(&pxsiz, &pysiz, pictfp) != (YMAJOR|YDECR)) { - fprintf("%s: bad picture resolution\n", fn); + getheader(pictfp, getexpos, NULL); + if (wrongformat || !fscnresolu(&pxsiz, &pysiz, pictfp)) { + fprintf(stderr, "%s: incompatible picture format\n", fn); exit(1); } initscans(); @@ -313,8 +305,6 @@ char *fn; close_pict() /* done with picture */ { - register int i; - if (pictfp == NULL) return; fclose(pictfp); @@ -326,92 +316,38 @@ close_pict() /* done with picture */ fork_rtrace(av) /* open pipe and start rtrace */ char *av[]; { - int p0[2], p1[2]; + int rval; - if (pipe(p0) < 0 || pipe(p1) < 0) { + rval = open_process(rt_pd, av); + if (rval < 0) { perror(progname); exit(1); } - if ((rt_pid = vfork()) == 0) { /* if child */ - close(p0[1]); - close(p1[0]); - if (p0[0] != 0) { /* connect p0 to stdin */ - dup2(p0[0], 0); - close(p0[0]); - } - if (p1[1] != 0) { /* connect p1 to stdout */ - dup2(p1[1], 1); - close(p1[1]); - } - execvp(av[0], av); - perror(av[0]); - _exit(127); - } - if (rt_pid == -1) { - perror(progname); + if (rval == 0) { + fprintf(stderr, "%s: command not found\n", av[0]); exit(1); } - close(p0[0]); - close(p1[1]); - fd_tort = p0[1]; - fd_fromrt = p1[0]; + maxpix = rval/(6*sizeof(float)); + if (maxpix > MAXPIX) + maxpix = MAXPIX; + maxpix--; } done_rtrace() /* wait for rtrace to finish */ { - int pid, status; + int status; - if (rt_pid == -1) - return; - close(fd_tort); - close(fd_fromrt); - while ((pid = wait(&status)) != -1 && pid != rt_pid) - ; - if (pid == rt_pid && status != 0) { + status = close_process(rt_pd); + if (status > 0) { fprintf(stderr, "%s: bad status (%d) from rtrace\n", progname, status); exit(1); } - rt_pid = -1; + rt_pd[0] = -1; } -int -readbuf(fd, bpos, siz) -int fd; -char *bpos; -int siz; -{ - register int cc, nrem = siz; - - while (nrem > 0 && (cc = read(fd, bpos, nrem)) > 0) { - bpos += cc; - nrem -= cc; - } - if (cc < 0) - return(cc); - return(siz-nrem); -} - - -int -writebuf(fd, bpos, siz) -char *bpos; -int siz; -{ - register int cc, nrem = siz; - - while (nrem > 0 && (cc = write(fd, bpos, nrem)) > 0) { - bpos += cc; - nrem -= cc; - } - if (cc < 0) - return(cc); - return(siz-nrem); -} - - SCAN * scanretire() /* retire old scanlines to free list */ { @@ -474,7 +410,7 @@ initscans() /* initialize scanline buffers */ /* allocate scanline buffers */ scansize = sizeof(SCAN) + pxsiz*sizeof(COLR); #ifdef ALIGN - scansize = scansize+(sizeof(ALIGN)-1)) & ~(sizeof(ALIGN)-1); + scansize = scansize+(sizeof(ALIGN)-1) & ~(sizeof(ALIGN)-1); #endif i = MAXSBUF / scansize; /* compute number to allocate */ if (i > HSIZE)