Back to index

radiance  4R0+20100331
Classes | Defines | Functions | Variables
warp3d.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "rterror.h"
#include "rtio.h"
#include "fvect.h"
#include "warp3d.h"

Go to the source code of this file.

Classes

struct  KEYDP

Defines

#define MIND   1e-5 /* minimum distance between input points */
#define fgetvec(p, v)
#define AHUNK   24 /* number of points to allocate at a time */

Functions

double wpdist2 (W3VEC p1, W3VEC p2)
static int gridpoint (GNDX ndx, W3VEC rem, W3VEC ipt, struct grid3d *gp)
static int get3dgpt (W3VEC ov, GNDX ndx, WARP3D *wp)
static int get3dgin (W3VEC ov, GNDX ndx, W3VEC rem, WARP3D *wp)
static void l3interp (W3VEC vo, W3VEC *cl, W3VEC dv, int n)
static int warp3dex (W3VEC ov, W3VEC pi, WARP3D *wp)
static int new3dgrid (WARP3D *wp)
static void done3dgrid (struct grid3d *gp)
double wpdist2 (register W3VEC p1, register W3VEC p2)
int warp3d (W3VEC po, W3VEC pi, register WARP3D *wp)
static int gridpoint (GNDX ndx, W3VEC rem, W3VEC ipt, register struct grid3d *gp)
static int get3dgpt (W3VEC ov, GNDX ndx, register WARP3D *wp)
static int warp3dex (W3VEC ov, W3VEC pi, register WARP3D *wp)
WARP3Dnew3dw (int flgs)
WARP3Dload3dw (char *fn, WARP3D *wp)
int set3dwfl (register WARP3D *wp, int flgs)
int add3dpt (register WARP3D *wp, W3VEC pti, W3VEC pto)
void free3dw (register WARP3D *wp)
static unsigned long gridhash (const void *gp)
static int new3dgrid (register WARP3D *wp)
static void done3dgrid (register struct grid3d *gp)

Variables

static const char RCSid [] = "$Id: warp3d.c,v 3.8 2004/05/25 22:04:14 greg Exp $"
static lut_hashf_t gridhash

Class Documentation

struct KEYDP

Definition at line 19 of file warp3d.c.

Class Members
GNDX n
W3VEC v

Define Documentation

#define AHUNK   24 /* number of points to allocate at a time */

Definition at line 27 of file warp3d.c.

#define fgetvec (   p,
  v 
)
Value:
(fgetval(p,'f',v) > 0 && fgetval(p,'f',v+1) > 0 \
                            && fgetval(p,'f',v+2) > 0)

Definition at line 24 of file warp3d.c.

#define MIND   1e-5 /* minimum distance between input points */

Definition at line 17 of file warp3d.c.


Function Documentation

int add3dpt ( register WARP3D wp,
W3VEC  pti,
W3VEC  pto 
)

Definition at line 301 of file warp3d.c.

