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

Comparing ray/src/px/pinterp.c (file contents):
Revision 1.1 by greg, Sun Dec 10 17:34:13 1989 UTC vs.
Revision 1.9 by greg, Wed Jan 3 12:52:30 1990 UTC

# Line 17 | Line 17 | static char SCCSid[] = "$SunId$ LBL";
17   #define pscan(y)        (ourpict+(y)*ourview.hresolu)
18   #define zscan(y)        (ourzbuf+(y)*ourview.hresolu)
19  
20 + #define ABS(x)          ((x)>0?(x):-(x))
21 +
22   VIEW    ourview = STDVIEW(512);         /* desired view */
23  
24 < double  zeps = 0.001;                   /* allowed z epsilon */
24 > double  zeps = .02;                     /* allowed z epsilon */
25  
26   COLR    *ourpict;                       /* output picture */
27   float   *ourzbuf;                       /* corresponding z-buffer */
# Line 29 | Line 31 | char   *progname;
31   VIEW    theirview = STDVIEW(512);       /* input view */
32   int     gotview;                        /* got input view? */
33  
34 + double  theirs2ours[4][4];              /* transformation matrix */
35  
36 +
37   main(argc, argv)                        /* interpolate pictures */
38   int     argc;
39   char    *argv[];
# Line 47 | Line 51 | char   *argv[];
51                          check(2,1);
52                          zeps = atof(argv[++i]);
53                          break;
54 +                case 'x':                               /* x resolution */
55 +                        check(2,1);
56 +                        ourview.hresolu = atoi(argv[++i]);
57 +                        break;
58 +                case 'y':                               /* y resolution */
59 +                        check(2,1);
60 +                        ourview.vresolu = atoi(argv[++i]);
61 +                        break;
62                  case 'v':                               /* view */
63                          switch (argv[i][2]) {
64                          case 't':                               /* type */
# Line 161 | Line 173 | addpicture(pfile, zfile)               /* add picture to output */
173   char    *pfile, *zfile;
174   {
175          FILE    *pfp, *zfp;
164        COLR    *scanin;
165        float   *zin;
176          char    *err;
177 <        int     xres, yres;
177 >        COLR    *scanin;
178 >        float   *zin, *zlast;
179 >        int     *plast;
180          int     y;
181                                          /* open input files */
182          if ((pfp = fopen(pfile, "r")) == NULL) {
# Line 179 | Line 191 | char   *pfile, *zfile;
191          printf("%s:\n", pfile);
192          gotview = 0;
193          getheader(pfp, headline);
194 <        if (!gotview || fgetresolu(&xres, &yres, pfp) != (YMAJOR|YDECR)) {
194 >        if (!gotview || fgetresolu(&theirview.hresolu, &theirview.vresolu, pfp)
195 >                        != (YMAJOR|YDECR)) {
196                  fprintf(stderr, "%s: picture view error\n", pfile);
197                  exit(1);
198          }
186        theirview.hresolu = xres;
187        theirview.vresolu = yres;
199          if (err = setview(&theirview)) {
200                  fprintf(stderr, "%s: %s\n", pfile, err);
201                  exit(1);
202          }
203 +                                        /* compute transformation */
204 +        pixform(theirs2ours, &theirview, &ourview);
205                                          /* allocate scanlines */
206 <        scanin = (COLR *)malloc(xres*sizeof(COLR));
207 <        zin = (float *)malloc(xres*sizeof(float));
208 <        if (scanin == NULL || zin == NULL) {
206 >        scanin = (COLR *)malloc(theirview.hresolu*sizeof(COLR));
207 >        zin = (float *)malloc(theirview.hresolu*sizeof(float));
208 >        zlast = (float *)calloc(theirview.hresolu, sizeof(float));
209 >        plast = (int *)calloc(theirview.hresolu, sizeof(int));
210 >        if (scanin == NULL || zin == NULL || zlast == NULL || plast == NULL) {
211                  perror(progname);
212                  exit(1);
213          }
214                                          /* load image */
215 <        for (y = yres-1; y >= 0; y--) {
216 <                if (freadcolrs(scanin, xres, pfp) < 0) {
215 >        for (y = theirview.vresolu-1; y >= 0; y--) {
216 >                if (freadcolrs(scanin, theirview.hresolu, pfp) < 0) {
217                          fprintf(stderr, "%s: read error\n", pfile);
218                          exit(1);
219                  }
220 <                if (fread(zin, sizeof(float), xres, zfp) < xres) {
220 >                if (fread(zin, sizeof(float), theirview.hresolu, zfp)
221 >                                < theirview.hresolu) {
222                          fprintf(stderr, "%s: read error\n", zfile);
223                          exit(1);
224                  }
225 <                addscanline(y, scanin, zin);
225 >                addscanline(y, scanin, zin, plast, zlast);
226          }
227                                          /* clean up */
228          free((char *)scanin);
229          free((char *)zin);
230 +        free((char *)plast);
231 +        free((char *)zlast);
232          fclose(pfp);
233          fclose(zfp);
234   }
235  
236  
237 < addscanline(y, pline, zline)            /* add scanline to output */
237 > pixform(xfmat, vw1, vw2)                /* compute view1 to view2 matrix */
238 > register double xfmat[4][4];
239 > register VIEW   *vw1, *vw2;
240 > {
241 >        double  m4t[4][4];
242 >
243 >        setident4(xfmat);
244 >        xfmat[0][0] = vw1->vhinc[0];
245 >        xfmat[0][1] = vw1->vhinc[1];
246 >        xfmat[0][2] = vw1->vhinc[2];
247 >        xfmat[1][0] = vw1->vvinc[0];
248 >        xfmat[1][1] = vw1->vvinc[1];
249 >        xfmat[1][2] = vw1->vvinc[2];
250 >        xfmat[2][0] = vw1->vdir[0];
251 >        xfmat[2][1] = vw1->vdir[1];
252 >        xfmat[2][2] = vw1->vdir[2];
253 >        xfmat[3][0] = vw1->vp[0];
254 >        xfmat[3][1] = vw1->vp[1];
255 >        xfmat[3][2] = vw1->vp[2];
256 >        setident4(m4t);
257 >        m4t[0][0] = vw2->vhinc[0]/vw2->vhn2;
258 >        m4t[1][0] = vw2->vhinc[1]/vw2->vhn2;
259 >        m4t[2][0] = vw2->vhinc[2]/vw2->vhn2;
260 >        m4t[3][0] = -DOT(vw2->vp,vw2->vhinc)/vw2->vhn2;
261 >        m4t[0][1] = vw2->vvinc[0]/vw2->vvn2;
262 >        m4t[1][1] = vw2->vvinc[1]/vw2->vvn2;
263 >        m4t[2][1] = vw2->vvinc[2]/vw2->vvn2;
264 >        m4t[3][1] = -DOT(vw2->vp,vw2->vvinc)/vw2->vvn2;
265 >        m4t[0][2] = vw2->vdir[0];
266 >        m4t[1][2] = vw2->vdir[1];
267 >        m4t[2][2] = vw2->vdir[2];
268 >        m4t[3][2] = -DOT(vw2->vp,vw2->vdir);
269 >        multmat4(xfmat, xfmat, m4t);
270 > }
271 >
272 >
273 > addscanline(y, pline, zline, lasty, lastyz)     /* add scanline to output */
274   int     y;
275   COLR    *pline;
276   float   *zline;
277 + int     *lasty;                 /* input/output */
278 + float   *lastyz;                /* input/output */
279   {
280 <        FVECT   p, dir;
281 <        double  xnew, ynew, znew;
280 >        extern double   sqrt(), fabs();
281 >        double  pos[3];
282 >        int     lastx = 0;
283 >        double  lastxz = 0;
284 >        double  zt;
285 >        int     xpos, ypos;
286          register int    x;
227        register int    xpos, ypos;
287  
288 <        for (x = 0; x < theirview.hresolu; x++) {
289 <                rayview(p, dir, &theirview, x+.5, y+.5);
290 <                p[0] += zline[x]*dir[0];
291 <                p[1] += zline[x]*dir[1];
292 <                p[2] += zline[x]*dir[2];
293 <                pixelview(&xnew, &ynew, &znew, &ourview, p);
294 <                if (znew <= 0.0 || xnew < 0 || xnew > ourview.hresolu
295 <                                || ynew < 0 || ynew > ourview.vresolu)
288 >        for (x = theirview.hresolu-1; x >= 0; x--) {
289 >                pos[0] = x - .5*(theirview.hresolu-1);
290 >                pos[1] = y - .5*(theirview.vresolu-1);
291 >                pos[2] = zline[x];
292 >                if (theirview.type == VT_PER) {
293 >                        /*
294 >                         * The following (single) statement can go
295 >                         * if z is along the view direction rather
296 >                         * than an eye ray.
297 >                         */
298 >                        pos[2] /= sqrt( 1.
299 >                                        + pos[0]*pos[0]*theirview.vhn2
300 >                                        + pos[1]*pos[1]*theirview.vvn2 );
301 >                        pos[0] *= pos[2];
302 >                        pos[1] *= pos[2];
303 >                }
304 >                multp3(pos, pos, theirs2ours);
305 >                if (pos[2] <= 0)
306                          continue;
307 <                                        /* check current value at position */
308 <                xpos = xnew;
309 <                ypos = ynew;
241 <                if (zscan(ypos)[xpos] <= 0.0
242 <                                || zscan(ypos)[xpos] - znew
243 <                                        > zeps*zscan(ypos)[xpos]) {
244 <                        zscan(ypos)[xpos] = znew;
245 <                        copycolr(pscan(ypos)[xpos], pline[x]);
307 >                if (ourview.type == VT_PER) {
308 >                        pos[0] /= pos[2];
309 >                        pos[1] /= pos[2];
310                  }
311 +                pos[0] += .5*ourview.hresolu;
312 +                pos[1] += .5*ourview.vresolu;
313 +                if (pos[0] < 0 || (xpos = pos[0]) >= ourview.hresolu
314 +                        || pos[1] < 0 || (ypos = pos[1]) >= ourview.vresolu)
315 +                        continue;
316 +                                        /* add pixel to our image */
317 +                zt = 2.*zeps*zline[x];
318 +                addpixel(xpos, ypos,
319 +                        (fabs(zline[x]-lastxz) <= zt) ? lastx - xpos : 1,
320 +                        (fabs(zline[x]-lastyz[x]) <= zt) ? lasty[x] - ypos : 1,
321 +                        pline[x], pos[2]);
322 +                lastx = xpos;
323 +                lasty[x] = ypos;
324 +                lastxz = lastyz[x] = zline[x];
325          }
326   }
327  
328  
329 + addpixel(xstart, ystart, width, height, pix, z) /* fill in area for pixel */
330 + int     xstart, ystart;
331 + int     width, height;
332 + COLR    pix;
333 + double  z;
334 + {
335 +        register int    x, y;
336 +                                        /* make width and height positive */
337 +        if (width < 0) {
338 +                width = -width;
339 +                xstart = xstart-width+1;
340 +        } else if (width == 0)
341 +                width = 1;
342 +        if (height < 0) {
343 +                height = -height;
344 +                ystart = ystart-height+1;
345 +        } else if (height == 0)
346 +                height = 1;
347 +                                        /* fill pixel(s) within rectangle */
348 +        for (y = ystart; y < ystart+height; y++)
349 +                for (x = xstart; x < xstart+width; x++)
350 +                        if (zscan(y)[x] <= 0
351 +                                        || zscan(y)[x]-z > zeps*zscan(y)[x]) {
352 +                                zscan(y)[x] = z;
353 +                                copycolr(pscan(y)[x], pix);
354 +                        }
355 + }
356 +
357 +
358   fillpicture()                           /* fill in empty spaces */
359   {
360 +        int     *yback, xback;
361          int     y;
362 <        COLR    cfill;
363 <        register int    x, xblank;
364 <        
362 >        COLR    pfill;
363 >        register int    x, i;
364 >                                                        /* get back buffer */
365 >        yback = (int *)malloc(ourview.hresolu*sizeof(int));
366 >        if (yback == NULL) {
367 >                perror(progname);
368 >                return;
369 >        }
370 >        for (x = 0; x < ourview.hresolu; x++)
371 >                yback[x] = -2;
372 >        /*
373 >         * Xback and yback are the pixel locations of suitable
374 >         * background values in each direction.
375 >         * A value of -2 means unassigned, and -1 means
376 >         * that there is no suitable background in this direction.
377 >         */
378 >                                                        /* fill image */
379          for (y = 0; y < ourview.vresolu; y++) {
380 <                xblank = -1;
380 >                xback = -2;
381                  for (x = 0; x < ourview.hresolu; x++)
382 <                        if (zscan(y)[x] <= 0.0) {
383 <                                if (xblank < 0)
384 <                                        xblank = x;
385 <                        } else if (xblank >= 0) {
386 <                                if (xblank == 0 || zscan(y)[xblank-1] < zscan(y)[x])
387 <                                        copycolr(cfill, pscan(y)[x]);
382 >                        if (zscan(y)[x] <= 0) {         /* empty pixel */
383 >                                /*
384 >                                 * First, find background from above or below.
385 >                                 * (farthest assigned pixel)
386 >                                 */
387 >                                if (yback[x] == -2) {
388 >                                        for (i = y+1; i < ourview.vresolu; i++)
389 >                                                if (zscan(i)[x] > 0)
390 >                                                        break;
391 >                                        if (i < ourview.vresolu
392 >                                && (y <= 0 || zscan(y-1)[x] < zscan(i)[x]))
393 >                                                yback[x] = i;
394 >                                        else
395 >                                                yback[x] = y-1;
396 >                                }
397 >                                /*
398 >                                 * Next, find background from left or right.
399 >                                 */
400 >                                if (xback == -2) {
401 >                                        for (i = x+1; x < ourview.hresolu; i++)
402 >                                                if (zscan(y)[i] > 0)
403 >                                                        break;
404 >                                        if (i < ourview.hresolu
405 >                                && (x <= 0 || zscan(y)[x-1] < zscan(y)[i]))
406 >                                                xback = i;
407 >                                        else
408 >                                                xback = x-1;
409 >                                }
410 >                                if (xback < 0 && yback[x] < 0)
411 >                                        continue;       /* no background */
412 >                                /*
413 >                                 * Compare, and use the background that is
414 >                                 * farther, unless one of them is next to us.
415 >                                 */
416 >                                if (yback[x] < 0 || ABS(x-xback) <= 1
417 >                                        || ( ABS(y-yback[x]) > 1
418 >                                && zscan(yback[x])[x] < zscan(y)[xback] ))
419 >                                        copycolr(pscan(y)[x],pscan(y)[xback]);
420                                  else
421 <                                        copycolr(cfill, pscan(y)[xblank-1]);
422 <                                for ( ; xblank < x; xblank++)
423 <                                        copycolr(pscan(y)[xblank], cfill);
424 <                                xblank = -1;
421 >                                        copycolr(pscan(y)[x],pscan(yback[x])[x]);
422 >                        } else {                                /* full pixel */
423 >                                yback[x] = -2;
424 >                                xback = -2;
425                          }
272                if (xblank > 0) {
273                        copycolr(cfill, pscan(y)[xblank-1]);
274                        for ( ; xblank < ourview.hresolu; xblank++)
275                                copycolr(pscan(y)[xblank], cfill);
276                }
426          }
427 +        free((char *)yback);
428   }
429  
430  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines