ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 2.9
Committed: Mon Jun 30 14:59:13 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.8: +6 -2 lines
Log Message:
Replaced most outdated BSD function calls with their posix equivalents, and cleaned up a few other platform dependencies.

File Contents

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