ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 2.5
Committed: Tue Oct 27 08:47:18 1998 UTC (25 years, 6 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.4: +2 -0 lines
Log Message:
changed getheader() to listen to return value of passed function

File Contents

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