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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: glareval.c,v 2.8 2003/06/27 06:53:23 greg Exp $";
3 #endif
4 /*
5 * Compute pixels for glare calculation
6 */
7
8 #include "copyright.h"
9
10 #include <string.h>
11
12 #include "rtprocess.h" /* Windows: must come first because of conflicts */
13 #include "glare.h"
14
15 /* maximum rtrace buffer size */
16 #define MAXPIX (4096/(6*sizeof(float)))
17
18 #define MAXSBUF 786432 /* maximum total size of scanline buffer */
19 #define HSIZE 317 /* size of scanline hash table */
20 #define NRETIRE 16 /* number of scanlines to retire at once */
21
22 static SUBPROC rt_pd = SP_INACTIVE; /* process id & descriptors for rtrace */
23
24 FILE *pictfp = NULL; /* picture file pointer */
25 double exposure; /* picture exposure */
26 int pxsiz, pysiz; /* picture dimensions */
27
28 static int curpos; /* current scanline */
29 static long *scanpos; /* scanline positions */
30
31 typedef struct scan {
32 int y; /* scanline position */
33 long lused; /* for LRU replacement */
34 struct scan *next; /* next in this hash or free list */
35 /* followed by the scanline data */
36 } SCAN; /* buffered scanline */
37
38 #define scandata(sl) ((COLR *)((sl)+1))
39 #define shash(y) ((y)%HSIZE)
40
41 static int maxpix; /* maximum number of pixels to buffer */
42
43 static SCAN *freelist; /* scanline free list */
44 static SCAN *hashtab[HSIZE]; /* scanline hash table */
45
46 static long scanbufsiz; /* size of allocated scanline buffer */
47
48 static long ncall = 0L; /* number of calls to getpictscan */
49 static long nread = 0L; /* number of scanlines read */
50 static long nrecl = 0L; /* number of scanlines reclaimed */
51
52 static int wrongformat = 0;
53
54 SCAN *scanretire();
55
56 extern long ftell();
57
58
59 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 nrecl++;
80 }
81 return(sl);
82 }
83 return(scanretire()); /* need more free scanlines */
84 }
85
86
87 COLR *
88 getpictscan(y) /* get picture scanline */
89 int y;
90 {
91 register SCAN *sl;
92 register int i;
93 /* first check our buffers */
94 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 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 scanpos[curpos] = ftell(pictfp);
111 if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
112 goto readerr;
113 nread++;
114 curpos--;
115 }
116 } else {
117 if (curpos != y && fseek(pictfp, scanpos[y], 0) < 0)
118 goto seekerr;
119 if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
120 goto readerr;
121 nread++;
122 curpos = y-1;
123 }
124 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 readerr:
130 fprintf(stderr, "%s: picture read error\n", progname);
131 exit(1);
132 seekerr:
133 fprintf(stderr, "%s: picture seek error\n", progname);
134 exit(1);
135 }
136
137
138 #ifdef DEBUG
139 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 static long lastrecl = 0L; /* nrecl at last report */
144
145 if (ncall == lastcall)
146 return;
147 fprintf(stderr, "%s: %ld scanlines read (%ld reclaimed) in %ld calls\n",
148 progname, nread-lastread, nrecl-lastrecl, ncall-lastcall);
149 lastcall = ncall;
150 lastread = nread;
151 lastrecl = nrecl;
152 }
153 #endif
154
155
156 double
157 pict_val(vd) /* find picture value for view direction */
158 FVECT vd;
159 {
160 FVECT pp;
161 FVECT ip;
162 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 viewloc(ip, &pictview, pp);
170 if (ip[2] <= FTINY || ip[0] < 0. || ip[0] >= 1. ||
171 ip[1] < 0. || ip[1] >= 1.)
172 return(-1.0);
173 colr_color(res, getpictscan((int)(ip[1]*pysiz))[(int)(ip[0]*pxsiz)]);
174 return(luminance(res)/exposure);
175 }
176
177
178 double
179 getviewpix(vh, vv) /* compute single view pixel */
180 int vh, vv;
181 {
182 FVECT dir;
183 float rt_buf[12];
184 double res;
185
186 if (compdir(dir, vh, vv) < 0)
187 return(-1.0);
188 npixinvw++;
189 if ((res = pict_val(dir)) >= 0.0)
190 return(res);
191 if (rt_pd.r == -1) {
192 npixmiss++;
193 return(-1.0);
194 }
195 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 register int n; /* number of pixels in buffer */
212 short buf_vh[MAXPIX]; /* pixel positions */
213 FVECT dir;
214 register int vh;
215
216 #ifdef DEBUG
217 if (verbose)
218 fprintf(stderr, "%s: computing view span at %d...\n",
219 progname, vv);
220 #endif
221 n = 0;
222 for (vh = -hsize; vh <= hsize; vh++) {
223 if (compdir(dir, vh, vv) < 0) { /* not in view */
224 vb[vh+hsize] = -1.0;
225 continue;
226 }
227 npixinvw++;
228 if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
229 continue;
230 if (rt_pd.r == -1) { /* missing information */
231 npixmiss++;
232 continue;
233 }
234 /* send to rtrace */
235 if (n >= maxpix) { /* flush */
236 rt_compute(rt_buf, n);
237 while (n-- > 0)
238 vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n);
239 }
240 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 }
248 #ifdef DEBUG
249 if (verbose)
250 pict_stats();
251 #endif
252 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 }
258
259
260 rt_compute(pb, np) /* process buffer through rtrace */
261 float *pb;
262 int np;
263 {
264 #ifdef DEBUG
265 if (verbose && np > 1)
266 fprintf(stderr, "%s: sending %d samples to rtrace...\n",
267 progname, np);
268 #endif
269 memset(pb+6*np, '\0', 6*sizeof(float));
270 if (process(&rt_pd, (char *)pb, (char *)pb, 3*sizeof(float)*(np+1),
271 6*sizeof(float)*(np+1)) < 3*sizeof(float)*(np+1)) {
272 fprintf(stderr, "%s: rtrace communication error\n",
273 progname);
274 exit(1);
275 }
276 }
277
278
279 int
280 getexpos(s) /* get exposure from header line */
281 char *s;
282 {
283 char fmt[32];
284
285 if (isexpos(s))
286 exposure *= exposval(s);
287 else if (isformat(s)) {
288 formatval(fmt, s);
289 wrongformat = strcmp(fmt, COLRFMT);
290 }
291 return(0);
292 }
293
294
295 open_pict(fn) /* open picture file */
296 char *fn;
297 {
298 if ((pictfp = fopen(fn, "r")) == NULL) {
299 fprintf(stderr, "%s: cannot open\n", fn);
300 exit(1);
301 }
302 exposure = 1.0;
303 getheader(pictfp, getexpos, NULL);
304 if (wrongformat || !fscnresolu(&pxsiz, &pysiz, pictfp)) {
305 fprintf(stderr, "%s: incompatible picture format\n", fn);
306 exit(1);
307 }
308 initscans();
309 }
310
311
312 close_pict() /* done with picture */
313 {
314 if (pictfp == NULL)
315 return;
316 fclose(pictfp);
317 donescans();
318 pictfp = NULL;
319 }
320
321
322 fork_rtrace(av) /* open pipe and start rtrace */
323 char *av[];
324 {
325 int rval;
326
327 rval = open_process(&rt_pd, av);
328 if (rval < 0) {
329 perror(progname);
330 exit(1);
331 }
332 if (rval == 0) {
333 fprintf(stderr, "%s: command not found\n", av[0]);
334 exit(1);
335 }
336 maxpix = rval/(6*sizeof(float));
337 if (maxpix > MAXPIX)
338 maxpix = MAXPIX;
339 maxpix--;
340 }
341
342
343 done_rtrace() /* wait for rtrace to finish */
344 {
345 int status;
346
347 status = close_process(&rt_pd);
348 if (status > 0) {
349 fprintf(stderr, "%s: bad status (%d) from rtrace\n",
350 progname, status);
351 exit(1);
352 }
353 rt_pd.r = -1;
354 }
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 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 sold[i] = sold[i-1];
372 if (i < NRETIRE) {
373 sold[i] = sl;
374 if (n < NRETIRE) /* grow list */
375 n++;
376 }
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 sl = sl->next;
387 sl->next = sold[i]->next;
388 }
389 if (i > 0) { /* save oldest as return value */
390 sold[i]->next = freelist;
391 freelist = sold[i];
392 }
393 }
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 scanpos = (long *)bmalloc(pysiz*sizeof(long));
408 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 #ifdef ALIGNT
419 scansize = scansize+(sizeof(ALIGNT)-1) & ~(sizeof(ALIGNT)-1);
420 #endif
421 i = MAXSBUF / scansize; /* compute number to allocate */
422 if (i > HSIZE)
423 i = HSIZE;
424 scanbufsiz = i*scansize;
425 scan_buf = bmalloc(scanbufsiz); /* get in one big chunk */
426 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 bfree(scan_buf, scanbufsiz);
443 bfree((char *)scanpos, pysiz*sizeof(long));
444 }