ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 2.1
Committed: Tue Nov 12 17:19:21 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.21: +0 -0 lines
Log Message:
changed revision number for 2.0 release

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 ncall = 0L; /* number of calls to getpictscan */
45 static long nread = 0L; /* number of scanlines read */
46 static long nrecl = 0L; /* number of scanlines reclaimed */
47
48 static int wrongformat = 0;
49
50 SCAN *scanretire();
51
52 extern long ftell();
53
54
55 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 nrecl++;
76 }
77 return(sl);
78 }
79 return(scanretire()); /* need more free scanlines */
80 }
81
82
83 COLR *
84 getpictscan(y) /* get picture scanline */
85 int y;
86 {
87 register SCAN *sl;
88 register int i;
89 /* first check our buffers */
90 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 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 scanpos[curpos] = ftell(pictfp);
107 if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
108 goto readerr;
109 nread++;
110 curpos--;
111 }
112 } else {
113 if (curpos != y && fseek(pictfp, scanpos[y], 0) < 0)
114 goto seekerr;
115 if (freadcolrs(scandata(sl), pxsiz, pictfp) < 0)
116 goto readerr;
117 nread++;
118 curpos = y-1;
119 }
120 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 readerr:
126 fprintf(stderr, "%s: picture read error\n", progname);
127 exit(1);
128 seekerr:
129 fprintf(stderr, "%s: picture seek error\n", progname);
130 exit(1);
131 }
132
133
134 #ifdef DEBUG
135 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 static long lastrecl = 0L; /* nrecl at last report */
140
141 if (ncall == lastcall)
142 return;
143 fprintf(stderr, "%s: %ld scanlines read (%ld reclaimed) in %ld calls\n",
144 progname, nread-lastread, nrecl-lastrecl, ncall-lastcall);
145 lastcall = ncall;
146 lastread = nread;
147 lastrecl = nrecl;
148 }
149 #endif
150
151
152 double
153 pict_val(vd) /* find picture value for view direction */
154 FVECT vd;
155 {
156 FVECT pp;
157 FVECT ip;
158 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 viewloc(ip, &pictview, pp);
166 if (ip[2] <= FTINY || ip[0] < 0. || ip[0] >= 1. ||
167 ip[1] < 0. || ip[1] >= 1.)
168 return(-1.0);
169 colr_color(res, getpictscan((int)(ip[1]*pysiz))[(int)(ip[0]*pxsiz)]);
170 return(luminance(res)/exposure);
171 }
172
173
174 double
175 getviewpix(vh, vv) /* compute single view pixel */
176 int vh, vv;
177 {
178 FVECT dir;
179 float rt_buf[12];
180 double res;
181
182 if (compdir(dir, vh, vv) < 0)
183 return(-1.0);
184 npixinvw++;
185 if ((res = pict_val(dir)) >= 0.0)
186 return(res);
187 if (rt_pd[0] == -1) {
188 npixmiss++;
189 return(-1.0);
190 }
191 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 register int n; /* number of pixels in buffer */
208 short buf_vh[MAXPIX]; /* pixel positions */
209 FVECT dir;
210 register int vh;
211
212 #ifdef DEBUG
213 if (verbose)
214 fprintf(stderr, "%s: computing view span at %d...\n",
215 progname, vv);
216 #endif
217 n = 0;
218 for (vh = -hsize; vh <= hsize; vh++) {
219 if (compdir(dir, vh, vv) < 0) { /* not in view */
220 vb[vh+hsize] = -1.0;
221 continue;
222 }
223 npixinvw++;
224 if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
225 continue;
226 if (rt_pd[0] == -1) { /* missing information */
227 npixmiss++;
228 continue;
229 }
230 /* send to rtrace */
231 if (n >= maxpix) { /* flush */
232 rt_compute(rt_buf, n);
233 while (n-- > 0)
234 vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n);
235 }
236 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 }
244 #ifdef DEBUG
245 if (verbose)
246 pict_stats();
247 #endif
248 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 }
254
255
256 rt_compute(pb, np) /* process buffer through rtrace */
257 float *pb;
258 int np;
259 {
260 #ifdef DEBUG
261 if (verbose && np > 1)
262 fprintf(stderr, "%s: sending %d samples to rtrace...\n",
263 progname, np);
264 #endif
265 bzero(pb+6*np, 6*sizeof(float));
266 if (process(rt_pd, pb, pb, 3*sizeof(float)*np,
267 6*sizeof(float)*(np+1)) < 3*sizeof(float)*np) {
268 fprintf(stderr, "%s: rtrace communication error\n",
269 progname);
270 exit(1);
271 }
272 }
273
274
275 getexpos(s) /* get exposure from header line */
276 char *s;
277 {
278 char fmt[32];
279
280 if (isexpos(s))
281 exposure *= exposval(s);
282 else if (isformat(s)) {
283 formatval(fmt, s);
284 wrongformat = strcmp(fmt, COLRFMT);
285 }
286 }
287
288
289 open_pict(fn) /* open picture file */
290 char *fn;
291 {
292 if ((pictfp = fopen(fn, "r")) == NULL) {
293 fprintf("%s: cannot open\n", fn);
294 exit(1);
295 }
296 exposure = 1.0;
297 getheader(pictfp, getexpos, NULL);
298 if (wrongformat || !fscnresolu(&pxsiz, &pysiz, pictfp)) {
299 fprintf(stderr, "%s: incompatible picture format\n", fn);
300 exit(1);
301 }
302 initscans();
303 }
304
305
306 close_pict() /* done with picture */
307 {
308 if (pictfp == NULL)
309 return;
310 fclose(pictfp);
311 donescans();
312 pictfp = NULL;
313 }
314
315
316 fork_rtrace(av) /* open pipe and start rtrace */
317 char *av[];
318 {
319 int rval;
320
321 rval = open_process(rt_pd, av);
322 if (rval < 0) {
323 perror(progname);
324 exit(1);
325 }
326 if (rval == 0) {
327 fprintf(stderr, "%s: command not found\n", av[0]);
328 exit(1);
329 }
330 maxpix = rval/(6*sizeof(float));
331 if (maxpix > MAXPIX)
332 maxpix = MAXPIX;
333 maxpix--;
334 }
335
336
337 done_rtrace() /* wait for rtrace to finish */
338 {
339 int status;
340
341 status = close_process(rt_pd);
342 if (status > 0) {
343 fprintf(stderr, "%s: bad status (%d) from rtrace\n",
344 progname, status);
345 exit(1);
346 }
347 rt_pd[0] = -1;
348 }
349
350
351 SCAN *
352 scanretire() /* retire old scanlines to free list */
353 {
354 SCAN *sold[NRETIRE];
355 int n;
356 int h;
357 register SCAN *sl;
358 register int i;
359 /* grab the NRETIRE oldest scanlines */
360 sold[n = 0] = NULL;
361 for (h = 0; h < HSIZE; h++)
362 for (sl = hashtab[h]; sl != NULL; sl = sl->next) {
363 for (i = n; i && sold[i-1]->lused > sl->lused; i--)
364 if (i < NRETIRE)
365 sold[i] = sold[i-1];
366 if (i < NRETIRE) {
367 sold[i] = sl;
368 if (n < NRETIRE) /* grow list */
369 n++;
370 }
371 }
372 /* put scanlines into free list */
373 for (i = 0; i < n; i++) {
374 h = shash(sold[i]->y);
375 sl = hashtab[h];
376 if (sl == sold[i])
377 hashtab[h] = sl->next;
378 else {
379 while (sl->next != sold[i]) /* IS in list */
380 sl = sl->next;
381 sl->next = sold[i]->next;
382 }
383 if (i > 0) { /* save oldest as return value */
384 sold[i]->next = freelist;
385 freelist = sold[i];
386 }
387 }
388 return(sold[0]);
389 }
390
391
392 static char *scan_buf;
393
394
395 initscans() /* initialize scanline buffers */
396 {
397 int scansize;
398 register SCAN *ptr;
399 register int i;
400 /* initialize positions */
401 scanpos = (long *)malloc(pysiz*sizeof(long));
402 if (scanpos == NULL)
403 memerr("scanline positions");
404 for (i = pysiz-1; i >= 0; i--)
405 scanpos[i] = -1L;
406 curpos = pysiz-1;
407 /* clear hash table */
408 for (i = 0; i < HSIZE; i++)
409 hashtab[i] = NULL;
410 /* allocate scanline buffers */
411 scansize = sizeof(SCAN) + pxsiz*sizeof(COLR);
412 #ifdef ALIGN
413 scansize = scansize+(sizeof(ALIGN)-1) & ~(sizeof(ALIGN)-1);
414 #endif
415 i = MAXSBUF / scansize; /* compute number to allocate */
416 if (i > HSIZE)
417 i = HSIZE;
418 scan_buf = malloc(i*scansize); /* get in one big chunk */
419 if (scan_buf == NULL)
420 memerr("scanline buffers");
421 ptr = (SCAN *)scan_buf;
422 freelist = NULL; /* build our free list */
423 while (i-- > 0) {
424 ptr->y = -1;
425 ptr->lused = -1;
426 ptr->next = freelist;
427 freelist = ptr;
428 ptr = (SCAN *)((char *)ptr + scansize); /* beware of C bugs */
429 }
430 }
431
432
433 donescans() /* free up scanlines */
434 {
435 free(scan_buf);
436 free((char *)scanpos);
437 }