ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glareval.c
(Generate patch)

Comparing ray/src/util/glareval.c (file contents):
Revision 1.9 by greg, Wed Apr 3 15:43:12 1991 UTC vs.
Revision 2.15 by greg, Wed Jan 24 04:39:52 2018 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1991 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Compute pixels for glare calculation
6   */
7  
8 + #include "copyright.h"
9 +
10 + #include <stdlib.h>
11 + #include <string.h>
12 +
13 + #include "platform.h"
14 + #include "rtprocess.h" /* Windows: must come first because of conflicts */
15   #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)
16  
17 < #ifndef BSD
18 < #define vfork           fork
21 < #endif
17 >                                        /* maximum rtrace buffer size */
18 > #define MAXPIX          (4096/(6*sizeof(float)))
19  
20 < #define MAXSBUF         1023980 /* maximum total size of scanline buffer */
20 > #define MAXSBUF         786432  /* maximum total size of scanline buffer */
21   #define HSIZE           317     /* size of scanline hash table */
22   #define NRETIRE         16      /* number of scanlines to retire at once */
23  
24 < int     rt_pid = -1;            /* process id for rtrace */
28 < int     fd_tort, fd_fromrt;     /* pipe descriptors */
24 > static SUBPROC  rt_pd = SP_INACTIVE; /* process id & descriptors for rtrace */
25  
26   FILE    *pictfp = NULL;         /* picture file pointer */
27   double  exposure;               /* picture exposure */
# Line 44 | Line 40 | typedef struct scan {
40   #define scandata(sl)    ((COLR *)((sl)+1))
41   #define shash(y)        ((y)%HSIZE)
42  
43 + static int      maxpix;         /* maximum number of pixels to buffer */
44 +
45   static SCAN     *freelist;              /* scanline free list */
46   static SCAN     *hashtab[HSIZE];        /* scanline hash table */
47  
48 + static long     scanbufsiz;             /* size of allocated scanline buffer */
49 +
50   static long     ncall = 0L;     /* number of calls to getpictscan */
51   static long     nread = 0L;     /* number of scanlines read */
52 + static long     nrecl = 0L;     /* number of scanlines reclaimed */
53  
54 < SCAN    *scanretire();
54 > static int      wrongformat = 0;
55  
56 < extern long     ftell();
56 > static SCAN * claimscan(int     y);
57 > static COLR * getpictscan(int   y);
58 > static double pict_val(FVECT    vd);
59 > static void rt_compute(float    *pb, int        np);
60 > static gethfunc getexpos;
61 > static SCAN * scanretire(void);
62 > static void initscans(void);
63 > static void donescans(void);
64  
65  
66 < SCAN *
67 < claimscan(y)                    /* claim scanline from buffers */
68 < int     y;
66 > static SCAN *
67 > claimscan(                      /* claim scanline from buffers */
68 >        int     y
69 > )
70   {
71          int     hi = shash(y);
72          SCAN    *slast;
# Line 75 | Line 84 | int    y;
84                          if (sl->y == y) {               /* reclaim */
85                                  sl->next = hashtab[hi];
86                                  hashtab[hi] = sl;
87 +                                nrecl++;
88                          }
89                          return(sl);
90                  }
# Line 82 | Line 92 | int    y;
92   }
93  
94  
95 < COLR *
96 < getpictscan(y)                  /* get picture scanline */
97 < int     y;
95 > static COLR *
96 > getpictscan(                    /* get picture scanline */
97 >        int     y
98 > )
99   {
100          register SCAN   *sl;
101          register int    i;
# Line 134 | Line 145 | seekerr:
145  
146  
147   #ifdef DEBUG
148 < pict_stats()                    /* print out picture read statistics */
148 > void
149 > pict_stats(void)                        /* print out picture read statistics */
150   {
151          static long     lastcall = 0L;  /* ncall at last report */
152          static long     lastread = 0L;  /* nread at last report */
153 +        static long     lastrecl = 0L;  /* nrecl at last report */
154  
155          if (ncall == lastcall)
156                  return;
157 <        fprintf(stderr, "%s: %ld scanlines read in %ld calls\n",
158 <                        progname, nread-lastread, ncall-lastcall);
157 >        fprintf(stderr, "%s: %ld scanlines read (%ld reclaimed) in %ld calls\n",
158 >                progname, nread-lastread, nrecl-lastrecl, ncall-lastcall);
159          lastcall = ncall;
160          lastread = nread;
161 +        lastrecl = nrecl;
162   }
163   #endif
164  
165  
166 < double
167 < pict_val(vd)                    /* find picture value for view direction */
168 < FVECT   vd;
166 > static double
167 > pict_val(                       /* find picture value for view direction */
168 >        FVECT   vd
169 > )
170   {
171          FVECT   pp;
172 <        double  vpx, vpy, vpz;
172 >        FVECT   ip;
173          COLOR   res;
174  
175          if (pictfp == NULL)
# Line 162 | Line 177 | FVECT  vd;
177          pp[0] = pictview.vp[0] + vd[0];
178          pp[1] = pictview.vp[1] + vd[1];
179          pp[2] = pictview.vp[2] + vd[2];
180 <        viewpixel(&vpx, &vpy, &vpz, &pictview, pp);
166 <        if (vpz <= FTINY || vpx < 0. || vpx >= 1. || vpy < 0. || vpy >= 1.)
180 >        if (viewloc(ip, &pictview, pp) != 1)
181                  return(-1.0);
182 <        colr_color(res, getpictscan((int)(vpy*pysiz))[(int)(vpx*pxsiz)]);
182 >        colr_color(res, getpictscan((int)(ip[1]*pysiz))[(int)(ip[0]*pxsiz)]);
183          return(luminance(res)/exposure);
184   }
185  
186  
187 < double
188 < getviewpix(vh, vv)              /* compute single view pixel */
189 < int     vh, vv;
187 > extern double
188 > getviewpix(             /* compute single view pixel */
189 >        int     vh,
190 >        int     vv
191 > )
192   {
193          FVECT   dir;
194 <        float   rt_buf[6];
194 >        float   rt_buf[12];
195          double  res;
196  
197          if (compdir(dir, vh, vv) < 0)
# Line 183 | Line 199 | int    vh, vv;
199          npixinvw++;
200          if ((res = pict_val(dir)) >= 0.0)
201                  return(res);
202 <        if (rt_pid == -1) {
202 >        if (rt_pd.r == -1) {
203                  npixmiss++;
204                  return(-1.0);
205          }
# Line 198 | Line 214 | int    vh, vv;
214   }
215  
216  
217 < getviewspan(vv, vb)             /* compute a span of view pixels */
218 < int     vv;
219 < float   *vb;
217 > extern void
218 > getviewspan(            /* compute a span of view pixels */
219 >        int     vv,
220 >        float   *vb
221 > )
222   {
223          float   rt_buf[6*MAXPIX];       /* rtrace send/receive buffer */
224          register int    n;              /* number of pixels in buffer */
# Line 215 | Line 233 | float  *vb;
233   #endif
234          n = 0;
235          for (vh = -hsize; vh <= hsize; vh++) {
236 <                if (compdir(dir, vh, vv) < 0) { /* off viewable region */
236 >                if (compdir(dir, vh, vv) < 0) {         /* not in view */
237                          vb[vh+hsize] = -1.0;
238                          continue;
239                  }
240                  npixinvw++;
241                  if ((vb[vh+hsize] = pict_val(dir)) >= 0.0)
242                          continue;
243 <                if (rt_pid == -1) {             /* missing information */
243 >                if (rt_pd.r == -1) {            /* missing information */
244                          npixmiss++;
245                          continue;
246                  }
247                                                  /* send to rtrace */
248 <                if (n >= MAXPIX) {                      /* flush */
248 >                if (n >= maxpix) {                      /* flush */
249                          rt_compute(rt_buf, n);
250 <                        while (n-- > 0)
250 >                        while (n > 0) {
251 >                                --n;
252                                  vb[buf_vh[n]+hsize] = luminance(rt_buf+3*n);
253 +                        }
254                  }
255                  rt_buf[6*n] = ourview.vp[0];
256                  rt_buf[6*n+1] = ourview.vp[1];
# Line 252 | Line 272 | float  *vb;
272   }
273  
274  
275 < rt_compute(pb, np)              /* process buffer through rtrace */
276 < float   *pb;
277 < int     np;
275 > static void
276 > rt_compute(             /* process buffer through rtrace */
277 >        float   *pb,
278 >        int     np
279 > )
280   {
259        static float    nbuf[6] = {0.,0.,0.,0.,0.,0.};
260
281   #ifdef DEBUG
282          if (verbose && np > 1)
283                  fprintf(stderr, "%s: sending %d samples to rtrace...\n",
284                                  progname, np);
285   #endif
286 <        if (writebuf(fd_tort,(char *)pb,6*sizeof(float)*np) < 6*sizeof(float)*np
287 <                || writebuf(fd_tort,(char *)nbuf,sizeof(nbuf)) < sizeof(nbuf)) {
288 <                fprintf(stderr, "%s: error writing to rtrace process\n",
286 >        memset(pb+6*np, '\0', 6*sizeof(float));
287 >        if (process(&rt_pd, (char *)pb, (char *)pb, 3*sizeof(float)*(np+1),
288 >                        6*sizeof(float)*(np+1)) < 3*sizeof(float)*(np+1)) {
289 >                fprintf(stderr, "%s: rtrace communication error\n",
290                                  progname);
291                  exit(1);
292          }
272        if (readbuf(fd_fromrt, (char *)pb, 3*sizeof(float)*np)
273                        < 3*sizeof(float)*np) {
274                fprintf(stderr, "%s: error reading from rtrace process\n",
275                                progname);
276                exit(1);
277        }
293   }
294  
295  
296 < getexpos(s)                     /* get exposure from header line */
297 < char    *s;
296 > static int
297 > getexpos(                       /* get exposure from header line */
298 >        char    *s,
299 >        void    *p
300 > )
301   {
302 +        char    fmt[32];
303 +
304          if (isexpos(s))
305                  exposure *= exposval(s);
306 +        else if (isformat(s)) {
307 +                formatval(fmt, s);
308 +                wrongformat = strcmp(fmt, COLRFMT);
309 +        }
310 +        return(0);
311   }
312  
313  
314 < open_pict(fn)                   /* open picture file */
315 < char    *fn;
314 > extern void
315 > open_pict(                      /* open picture file */
316 >        char    *fn
317 > )
318   {
292        register int    i;
293
319          if ((pictfp = fopen(fn, "r")) == NULL) {
320 <                fprintf("%s: cannot open\n", fn);
320 >                fprintf(stderr, "%s: cannot open\n", fn);
321                  exit(1);
322          }
323 +        SET_FILE_BINARY(pictfp);
324          exposure = 1.0;
325 <        getheader(pictfp, getexpos);
326 <        if (fgetresolu(&pxsiz, &pysiz, pictfp) != (YMAJOR|YDECR)) {
327 <                fprintf("%s: bad picture resolution\n", fn);
325 >        getheader(pictfp, getexpos, NULL);
326 >        if (wrongformat || !fscnresolu(&pxsiz, &pysiz, pictfp)) {
327 >                fprintf(stderr, "%s: incompatible picture format\n", fn);
328                  exit(1);
329          }
330          initscans();
331   }
332  
333  
334 < close_pict()                    /* done with picture */
334 > extern void
335 > close_pict(void)                        /* done with picture */
336   {
310        register int    i;
311
337          if (pictfp == NULL)
338                  return;
339          fclose(pictfp);
# Line 317 | Line 342 | close_pict()                   /* done with picture */
342   }
343  
344  
345 < fork_rtrace(av)                 /* open pipe and start rtrace */
346 < char    *av[];
345 > extern void
346 > fork_rtrace(                    /* open pipe and start rtrace */
347 >        char    *av[]
348 > )
349   {
350 <        int     p0[2], p1[2];
350 >        int     rval;
351  
352 <        if (pipe(p0) < 0 || pipe(p1) < 0) {
352 >        rval = open_process(&rt_pd, av);
353 >        if (rval < 0) {
354                  perror(progname);
355                  exit(1);
356          }
357 <        if ((rt_pid = vfork()) == 0) {          /* if child */
358 <                close(p0[1]);
331 <                close(p1[0]);
332 <                if (p0[0] != 0) {       /* connect p0 to stdin */
333 <                        dup2(p0[0], 0);
334 <                        close(p0[0]);
335 <                }
336 <                if (p1[1] != 0) {       /* connect p1 to stdout */
337 <                        dup2(p1[1], 1);
338 <                        close(p1[1]);
339 <                }
340 <                execvp(av[0], av);
341 <                perror(av[0]);
342 <                _exit(127);
343 <        }
344 <        if (rt_pid == -1) {
345 <                perror(progname);
357 >        if (rval == 0) {
358 >                fprintf(stderr, "%s: command not found\n", av[0]);
359                  exit(1);
360          }
361 <        close(p0[0]);
362 <        close(p1[1]);
363 <        fd_tort = p0[1];
364 <        fd_fromrt = p1[0];
361 >        maxpix = rval/(6*sizeof(float));
362 >        if (maxpix > MAXPIX)
363 >                maxpix = MAXPIX;
364 >        maxpix--;
365   }
366  
367  
368 < done_rtrace()                   /* wait for rtrace to finish */
368 > extern void
369 > done_rtrace(void)                       /* wait for rtrace to finish */
370   {
371 <        int     pid, status;
371 >        int     status;
372  
373 <        if (rt_pid == -1)
374 <                return;
361 <        close(fd_tort);
362 <        close(fd_fromrt);
363 <        while ((pid = wait(&status)) != -1 && pid != rt_pid)
364 <                ;
365 <        if (pid == rt_pid && status != 0) {
373 >        status = close_process(&rt_pd);
374 >        if (status > 0) {
375                  fprintf(stderr, "%s: bad status (%d) from rtrace\n",
376                                  progname, status);
377                  exit(1);
378          }
379 <        rt_pid = -1;
379 >        rt_pd.r = -1;
380   }
381  
382  
383 < int
384 < readbuf(fd, bpos, siz)
376 < int     fd;
377 < char    *bpos;
378 < int     siz;
383 > static SCAN *
384 > scanretire(void)                        /* retire old scanlines to free list */
385   {
380        register int    cc, nrem = siz;
381
382        while (nrem > 0 && (cc = read(fd, bpos, nrem)) > 0) {
383                bpos += cc;
384                nrem -= cc;
385        }
386        if (cc < 0)
387                return(cc);
388        return(siz-nrem);
389 }
390
391
392 int
393 writebuf(fd, bpos, siz)
394 char    *bpos;
395 int     siz;
396 {
397        register int    cc, nrem = siz;
398
399        while (nrem > 0 && (cc = write(fd, bpos, nrem)) > 0) {
400                bpos += cc;
401                nrem -= cc;
402        }
403        if (cc < 0)
404                return(cc);
405        return(siz-nrem);
406 }
407
408
409 SCAN *
410 scanretire()                    /* retire old scanlines to free list */
411 {
386          SCAN    *sold[NRETIRE];
413        SCAN    head;
387          int     n;
388          int     h;
389          register SCAN   *sl;
390          register int    i;
391                                          /* grab the NRETIRE oldest scanlines */
392          sold[n = 0] = NULL;
393 <        for (h = 0; h < HSIZE; h++) {
394 <                head.next = hashtab[h];
395 <                sl = &head;
396 <                while (sl->next != NULL) {
424 <                        for (i = n; i && sold[i-1]->lused > sl->next->lused; i--)
425 <                                if (i == NRETIRE) {     /* reallocate */
426 <                                        register int    oh;
427 <                                        oh = shash(sold[NRETIRE-1]->y);
428 <                                        sold[NRETIRE-1]->next = hashtab[oh];
429 <                                        if (h == oh) {
430 <                                                head.next = sold[NRETIRE-1];
431 <                                                if (sl == &head)
432 <                                                        sl = head.next;
433 <                                        } else
434 <                                                hashtab[oh] = sold[NRETIRE-1];
435 <                                } else                  /* else bubble up */
393 >        for (h = 0; h < HSIZE; h++)
394 >                for (sl = hashtab[h]; sl != NULL; sl = sl->next) {
395 >                        for (i = n; i && sold[i-1]->lused > sl->lused; i--)
396 >                                if (i < NRETIRE)
397                                          sold[i] = sold[i-1];
398                          if (i < NRETIRE) {
399 <                                sold[i] = sl->next;
439 <                                sl->next = sl->next->next;
399 >                                sold[i] = sl;
400                                  if (n < NRETIRE)        /* grow list */
401                                          n++;
402 <                        } else
402 >                        }
403 >                }
404 >                                        /* put scanlines into free list */
405 >        for (i = 0; i < n; i++) {
406 >                h = shash(sold[i]->y);
407 >                sl = hashtab[h];
408 >                if (sl == sold[i])
409 >                        hashtab[h] = sl->next;
410 >                else {
411 >                        while (sl->next != sold[i])     /* IS in list */
412                                  sl = sl->next;
413 +                        sl->next = sold[i]->next;
414                  }
415 <                hashtab[h] = head.next;
415 >                if (i > 0) {            /* save oldest as return value */
416 >                        sold[i]->next = freelist;
417 >                        freelist = sold[i];
418 >                }
419          }
447                                        /* put scanlines into free list */
448        for (i = 1; i < n; i++) {
449                sold[i]->next = freelist;
450                freelist = sold[i];
451        }
420          return(sold[0]);
421   }
422  
# Line 456 | Line 424 | scanretire()                   /* retire old scanlines to free list */
424   static char     *scan_buf;
425  
426  
427 < initscans()                             /* initialize scanline buffers */
427 > static void
428 > initscans(void)                         /* initialize scanline buffers */
429   {
430          int     scansize;
431          register SCAN   *ptr;
432          register int    i;
433                                          /* initialize positions */
434 <        scanpos = (long *)malloc(pysiz*sizeof(long));
434 >        scanpos = (long *)bmalloc(pysiz*sizeof(long));
435          if (scanpos == NULL)
436                  memerr("scanline positions");
437          for (i = pysiz-1; i >= 0; i--)
# Line 473 | Line 442 | initscans()                            /* initialize scanline buffers */
442                  hashtab[i] = NULL;
443                                          /* allocate scanline buffers */
444          scansize = sizeof(SCAN) + pxsiz*sizeof(COLR);
445 < #ifdef ALIGN
446 <        scansize = scansize+(sizeof(ALIGN)-1)) & ~(sizeof(ALIGN)-1);
445 > #ifdef ALIGNT
446 >        scansize = scansize+(sizeof(ALIGNT)-1) & ~(sizeof(ALIGNT)-1);
447   #endif
448          i = MAXSBUF / scansize;         /* compute number to allocate */
449          if (i > HSIZE)
450                  i = HSIZE;
451 <        scan_buf = malloc(i*scansize);  /* get in one big chunk */
451 >        scanbufsiz = i*scansize;
452 >        scan_buf = bmalloc(scanbufsiz); /* get in one big chunk */
453          if (scan_buf == NULL)
454                  memerr("scanline buffers");
455          ptr = (SCAN *)scan_buf;
# Line 494 | Line 464 | initscans()                            /* initialize scanline buffers */
464   }
465  
466  
467 < donescans()                             /* free up scanlines */
467 > static void
468 > donescans(void)                         /* free up scanlines */
469   {
470 <        free(scan_buf);
471 <        free((char *)scanpos);
470 >        bfree(scan_buf, scanbufsiz);
471 >        bfree((char *)scanpos, pysiz*sizeof(long));
472   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines