ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 2.7
Committed: Thu Jun 26 00:58:11 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.6: +10 -8 lines
Log Message:
Abstracted process and path handling for Windows.
Renamed FLOAT to RREAL because of conflict on Windows.
Added conditional compiles for some signal handlers.

File Contents

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