ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 2.5
Committed: Tue Oct 27 08:47:18 1998 UTC (25 years, 5 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.4: +2 -0 lines
Log Message:
changed getheader() to listen to return value of passed function

File Contents

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