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.6 by greg, Thu Mar 21 16:46:25 1991 UTC vs.
Revision 1.13 by greg, Thu Apr 18 15:18:25 1991 UTC

# Line 20 | Line 20 | static char SCCSid[] = "$SunId$ LBL";
20   #define vfork           fork
21   #endif
22  
23 < #define NSCANS          64              /* 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 + static int      wrongformat = 0;
54 +
55 + SCAN    *scanretire();
56 +
57   extern long     ftell();
58  
59  
60 + SCAN *
61 + claimscan(y)                    /* claim scanline from buffers */
62 + int     y;
63 + {
64 +        int     hi = shash(y);
65 +        SCAN    *slast;
66 +        register SCAN   *sl;
67 +
68 +        for (sl = hashtab[hi]; sl != NULL; sl = sl->next)
69 +                if (sl->y == y)                         /* active scanline */
70 +                        return(sl);
71 +        for (slast = NULL, sl = freelist; sl != NULL; slast = sl, sl = sl->next)
72 +                if (sl->y == -1 || sl->y == y || sl->next == NULL) {
73 +                        if (slast == NULL)              /* remove from free */
74 +                                freelist = sl->next;
75 +                        else
76 +                                slast->next = sl->next;
77 +                        if (sl->y == y) {               /* reclaim */
78 +                                sl->next = hashtab[hi];
79 +                                hashtab[hi] = sl;
80 + #ifdef DEBUG
81 +                                if (verbose)
82 +                                        fprintf(stderr,
83 +                                                "%s: scanline %d reclaimed\n",
84 +                                                        progname, y);
85 + #endif
86 +                        }
87 +                        return(sl);
88 +                }
89 +        return(scanretire());           /* need more free scanlines */
90 + }
91 +
92 +
93   COLR *
94   getpictscan(y)                  /* get picture scanline */
95   int     y;
96   {
97 <        int     minused;
97 >        register SCAN   *sl;
98          register int    i;
99                                          /* first check our buffers */
100 <        ncall++;
101 <        minused = 0;
102 <        for (i = 0; i < NSCANS; i++) {
103 <                if (scan[i].y == y) {
104 <                        scan[i].lused = ncall;
105 <                        return(scan[i].sl);
106 <                }
59 <                if (scan[i].lused < scan[minused].lused)
60 <                        minused = i;
61 <        }
62 <                                        /* not there, read it in */
100 >        sl = claimscan(y);
101 >        if (sl == NULL)
102 >                memerr("claimscan()");
103 >        sl->lused = ncall++;
104 >        if (sl->y == y)                 /* scan hit */
105 >                return(scandata(sl));
106 >                                        /* else read in replacement */
107          if (scanpos[y] < 0) {                   /* need to search */
108                  for (i = y+1; i < curpos; i++)
109                          if (scanpos[i] >= 0) {
# Line 70 | Line 114 | int    y;
114                          }
115                  while (curpos >= y) {
116                          scanpos[curpos] = ftell(pictfp);
117 <                        if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
117 >                        if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
118                                  goto readerr;
119                          nread++;
120                          curpos--;
# Line 78 | Line 122 | int    y;
122          } else {
123                  if (curpos != y && fseek(pictfp, scanpos[y], 0) < 0)
124                          goto seekerr;
125 <                if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
125 >                if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
126                          goto readerr;
127                  nread++;
128                  curpos = y-1;
129          }
130 <        scan[minused].lused = ncall;
131 <        scan[minused].y = y;
132 <        return(scan[minused].sl);
130 >        sl->y = y;
131 >        i = shash(y);                   /* add to hash list */
132 >        sl->next = hashtab[i];
133 >        hashtab[i] = sl;
134 >        return(scandata(sl));
135   readerr:
136          fprintf(stderr, "%s: picture read error\n", progname);
137          exit(1);
# Line 133 | Line 179 | FVECT  vd;
179  
180  
181   double
182 < getviewpix(vh, vv)              /* compute single view pixel */
182 > getviewpix(vh, vv, se)          /* compute single view pixel */
183   int     vh, vv;
184 + SPANERR *se;
185   {
186          FVECT   dir;
187          float   rt_buf[6];
188          double  res;
189  
190 <        if (compdir(dir, vh, vv) < 0)
190 >        if (compdir(dir, vh, vv, se) < 0)
191                  return(-1.0);
192 +        npixinvw++;
193          if ((res = pict_val(dir)) >= 0.0)
194                  return(res);
195 <        if (rt_pid == -1)
195 >        if (rt_pid == -1) {
196 >                npixmiss++;
197                  return(-1.0);
198 +        }
199          rt_buf[0] = ourview.vp[0];
200          rt_buf[1] = ourview.vp[1];
201          rt_buf[2] = ourview.vp[2];
# Line 164 | Line 214 | float  *vb;
214          float   rt_buf[6*MAXPIX];       /* rtrace send/receive buffer */
215          register int    n;              /* number of pixels in buffer */
216          short   buf_vh[MAXPIX];         /* pixel positions */
217 +        SPANERR sperr;
218          FVECT   dir;
219          register int    vh;
220  
# Line 172 | Line 223 | float  *vb;
223                  fprintf(stderr, "%s: computing view span at %d...\n",
224                                  progname, vv);
225   #endif
226 +        setspanerr(&sperr, vv);
227          n = 0;
228          for (vh = -hsize; vh <= hsize; vh++) {
229 <                if (compdir(dir, vh, vv) < 0) { /* off viewable region */
229 >                if (compdir(dir, vh, vv, &sperr) < 0) { /* not in view */
230                          vb[vh+hsize] = -1.0;
231                          continue;
232                  }
233 +                npixinvw++;
234                  if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
235                          continue;
236 <                if (rt_pid == -1)               /* missing information */
236 >                if (rt_pid == -1) {             /* missing information */
237 >                        npixmiss++;
238                          continue;
239 +                }
240                                                  /* send to rtrace */
241                  if (n >= MAXPIX) {                      /* flush */
242                          rt_compute(rt_buf, n);
# Line 237 | Line 292 | int    np;
292   getexpos(s)                     /* get exposure from header line */
293   char    *s;
294   {
295 +        char    fmt[32];
296 +
297          if (isexpos(s))
298                  exposure *= exposval(s);
299 +        else if (isformat(s)) {
300 +                formatval(fmt, s);
301 +                wrongformat = strcmp(fmt, COLRFMT);
302 +        }
303   }
304  
305  
306   open_pict(fn)                   /* open picture file */
307   char    *fn;
308   {
248        register int    i;
249
309          if ((pictfp = fopen(fn, "r")) == NULL) {
310                  fprintf("%s: cannot open\n", fn);
311                  exit(1);
312          }
313          exposure = 1.0;
314 <        getheader(pictfp, getexpos);
315 <        if (fgetresolu(&pxsiz, &pysiz, pictfp) != (YMAJOR|YDECR)) {
316 <                fprintf("%s: bad picture resolution\n", fn);
314 >        getheader(pictfp, getexpos, NULL);
315 >        if (wrongformat ||
316 >                        fgetresolu(&pxsiz, &pysiz, pictfp) != (YMAJOR|YDECR)) {
317 >                fprintf("%s: bad picture format\n", fn);
318                  exit(1);
319          }
320 <        scanpos = (long *)malloc(pysiz*sizeof(long));
261 <        if (scanpos == NULL)
262 <                memerr("scanline positions");
263 <        for (i = pysiz-1; i >= 0; i--)
264 <                scanpos[i] = -1L;
265 <        curpos = pysiz-1;
266 <        for (i = 0; i < NSCANS; i++) {
267 <                scan[i].lused = -1;
268 <                scan[i].y = -1;
269 <                scan[i].sl = (COLR *)malloc(pxsiz*sizeof(COLR));
270 <                if (scan[i].sl == NULL)
271 <                        memerr("scanline buffers");
272 <        }
320 >        initscans();
321   }
322  
323  
324   close_pict()                    /* done with picture */
325   {
278        register int    i;
279
326          if (pictfp == NULL)
327                  return;
328          fclose(pictfp);
329 <        free((char *)scanpos);
284 <        for (i = 0; i < NSCANS; i++)
285 <                free((char *)scan[i].sl);
329 >        donescans();
330          pictfp = NULL;
331   }
332  
# Line 373 | Line 417 | int    siz;
417          if (cc < 0)
418                  return(cc);
419          return(siz-nrem);
420 + }
421 +
422 +
423 + SCAN *
424 + scanretire()                    /* retire old scanlines to free list */
425 + {
426 +        SCAN    *sold[NRETIRE];
427 +        int     n;
428 +        int     h;
429 +        register SCAN   *sl;
430 +        register int    i;
431 +                                        /* grab the NRETIRE oldest scanlines */
432 +        sold[n = 0] = NULL;
433 +        for (h = 0; h < HSIZE; h++)
434 +                for (sl = hashtab[h]; sl != NULL; sl = sl->next) {
435 +                        for (i = n; i && sold[i-1]->lused > sl->lused; i--)
436 +                                if (i < NRETIRE)
437 +                                        sold[i] = sold[i-1];
438 +                        if (i < NRETIRE) {
439 +                                sold[i] = sl;
440 +                                if (n < NRETIRE)        /* grow list */
441 +                                        n++;
442 +                        }
443 +                }
444 +                                        /* put scanlines into free list */
445 +        for (i = 0; i < n; i++) {
446 +                h = shash(sold[i]->y);
447 +                sl = hashtab[h];
448 +                if (sl == sold[i])
449 +                        hashtab[h] = sl->next;
450 +                else {
451 +                        while (sl->next != sold[i])     /* IS in list */
452 +                                sl = sl->next;
453 +                        sl->next = sold[i]->next;
454 +                }
455 +                if (i > 0) {            /* save oldest as return value */
456 +                        sold[i]->next = freelist;
457 +                        freelist = sold[i];
458 +                }
459 +        }
460 +        return(sold[0]);
461 + }
462 +
463 +
464 + static char     *scan_buf;
465 +
466 +
467 + initscans()                             /* initialize scanline buffers */
468 + {
469 +        int     scansize;
470 +        register SCAN   *ptr;
471 +        register int    i;
472 +                                        /* initialize positions */
473 +        scanpos = (long *)malloc(pysiz*sizeof(long));
474 +        if (scanpos == NULL)
475 +                memerr("scanline positions");
476 +        for (i = pysiz-1; i >= 0; i--)
477 +                scanpos[i] = -1L;
478 +        curpos = pysiz-1;
479 +                                        /* clear hash table */
480 +        for (i = 0; i < HSIZE; i++)
481 +                hashtab[i] = NULL;
482 +                                        /* allocate scanline buffers */
483 +        scansize = sizeof(SCAN) + pxsiz*sizeof(COLR);
484 + #ifdef ALIGN
485 +        scansize = scansize+(sizeof(ALIGN)-1)) & ~(sizeof(ALIGN)-1);
486 + #endif
487 +        i = MAXSBUF / scansize;         /* compute number to allocate */
488 +        if (i > HSIZE)
489 +                i = HSIZE;
490 +        scan_buf = malloc(i*scansize);  /* get in one big chunk */
491 +        if (scan_buf == NULL)
492 +                memerr("scanline buffers");
493 +        ptr = (SCAN *)scan_buf;
494 +        freelist = NULL;                /* build our free list */
495 +        while (i-- > 0) {
496 +                ptr->y = -1;
497 +                ptr->lused = -1;
498 +                ptr->next = freelist;
499 +                freelist = ptr;
500 +                ptr = (SCAN *)((char *)ptr + scansize); /* beware of C bugs */
501 +        }
502 + }
503 +
504 +
505 + donescans()                             /* free up scanlines */
506 + {
507 +        free(scan_buf);
508 +        free((char *)scanpos);
509   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines