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.12 by greg, Fri Apr 12 10:28:34 1991 UTC

# Line 20 | Line 20 | static char SCCSid[] = "$SunId$ LBL";
20   #define vfork           fork
21   #endif
22  
23 < #define NSCANS          16              /* number of scanlines to buffer */
23 > #define MAXSBUF         524268  /* maximum total size of scanline buffer */
24 > #define HSIZE           317     /* size of scanline hash table */
25 > #define NRETIRE         16      /* number of scanlines to retire at once */
26  
27   int     rt_pid = -1;            /* process id for rtrace */
28   int     fd_tort, fd_fromrt;     /* pipe descriptors */
# Line 28 | Line 30 | int    fd_tort, fd_fromrt;     /* pipe descriptors */
30   FILE    *pictfp = NULL;         /* picture file pointer */
31   double  exposure;               /* picture exposure */
32   int     pxsiz, pysiz;           /* picture dimensions */
33 < int     curpos;                 /* current scanline */
34 < long    *scanpos;               /* scanline positions */
35 < struct {
36 <        long    lused;          /* for LRU replacement */
33 >
34 > static int      curpos;         /* current scanline */
35 > static long     *scanpos;       /* scanline positions */
36 >
37 > typedef struct scan {
38          int     y;              /* scanline position */
39 <        COLR    *sl;            /* scanline contents */
40 < } scan[NSCANS];         /* buffered scanlines */
39 >        long    lused;          /* for LRU replacement */
40 >        struct scan     *next;  /* next in this hash or free list */
41 >        /* followed by the scanline data */
42 > } SCAN;                 /* buffered scanline */
43  
44 + #define scandata(sl)    ((COLR *)((sl)+1))
45 + #define shash(y)        ((y)%HSIZE)
46  
47 + static SCAN     *freelist;              /* scanline free list */
48 + static SCAN     *hashtab[HSIZE];        /* scanline hash table */
49 +
50 + static long     ncall = 0L;     /* number of calls to getpictscan */
51 + static long     nread = 0L;     /* number of scanlines read */
52 +
53 + SCAN    *scanretire();
54 +
55 + extern long     ftell();
56 +
57 +
58 + SCAN *
59 + claimscan(y)                    /* claim scanline from buffers */
60 + int     y;
61 + {
62 +        int     hi = shash(y);
63 +        SCAN    *slast;
64 +        register SCAN   *sl;
65 +
66 +        for (sl = hashtab[hi]; sl != NULL; sl = sl->next)
67 +                if (sl->y == y)                         /* active scanline */
68 +                        return(sl);
69 +        for (slast = NULL, sl = freelist; sl != NULL; slast = sl, sl = sl->next)
70 +                if (sl->y == -1 || sl->y == y || sl->next == NULL) {
71 +                        if (slast == NULL)              /* remove from free */
72 +                                freelist = sl->next;
73 +                        else
74 +                                slast->next = sl->next;
75 +                        if (sl->y == y) {               /* reclaim */
76 +                                sl->next = hashtab[hi];
77 +                                hashtab[hi] = sl;
78 + #ifdef DEBUG
79 +                                if (verbose)
80 +                                        fprintf(stderr,
81 +                                                "%s: scanline %d reclaimed\n",
82 +                                                        progname, y);
83 + #endif
84 +                        }
85 +                        return(sl);
86 +                }
87 +        return(scanretire());           /* need more free scanlines */
88 + }
89 +
90 +
91   COLR *
92   getpictscan(y)                  /* get picture scanline */
93   int     y;
94   {
95 <        extern long     ftell();
45 <        static long     ncall = 0;
46 <        int     minused;
95 >        register SCAN   *sl;
96          register int    i;
97                                          /* first check our buffers */
98 <        ncall++;
99 <        minused = 0;
100 <        for (i = 0; i < NSCANS; i++) {
101 <                if (scan[i].y == y) {
102 <                        scan[i].lused = ncall;
103 <                        return(scan[i].sl);
104 <                }
105 <                if (scan[i].lused < scan[minused].lused)
106 <                        minused = i;
107 <        }
108 <                                        /* not there, read it in */
109 <        if (scanpos[y] == -1) {                 /* need to search */
110 <                if (verbose)
111 <                        fprintf(stderr, "%s: reading picture...\n",
112 <                                        progname);
113 <                while (curpos > y) {
98 >        sl = claimscan(y);
99 >        if (sl == NULL)
100 >                memerr("claimscan()");
101 >        sl->lused = ncall++;
102 >        if (sl->y == y)                 /* scan hit */
103 >                return(scandata(sl));
104 >                                        /* else read in replacement */
105 >        if (scanpos[y] < 0) {                   /* need to search */
106 >                for (i = y+1; i < curpos; i++)
107 >                        if (scanpos[i] >= 0) {
108 >                                if (fseek(pictfp, scanpos[i], 0) < 0)
109 >                                        goto seekerr;
110 >                                curpos = i;
111 >                                break;
112 >                        }
113 >                while (curpos >= y) {
114                          scanpos[curpos] = ftell(pictfp);
115 <                        if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
115 >                        if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
116                                  goto readerr;
117 +                        nread++;
118                          curpos--;
119                  }
120 <        } else if (fseek(pictfp, scanpos[y], 0) < 0) {
121 <                fprintf(stderr, "%s: picture seek error\n", progname);
122 <                exit(1);
120 >        } else {
121 >                if (curpos != y && fseek(pictfp, scanpos[y], 0) < 0)
122 >                        goto seekerr;
123 >                if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
124 >                        goto readerr;
125 >                nread++;
126 >                curpos = y-1;
127          }
128 <        if (verbose)
129 <                fprintf(stderr, "%s: reading scanline %d...\n", progname, y);
130 <        if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
131 <                goto readerr;
132 <        curpos = y-1;
79 <        scan[minused].lused = ncall;
80 <        scan[minused].y = y;
81 <        return(scan[minused].sl);
128 >        sl->y = y;
129 >        i = shash(y);                   /* add to hash list */
130 >        sl->next = hashtab[i];
131 >        hashtab[i] = sl;
132 >        return(scandata(sl));
133   readerr:
134          fprintf(stderr, "%s: picture read error\n", progname);
135          exit(1);
136 + seekerr:
137 +        fprintf(stderr, "%s: picture seek error\n", progname);
138 +        exit(1);
139   }
140  
141  
142 + #ifdef DEBUG
143 + pict_stats()                    /* print out picture read statistics */
144 + {
145 +        static long     lastcall = 0L;  /* ncall at last report */
146 +        static long     lastread = 0L;  /* nread at last report */
147 +
148 +        if (ncall == lastcall)
149 +                return;
150 +        fprintf(stderr, "%s: %ld scanlines read in %ld calls\n",
151 +                        progname, nread-lastread, ncall-lastcall);
152 +        lastcall = ncall;
153 +        lastread = nread;
154 + }
155 + #endif
156 +
157 +
158   double
159   pict_val(vd)                    /* find picture value for view direction */
160   FVECT   vd;
# Line 107 | Line 177 | FVECT  vd;
177  
178  
179   double
180 < getviewpix(vh, vv)              /* compute single view pixel */
180 > getviewpix(vh, vv, se)          /* compute single view pixel */
181   int     vh, vv;
182 + SPANERR *se;
183   {
184          FVECT   dir;
185          float   rt_buf[6];
186          double  res;
187  
188 <        if (compdir(dir, vh, vv) < 0)
188 >        if (compdir(dir, vh, vv, se) < 0)
189                  return(-1.0);
190 +        npixinvw++;
191          if ((res = pict_val(dir)) >= 0.0)
192                  return(res);
193 <        if (rt_pid == -1)
193 >        if (rt_pid == -1) {
194 >                npixmiss++;
195                  return(-1.0);
196 +        }
197          rt_buf[0] = ourview.vp[0];
198          rt_buf[1] = ourview.vp[1];
199          rt_buf[2] = ourview.vp[2];
# Line 136 | Line 210 | int    vv;
210   float   *vb;
211   {
212          float   rt_buf[6*MAXPIX];       /* rtrace send/receive buffer */
213 <        int     npix_tort;              /* number of pixels in buffer */
213 >        register int    n;              /* number of pixels in buffer */
214          short   buf_vh[MAXPIX];         /* pixel positions */
215 +        SPANERR sperr;
216          FVECT   dir;
217          register int    vh;
143        register int    i;
218  
219 + #ifdef DEBUG
220          if (verbose)
221                  fprintf(stderr, "%s: computing view span at %d...\n",
222                                  progname, vv);
223 <        npix_tort = 0;
223 > #endif
224 >        setspanerr(&sperr, vv);
225 >        n = 0;
226          for (vh = -hsize; vh <= hsize; vh++) {
227 <                if (compdir(dir, vh, vv) < 0) { /* off viewable region */
227 >                if (compdir(dir, vh, vv, &sperr) < 0) { /* not in view */
228                          vb[vh+hsize] = -1.0;
229                          continue;
230                  }
231 +                npixinvw++;
232                  if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
233                          continue;
234 <                if (rt_pid == -1)               /* missing information */
234 >                if (rt_pid == -1) {             /* missing information */
235 >                        npixmiss++;
236                          continue;
237 +                }
238                                                  /* send to rtrace */
239 <                if (npix_tort >= MAXPIX) {              /* flush */
240 <                        rt_compute(rt_buf, npix_tort);
241 <                        for (i = 0; i < npix_tort; i++)
242 <                                vb[buf_vh[i]+hsize] = luminance(rt_buf+3*i);
163 <                        npix_tort = 0;
239 >                if (n >= MAXPIX) {                      /* flush */
240 >                        rt_compute(rt_buf, n);
241 >                        while (n-- > 0)
242 >                                vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n);
243                  }
244 <                rt_buf[npix_tort] = ourview.vp[0];
245 <                rt_buf[npix_tort+1] = ourview.vp[1];
246 <                rt_buf[npix_tort+2] = ourview.vp[2];
247 <                rt_buf[npix_tort+3] = dir[0];
248 <                rt_buf[npix_tort+4] = dir[1];
249 <                rt_buf[npix_tort+5] = dir[2];
250 <                buf_vh[npix_tort++] = vh;
244 >                rt_buf[6*n] = ourview.vp[0];
245 >                rt_buf[6*n+1] = ourview.vp[1];
246 >                rt_buf[6*n+2] = ourview.vp[2];
247 >                rt_buf[6*n+3] = dir[0];
248 >                rt_buf[6*n+4] = dir[1];
249 >                rt_buf[6*n+5] = dir[2];
250 >                buf_vh[n++] = vh;
251          }
252 <        if (npix_tort > 0) {                    /* process pending buffer */
253 <                rt_compute(rt_buf, npix_tort);
254 <                for (i = 0; i < npix_tort; i++)
255 <                        vb[buf_vh[i]+hsize] = luminance(rt_buf+3*i);
252 > #ifdef DEBUG
253 >        if (verbose)
254 >                pict_stats();
255 > #endif
256 >        if (n > 0) {                            /* process pending buffer */
257 >                rt_compute(rt_buf, n);
258 >                while (n-- > 0)
259 >                        vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n);
260          }
261   }
262  
# Line 184 | Line 267 | int    np;
267   {
268          static float    nbuf[6] = {0.,0.,0.,0.,0.,0.};
269  
270 + #ifdef DEBUG
271          if (verbose && np > 1)
272                  fprintf(stderr, "%s: sending %d samples to rtrace...\n",
273                                  progname, np);
274 + #endif
275          if (writebuf(fd_tort,(char *)pb,6*sizeof(float)*np) < 6*sizeof(float)*np
276                  || writebuf(fd_tort,(char *)nbuf,sizeof(nbuf)) < sizeof(nbuf)) {
277                  fprintf(stderr, "%s: error writing to rtrace process\n",
# Line 213 | Line 298 | char   *s;
298   open_pict(fn)                   /* open picture file */
299   char    *fn;
300   {
216        register int    i;
217
301          if ((pictfp = fopen(fn, "r")) == NULL) {
302                  fprintf("%s: cannot open\n", fn);
303                  exit(1);
# Line 225 | Line 308 | char   *fn;
308                  fprintf("%s: bad picture resolution\n", fn);
309                  exit(1);
310          }
311 <        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;
311 >        initscans();
312   }
313  
314  
315   close_pict()                    /* done with picture */
316   {
246        register int    i;
247
317          if (pictfp == NULL)
318                  return;
319          fclose(pictfp);
320 <        free((char *)scanpos);
252 <        for (i = 0; i < NSCANS; i++)
253 <                free((char *)scan[i].sl);
320 >        donescans();
321          pictfp = NULL;
322   }
323  
# Line 283 | Line 350 | char   *av[];
350                  perror(progname);
351                  exit(1);
352          }
353 +        close(p0[0]);
354 +        close(p1[1]);
355          fd_tort = p0[1];
356          fd_fromrt = p1[0];
357   }
# Line 339 | Line 408 | int    siz;
408          if (cc < 0)
409                  return(cc);
410          return(siz-nrem);
411 + }
412 +
413 +
414 + SCAN *
415 + scanretire()                    /* retire old scanlines to free list */
416 + {
417 +        SCAN    *sold[NRETIRE];
418 +        int     n;
419 +        int     h;
420 +        register SCAN   *sl;
421 +        register int    i;
422 +                                        /* grab the NRETIRE oldest scanlines */
423 +        sold[n = 0] = NULL;
424 +        for (h = 0; h < HSIZE; h++)
425 +                for (sl = hashtab[h]; sl != NULL; sl = sl->next) {
426 +                        for (i = n; i && sold[i-1]->lused > sl->lused; i--)
427 +                                if (i < NRETIRE)
428 +                                        sold[i] = sold[i-1];
429 +                        if (i < NRETIRE) {
430 +                                sold[i] = sl;
431 +                                if (n < NRETIRE)        /* grow list */
432 +                                        n++;
433 +                        }
434 +                }
435 +                                        /* put scanlines into free list */
436 +        for (i = 0; i < n; i++) {
437 +                h = shash(sold[i]->y);
438 +                sl = hashtab[h];
439 +                if (sl == sold[i])
440 +                        hashtab[h] = sl->next;
441 +                else {
442 +                        while (sl->next != sold[i])     /* IS in list */
443 +                                sl = sl->next;
444 +                        sl->next = sold[i]->next;
445 +                }
446 +                if (i > 0) {            /* save oldest as return value */
447 +                        sold[i]->next = freelist;
448 +                        freelist = sold[i];
449 +                }
450 +        }
451 +        return(sold[0]);
452 + }
453 +
454 +
455 + static char     *scan_buf;
456 +
457 +
458 + initscans()                             /* initialize scanline buffers */
459 + {
460 +        int     scansize;
461 +        register SCAN   *ptr;
462 +        register int    i;
463 +                                        /* initialize positions */
464 +        scanpos = (long *)malloc(pysiz*sizeof(long));
465 +        if (scanpos == NULL)
466 +                memerr("scanline positions");
467 +        for (i = pysiz-1; i >= 0; i--)
468 +                scanpos[i] = -1L;
469 +        curpos = pysiz-1;
470 +                                        /* clear hash table */
471 +        for (i = 0; i < HSIZE; i++)
472 +                hashtab[i] = NULL;
473 +                                        /* allocate scanline buffers */
474 +        scansize = sizeof(SCAN) + pxsiz*sizeof(COLR);
475 + #ifdef ALIGN
476 +        scansize = scansize+(sizeof(ALIGN)-1)) & ~(sizeof(ALIGN)-1);
477 + #endif
478 +        i = MAXSBUF / scansize;         /* compute number to allocate */
479 +        if (i > HSIZE)
480 +                i = HSIZE;
481 +        scan_buf = malloc(i*scansize);  /* get in one big chunk */
482 +        if (scan_buf == NULL)
483 +                memerr("scanline buffers");
484 +        ptr = (SCAN *)scan_buf;
485 +        freelist = NULL;                /* build our free list */
486 +        while (i-- > 0) {
487 +                ptr->y = -1;
488 +                ptr->lused = -1;
489 +                ptr->next = freelist;
490 +                freelist = ptr;
491 +                ptr = (SCAN *)((char *)ptr + scansize); /* beware of C bugs */
492 +        }
493 + }
494 +
495 +
496 + donescans()                             /* free up scanlines */
497 + {
498 +        free(scan_buf);
499 +        free((char *)scanpos);
500   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines