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

# 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 64 /* 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 extern long ftell();
43
44
45 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 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 scanpos[curpos] = ftell(pictfp);
73 if (freadcolrs(scan[minused].sl, pxsiz, pictfp) < 0)
74 goto readerr;
75 nread++;
76 curpos--;
77 }
78 } 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 }
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 seekerr:
93 fprintf(stderr, "%s: picture seek error\n", progname);
94 exit(1);
95 }
96
97
98 #ifdef DEBUG
99 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 fprintf(stderr, "%s: %ld scanlines read in %ld calls\n",
107 progname, nread-lastread, ncall-lastcall);
108 lastcall = ncall;
109 lastread = nread;
110 }
111 #endif
112
113
114 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 npixinvw++;
146 if ((res = pict_val(dir)) >= 0.0)
147 return(res);
148 if (rt_pid == -1) {
149 npixmiss++;
150 return(-1.0);
151 }
152 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 register int n; /* number of pixels in buffer */
169 short buf_vh[MAXPIX]; /* pixel positions */
170 FVECT dir;
171 register int vh;
172
173 #ifdef DEBUG
174 if (verbose)
175 fprintf(stderr, "%s: computing view span at %d...\n",
176 progname, vv);
177 #endif
178 n = 0;
179 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 npixinvw++;
185 if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
186 continue;
187 if (rt_pid == -1) { /* missing information */
188 npixmiss++;
189 continue;
190 }
191 /* send to rtrace */
192 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 }
197 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 }
205 #ifdef DEBUG
206 if (verbose)
207 pict_stats();
208 #endif
209 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 }
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 #ifdef DEBUG
224 if (verbose && np > 1)
225 fprintf(stderr, "%s: sending %d samples to rtrace...\n",
226 progname, np);
227 #endif
228 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 for (i = pysiz-1; i >= 0; i--)
270 scanpos[i] = -1L;
271 curpos = pysiz-1;
272 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 close(p0[0]);
325 close(p1[1]);
326 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 }