ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 1.17
Committed: Wed May 1 08:50:49 1991 UTC (32 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.16: +1 -1 lines
Log Message:
fixed syntax error

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