ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 1.7
Committed: Tue Apr 2 14:29:17 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.6: +8 -2 lines
Log Message:
added test for insufficient data

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