ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
(Generate patch)

Comparing ray/src/util/glareval.c (file contents):
Revision 1.1 by greg, Mon Mar 18 12:15:41 1991 UTC vs.
Revision 1.20 by greg, Tue Jul 30 12:56:36 1991 UTC

# Line 9 | Line 9 | static char SCCSid[] = "$SunId$ LBL";
9   */
10  
11   #include "glare.h"
12 < #include <sys/param.h>
13 <                                        /* compute rtrace buffer size */
14 < #ifndef PIPE_BUF
15 < #define PIPE_BUF        512             /* hyperconservative */
16 < #endif
17 < #define MAXPIX          (PIPE_BUF/(6*sizeof(float)) - 1)
12 >                                        /* maximum rtrace buffer size */
13 > #define MAXPIX          (4096/(6*sizeof(float)))
14  
15 < #ifndef BSD
16 < #define vfork           fork
17 < #endif
15 > #define MAXSBUF         786432  /* maximum total size of scanline buffer */
16 > #define HSIZE           317     /* size of scanline hash table */
17 > #define NRETIRE         16      /* number of scanlines to retire at once */
18  
19 < #define NSCANS          16              /* number of scanlines to buffer */
19 > int     rt_pd[3] = {-1,-1,-1};  /* process id & descriptors for rtrace */
20  
25 int     rt_pid = -1;            /* process id for rtrace */
26 int     fd_tort, fd_fromrt;     /* pipe descriptors */
27
21   FILE    *pictfp = NULL;         /* picture file pointer */
22   double  exposure;               /* picture exposure */
23   int     pxsiz, pysiz;           /* picture dimensions */
24 < int     curpos;                 /* current scanline */
25 < long    *scanpos;               /* scanline positions */
26 < struct {
27 <        long    lused;          /* for LRU replacement */
24 >
25 > static int      curpos;         /* current scanline */
26 > static long     *scanpos;       /* scanline positions */
27 >
28 > typedef struct scan {
29          int     y;              /* scanline position */
30 <        COLR    *sl;            /* scanline contents */
31 < } scan[NSCANS];         /* buffered scanlines */
30 >        long    lused;          /* for LRU replacement */
31 >        struct scan     *next;  /* next in this hash or free list */
32 >        /* followed by the scanline data */
33 > } SCAN;                 /* buffered scanline */
34  
35 + #define scandata(sl)    ((COLR *)((sl)+1))
36 + #define shash(y)        ((y)%HSIZE)
37  
38 + static int      maxpix;         /* maximum number of pixels to buffer */
39 +
40 + static SCAN     *freelist;              /* scanline free list */
41 + static SCAN     *hashtab[HSIZE];        /* scanline hash table */
42 +
43 + static long     ncall = 0L;     /* number of calls to getpictscan */
44 + static long     nread = 0L;     /* number of scanlines read */
45 + static long     nrecl = 0L;     /* number of scanlines reclaimed */
46 +
47 + static int      wrongformat = 0;
48 +
49 + SCAN    *scanretire();
50 +
51 + extern long     ftell();
52 +
53 +
54 + SCAN *
55 + claimscan(y)                    /* claim scanline from buffers */
56 + int     y;
57 + {
58 +        int     hi = shash(y);
59 +        SCAN    *slast;
60 +        register SCAN   *sl;
61 +
62 +        for (sl = hashtab[hi]; sl != NULL; sl = sl->next)
63 +                if (sl->y == y)                         /* active scanline */
64 +                        return(sl);
65 +        for (slast = NULL, sl = freelist; sl != NULL; slast = sl, sl = sl->next)
66 +                if (sl->y == -1 || sl->y == y || sl->next == NULL) {
67 +                        if (slast == NULL)              /* remove from free */
68 +                                freelist = sl->next;
69 +                        else
70 +                                slast->next = sl->next;
71 +                        if (sl->y == y) {               /* reclaim */
72 +                                sl->next = hashtab[hi];
73 +                                hashtab[hi] = sl;
74 +                                nrecl++;
75 +                        }
76 +                        return(sl);
77 +                }
78 +        return(scanretire());           /* need more free scanlines */
79 + }
80 +
81 +
82   COLR *
83   getpictscan(y)                  /* get picture scanline */
84   int     y;
85   {
86 <        extern long     ftell();
45 <        static long     ncall = 0;
46 <        int     minused;
86 >        register SCAN   *sl;
87          register int    i;
88                                          /* first check our buffers */
89 <        ncall++;
90 <        minused = 0;
91 <        for (i = 0; i < NSCANS; i++) {
92 <                if (scan[i].y == y) {
93 <                        scan[i].lused = ncall;
94 <                        return(scan[i].sl);
95 <                }
96 <                if (scan[i].lused < scan[minused].lused)
97 <                        minused = i;
98 <        }
99 <                                        /* not there, read it in */
100 <        if (scanpos[y] == -1) {                 /* need to search */
101 <                if (verbose)
102 <                        fprintf(stderr, "%s: reading picture...\n",
103 <                                        progname);
104 <                while (curpos > y) {
89 >        sl = claimscan(y);
90 >        if (sl == NULL)
91 >                memerr("claimscan()");
92 >        sl->lused = ncall++;
93 >        if (sl->y == y)                 /* scan hit */
94 >                return(scandata(sl));
95 >                                        /* else read in replacement */
96 >        if (scanpos[y] < 0) {                   /* need to search */
97 >                for (i = y+1; i < curpos; i++)
98 >                        if (scanpos[i] >= 0) {
99 >                                if (fseek(pictfp, scanpos[i], 0) < 0)
100 >                                        goto seekerr;
101 >                                curpos = i;
102 >                                break;
103 >                        }
104 >                while (curpos >= y) {
105                          scanpos[curpos] = ftell(pictfp);
106 <                        if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
106 >                        if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
107                                  goto readerr;
108 +                        nread++;
109                          curpos--;
110                  }
111 <        } else if (fseek(pictfp, scanpos[y], 0) < 0) {
112 <                fprintf(stderr, "%s: picture seek error\n", progname);
113 <                exit(1);
111 >        } else {
112 >                if (curpos != y && fseek(pictfp, scanpos[y], 0) < 0)
113 >                        goto seekerr;
114 >                if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
115 >                        goto readerr;
116 >                nread++;
117 >                curpos = y-1;
118          }
119 <        if (verbose)
120 <                fprintf(stderr, "%s: reading scanline %d...\n", progname, y);
121 <        if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
122 <                goto readerr;
123 <        curpos = y-1;
79 <        scan[minused].lused = ncall;
80 <        scan[minused].y = y;
81 <        return(scan[minused].sl);
119 >        sl->y = y;
120 >        i = shash(y);                   /* add to hash list */
121 >        sl->next = hashtab[i];
122 >        hashtab[i] = sl;
123 >        return(scandata(sl));
124   readerr:
125          fprintf(stderr, "%s: picture read error\n", progname);
126          exit(1);
127 + seekerr:
128 +        fprintf(stderr, "%s: picture seek error\n", progname);
129 +        exit(1);
130   }
131  
132  
133 + #ifdef DEBUG
134 + pict_stats()                    /* print out picture read statistics */
135 + {
136 +        static long     lastcall = 0L;  /* ncall at last report */
137 +        static long     lastread = 0L;  /* nread at last report */
138 +        static long     lastrecl = 0L;  /* nrecl at last report */
139 +
140 +        if (ncall == lastcall)
141 +                return;
142 +        fprintf(stderr, "%s: %ld scanlines read (%ld reclaimed) in %ld calls\n",
143 +                progname, nread-lastread, nrecl-lastrecl, ncall-lastcall);
144 +        lastcall = ncall;
145 +        lastread = nread;
146 +        lastrecl = nrecl;
147 + }
148 + #endif
149 +
150 +
151   double
152   pict_val(vd)                    /* find picture value for view direction */
153   FVECT   vd;
# Line 111 | Line 174 | getviewpix(vh, vv)             /* compute single view pixel */
174   int     vh, vv;
175   {
176          FVECT   dir;
177 <        float   rt_buf[6];
177 >        float   rt_buf[12];
178          double  res;
179  
180          if (compdir(dir, vh, vv) < 0)
181                  return(-1.0);
182 +        npixinvw++;
183          if ((res = pict_val(dir)) >= 0.0)
184                  return(res);
185 <        if (rt_pid == -1)
185 >        if (rt_pd[0] == -1) {
186 >                npixmiss++;
187                  return(-1.0);
188 +        }
189          rt_buf[0] = ourview.vp[0];
190          rt_buf[1] = ourview.vp[1];
191          rt_buf[2] = ourview.vp[2];
# Line 136 | Line 202 | int    vv;
202   float   *vb;
203   {
204          float   rt_buf[6*MAXPIX];       /* rtrace send/receive buffer */
205 <        int     npix_tort;              /* number of pixels in buffer */
205 >        register int    n;              /* number of pixels in buffer */
206          short   buf_vh[MAXPIX];         /* pixel positions */
207          FVECT   dir;
208          register int    vh;
143        register int    i;
209  
210 + #ifdef DEBUG
211          if (verbose)
212                  fprintf(stderr, "%s: computing view span at %d...\n",
213                                  progname, vv);
214 <        npix_tort = 0;
214 > #endif
215 >        n = 0;
216          for (vh = -hsize; vh <= hsize; vh++) {
217 <                if (compdir(dir, vh, vv) < 0) { /* off viewable region */
217 >                if (compdir(dir, vh, vv) < 0) {         /* not in view */
218                          vb[vh+hsize] = -1.0;
219                          continue;
220                  }
221 +                npixinvw++;
222                  if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
223                          continue;
224 <                if (rt_pid == -1)               /* missing information */
224 >                if (rt_pd[0] == -1) {           /* missing information */
225 >                        npixmiss++;
226                          continue;
227 +                }
228                                                  /* send to rtrace */
229 <                if (npix_tort >= MAXPIX) {              /* flush */
230 <                        rt_compute(rt_buf, npix_tort);
231 <                        for (i = 0; i < npix_tort; i++)
232 <                                vb[buf_vh[i]+hsize] = luminance(rt_buf+3*i);
163 <                        npix_tort = 0;
229 >                if (n >= maxpix) {                      /* flush */
230 >                        rt_compute(rt_buf, n);
231 >                        while (n-- > 0)
232 >                                vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n);
233                  }
234 <                rt_buf[npix_tort] = ourview.vp[0];
235 <                rt_buf[npix_tort+1] = ourview.vp[1];
236 <                rt_buf[npix_tort+2] = ourview.vp[2];
237 <                rt_buf[npix_tort+3] = dir[0];
238 <                rt_buf[npix_tort+4] = dir[1];
239 <                rt_buf[npix_tort+5] = dir[2];
240 <                buf_vh[npix_tort++] = vh;
234 >                rt_buf[6*n] = ourview.vp[0];
235 >                rt_buf[6*n+1] = ourview.vp[1];
236 >                rt_buf[6*n+2] = ourview.vp[2];
237 >                rt_buf[6*n+3] = dir[0];
238 >                rt_buf[6*n+4] = dir[1];
239 >                rt_buf[6*n+5] = dir[2];
240 >                buf_vh[n++] = vh;
241          }
242 <        if (npix_tort > 0) {                    /* process pending buffer */
243 <                rt_compute(rt_buf, npix_tort);
244 <                for (i = 0; i < npix_tort; i++)
245 <                        vb[buf_vh[i]+hsize] = luminance(rt_buf+3*i);
242 > #ifdef DEBUG
243 >        if (verbose)
244 >                pict_stats();
245 > #endif
246 >        if (n > 0) {                            /* process pending buffer */
247 >                rt_compute(rt_buf, n);
248 >                while (n-- > 0)
249 >                        vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n);
250          }
251   }
252  
# Line 182 | Line 255 | rt_compute(pb, np)             /* process buffer through rtrace *
255   float   *pb;
256   int     np;
257   {
258 <        static float    nbuf[6] = {0.,0.,0.,0.,0.,0.};
186 <
258 > #ifdef DEBUG
259          if (verbose && np > 1)
260                  fprintf(stderr, "%s: sending %d samples to rtrace...\n",
261                                  progname, np);
262 <        if (writebuf(fd_tort,(char *)pb,6*sizeof(float)*np) < 6*sizeof(float)*np
263 <                || writebuf(fd_tort,(char *)nbuf,sizeof(nbuf)) < sizeof(nbuf)) {
264 <                fprintf(stderr, "%s: error writing to rtrace process\n",
262 > #endif
263 >        bzero(pb+6*np, 6*sizeof(float));
264 >        if (process(rt_pd, pb, pb, 3*sizeof(float)*np,
265 >                        6*sizeof(float)*(np+1)) < 3*sizeof(float)*np) {
266 >                fprintf(stderr, "%s: rtrace communication error\n",
267                                  progname);
268                  exit(1);
269          }
196        if (readbuf(fd_fromrt, (char *)pb, 3*sizeof(float)*np)
197                        < 3*sizeof(float)*np) {
198                fprintf(stderr, "%s: error reading from rtrace process\n",
199                                progname);
200                exit(1);
201        }
270   }
271  
272  
273   getexpos(s)                     /* get exposure from header line */
274   char    *s;
275   {
276 +        char    fmt[32];
277 +
278          if (isexpos(s))
279                  exposure *= exposval(s);
280 +        else if (isformat(s)) {
281 +                formatval(fmt, s);
282 +                wrongformat = strcmp(fmt, COLRFMT);
283 +        }
284   }
285  
286  
287   open_pict(fn)                   /* open picture file */
288   char    *fn;
289   {
216        register int    i;
217
290          if ((pictfp = fopen(fn, "r")) == NULL) {
291                  fprintf("%s: cannot open\n", fn);
292                  exit(1);
293          }
294          exposure = 1.0;
295 <        getheader(pictfp, getexpos);
296 <        if (fgetresolu(&pxsiz, &pysiz, pictfp) != (YMAJOR|YDECR)) {
297 <                fprintf("%s: bad picture resolution\n", fn);
295 >        getheader(pictfp, getexpos, NULL);
296 >        if (wrongformat ||
297 >                        fgetresolu(&pxsiz, &pysiz, pictfp) != (YMAJOR|YDECR)) {
298 >                fprintf("%s: bad picture format\n", fn);
299                  exit(1);
300          }
301 <        scanpos = (long *)malloc(pysiz*sizeof(long));
229 <        if (scanpos == NULL)
230 <                memerr("scanline positions");
231 <        for (i = 0; i < pysiz; i++)
232 <                scanpos[i] = -1L;
233 <        for (i = 0; i < NSCANS; i++) {
234 <                scan[i].lused = -1;
235 <                scan[i].y = -1;
236 <                scan[i].sl = (COLR *)malloc(pxsiz*sizeof(COLR));
237 <                if (scan[i].sl == NULL)
238 <                        memerr("scanline buffers");
239 <        }
240 <        curpos = pysiz-1;
301 >        initscans();
302   }
303  
304  
305   close_pict()                    /* done with picture */
306   {
246        register int    i;
247
307          if (pictfp == NULL)
308                  return;
309          fclose(pictfp);
310 <        free((char *)scanpos);
252 <        for (i = 0; i < NSCANS; i++)
253 <                free((char *)scan[i].sl);
310 >        donescans();
311          pictfp = NULL;
312   }
313  
# Line 258 | Line 315 | close_pict()                   /* done with picture */
315   fork_rtrace(av)                 /* open pipe and start rtrace */
316   char    *av[];
317   {
318 <        int     p0[2], p1[2];
318 >        int     rval;
319  
320 <        if (pipe(p0) < 0 || pipe(p1) < 0) {
320 >        rval = open_process(rt_pd, av);
321 >        if (rval < 0) {
322                  perror(progname);
323                  exit(1);
324          }
325 <        if ((rt_pid = vfork()) == 0) {          /* if child */
326 <                close(p0[1]);
269 <                close(p1[0]);
270 <                if (p0[0] != 0) {       /* connect p0 to stdin */
271 <                        dup2(p0[0], 0);
272 <                        close(p0[0]);
273 <                }
274 <                if (p1[1] != 0) {       /* connect p1 to stdout */
275 <                        dup2(p1[1], 1);
276 <                        close(p1[1]);
277 <                }
278 <                execvp(av[0], av);
279 <                perror(av[0]);
280 <                _exit(127);
281 <        }
282 <        if (rt_pid == -1) {
283 <                perror(progname);
325 >        if (rval == 0) {
326 >                fprintf(stderr, "%s: command not found\n", av[0]);
327                  exit(1);
328          }
329 <        fd_tort = p0[1];
330 <        fd_fromrt = p1[0];
329 >        maxpix = rval/(6*sizeof(float));
330 >        if (maxpix > MAXPIX)
331 >                maxpix = MAXPIX;
332 >        maxpix--;
333   }
334  
335  
336   done_rtrace()                   /* wait for rtrace to finish */
337   {
338 <        int     pid, status;
338 >        int     status;
339  
340 <        if (rt_pid == -1)
341 <                return;
297 <        close(fd_tort);
298 <        close(fd_fromrt);
299 <        while ((pid = wait(&status)) != -1 && pid != rt_pid)
300 <                ;
301 <        if (pid == rt_pid && status != 0) {
340 >        status = close_process(rt_pd);
341 >        if (status > 0) {
342                  fprintf(stderr, "%s: bad status (%d) from rtrace\n",
343                                  progname, status);
344                  exit(1);
345          }
346 <        rt_pid = -1;
346 >        rt_pd[0] = -1;
347   }
348  
349  
350 < int
351 < readbuf(fd, bpos, siz)
312 < int     fd;
313 < char    *bpos;
314 < int     siz;
350 > SCAN *
351 > scanretire()                    /* retire old scanlines to free list */
352   {
353 <        register int    cc, nrem = siz;
354 <
355 <        while (nrem > 0 && (cc = read(fd, bpos, nrem)) > 0) {
356 <                bpos += cc;
357 <                nrem -= cc;
353 >        SCAN    *sold[NRETIRE];
354 >        int     n;
355 >        int     h;
356 >        register SCAN   *sl;
357 >        register int    i;
358 >                                        /* grab the NRETIRE oldest scanlines */
359 >        sold[n = 0] = NULL;
360 >        for (h = 0; h < HSIZE; h++)
361 >                for (sl = hashtab[h]; sl != NULL; sl = sl->next) {
362 >                        for (i = n; i && sold[i-1]->lused > sl->lused; i--)
363 >                                if (i < NRETIRE)
364 >                                        sold[i] = sold[i-1];
365 >                        if (i < NRETIRE) {
366 >                                sold[i] = sl;
367 >                                if (n < NRETIRE)        /* grow list */
368 >                                        n++;
369 >                        }
370 >                }
371 >                                        /* put scanlines into free list */
372 >        for (i = 0; i < n; i++) {
373 >                h = shash(sold[i]->y);
374 >                sl = hashtab[h];
375 >                if (sl == sold[i])
376 >                        hashtab[h] = sl->next;
377 >                else {
378 >                        while (sl->next != sold[i])     /* IS in list */
379 >                                sl = sl->next;
380 >                        sl->next = sold[i]->next;
381 >                }
382 >                if (i > 0) {            /* save oldest as return value */
383 >                        sold[i]->next = freelist;
384 >                        freelist = sold[i];
385 >                }
386          }
387 <        if (cc < 0)
323 <                return(cc);
324 <        return(siz-nrem);
387 >        return(sold[0]);
388   }
389  
390  
391 < int
329 < writebuf(fd, bpos, siz)
330 < char    *bpos;
331 < int     siz;
332 < {
333 <        register int    cc, nrem = siz;
391 > static char     *scan_buf;
392  
393 <        while (nrem > 0 && (cc = write(fd, bpos, nrem)) > 0) {
394 <                bpos += cc;
395 <                nrem -= cc;
393 >
394 > initscans()                             /* initialize scanline buffers */
395 > {
396 >        int     scansize;
397 >        register SCAN   *ptr;
398 >        register int    i;
399 >                                        /* initialize positions */
400 >        scanpos = (long *)malloc(pysiz*sizeof(long));
401 >        if (scanpos == NULL)
402 >                memerr("scanline positions");
403 >        for (i = pysiz-1; i >= 0; i--)
404 >                scanpos[i] = -1L;
405 >        curpos = pysiz-1;
406 >                                        /* clear hash table */
407 >        for (i = 0; i < HSIZE; i++)
408 >                hashtab[i] = NULL;
409 >                                        /* allocate scanline buffers */
410 >        scansize = sizeof(SCAN) + pxsiz*sizeof(COLR);
411 > #ifdef ALIGN
412 >        scansize = scansize+(sizeof(ALIGN)-1) & ~(sizeof(ALIGN)-1);
413 > #endif
414 >        i = MAXSBUF / scansize;         /* compute number to allocate */
415 >        if (i > HSIZE)
416 >                i = HSIZE;
417 >        scan_buf = malloc(i*scansize);  /* get in one big chunk */
418 >        if (scan_buf == NULL)
419 >                memerr("scanline buffers");
420 >        ptr = (SCAN *)scan_buf;
421 >        freelist = NULL;                /* build our free list */
422 >        while (i-- > 0) {
423 >                ptr->y = -1;
424 >                ptr->lused = -1;
425 >                ptr->next = freelist;
426 >                freelist = ptr;
427 >                ptr = (SCAN *)((char *)ptr + scansize); /* beware of C bugs */
428          }
429 <        if (cc < 0)
430 <                return(cc);
431 <        return(siz-nrem);
429 > }
430 >
431 >
432 > donescans()                             /* free up scanlines */
433 > {
434 >        free(scan_buf);
435 >        free((char *)scanpos);
436   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines