ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 2.10
Committed: Thu Jul 3 22:41:45 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.9: +2 -1 lines
Log Message:
Reduced compile problems on Windows.

File Contents

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