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

# 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 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 }