ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 1.19
Committed: Mon Jul 22 09:40:20 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.18: +26 -94 lines
Log Message:
moved rtrace i/o routines to library

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