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

Comparing ray/src/rt/rpict.c (file contents):
Revision 1.5 by greg, Tue Jun 13 10:57:40 1989 UTC vs.
Revision 2.8 by greg, Fri Jul 10 14:58:19 1992 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1986 Regents of the University of California */
1 > /* Copyright (c) 1992 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 17 | Line 17 | static char SCCSid[] = "$SunId$ LBL";
17   #include  <sys/resource.h>
18   #endif
19  
20 + #include  <signal.h>
21 + #include  <fcntl.h>
22 +
23   #include  "view.h"
24  
25 + #include  "resolu.h"
26 +
27   #include  "random.h"
28  
29 < VIEW  ourview = STDVIEW(512);           /* view parameters */
29 > int  dimlist[MAXDIM];                   /* sampling dimensions */
30 > int  ndims = 0;                         /* number of sampling dimensions */
31 > int  samplendx;                         /* sample index number */
32  
33 + VIEW  ourview = STDVIEW;                /* view parameters */
34 + int  hresolu = 512;                     /* horizontal resolution */
35 + int  vresolu = 512;                     /* vertical resolution */
36 + double  pixaspect = 1.0;                /* pixel aspect ratio */
37 +
38   int  psample = 4;                       /* pixel sample size */
39   double  maxdiff = .05;                  /* max. difference for interpolation */
40   double  dstrpix = 0.67;                 /* square pixel distribution */
# Line 30 | Line 42 | double  dstrpix = 0.67;                        /* square pixel distribution
42   double  dstrsrc = 0.0;                  /* square source distribution */
43   double  shadthresh = .05;               /* shadow threshold */
44   double  shadcert = .5;                  /* shadow certainty */
45 + int  directrelay = 1;                   /* number of source relays */
46 + int  vspretest = 512;                   /* virtual source pretest density */
47 + int  directinvis = 0;                   /* sources invisible? */
48 + double  srcsizerat = .25;               /* maximum ratio source size/dist. */
49  
50 + double  specthresh = .15;               /* specular sampling threshold */
51 + double  specjitter = 1.;                /* specular sampling jitter */
52 +
53   int  maxdepth = 6;                      /* maximum recursion depth */
54   double  minweight = 5e-3;               /* minimum ray weight */
55  
56   COLOR  ambval = BLKCOLOR;               /* ambient value */
57   double  ambacc = 0.2;                   /* ambient accuracy */
58 < int  ambres = 128;                      /* ambient resolution */
58 > int  ambres = 32;                       /* ambient resolution */
59   int  ambdiv = 128;                      /* ambient divisions */
60   int  ambssamp = 0;                      /* ambient super-samples */
61   int  ambounce = 0;                      /* ambient bounces */
# Line 47 | Line 66 | int  ralrm = 0;                                /* seconds between reports */
66  
67   double  pctdone = 0.0;                  /* percentage done */
68  
69 + long  tlastrept = 0L;                   /* time at last report */
70 +
71 + extern long  time();
72 + extern long  tstart;                    /* starting time */
73 +
74   extern long  nrays;                     /* number of rays traced */
75  
76 < #define  MAXDIV         32              /* maximum sample size */
76 > #define  MAXDIV         16              /* maximum sample size */
77  
78   #define  pixjitter()    (.5+dstrpix*(.5-frandom()))
79  
80 + #define  HFTEMPLATE     "/tmp/hfXXXXXX"
81  
82 + static char  *hfname = NULL;            /* header file name */
83 + static FILE  *hfp = NULL;               /* header file pointer */
84 +
85 + static int  hres, vres;                 /* resolution for this frame */
86 +
87 + extern char  *mktemp();
88 +
89 + double  pixvalue();
90 +
91 +
92   quit(code)                      /* quit program */
93   int  code;
94   {
95 <        if (code || ralrm > 0)          /* report status */
95 >        if (code)                       /* report status */
96                  report();
97 <
97 >        if (hfname != NULL) {           /* delete header file */
98 >                if (hfp != NULL)
99 >                        fclose(hfp);
100 >                unlink(hfname);
101 >        }
102          exit(code);
103   }
104  
105  
106 + #ifdef BSD
107   report()                /* report progress */
108   {
69 #ifdef BSD
109          struct rusage  rubuf;
110          double  t;
111  
# Line 79 | Line 118 | report()               /* report progress */
118  
119          sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f CPU hours\n",
120                          nrays, pctdone, t/3600.0);
121 +        eputs(errmsg);
122 +        tlastrept = time((long *)0);
123 + }
124   #else
125 <        sprintf(errmsg, "%ld rays, %4.2f%% done\n", nrays, pctdone);
126 < #endif
125 > report()                /* report progress */
126 > {
127 >        tlastrept = time((long *)0);
128 >        sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f hours\n",
129 >                        nrays, pctdone, (tlastrept-tstart)/3600.0);
130          eputs(errmsg);
131 +        signal(SIGALRM, report);
132 + }
133 + #endif
134  
135 <        if (ralrm > 0)
136 <                alarm(ralrm);
135 >
136 > openheader()                    /* save standard output to header file */
137 > {
138 >        hfname = mktemp(HFTEMPLATE);
139 >        if (freopen(hfname, "w", stdout) == NULL) {
140 >                sprintf(errmsg, "cannot open header file \"%s\"", hfname);
141 >                error(SYSTEM, errmsg);
142 >        }
143   }
144  
145  
146 < render(oldfile)                         /* render the scene */
93 < char  *oldfile;
146 > closeheader()                   /* done with header output */
147   {
148 <        COLOR  *scanbar[MAXDIV+1];      /* scanline arrays of pixel values */
149 <        int  ypos;                      /* current scanline */
150 <        COLOR  *colptr;
151 <        register int  i;
148 >        if (hfname == NULL)
149 >                return;
150 >        if (fflush(stdout) == EOF || (hfp = fopen(hfname, "r")) == NULL)
151 >                error(SYSTEM, "error reopening header file");
152 > }
153  
154 +
155 + dupheader()                     /* repeat header on standard output */
156 + {
157 +        register int  c;
158 +
159 +        if (fseek(hfp, 0L, 0) < 0)
160 +                error(SYSTEM, "seek error on header file");
161 +        while ((c = getc(hfp)) != EOF)
162 +                putchar(c);
163 + }
164 +
165 +
166 + rpict(seq, pout, zout, prvr)                    /* generate image(s) */
167 + int  seq;
168 + char  *pout, *zout, *prvr;
169 + /*
170 + * If seq is greater than zero, then we will render a sequence of
171 + * images based on view parameter strings read from the standard input.
172 + * If pout is NULL, then all images will be sent to the standard ouput.
173 + * If seq is greater than zero and prvr is an integer, then it is the
174 + * frame number at which rendering should begin.  Preceeding view parameter
175 + * strings will be skipped in the input.
176 + * If pout and prvr are the same, prvr is renamed to avoid overwriting.
177 + * Note that pout and zout should contain %d format specifications for
178 + * sequenced file naming.
179 + */
180 + {
181 +        extern char  *rindex(), *strncpy(), *strcat();
182 +        char  fbuf[128], fbuf2[128], *zf;
183 +        RESOLU  rs;
184 +        double  pa;
185 +                                        /* finished writing header */
186 +        closeheader();
187 +                                        /* check sampling */
188          if (psample < 1)
189                  psample = 1;
190 <        else if (psample > MAXDIV)
190 >        else if (psample > MAXDIV) {
191 >                sprintf(errmsg, "pixel sampling reduced from %d to %d",
192 >                                psample, MAXDIV);
193 >                error(WARNING, errmsg);
194                  psample = MAXDIV;
195 +        }
196 +                                        /* get starting frame */
197 +        if (seq <= 0)
198 +                seq = 0;
199 +        else if (prvr != NULL && isint(prvr)) {
200 +                int  rn;                        /* skip to specified view */
201 +                if ((rn = atoi(prvr)) < seq)
202 +                        error(USER, "recover frame less than start frame");
203 +                if (pout == NULL)
204 +                        error(USER, "missing output file specification");
205 +                for ( ; seq < rn; seq++)
206 +                        if (nextview(stdin) == EOF)
207 +                                error(USER, "unexpected EOF on view input");
208 +                prvr = fbuf;                    /* mark for renaming */
209 +        }
210 +        if (pout != NULL) {
211 +                sprintf(fbuf, pout, seq);
212 +                if (!strcmp(prvr, fbuf)) {      /* rename recover file */
213 +                        fbuf2[0] = '\0';
214 +                        if ((prvr = rindex(fbuf, '/')) != NULL)
215 +                                strncpy(fbuf2, fbuf, prvr-fbuf+1);
216 +                        strcat(fbuf2, "rfXXXXXX");
217 +                        prvr = mktemp(fbuf2);
218 +                        if (rename(fbuf, prvr) < 0 && errno != ENOENT) {
219 +                                sprintf(errmsg,
220 +                                        "cannot rename \"%s\" to \"%s\"",
221 +                                                fbuf, prvr);
222 +                                error(SYSTEM, errmsg);
223 +                        }
224 +                }
225 +        }
226 +                                        /* render sequence */
227 +        do {
228 +                if (seq && nextview(stdin) == EOF)
229 +                        break;
230 +                if (pout != NULL) {
231 +                        sprintf(fbuf, pout, seq);
232 +                        if (freopen(fbuf, "w", stdout) == NULL) {
233 +                                sprintf(errmsg,
234 +                                        "cannot open output file \"%s\"", fbuf);
235 +                                error(SYSTEM, errmsg);
236 +                        }
237 +                        dupheader();
238 +                }
239 +                hres = hresolu; vres = vresolu; pa = pixaspect;
240 +                if (prvr != NULL)
241 +                        if (viewfile(prvr, &ourview, &rs) <= 0
242 +                                        || rs.or != PIXSTANDARD) {
243 +                                sprintf(errmsg,
244 +                        "cannot recover view parameters from \"%s\"", prvr);
245 +                                error(WARNING, errmsg);
246 +                        } else {
247 +                                char  *err;
248 +                                if ((err = setview(&ourview)) != NULL)
249 +                                        error(USER, err);
250 +                                pa = 0.0;
251 +                                hres = scanlen(&rs);
252 +                                vres = numscans(&rs);
253 +                        }
254 +                normaspect(viewaspect(&ourview), &pa, &hres, &vres);
255 +                if (seq) {
256 +                        if (ralrm > 0) {
257 +                                sprintf(errmsg, "starting frame %d\n", seq);
258 +                                eputs(errmsg);
259 +                        }
260 +                        printf("FRAME=%d\n", seq);
261 +                }
262 +                fputs(VIEWSTR, stdout);
263 +                fprintview(&ourview, stdout);
264 +                putchar('\n');
265 +                if (pa < .99 || pa > 1.01)
266 +                        fputaspect(pa, stdout);
267 +                fputformat(COLRFMT, stdout);
268 +                putchar('\n');
269 +                if (zout != NULL)
270 +                        sprintf(zf=fbuf, zout, seq);
271 +                else
272 +                        zf = NULL;
273 +                render(zf, prvr);
274 +                prvr = NULL;
275 +        } while (seq++);
276 + }
277  
278 <        ourview.hresolu -= ourview.hresolu % psample;
279 <        ourview.vresolu -= ourview.vresolu % psample;
280 <                
278 >
279 > nextview(fp)                            /* get next view from fp */
280 > FILE  *fp;
281 > {
282 >        char  linebuf[256], *err;
283 >
284 >        while (fgets(linebuf, sizeof(linebuf), fp) != NULL)
285 >                if (isview(linebuf) && sscanview(&ourview, linebuf) > 0) {
286 >                        if ((err = setview(&ourview)) != NULL)
287 >                                error(USER, err);
288 >                        return(0);
289 >                }
290 >        return(EOF);
291 > }      
292 >
293 >
294 > render(zfile, oldfile)                          /* render the scene */
295 > char  *zfile, *oldfile;
296 > {
297 >        extern long  lseek();
298 >        COLOR  *scanbar[MAXDIV+1];      /* scanline arrays of pixel values */
299 >        float  *zbar[MAXDIV+1];         /* z values */
300 >        char  *sampdens;                /* previous sample density */
301 >        int  ypos;                      /* current scanline */
302 >        int  ystep;                     /* current y step size */
303 >        int  hstep;                     /* h step size */
304 >        int  zfd;
305 >        COLOR  *colptr;
306 >        float  *zptr;
307 >        register int  i;
308 >                                        /* allocate scanlines */
309          for (i = 0; i <= psample; i++) {
310 <                scanbar[i] = (COLOR *)malloc((ourview.hresolu+1)*sizeof(COLOR));
310 >                scanbar[i] = (COLOR *)malloc(hres*sizeof(COLOR));
311                  if (scanbar[i] == NULL)
312 <                        error(SYSTEM, "out of memory in render");
312 >                        goto memerr;
313          }
314 <        
314 >        hstep = (psample*140+49)/99;            /* quincunx sampling */
315 >        ystep = (psample*99+70)/140;
316 >        if (hstep > 2) {
317 >                i = hres/hstep + 2;
318 >                if ((sampdens = malloc(i)) == NULL)
319 >                        goto memerr;
320 >                while (i--)
321 >                        sampdens[i] = hstep;
322 >        } else
323 >                sampdens = NULL;
324 >                                        /* open z file */
325 >        if (zfile != NULL) {
326 >                if ((zfd = open(zfile, O_WRONLY|O_CREAT, 0666)) == -1) {
327 >                        sprintf(errmsg, "cannot open z file \"%s\"", zfile);
328 >                        error(SYSTEM, errmsg);
329 >                }
330 >                for (i = 0; i <= psample; i++) {
331 >                        zbar[i] = (float *)malloc(hres*sizeof(float));
332 >                        if (zbar[i] == NULL)
333 >                                goto memerr;
334 >                }
335 >        } else {
336 >                zfd = -1;
337 >                for (i = 0; i <= psample; i++)
338 >                        zbar[i] = NULL;
339 >        }
340                                          /* write out boundaries */
341 <        printf("-Y %d +X %d\n", ourview.vresolu, ourview.hresolu);
342 <
343 <        ypos = ourview.vresolu - salvage(oldfile);      /* find top line */
344 <        fillscanline(scanbar[0], ypos, psample);        /* top scan */
345 <
346 <        for (ypos -= psample; ypos > -psample; ypos -= psample) {
347 <        
348 <                colptr = scanbar[psample];              /* get last scanline */
349 <                scanbar[psample] = scanbar[0];
341 >        fprtresolu(hres, vres, stdout);
342 >                                        /* recover file and compute first */
343 >        i = salvage(oldfile);
344 >        if (zfd != -1 && i > 0 &&
345 >                        lseek(zfd, (long)i*hres*sizeof(float), 0) == -1)
346 >                error(SYSTEM, "z file seek error in render");
347 >        pctdone = 100.0*i/vres;
348 >        if (ralrm > 0)                  /* report init stats */
349 >                report();
350 > #ifndef  BSD
351 >        else
352 > #endif
353 >        signal(SIGALRM, report);
354 >        ypos = vres-1 - i;
355 >        fillscanline(scanbar[0], zbar[0], sampdens, hres, ypos, hstep);
356 >                                                /* compute scanlines */
357 >        for (ypos -= ystep; ypos > -ystep; ypos -= ystep) {
358 >                                                        /* bottom adjust? */
359 >                if (ypos < 0) {
360 >                        ystep += ypos;
361 >                        ypos = 0;
362 >                }
363 >                colptr = scanbar[ystep];                /* move base to top */
364 >                scanbar[ystep] = scanbar[0];
365                  scanbar[0] = colptr;
366 <
367 <                fillscanline(scanbar[0], ypos, psample);        /* base scan */
368 <        
369 <                fillscanbar(scanbar, ypos, psample);
370 <                
371 <                for (i = psample-1; i >= 0; i--)
372 <                        if (fwritescan(scanbar[i], ourview.hresolu, stdout) < 0)
366 >                zptr = zbar[ystep];
367 >                zbar[ystep] = zbar[0];
368 >                zbar[0] = zptr;
369 >                                                        /* fill base line */
370 >                fillscanline(scanbar[0], zbar[0], sampdens,
371 >                                hres, ypos, hstep);
372 >                                                        /* fill bar */
373 >                fillscanbar(scanbar, zbar, hres, ypos, ystep);
374 >                                                        /* write it out */
375 > #ifndef  BSD
376 >                signal(SIGALRM, SIG_IGN);       /* don't interrupt writes */
377 > #endif
378 >                for (i = ystep; i > 0; i--) {
379 >                        if (zfd != -1 && write(zfd, (char *)zbar[i],
380 >                                        hres*sizeof(float))
381 >                                        < hres*sizeof(float))
382                                  goto writerr;
383 +                        if (fwritescan(scanbar[i], hres, stdout) < 0)
384 +                                goto writerr;
385 +                }
386                  if (fflush(stdout) == EOF)
387                          goto writerr;
388 <                pctdone = 100.0*(ourview.vresolu-ypos)/ourview.vresolu;
388 >                                                        /* record progress */
389 >                pctdone = 100.0*(vres-1-ypos)/vres;
390 >                if (ralrm > 0 && time((long *)0) >= tlastrept+ralrm)
391 >                        report();
392 > #ifndef  BSD
393 >                else
394 >                        signal(SIGALRM, report);
395 > #endif
396          }
397 <                
397 >                                                /* clean up */
398 >        signal(SIGALRM, SIG_IGN);
399 >        if (zfd != -1) {
400 >                if (write(zfd, (char *)zbar[0], hres*sizeof(float))
401 >                                < hres*sizeof(float))
402 >                        goto writerr;
403 >                if (close(zfd) == -1)
404 >                        goto writerr;
405 >                for (i = 0; i <= psample; i++)
406 >                        free((char *)zbar[i]);
407 >        }
408 >        fwritescan(scanbar[0], hres, stdout);
409 >        if (fflush(stdout) == EOF)
410 >                goto writerr;
411          for (i = 0; i <= psample; i++)
412                  free((char *)scanbar[i]);
413 +        if (sampdens != NULL)
414 +                free(sampdens);
415 +        pctdone = 100.0;
416          return;
417   writerr:
418          error(SYSTEM, "write error in render");
419 + memerr:
420 +        error(SYSTEM, "out of memory in render");
421   }
422  
423  
424 < fillscanline(scanline, y, xstep)                /* fill scan line at y */
424 > fillscanline(scanline, zline, sd, xres, y, xstep)       /* fill scan at y */
425   register COLOR  *scanline;
426 < int  y, xstep;
426 > register float  *zline;
427 > register char  *sd;
428 > int  xres, y, xstep;
429   {
430 <        int  b = xstep;
430 >        static int  nc = 0;             /* number of calls */
431 >        int  bl = xstep, b = xstep;
432 >        double  z;
433          register int  i;
434          
435 <        pixvalue(scanline[0], 0, y);
436 <
437 <        for (i = xstep; i <= ourview.hresolu; i += xstep) {
438 <        
439 <                pixvalue(scanline[i], i, y);
440 <                
441 <                b = fillsample(scanline+i-xstep, i-xstep, y, xstep, 0, b/2);
435 >        z = pixvalue(scanline[0], 0, y);
436 >        if (zline) zline[0] = z;
437 >                                /* zig-zag start for quincunx pattern */
438 >        for (i = ++nc & 1 ? xstep : xstep/2; i < xres-1+xstep; i += xstep) {
439 >                if (i >= xres) {
440 >                        xstep += xres-1-i;
441 >                        i = xres-1;
442 >                }
443 >                z = pixvalue(scanline[i], i, y);
444 >                if (zline) zline[i] = z;
445 >                if (sd) b = sd[0] > sd[1] ? sd[0] : sd[1];
446 >                if (i <= xstep)
447 >                        b = fillsample(scanline, zline, 0, y, i, 0, b/2);
448 >                else
449 >                        b = fillsample(scanline+i-xstep,
450 >                                        zline ? zline+i-xstep : NULL,
451 >                                        i-xstep, y, xstep, 0, b/2);
452 >                if (sd) *sd++ = nc & 1 ? bl : b;
453 >                bl = b;
454          }
455 +        if (sd && nc & 1) *sd = bl;
456   }
457  
458  
459 < fillscanbar(scanbar, y, ysize)          /* fill interior */
459 > fillscanbar(scanbar, zbar, xres, y, ysize)      /* fill interior */
460   register COLOR  *scanbar[];
461 < int  y, ysize;
461 > register float  *zbar[];
462 > int  xres, y, ysize;
463   {
464          COLOR  vline[MAXDIV+1];
465 +        float  zline[MAXDIV+1];
466          int  b = ysize;
467          register int  i, j;
468          
469 <        for (i = 0; i < ourview.hresolu; i++) {
469 >        for (i = 0; i < xres; i++) {
470                  
471                  copycolor(vline[0], scanbar[0][i]);
472                  copycolor(vline[ysize], scanbar[ysize][i]);
473 +                if (zbar[0]) {
474 +                        zline[0] = zbar[0][i];
475 +                        zline[ysize] = zbar[ysize][i];
476 +                }
477                  
478 <                b = fillsample(vline, i, y, 0, ysize, b/2);
478 >                b = fillsample(vline, zbar[0] ? zline : NULL,
479 >                                i, y, 0, ysize, b/2);
480                  
481                  for (j = 1; j < ysize; j++)
482                          copycolor(scanbar[j][i], vline[j]);
483 +                if (zbar[0])
484 +                        for (j = 1; j < ysize; j++)
485 +                                zbar[j][i] = zline[j];
486          }
487   }
488  
489  
490   int
491 < fillsample(colline, x, y, xlen, ylen, b)        /* fill interior points */
491 > fillsample(colline, zline, x, y, xlen, ylen, b) /* fill interior points */
492   register COLOR  *colline;
493 + register float  *zline;
494   int  x, y;
495   int  xlen, ylen;
496   int  b;
497   {
498 +        extern double  fabs();
499          double  ratio;
500 +        double  z;
501          COLOR  ctmp;
502          int  ncut;
503          register int  len;
# Line 202 | Line 510 | int  b;
510          if (len <= 1)                   /* limit recursion */
511                  return(0);
512          
513 <        if (b > 0 || bigdiff(colline[0], colline[len], maxdiff)) {
513 >        if (b > 0
514 >        || (zline && 2.*fabs(zline[0]-zline[len]) > maxdiff*(zline[0]+zline[len]))
515 >                        || bigdiff(colline[0], colline[len], maxdiff)) {
516          
517 <                pixvalue(colline[len>>1], x + (xlen>>1), y + (ylen>>1));
517 >                z = pixvalue(colline[len>>1], x + (xlen>>1), y + (ylen>>1));
518 >                if (zline) zline[len>>1] = z;
519                  ncut = 1;
520                  
521          } else {                                        /* interpolate */
# Line 212 | Line 523 | int  b;
523                  copycolor(colline[len>>1], colline[len]);
524                  ratio = (double)(len>>1) / len;
525                  scalecolor(colline[len>>1], ratio);
526 <                copycolor(ctmp, colline[0]);
526 >                if (zline) zline[len>>1] = zline[len] * ratio;
527                  ratio = 1.0 - ratio;
528 +                copycolor(ctmp, colline[0]);
529                  scalecolor(ctmp, ratio);
530                  addcolor(colline[len>>1], ctmp);
531 +                if (zline) zline[len>>1] += zline[0] * ratio;
532                  ncut = 0;
533          }
534                                                          /* recurse */
535 <        ncut += fillsample(colline, x, y, xlen>>1, ylen>>1, (b-1)/2);
535 >        ncut += fillsample(colline, zline, x, y, xlen>>1, ylen>>1, (b-1)/2);
536          
537 <        ncut += fillsample(colline + (len>>1), x + (xlen>>1), y + (ylen>>1),
538 <                                xlen - (xlen>>1), ylen - (ylen>>1), b/2);
537 >        ncut += fillsample(colline+(len>>1), zline ? zline+(len>>1) : NULL,
538 >                        x+(xlen>>1), y+(ylen>>1),
539 >                        xlen-(xlen>>1), ylen-(ylen>>1), b/2);
540  
541          return(ncut);
542   }
543  
544  
545 + double
546   pixvalue(col, x, y)             /* compute pixel value */
547   COLOR  col;                     /* returned color */
548   int  x, y;                      /* pixel position */
549   {
550 <        static RAY  thisray;    /* our ray for this pixel */
550 >        static RAY  thisray;
551  
552 <        rayview(thisray.rorg, thisray.rdir, &ourview,
553 <                        x + pixjitter(), y + pixjitter());
552 >        if (viewray(thisray.rorg, thisray.rdir, &ourview,
553 >                        (x+pixjitter())/hres, (y+pixjitter())/vres) < 0) {
554 >                setcolor(col, 0.0, 0.0, 0.0);
555 >                return(0.0);
556 >        }
557  
558          rayorigin(&thisray, NULL, PRIMARY, 1.0);
559 <        
559 >
560 >        samplendx = pixnumber(x,y,hres,vres);   /* set pixel index */
561 >
562          rayvalue(&thisray);                     /* trace ray */
563  
564          copycolor(col, thisray.rcol);           /* return color */
565 +        
566 +        return(thisray.rt);                     /* return distance */
567   }
568  
569  
# Line 255 | Line 577 | char  *oldfile;
577  
578          if (oldfile == NULL)
579                  return(0);
580 <        else if ((fp = fopen(oldfile, "r")) == NULL) {
580 >        
581 >        if ((fp = fopen(oldfile, "r")) == NULL) {
582                  sprintf(errmsg, "cannot open recover file \"%s\"", oldfile);
583                  error(WARNING, errmsg);
584                  return(0);
# Line 263 | Line 586 | char  *oldfile;
586                                  /* discard header */
587          getheader(fp, NULL);
588                                  /* get picture size */
589 <        if (fscanf(fp, "-Y %d +X %d\n", &y, &x) != 2) {
589 >        if (!fscnresolu(&x, &y, fp)) {
590                  sprintf(errmsg, "bad recover file \"%s\"", oldfile);
591                  error(WARNING, errmsg);
592                  fclose(fp);
593                  return(0);
594          }
595  
596 <        if (x != ourview.hresolu || y != ourview.vresolu) {
596 >        if (x != hres || y != vres) {
597                  sprintf(errmsg, "resolution mismatch in recover file \"%s\"",
598                                  oldfile);
599                  error(USER, errmsg);
277                return(0);
600          }
601  
602 <        scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
602 >        scanline = (COLR *)malloc(hres*sizeof(COLR));
603          if (scanline == NULL)
604                  error(SYSTEM, "out of memory in salvage");
605 <        for (y = 0; y < ourview.vresolu; y++) {
606 <                if (freadcolrs(scanline, ourview.hresolu, fp) < 0)
605 >        for (y = 0; y < vres; y++) {
606 >                if (freadcolrs(scanline, hres, fp) < 0)
607                          break;
608 <                if (fwritecolrs(scanline, ourview.hresolu, stdout) < 0)
608 >                if (fwritecolrs(scanline, hres, stdout) < 0)
609                          goto writerr;
610          }
611          if (fflush(stdout) == EOF)
# Line 294 | Line 616 | char  *oldfile;
616          return(y);
617   writerr:
618          error(SYSTEM, "write error in salvage");
619 + }
620 +
621 +
622 + int
623 + pixnumber(x, y, xres, yres)             /* compute pixel index (brushed) */
624 + register int  x, y;
625 + int  xres, yres;
626 + {
627 +        x -= y;
628 +        while (x < 0)
629 +                x += xres;
630 +        return((((x>>2)*yres + y) << 2) + (x & 3));
631   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines