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.2 by greg, Mon Mar 18 14:33:53 1991 UTC vs.
Revision 1.17 by greg, Wed May 1 08:50:49 1991 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines