ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 1.5
Committed: Thu Mar 21 12:28:23 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +24 -12 lines
Log Message:
fixed bug in getpictscan()

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