{
       double d2;
       register W3VEC       *na;
       register int  i;

       if (wp->npts == 0) {               /* initialize */
              wp->ip = (W3VEC *)malloc(AHUNK*sizeof(W3VEC));
              if (wp->ip == NULL) return(0);
              wp->ov = (W3VEC *)malloc(AHUNK*sizeof(W3VEC));
              if (wp->ov == NULL) return(0);
              wp->d2min = 1e10;
              wp->d2max = 0.;
              W3VCPY(wp->llim, pti);
              W3VCPY(wp->ulim, pti);
       } else {
              if (wp->npts % AHUNK == 0) {       /* allocate another hunk */
                     na = (W3VEC *)realloc((void *)wp->ip,
                                   (wp->npts+AHUNK)*sizeof(W3VEC));
                     if (na == NULL) return(0);
                     wp->ip = na;
                     na = (W3VEC *)realloc((void *)wp->ov,
                                   (wp->npts+AHUNK)*sizeof(W3VEC));
                     if (na == NULL) return(0);
                     wp->ov = na;
              }
              for (i = 0; i < 3; i++)            /* check boundaries */
                     if (pti[i] < wp->llim[i])
                            wp->llim[i] = pti[i];
                     else if (pti[i] > wp->ulim[i])
                            wp->ulim[i] = pti[i];
              for (i = wp->npts; i--; ) { /* check distances */
                     d2 = wpdist2(pti, wp->ip[i]);
                     if (d2 < MIND*MIND)  /* value is too close */
                            return(wp->npts);
                     if (d2 < wp->d2min)
                            wp->d2min = d2;
                     if (d2 > wp->d2max)
                            wp->d2max = d2;
              }
       }
       W3VCPY(wp->ip[wp->npts], pti);     /* add new point */
       wp->ov[wp->npts][0] = pto[0] - pti[0];
       wp->ov[wp->npts][1] = pto[1] - pti[1];
       wp->ov[wp->npts][2] = pto[2] - pti[2];
       done3dgrid(&wp->grid);             /* old grid is invalid */
       return(++wp->npts);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void done3dgrid ( struct grid3d gp) [static]

Here is the caller graph for this function:

static void done3dgrid ( register struct grid3d gp) [static]

Definition at line 428 of file warp3d.c.

{
       if (gp->gn[0] == 0)
              return;
       lu_done(&gp->gtab);
       gp->gn[0] = gp->gn[1] = gp->gn[2] = 0;
}

Here is the call graph for this function:

void free3dw ( register WARP3D wp)

Definition at line 356 of file warp3d.c.

{
       done3dgrid(&wp->grid);
       free((void *)wp->ip);
       free((void *)wp->ov);
       free((void *)wp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get3dgin ( W3VEC  ov,
GNDX  ndx,
W3VEC  rem,
WARP3D wp 
) [static]

Definition at line 148 of file warp3d.c.

{
       W3VEC  cv[8];
       GNDX   gi;
       int    rval = W3OK;
       register int  i;
                                   /* get corner values */
       for (i = 0; i < 8; i++) {
              gi[0] = ndx[0] + (i & 1);
              gi[1] = ndx[1] + (i>>1 & 1);
              gi[2] = ndx[2] + (i>>2);
              rval |= get3dgpt(cv[i], gi, wp);
       }
       if (rval & W3ERROR)
              return(rval);
       l3interp(ov, cv, rem, 3);   /* perform trilinear interpolation */
       return(rval);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get3dgpt ( W3VEC  ov,
GNDX  ndx,
WARP3D wp 
) [static]

Here is the caller graph for this function:

static int get3dgpt ( W3VEC  ov,
GNDX  ndx,
register WARP3D wp 
) [static]

Definition at line 112 of file warp3d.c.

{
       W3VEC  gpt;
       register LUENT       *le;
       KEYDP  *kd;
       int    rval = W3OK;
       register int  i;

       le = lu_find(&wp->grid.gtab, ndx);
       if (le == NULL)
              return(W3ERROR);
       if (le->data == NULL) {
              if (le->key != NULL)
                     kd = (KEYDP *)le->key;
              else if ((kd = (KEYDP *)malloc(sizeof(KEYDP))) == NULL)
                     return(W3ERROR);
              for (i = 0; i < 3; i++) {
                     kd->n[i] = ndx[i];
                     gpt[i] = wp->grid.gmin[i] + ndx[i]*wp->grid.gstep[i];
                     if (wp->grid.flags & W3FAST)       /* on centers */
                            gpt[i] += .5*wp->grid.gstep[i];
              }
              rval = warp3dex(kd->v, gpt, wp);
              le->key = (char *)kd->n;
              le->data = (char *)kd->v;
       }
       W3VCPY(ov, (float *)le->data);
       return(rval);
}

Here is the call graph for this function:

static unsigned long gridhash ( const void *  gp) [static]

Definition at line 368 of file warp3d.c.

{
       //return(((unsigned long)gp[0]<<GNBITS | gp[1])<<GNBITS | gp[2]);
       return(((unsigned long)((const unsigned char*)gp)[0]<<GNBITS | ((const unsigned char*)gp)[1])<<GNBITS | ((const unsigned char*)gp)[2]);
}
static int gridpoint ( GNDX  ndx,
W3VEC  rem,
W3VEC  ipt,
struct grid3d gp 
) [static]

Here is the caller graph for this function:

static int gridpoint ( GNDX  ndx,
W3VEC  rem,
W3VEC  ipt,
register struct grid3d gp 
) [static]

Definition at line 85 of file warp3d.c.

{
       int    rval = W3OK;
       register int  i;

       for (i = 0; i < 3; i++) {
              rem[i] = (ipt[i] - gp->gmin[i])/gp->gstep[i];
              if (rem[i] < 0.) {
                     ndx[i] = 0;
                     rval = W3GAMUT;
              } else if ((int)rem[i] >= gp->gn[i]) {
                     ndx[i] = gp->gn[i] - 1;
                     rval = W3GAMUT;
              } else
                     ndx[i] = (int)rem[i];
              rem[i] -= (double)ndx[i];
       }
       return(rval);
}
static void l3interp ( W3VEC  vo,
W3VEC cl,
W3VEC  dv,
int  n 
) [static]

Definition at line 174 of file warp3d.c.

{
       W3VEC  v0, v1;
       register int  i;

       if (--n) {
              l3interp(v0, cl, dv, n);
              l3interp(v1, cl+(1<<n), dv, n);
       } else {
              W3VCPY(v0, cl[0]);
              W3VCPY(v1, cl[1]);
       }
       for (i = 0; i < 3; i++)
              vo[i] = (1.-dv[n])*v0[i] + dv[n]*v1[i];
}

Here is the caller graph for this function:

WARP3D* load3dw ( char *  fn,
WARP3D wp 
)

Definition at line 251 of file warp3d.c.

{
       FILE   *fp;
       W3VEC  inp, outp;

       if ((fp = fopen(fn, "r")) == NULL) {
              eputs(fn);
              eputs(": cannot open\n");
              return(NULL);
       }
       if (wp == NULL && (wp = new3dw(0)) == NULL)
              goto memerr;
       while (fgetvec(fp, inp) && fgetvec(fp, outp))
              if (!add3dpt(wp, inp, outp))
                     goto memerr;
       if (!feof(fp)) {
              wputs(fn);
              wputs(": non-number in 3D warp file\n");
       }
       goto cleanup;
memerr:
       eputs("load3dw: out of memory\n");
cleanup:
       fclose(fp);
       return(wp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int new3dgrid ( WARP3D wp) [static]

Here is the caller graph for this function:

static int new3dgrid ( register WARP3D wp) [static]

Definition at line 379 of file warp3d.c.

{
       W3VEC  gmax;
       double gridstep, d;
       int    n;
       register int  i;
                            /* free old grid (if any) */
       done3dgrid(&wp->grid);
                            /* check parameters */
       if (wp->npts < 2)
              return(W3BADMAP);    /* undefined for less than 2 points */
       if (wp->d2max < MIND)
              return(W3BADMAP);    /* not enough disparity */
                            /* compute gamut */
       W3VCPY(wp->grid.gmin, wp->llim);
       W3VCPY(gmax, wp->ulim);
       gridstep = sqrt(wp->d2min);
       for (i = 0; i < 3; i++) {
              wp->grid.gmin[i] -= .501*gridstep;
              gmax[i] += .501*gridstep;
       }
       if (wp->grid.flags & W3EXACT) {
              wp->grid.gn[0] = wp->grid.gn[1] = wp->grid.gn[2] = 1;
              wp->grid.gstep[0] = gmax[0] - wp->grid.gmin[0];
              wp->grid.gstep[1] = gmax[1] - wp->grid.gmin[1];
              wp->grid.gstep[2] = gmax[2] - wp->grid.gmin[2];
              return(W3OK);        /* no interpolation, so no grid */
       }
                            /* create grid */
       for (i = 0; i < 3; i++) {
              d = gmax[i] - wp->grid.gmin[i];
              n = d/gridstep + .5;
              if (n >= MAXGN-1)
                     n = MAXGN-2;
              wp->grid.gstep[i] = d / n;
              wp->grid.gn[i] = n;
       }
                            /* initialize lookup table */
       wp->grid.gtab.hashf = gridhash;
       wp->grid.gtab.keycmp = NULL;
       wp->grid.gtab.freek = free;
       wp->grid.gtab.freed = NULL;
       return(lu_init(&wp->grid.gtab, 1024) ? W3OK : W3ERROR);
}

Here is the call graph for this function:

WARP3D* new3dw ( int  flgs)

Definition at line 228 of file warp3d.c.

{
       register WARP3D  *wp;

       if ((flgs & (W3EXACT|W3FAST)) == (W3EXACT|W3FAST)) {
              eputs("new3dw: only one of W3EXACT or W3FAST\n");
              return(NULL);
       }
       if ((wp = (WARP3D *)malloc(sizeof(WARP3D))) == NULL) {
              eputs("new3dw: no memory\n");
              return(NULL);
       }
       wp->ip = wp->ov = NULL;
       wp->npts = 0;
       wp->grid.flags = flgs;
       wp->grid.gn[0] = wp->grid.gn[1] = wp->grid.gn[2] = 0;
       return(wp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int set3dwfl ( register WARP3D wp,
int  flgs 
)

Definition at line 283 of file warp3d.c.

{
       if (flgs == wp->grid.flags)
              return(0);
       if ((flgs & (W3EXACT|W3FAST)) == (W3EXACT|W3FAST)) {
              eputs("set3dwfl: only one of W3EXACT or W3FAST\n");
              return(-1);
       }
       wp->grid.flags = flgs;
       done3dgrid(&wp->grid);             /* old grid is invalid */
       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int warp3d ( W3VEC  po,
W3VEC  pi,
register WARP3D wp 
)

Definition at line 58 of file warp3d.c.

{
       int    rval = W3OK;
       GNDX   gi;
       W3VEC  gd, ov;

       if (wp->grid.gn[0] == 0 && (rval = new3dgrid(wp)) != W3OK)
              return(rval);
       rval |= gridpoint(gi, gd, pi, &wp->grid);
       if (wp->grid.flags & W3EXACT)
              rval |= warp3dex(ov, pi, wp);
       else if (wp->grid.flags & W3FAST)
              rval |= get3dgpt(ov, gi, wp);
       else
              rval |= get3dgin(ov, gi, gd, wp);
       po[0] = pi[0] + ov[0];
       po[1] = pi[1] + ov[1];
       po[2] = pi[2] + ov[2];
       return(rval);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int warp3dex ( W3VEC  ov,
W3VEC  pi,
WARP3D wp 
) [static]

Here is the caller graph for this function:

static int warp3dex ( W3VEC  ov,
W3VEC  pi,
register WARP3D wp 
) [static]

Definition at line 197 of file warp3d.c.

{
       double d2, w, wsum;
       W3VEC  vt;
       register int  i;

       vt[0] = vt[1] = vt[2] = 0.;
       wsum = 0.;
       for (i = wp->npts; i--; ) {
              d2 = wpdist2(pi, wp->ip[i]);
              if (d2 <= MIND*MIND) w = 1./(MIND*MIND);
              else w = 1./d2;
              vt[0] += w*wp->ov[i][0];
              vt[1] += w*wp->ov[i][1];
              vt[2] += w*wp->ov[i][2];
              wsum += w;
       }
       if (wsum > 0.) {
              ov[0] = vt[0]/wsum;
              ov[1] = vt[1]/wsum;
              ov[2] = vt[2]/wsum;
       }
       return(W3OK);
}

Here is the call graph for this function:

double wpdist2 ( W3VEC  p1,
W3VEC  p2 
)

Here is the caller graph for this function:

double wpdist2 ( register W3VEC  p1,
register W3VEC  p2 
)

Definition at line 43 of file warp3d.c.

{
       double d, d2;

       d = p1[0] - p2[0]; d2  = d*d;
       d = p1[1] - p2[1]; d2 += d*d;
       d = p1[2] - p2[2]; d2 += d*d;
       return(d2);
}

Variable Documentation

Definition at line 37 of file warp3d.c.

const char RCSid[] = "$Id: warp3d.c,v 3.8 2004/05/25 22:04:14 greg Exp $" [static]

Definition at line 2 of file warp3d.c.