ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 1.1
Committed: Mon Mar 18 12:15:41 1991 UTC (33 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 greg 1.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 NSCANS 16 /* number of scanlines to buffer */
24    
25     int rt_pid = -1; /* process id for rtrace */
26     int fd_tort, fd_fromrt; /* pipe descriptors */
27    
28     FILE *pictfp = NULL; /* picture file pointer */
29     double exposure; /* picture exposure */
30     int pxsiz, pysiz; /* picture dimensions */
31     int curpos; /* current scanline */
32     long *scanpos; /* scanline positions */
33     struct {
34     long lused; /* for LRU replacement */
35     int y; /* scanline position */
36     COLR *sl; /* scanline contents */
37     } scan[NSCANS]; /* buffered scanlines */
38    
39    
40     COLR *
41     getpictscan(y) /* get picture scanline */
42     int y;
43     {
44     extern long ftell();
45     static long ncall = 0;
46     int minused;
47     register int i;
48     /* first check our buffers */
49     ncall++;
50     minused = 0;
51     for (i = 0; i < NSCANS; i++) {
52     if (scan[i].y == y) {
53     scan[i].lused = ncall;
54     return(scan[i].sl);
55     }
56     if (scan[i].lused < scan[minused].lused)
57     minused = i;
58     }
59     /* not there, read it in */
60     if (scanpos[y] == -1) { /* need to search */
61     if (verbose)
62     fprintf(stderr, "%s: reading picture...\n",
63     progname);
64     while (curpos > y) {
65     scanpos[curpos] = ftell(pictfp);
66     if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
67     goto readerr;
68     curpos--;
69     }
70     } else if (fseek(pictfp, scanpos[y], 0) < 0) {
71     fprintf(stderr, "%s: picture seek error\n", progname);
72     exit(1);
73     }
74     if (verbose)
75     fprintf(stderr, "%s: reading scanline %d...\n", progname, y);
76     if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
77     goto readerr;
78     curpos = y-1;
79     scan[minused].lused = ncall;
80     scan[minused].y = y;
81     return(scan[minused].sl);
82     readerr:
83     fprintf(stderr, "%s: picture read error\n", progname);
84     exit(1);
85     }
86    
87    
88     double
89     pict_val(vd) /* find picture value for view direction */
90     FVECT vd;
91     {
92     FVECT pp;
93     double vpx, vpy, vpz;
94     COLOR res;
95    
96     if (pictfp == NULL)
97     return(-1.0);
98     pp[0] = pictview.vp[0] + vd[0];
99     pp[1] = pictview.vp[1] + vd[1];
100     pp[2] = pictview.vp[2] + vd[2];
101     viewpixel(&vpx, &vpy, &vpz, &pictview, pp);
102     if (vpz <= FTINY || vpx < 0. || vpx >= 1. || vpy < 0. || vpy >= 1.)
103     return(-1.0);
104     colr_color(res, getpictscan((int)(vpy*pysiz))[(int)(vpx*pxsiz)]);
105     return(luminance(res)/exposure);
106     }
107    
108    
109     double
110     getviewpix(vh, vv) /* compute single view pixel */
111     int vh, vv;
112     {
113     FVECT dir;
114     float rt_buf[6];
115     double res;
116    
117     if (compdir(dir, vh, vv) < 0)
118     return(-1.0);
119     if ((res = pict_val(dir)) >= 0.0)
120     return(res);
121     if (rt_pid == -1)
122     return(-1.0);
123     rt_buf[0] = ourview.vp[0];
124     rt_buf[1] = ourview.vp[1];
125     rt_buf[2] = ourview.vp[2];
126     rt_buf[3] = dir[0];
127     rt_buf[4] = dir[1];
128     rt_buf[5] = dir[2];
129     rt_compute(rt_buf, 1);
130     return(luminance(rt_buf));
131     }
132    
133    
134     getviewspan(vv, vb) /* compute a span of view pixels */
135     int vv;
136     float *vb;
137     {
138     float rt_buf[6*MAXPIX]; /* rtrace send/receive buffer */
139     int npix_tort; /* number of pixels in buffer */
140     short buf_vh[MAXPIX]; /* pixel positions */
141     FVECT dir;
142     register int vh;
143     register int i;
144    
145     if (verbose)
146     fprintf(stderr, "%s: computing view span at %d...\n",
147     progname, vv);
148     npix_tort = 0;
149     for (vh = -hsize; vh <= hsize; vh++) {
150     if (compdir(dir, vh, vv) < 0) { /* off viewable region */
151     vb[vh+hsize] = -1.0;
152     continue;
153     }
154     if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
155     continue;
156     if (rt_pid == -1) /* missing information */
157     continue;
158     /* send to rtrace */
159     if (npix_tort >= MAXPIX) { /* flush */
160     rt_compute(rt_buf, npix_tort);
161     for (i = 0; i < npix_tort; i++)
162     vb[buf_vh[i]+hsize] = luminance(rt_buf+3*i);
163     npix_tort = 0;
164     }
165     rt_buf[npix_tort] = ourview.vp[0];
166     rt_buf[npix_tort+1] = ourview.vp[1];
167     rt_buf[npix_tort+2] = ourview.vp[2];
168     rt_buf[npix_tort+3] = dir[0];
169     rt_buf[npix_tort+4] = dir[1];
170     rt_buf[npix_tort+5] = dir[2];
171     buf_vh[npix_tort++] = vh;
172     }
173     if (npix_tort > 0) { /* process pending buffer */
174     rt_compute(rt_buf, npix_tort);
175     for (i = 0; i < npix_tort; i++)
176     vb[buf_vh[i]+hsize] = luminance(rt_buf+3*i);
177     }
178     }
179    
180    
181     rt_compute(pb, np) /* process buffer through rtrace */
182     float *pb;
183     int np;
184     {
185     static float nbuf[6] = {0.,0.,0.,0.,0.,0.};
186    
187     if (verbose && np > 1)
188     fprintf(stderr, "%s: sending %d samples to rtrace...\n",
189     progname, np);
190     if (writebuf(fd_tort,(char *)pb,6*sizeof(float)*np) < 6*sizeof(float)*np
191     || writebuf(fd_tort,(char *)nbuf,sizeof(nbuf)) < sizeof(nbuf)) {
192     fprintf(stderr, "%s: error writing to rtrace process\n",
193     progname);
194     exit(1);
195     }
196     if (readbuf(fd_fromrt, (char *)pb, 3*sizeof(float)*np)
197     < 3*sizeof(float)*np) {
198     fprintf(stderr, "%s: error reading from rtrace process\n",
199     progname);
200     exit(1);
201     }
202     }
203    
204    
205     getexpos(s) /* get exposure from header line */
206     char *s;
207     {
208     if (isexpos(s))
209     exposure *= exposval(s);
210     }
211    
212    
213     open_pict(fn) /* open picture file */
214     char *fn;
215     {
216     register int i;
217    
218     if ((pictfp = fopen(fn, "r")) == NULL) {
219     fprintf("%s: cannot open\n", fn);
220     exit(1);
221     }
222     exposure = 1.0;
223     getheader(pictfp, getexpos);
224     if (fgetresolu(&pxsiz, &pysiz, pictfp) != (YMAJOR|YDECR)) {
225     fprintf("%s: bad picture resolution\n", fn);
226     exit(1);
227     }
228     scanpos = (long *)malloc(pysiz*sizeof(long));
229     if (scanpos == NULL)
230     memerr("scanline positions");
231     for (i = 0; i < pysiz; i++)
232     scanpos[i] = -1L;
233     for (i = 0; i < NSCANS; i++) {
234     scan[i].lused = -1;
235     scan[i].y = -1;
236     scan[i].sl = (COLR *)malloc(pxsiz*sizeof(COLR));
237     if (scan[i].sl == NULL)
238     memerr("scanline buffers");
239     }
240     curpos = pysiz-1;
241     }
242    
243    
244     close_pict() /* done with picture */
245     {
246     register int i;
247    
248     if (pictfp == NULL)
249     return;
250     fclose(pictfp);
251     free((char *)scanpos);
252     for (i = 0; i < NSCANS; i++)
253     free((char *)scan[i].sl);
254     pictfp = NULL;
255     }
256    
257    
258     fork_rtrace(av) /* open pipe and start rtrace */
259     char *av[];
260     {
261     int p0[2], p1[2];
262    
263     if (pipe(p0) < 0 || pipe(p1) < 0) {
264     perror(progname);
265     exit(1);
266     }
267     if ((rt_pid = vfork()) == 0) { /* if child */
268     close(p0[1]);
269     close(p1[0]);
270     if (p0[0] != 0) { /* connect p0 to stdin */
271     dup2(p0[0], 0);
272     close(p0[0]);
273     }
274     if (p1[1] != 0) { /* connect p1 to stdout */
275     dup2(p1[1], 1);
276     close(p1[1]);
277     }
278     execvp(av[0], av);
279     perror(av[0]);
280     _exit(127);
281     }
282     if (rt_pid == -1) {
283     perror(progname);
284     exit(1);
285     }
286     fd_tort = p0[1];
287     fd_fromrt = p1[0];
288     }
289    
290    
291     done_rtrace() /* wait for rtrace to finish */
292     {
293     int pid, status;
294    
295     if (rt_pid == -1)
296     return;
297     close(fd_tort);
298     close(fd_fromrt);
299     while ((pid = wait(&status)) != -1 && pid != rt_pid)
300     ;
301     if (pid == rt_pid && status != 0) {
302     fprintf(stderr, "%s: bad status (%d) from rtrace\n",
303     progname, status);
304     exit(1);
305     }
306     rt_pid = -1;
307     }
308    
309    
310     int
311     readbuf(fd, bpos, siz)
312     int fd;
313     char *bpos;
314     int siz;
315     {
316     register int cc, nrem = siz;
317    
318     while (nrem > 0 && (cc = read(fd, bpos, nrem)) > 0) {
319     bpos += cc;
320     nrem -= cc;
321     }
322     if (cc < 0)
323     return(cc);
324     return(siz-nrem);
325     }
326    
327    
328     int
329     writebuf(fd, bpos, siz)
330     char *bpos;
331     int siz;
332     {
333     register int cc, nrem = siz;
334    
335     while (nrem > 0 && (cc = write(fd, bpos, nrem)) > 0) {
336     bpos += cc;
337     nrem -= cc;
338     }
339     if (cc < 0)
340     return(cc);
341     return(siz-nrem);
342     }