ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
Revision: 1.2
Committed: Mon Mar 18 14:33:53 1991 UTC (33 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +28 -13 lines
Log Message:
bug fixes and enhancements

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