ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 2.6
Committed: Sat Feb 22 02:07:30 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.5: +2 -6 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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