コード例 #1
0
int
_echoRayIntx_Sphere(RAYINTX_ARGS(Sphere)) {
  echoPos_t t, A, B, C, r[3], dscr, pos[3], tmp;

  AIR_UNUSED(parm);
  AIR_UNUSED(tstate);
  ELL_3V_SUB(r, ray->from, obj->pos);
  A = ELL_3V_DOT(ray->dir, ray->dir);
  B = 2*ELL_3V_DOT(ray->dir, r);
  C = ELL_3V_DOT(r, r) - obj->rad*obj->rad;
  dscr = B*B - 4*A*C;
  if (dscr <= 0) {
    /* grazes or misses (most common case) */
    return AIR_FALSE;
  }
  /* else */
  dscr = sqrt(dscr);
  t = (-B - dscr)/(2*A);
  if (!AIR_IN_CL(ray->neer, t, ray->faar)) {
    t = (-B + dscr)/(2*A);
    if (!AIR_IN_CL(ray->neer, t, ray->faar)) {
      return AIR_FALSE;
    }
  }
  /* else one of the intxs is in [neer,faar] segment */
  intx->t = t;
  ELL_3V_SCALE_ADD2(pos, 1, ray->from, t, ray->dir);
  ELL_3V_SUB(intx->norm, pos, obj->pos);
  ELL_3V_NORM(intx->norm, intx->norm, tmp);
  intx->obj = OBJECT(obj);
  /* does NOT set u, v */
  return AIR_TRUE;
}
コード例 #2
0
ファイル: light.c プロジェクト: SCIInstitute/Cleaver
/*
******** limnLightSwitch
**
** can toggle a light on/off
**
** returns 1 on error, 0 if okay
*/
void
limnLightSwitch(limnLight *lit, int which, int on) {

  if (lit && AIR_IN_CL(0, which, LIMN_LIGHT_NUM-1)) {
    lit->on[which] = on;
  }
}
コード例 #3
0
ファイル: methodsNrrd.c プロジェクト: ewong718/freesurfer
/*
******** nrrdAlloc_nva()
**
** allocates data array and sets information.  If this is a block type
** nrrd, it is necessary to set nrrd->blockSize PRIOR to calling
** this function.
**
** This function will always allocate more memory (via calloc), but
** it will free() nrrd->data if it is non-NULL when passed in.
**
** This function takes the same "don't mess with peripheral information"
** attitude as nrrdWrap().
**
** Note to Gordon: don't get clever and change ANY axis-specific
** information here.  It may be very convenient to set that before
** nrrdAlloc or nrrdMaybeAlloc
**
** Note: This function DOES use biff
*/
int
nrrdAlloc_nva(Nrrd *nrrd, int type, unsigned int dim, const size_t *size)
{
  char me[]="nrrdAlloc_nva", err[BIFF_STRLEN];
  size_t num;
  int esize;

  if (!(nrrd && size))
  {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(NRRD, err);
    return 1;
  }
  if (airEnumValCheck(nrrdType, type))
  {
    sprintf(err, "%s: type (%d) is invalid", me, type);
    biffAdd(NRRD, err);
    return 1;
  }
  if (nrrdTypeBlock == type)
  {
    if (!(0 < nrrd->blockSize))
    {
      sprintf(err, "%s: given nrrd->blockSize " _AIR_SIZE_T_CNV " invalid",
              me, nrrd->blockSize);
      biffAdd(NRRD, err);
      return 1;
    }
  }
  if (!AIR_IN_CL(1, dim, NRRD_DIM_MAX))
  {
    sprintf(err, "%s: dim (%d) not in valid range [1,%d]",
            me, dim, NRRD_DIM_MAX);
    biffAdd(NRRD, err);
    return 1;
  }

  nrrd->data = airFree(nrrd->data);
  if (nrrdWrap_nva(nrrd, NULL, type, dim, size))
  {
    sprintf(err, "%s:", me);
    biffAdd(NRRD, err);
    return 1 ;
  }
  num = nrrdElementNumber(nrrd);
  esize = nrrdElementSize(nrrd);
  nrrd->data = calloc(num, esize);
  if (!(nrrd->data))
  {
    sprintf(err, "%s: calloc(" _AIR_SIZE_T_CNV ",%d) failed",
            me, num, esize);
    biffAdd(NRRD, err);
    return 1 ;
  }

  return 0;
}
コード例 #4
0
ファイル: ninspect.c プロジェクト: CIBC-Internal/teem
int
ninspect_proj(Nrrd *nout, Nrrd *nin, int axis, int smart, float amount) {
  static const char me[]="ninspect_proj";
  airArray *mop;
  Nrrd *ntmpA, *ntmpB, **nrgb;
  int bins;

  if (!(nout && nin)) {
    biffAddf(NINSPECT, "%s: got NULL pointer", me);
    return 1;
  }
  if (!( AIR_IN_CL(0, axis, 2) )) {
    biffAddf(NINSPECT, "%s: given axis %d outside valid range [0,1,2]",
             me, axis);
    return 1;
  }

  /* allocate a bunch of nrrds to use as basically temp variables */
  mop = airMopNew();
  airMopAdd(mop, ntmpA = nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
  airMopAdd(mop, ntmpB = nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
  /* HEY: this used to be nrgb[3], but its passing to nrrdJoin caused
     "dereferencing type-punned pointer might break strict-aliasing rules"
     warning; GLK not sure how else to fix it */
  nrgb = AIR_CALLOC(3, Nrrd*);
  airMopAdd(mop, nrgb, airFree, airMopAlways);
  airMopAdd(mop, nrgb[0] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
  airMopAdd(mop, nrgb[1] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways);
  airMopAdd(mop, nrgb[2] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways);

  /* these arguments to nrrdHistoEq will control its behavior */
  bins = 3000;  /* equalization will use a histogram with this many bins */

  /* the following idiom is one way of handling the fact that any
     non-trivial nrrd call can fail, and if it does, then any subsequent
     nrrd calls should be avoided (to be perfectly safe), so that you can
     get the error message from biff.  Because of the left-to-right ordering
     ensured for logical expressions, this will all be called in sequence
     until one of them has a non-zero return.  If he had exception handling,
     we'd put all the nrrd calls in one "try" block.  */
  if (nrrdProject(ntmpA, nin, axis, nrrdMeasureSum, nrrdTypeDefault)
      || nrrdHistoEq(ntmpB, ntmpA, NULL, bins, smart, amount)
      || nrrdQuantize(nrgb[0], ntmpB, NULL, 8)
      || nrrdProject(ntmpA, nin, axis, nrrdMeasureVariance, nrrdTypeDefault)
      || nrrdHistoEq(ntmpB, ntmpA, NULL, bins, smart, amount)
      || nrrdQuantize(nrgb[1], ntmpB, NULL, 8)
      || nrrdProject(ntmpA, nin, axis, nrrdMeasureMax, nrrdTypeDefault)
      || nrrdQuantize(nrgb[2], ntmpA, NULL, 8)
      || nrrdJoin(nout, (const Nrrd*const*)nrgb, 3, 0, AIR_TRUE)) {
    biffMovef(NINSPECT, NRRD, "%s: trouble with nrrd operations", me);
    airMopError(mop); return 1;
  }

  airMopOkay(mop);
  return 0;
}
コード例 #5
0
ファイル: dio.c プロジェクト: 151706061/ITK
const char *
airNoDioErr(int noDio) {

  if (AIR_IN_CL(0, noDio, AIR_NODIO_MAX)) {
    return _airNoDioErr[noDio+1];
  }
  else {
    return _airNoDioErr[0];
  }
}
コード例 #6
0
ファイル: hestNrrd.c プロジェクト: CIBC-Internal/teem
int
_nrrdLooksLikeANumber(char *str) {
  /* 0: -+                (no restriction, but that's a little daft)
     1: 0123456789        n > 0
     2: .                 0 <= n <= 1
     3: eE                0 <= n <= 1
     4: everything else   0 == n
  */
  int count[5];

  count[0] = count[1] = count[2] = count[3] = count[4] = 0;
  while (*str) {
    int lwc, cc = *str;
    lwc = tolower(cc);
    switch (lwc) {
    case '-': case '+':
      count[0]++;
      break;
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      count[1]++;
      break;
    case '.':
      count[2]++;
      break;
    case 'e':
      count[3]++;
      break;
    default:
      count[4]++;
      break;
    }
    str++;
  }
  if (count[1] > 0 &&
      AIR_IN_CL(0, count[2], 1) &&
      AIR_IN_CL(0, count[3], 1) &&
      count[4] == 0) {
    return AIR_TRUE;
  } else {
    return AIR_FALSE;
  }
}
コード例 #7
0
ファイル: sane.c プロジェクト: BishopWolf/ITK
const char *
airInsaneErr(int insane) {

  if (AIR_IN_CL(0, insane, AIR_INSANE_MAX)) {
    return _airInsaneErr[insane];
  }
  else {
    return _airBadInsane;
  }
}
コード例 #8
0
ファイル: splineEval.c プロジェクト: rblake/seg3d2
void
_limnSplineIntervalFind_Warp(int *ii, double *ff,
                             limnSpline *spline, double tt) {
  int N;

  N = spline->ncpt->axis[2].size;
  tt = AIR_CLAMP(spline->time[0], tt, spline->time[N-1]);
  *ii = AIR_CLAMP(0, *ii, N-2);
  /* the last value of ii may be the right one */
  if (!AIR_IN_CL(spline->time[*ii], tt, spline->time[*ii+1])) {
    /* HEY: make this a binary search */
    for (*ii=0; *ii<N-2; (*ii)++) {
      if (AIR_IN_CL(spline->time[*ii], tt, spline->time[*ii+1])) {
        break;
      }
    }
  }
  *ff = (tt - spline->time[*ii])/(spline->time[*ii+1] - spline->time[*ii]);
  return;
}
コード例 #9
0
ファイル: simple.c プロジェクト: ryanfb/teem-parallel
int
_nrrdFieldCheck_dimension(const Nrrd *nrrd, int useBiff) {
  char me[]="_nrrdFieldCheck_dimension", err[BIFF_STRLEN];
  
  if (!AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX)) {
    sprintf(err, "%s: dimension %u is outside valid range [1,%d]",
            me, nrrd->dim, NRRD_DIM_MAX);
    biffMaybeAdd(NRRD, err, useBiff); return 1;
  }
  return 0;
}
コード例 #10
0
ファイル: simple.c プロジェクト: 151706061/ITK
static int
_nrrdFieldCheck_dimension(const Nrrd *nrrd, int useBiff) {
  static const char me[]="_nrrdFieldCheck_dimension";

  if (!AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX)) {
    biffMaybeAddf(useBiff, NRRD,
                  "%s: dimension %u is outside valid range [1,%d]",
                  me, nrrd->dim, NRRD_DIM_MAX);
    return 1;
  }
  return 0;
}
コード例 #11
0
ファイル: light.c プロジェクト: SCIInstitute/Cleaver
/*
******** limnLightSet()
** 
** turns on a light
**
*/
void
limnLightSet(limnLight *lit, int which, int vsp,
             float r, float g, float b,
             float x, float y, float z) {
  
  if (lit && AIR_IN_CL(0, which, LIMN_LIGHT_NUM-1)) {
    lit->on[which] = 1;
    lit->vsp[which] = vsp;
    ELL_4V_SET(lit->col[which], r, g, b, 1.0);
    ELL_4V_SET(lit->_dir[which], x, y, z, 0.0);
  }
}
コード例 #12
0
int
_echoRayIntx_CubeSurf(echoPos_t *tP, int *axP, int *dirP,
                      echoPos_t xmin, echoPos_t xmax,
                      echoPos_t ymin, echoPos_t ymax,
                      echoPos_t zmin, echoPos_t zmax,
                      echoRay *ray) {
  echoPos_t txmin, tymin, tzmin, txmax, tymax, tzmax,
    dx, dy, dz, ox, oy, oz, tmin, tmax;
  int axmin, axmax, sgn[3];

  ELL_3V_GET(dx, dy, dz, ray->dir);
  ELL_3V_GET(ox, oy, oz, ray->from);
  if (dx >= 0) { txmin = (xmin - ox)/dx; txmax = (xmax - ox)/dx; sgn[0] = -1; }
  else         { txmin = (xmax - ox)/dx; txmax = (xmin - ox)/dx; sgn[0] =  1; }
  if (dy >= 0) { tymin = (ymin - oy)/dy; tymax = (ymax - oy)/dy; sgn[1] = -1; }
  else         { tymin = (ymax - oy)/dy; tymax = (ymin - oy)/dy; sgn[1] =  1; }
  if (dz >= 0) { tzmin = (zmin - oz)/dz; tzmax = (zmax - oz)/dz; sgn[2] = -1; }
  else         { tzmin = (zmax - oz)/dz; tzmax = (zmin - oz)/dz; sgn[2] =  1; }
  if (txmin > tymin) { tmin = txmin; axmin = 0; }
  else               { tmin = tymin; axmin = 1; }
  if (tzmin > tmin)  { tmin = tzmin; axmin = 2; }
  if (txmax < tymax) { tmax = txmax; axmax = 0; }
  else               { tmax = tymax; axmax = 1; }
  if (tzmax < tmax)  { tmax = tzmax; axmax = 2; }
  if (tmin >= tmax)
    return AIR_FALSE;
  *tP = tmin;
  *axP = axmin;
  *dirP = sgn[axmin];
  if (!AIR_IN_CL(ray->neer, tmin, ray->faar)) {
    *tP = tmax;
    *axP = axmax;
    *dirP = -sgn[axmax];
    if (!AIR_IN_CL(ray->neer, tmax, ray->faar)) {
      return AIR_FALSE;
    }
  }
  return AIR_TRUE;
}
コード例 #13
0
ファイル: enum.c プロジェクト: SCIInstitute/Cleaver
/*
** _airEnumIndex()
**
** given an enum "enm" and value "val", return the index into enm->str[] 
** and enm->desc[] which correspond to that value.  To be safe, when
** given an invalid enum value, we return zero.
*/
unsigned int
_airEnumIndex(const airEnum *enm, int val) {
  unsigned int ii, ret;

  ret = 0;
  if (enm->val) {
    for (ii=1; ii<=enm->M; ii++) {
      if (val == enm->val[ii]) {
        ret = ii;
        break;
      }
    }
  } else {
    ret = AIR_IN_CL(0, val, (int)(enm->M)) ? val : 0; /* HEY scrutinize cast */
  }
  return ret;
}
コード例 #14
0
ファイル: axis.c プロジェクト: SCIInstitute/Cleaver
/*
******** nrrdAxisInfoCopy()
**
** For copying all the per-axis peripheral information.  Takes a
** permutation "map"; map[d] tells from which axis in input should the
** output axis d copy its information.  The length of this permutation
** array is nout->dim.  If map is NULL, the identity permutation is
** assumed.  If map[i]==-1 for any i in [0,dim-1], then nothing is
** copied into axis i of output.  The "bitflag" field controls which
** per-axis fields will NOT be copied; if bitflag==0, then all fields
** are copied.  The value of bitflag should be |'s of NRRD_AXIS_INFO_*
** defines.
**
** Decided to Not use Biff, since many times map will be NULL, in
** which case the only error is getting a NULL nrrd, or an invalid map
** permutation, which will probably be unlikely given the contexts in
** which this is called.  For the paranoid, the integer return value
** indicates error.
**
** Sun Feb 27 21:12:57 EST 2005: decided to allow nout==nin, so now
** use a local array of NrrdAxisInfo as buffer.
*/
int
nrrdAxisInfoCopy(Nrrd *nout, const Nrrd *nin, const int *axmap, int bitflag) {
  NrrdAxisInfo axisBuffer[NRRD_DIM_MAX];
  const NrrdAxisInfo *axis;
  unsigned int from, axi;
  
  if (!(nout && nin)) {
    return 1;
  }
  if (axmap) {
    for (axi=0; axi<nout->dim; axi++) {
      if (-1 == axmap[axi]) {
        continue;
      }
      if (!AIR_IN_CL(0, axmap[axi], (int)nin->dim-1)) {
        return 3;
      }
    }
  }
  if (nout == nin) {
    /* copy axis info to local buffer */
    for (axi=0; axi<nin->dim; axi++) {
      _nrrdAxisInfoNewInit(axisBuffer + axi);
      _nrrdAxisInfoCopy(axisBuffer + axi, nin->axis + axi, bitflag);
    }
    axis = axisBuffer;
  } else {
    axis = nin->axis;
  }
  for (axi=0; axi<nout->dim; axi++) {
    if (axmap && -1 == axmap[axi]) {
      /* for this axis, we don't touch a thing */
      continue;
    }
    from = axmap ? (unsigned int)axmap[axi] : axi;
    _nrrdAxisInfoCopy(nout->axis + axi, axis + from, bitflag);
  }
  if (nout == nin) {
    /* free dynamically allocated stuff */
    for (axi=0; axi<nin->dim; axi++) {
      _nrrdAxisInfoInit(axisBuffer + axi);
    }
  }
  return 0;
}
コード例 #15
0
ファイル: stack.c プロジェクト: CIBC-Internal/teem
double
gageStackWtoI(gageContext *ctx, double swrl, int *outside) {
  double si;

  if (ctx && ctx->parm.stackUse && outside) {
    unsigned int sidx;
    if (swrl < ctx->stackPos[0]) {
      /* we'll extrapolate from stackPos[0] and [1] */
      sidx = 0;
      *outside = AIR_TRUE;
    } else if (swrl > ctx->stackPos[ctx->pvlNum-2]) {
      /* extrapolate from stackPos[ctx->pvlNum-3] and [ctx->pvlNum-2];
         gageStackPerVolumeAttach ensures that we there are at least two
         blurrings pvls & one base pvl ==> pvlNum >= 3 ==> pvlNum-3 >= 0 */
      sidx = ctx->pvlNum-3;
      *outside = AIR_TRUE;
    } else {
      /* HEY: stupid linear search */
      for (sidx=0; sidx<ctx->pvlNum-2; sidx++) {
        if (AIR_IN_CL(ctx->stackPos[sidx], swrl, ctx->stackPos[sidx+1])) {
          break;
        }
      }
      if (sidx == ctx->pvlNum-2) {
        /* search failure */
        *outside = AIR_FALSE;
        return AIR_NAN;
      }
      *outside = AIR_FALSE;
    }
    si = AIR_AFFINE(ctx->stackPos[sidx], swrl, ctx->stackPos[sidx+1],
                    sidx, sidx+1);
  } else {
    si = AIR_NAN;
  }
  return si;
}
コード例 #16
0
ファイル: filter.c プロジェクト: SCIInstitute/Cleaver
/*
** _gageLocationSet
**
** updates probe location in general context, and things which
** depend on it:
** fsl, fw
**
** (_xi,_yi,_zi) is *index* space position in the volume
** _si is the index-space position in the stack, the value is ignored
** if there is no stack behavior 
**
** does NOT use biff, but returns 1 on error and 0 if all okay
** Currently only error is probing outside volume, which sets
** ctx->errNum and sprints message into ctx->errStr.
*/
int
_gageLocationSet(gageContext *ctx, double _xi, double _yi, double _zi,
                 double stackIdx) {
  char me[]="_gageProbeLocationSet";
  unsigned int top[3];  /* "top" x, y, z: highest valid index in volume */
  int xi, yi, zi;       /* computed integral positions in volume */
  double xf, yf, zf, min, max[3];

  top[0] = ctx->shape->size[0] - 1;
  top[1] = ctx->shape->size[1] - 1;
  top[2] = ctx->shape->size[2] - 1;
  if (nrrdCenterNode == ctx->shape->center) {
    min = 0;
    max[0] = top[0];
    max[1] = top[1];
    max[2] = top[2];
  } else {
    min = -0.5;
    max[0] = top[0] + 0.5;
    max[1] = top[1] + 0.5;
    max[2] = top[2] + 0.5;
  }
  if (!( AIR_IN_CL(min, _xi, max[0]) && 
         AIR_IN_CL(min, _yi, max[1]) && 
         AIR_IN_CL(min, _zi, max[2]) )) {
    sprintf(ctx->errStr, "%s: position (%g,%g,%g) outside (%s-centered) "
            "bounds [%g,%g]x[%g,%g]x[%g,%g]",
            me, _xi, _yi, _zi,
            airEnumStr(nrrdCenter, ctx->shape->center),
            min, max[0], min, max[1], min, max[2]);
    ctx->errNum = gageErrBoundsSpace;
    return 1;
  }
  if (ctx->parm.stackUse) {
    if (!( AIR_IN_CL(0, stackIdx, ctx->pvlNum-2) )) {
      sprintf(ctx->errStr, "%s: stack position %g outside (%s-centered) "
              "bounds [0,%u]", me,
              stackIdx, airEnumStr(nrrdCenter, nrrdCenterNode), ctx->pvlNum-2);
      ctx->errNum = gageErrBoundsStack;
      return 1;
    }
  }
  /* even after all these years, GLK is still tweaking this stuff ...
  if (nrrdCenterCell == ctx->shape->center) {
    xi = AIR_CAST(unsigned int, _xi+1) - 1; 
    yi = AIR_CAST(unsigned int, _yi+1) - 1;
    zi = AIR_CAST(unsigned int, _zi+1) - 1;
    xi -= (xi == max[0]);
    yi -= (yi == max[1]);
    zi -= (zi == max[2]);
  } else {
    xi = AIR_CAST(unsigned int, _xi);
    yi = AIR_CAST(unsigned int, _yi);
    zi = AIR_CAST(unsigned int, _zi);
  }
  */
  xi = AIR_CAST(unsigned int, _xi); /* for cell-centered, [-0.5,0] --> 0 */
  yi = AIR_CAST(unsigned int, _yi);
  zi = AIR_CAST(unsigned int, _zi);
  xi -= (xi == max[0]);  /* only can kick in for node-centered */
  yi -= (yi == max[1]);
  zi -= (zi == max[2]);
  xf = _xi - xi;
  yf = _yi - yi;
  zf = _zi - zi;
  ctx->point.xi = xi;
  ctx->point.yi = yi;
  ctx->point.zi = zi;
  if (ctx->verbose > 2) {
    fprintf(stderr, "%s: \n"
            "        pos (% 15.7f,% 15.7f,% 15.7f) \n"
            "        -> i(%5d,%5d,%5d) \n"
            "         + f(% 15.7f,% 15.7f,% 15.7f) \n",
            me, _xi, _yi, _zi, xi, yi, zi, xf, yf, zf);
  }

  /* HEY: the position optimization has to be turned off in the context
     of stacks; Raul found this bug using vprobe */
  if (ctx->parm.stackUse
      || !( ctx->point.xf == xf &&
            ctx->point.yf == yf &&
            ctx->point.zf == zf )) {
    ctx->point.xf = xf;
    ctx->point.yf = yf;
    ctx->point.zf = zf;
    /* these may take some time (especially if using renormalization),
       hence the conditional above */
    _gageFslSet(ctx);
    _gageFwSet(ctx);
  }

  if (ctx->parm.stackUse) {
    double sum;
    unsigned int ii;
    NrrdKernelSpec *sksp;

    /* node-centered sampling of stack indices from 0 to ctx->pvlNum-2 */
    for (ii=0; ii<ctx->pvlNum-1; ii++) {
      ctx->stackFslw[ii] = stackIdx - ii;
      if (ctx->verbose > 2) {
        fprintf(stderr, "%s: ctx->stackFslw[%u] (fsl) = %g\n", 
                me, ii, ctx->stackFslw[ii]);
      }
    }
    sksp = ctx->ksp[gageKernelStack];
    sksp->kernel->evalN_d(ctx->stackFslw, ctx->stackFslw,
                          ctx->pvlNum-1, sksp->parm);
    if (ctx->verbose > 2) {
      for (ii=0; ii<ctx->pvlNum-1; ii++) {
        fprintf(stderr, "%s: ctx->stackFslw[%u] (fw) = %g\n", 
                me, ii, ctx->stackFslw[ii]);
      }
    }
  
    /* HEY: we really are quite far from implementing arbitrary
       nrrdBoundary behaviors here!!!! */
    /* HEY: surprise: gageParmStackRenormalize does NOT control this,
       since that refers to *derivative* normalization */
    /* renormalize weights */
    sum = 0;
    for (ii=0; ii<ctx->pvlNum-1; ii++) {
      sum += ctx->stackFslw[ii];
    }
    if (!sum) {
      sprintf(ctx->errStr, "%s: integral of stackFslw[] is zero, "
              "can't do stack reconstruction", me);
      ctx->errNum = gageErrStackIntegral;
      return 1;
    }
    for (ii=0; ii<ctx->pvlNum-1; ii++) {
      ctx->stackFslw[ii] /= sum;
    }
    if (ctx->verbose > 2) {
      for (ii=0; ii<ctx->pvlNum-1; ii++) {
        fprintf(stderr, "%s: ctx->stackFslw[%u] (fw) = %g\n", 
                me, ii, ctx->stackFslw[ii]);
      }
    }

    /* fix derivative kernel weights for stack. Have to reconstruct
       the world-space stack position from stackFrac and stackBaseIdx */
    if (ctx->parm.stackRenormalize) {
      unsigned int kidx, fd, j, stackBaseIdx;
      double stackFrac, scl, *fwX, *fwY, *fwZ;

      stackBaseIdx = AIR_CAST(unsigned int, stackIdx);
      stackBaseIdx -= (stackBaseIdx == ctx->pvlNum-1);
      stackFrac = stackIdx - stackBaseIdx;
      scl = AIR_AFFINE(0.0, stackFrac, 1.0,
                       ctx->stackPos[stackBaseIdx],
                       ctx->stackPos[stackBaseIdx+1]);
      fd = 2*ctx->radius;
      kidx = gageKernel11;
      fwX = ctx->fw + 0 + fd*(0 + 3*kidx);
      fwY = ctx->fw + 0 + fd*(1 + 3*kidx);
      fwZ = ctx->fw + 0 + fd*(2 + 3*kidx);
      for (j=0; j<fd; j++) {
        fwX[j] *= scl;
        fwY[j] *= scl;
        fwZ[j] *= scl;
      }
      kidx = gageKernel22;
      fwX = ctx->fw + 0 + fd*(0 + 3*kidx);
      fwY = ctx->fw + 0 + fd*(1 + 3*kidx);
      fwZ = ctx->fw + 0 + fd*(2 + 3*kidx);
      for (j=0; j<fd; j++) {
        fwX[j] *= scl*scl;
        fwY[j] *= scl*scl;
        fwZ[j] *= scl*scl;
      }
    }
コード例 #17
0
ファイル: resampleNrrd.c プロジェクト: rblake/seg3d2
/*
** _nrrdResampleMakeWeightIndex()
**
** _allocate_ and fill the arrays of indices and weights that are
** needed to process all the scanlines along a given axis; also
** be so kind as to set the sampling ratio (<1: downsampling,
** new sample spacing larger, >1: upsampling, new sample spacing smaller)
**
** returns "dotLen", the number of input samples which are required
** for resampling this axis, or 0 if there was an error.  Uses biff.
*/
int
_nrrdResampleMakeWeightIndex(nrrdResample_t **weightP,
                             int **indexP, double *ratioP,
                             const Nrrd *nin, const NrrdResampleInfo *info,
                             unsigned int ai) {
  char me[]="_nrrdResampleMakeWeightIndex", err[BIFF_STRLEN];
  int sizeIn, sizeOut, center, dotLen, halfLen, *index, base, idx;
  nrrdResample_t minIn, maxIn, minOut, maxOut, spcIn, spcOut,
    ratio, support, integral, pos, idxD, wght;
  nrrdResample_t *weight;
  double parm[NRRD_KERNEL_PARMS_NUM];

  int e, i;

  if (!(info->kernel[ai])) {
    sprintf(err, "%s: don't see a kernel for dimension %d", me, ai);
    biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
  }

  center = _nrrdCenter(nin->axis[ai].center);
  sizeIn = nin->axis[ai].size;
  sizeOut = info->samples[ai];
  minIn = AIR_CAST(nrrdResample_t, nin->axis[ai].min);
  maxIn = AIR_CAST(nrrdResample_t, nin->axis[ai].max);
  minOut = AIR_CAST(nrrdResample_t, info->min[ai]);
  maxOut = AIR_CAST(nrrdResample_t, info->max[ai]);
  spcIn = NRRD_SPACING(center, minIn, maxIn, sizeIn);
  spcOut = NRRD_SPACING(center, minOut, maxOut, sizeOut);
  *ratioP = ratio = spcIn/spcOut;
  support = AIR_CAST(nrrdResample_t,
                     info->kernel[ai]->support(info->parm[ai]));
  integral = AIR_CAST(nrrdResample_t,
                      info->kernel[ai]->integral(info->parm[ai]));
  /*
  fprintf(stderr, 
          "!%s(%d): size{In,Out} = %d, %d, support = %f; ratio = %f\n", 
          me, d, sizeIn, sizeOut, support, ratio);
  */
  if (ratio > 1) {
    /* if upsampling, we need only as many samples as needed for
       interpolation with the given kernel */
    dotLen = (int)(2*ceil(support));
  } else {
    /* if downsampling, we need to use all the samples covered by
       the stretched out version of the kernel */
    if (info->cheap) {
      dotLen = (int)(2*ceil(support));
    } else {
      dotLen = (int)(2*ceil(support/ratio));
    }
  }
  /*
  fprintf(stderr, "!%s(%d): dotLen = %d\n", me, d, dotLen);
  */

  weight = (nrrdResample_t*)calloc(sizeOut*dotLen, sizeof(nrrdResample_t));
  index = (int*)calloc(sizeOut*dotLen, sizeof(int));
  if (!(weight && index)) {
    sprintf(err, "%s: can't allocate weight and index arrays", me);
    biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
  }

  /* calculate sample locations and do first pass on indices */
  halfLen = dotLen/2;
  for (i=0; i<sizeOut; i++) {
    pos = AIR_CAST(nrrdResample_t,
                   NRRD_POS(center, minOut, maxOut, sizeOut, i));
    idxD = AIR_CAST(nrrdResample_t,
                    NRRD_IDX(center, minIn, maxIn, sizeIn, pos));
    base = (int)floor(idxD) - halfLen + 1;
    for (e=0; e<dotLen; e++) {
      index[e + dotLen*i] = base + e;
      weight[e + dotLen*i] = idxD - index[e + dotLen*i];
    }
    /* ********
    if (!i) {
      fprintf(stderr, "%s: sample locations:\n", me);
    }
    fprintf(stderr, "%s: %d (sample locations)\n        ", me, i);
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
    }
    fprintf(stderr, "\n");
    ******** */
  }

  /*
  nrrdBoundaryPad,      1: fill with some user-specified value
  nrrdBoundaryBleed,    2: copy the last/first value out as needed
  nrrdBoundaryWrap,     3: wrap-around
  nrrdBoundaryWeight,   4: normalize the weighting on the existing samples;
                        ONLY sensible for a strictly positive kernel
                        which integrates to unity (as in blurring)
  */

  /* figure out what to do with the out-of-range indices */
  for (i=0; i<dotLen*sizeOut; i++) {
    idx = index[i];
    if (!AIR_IN_CL(0, idx, sizeIn-1)) {
      switch(info->boundary) {
      case nrrdBoundaryPad:
      case nrrdBoundaryWeight:  /* this will be further handled later */
        idx = sizeIn;
        break;
      case nrrdBoundaryBleed:
        idx = AIR_CLAMP(0, idx, sizeIn-1);
        break;
      case nrrdBoundaryWrap:
        idx = AIR_MOD(idx, sizeIn);
        break;
      default:
        sprintf(err, "%s: boundary behavior %d unknown/unimplemented", 
                me, info->boundary);
        biffAdd(NRRD, err); *weightP = NULL; *indexP = NULL; return 0;
      }
      index[i] = idx;
    }
  }

  /* run the sample locations through the chosen kernel.  We play a 
     sneaky trick on the kernel parameter 0 in case of downsampling
     to create the blurring of the old index space, but only if !cheap */
  memcpy(parm, info->parm[ai], NRRD_KERNEL_PARMS_NUM*sizeof(double));
  if (ratio < 1 && !(info->cheap)) {
    parm[0] /= ratio;
  }
  info->kernel[ai]->EVALN(weight, weight, dotLen*sizeOut, parm);

  /* ********
  for (i=0; i<sizeOut; i++) {
    fprintf(stderr, "%s: %d (sample weights)\n        ", me, i);
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
    }
    fprintf(stderr, "\n");
  }
  ******** */

  if (nrrdBoundaryWeight == info->boundary) {
    if (integral) {
      /* above, we set to sizeIn all the indices that were out of 
         range.  We now use that to determine the sum of the weights
         for the indices that were in-range */
      for (i=0; i<sizeOut; i++) {
        wght = 0;
        for (e=0; e<dotLen; e++) {
          if (sizeIn != index[e + dotLen*i]) {
            wght += weight[e + dotLen*i];
          }
        }
        for (e=0; e<dotLen; e++) {
          idx = index[e + dotLen*i];
          if (sizeIn != idx) {
            weight[e + dotLen*i] *= integral/wght;
          } else {
            weight[e + dotLen*i] = 0;
          }
        }
      }
    }
  } else {
    /* try to remove ripple/grating on downsampling */
    /* if (ratio < 1 && info->renormalize && integral) { */
    if (info->renormalize && integral) {
      for (i=0; i<sizeOut; i++) {
        wght = 0;
        for (e=0; e<dotLen; e++) {
          wght += weight[e + dotLen*i];
        }
        if (wght) {
          for (e=0; e<dotLen; e++) {
            /* this used to normalize the weights so that they summed
               to integral ("*= integral/wght"), which meant that if
               you use a very truncated Gaussian, then your over-all
               image brightness goes down.  This seems very contrary
               to the whole point of renormalization. */
            weight[e + dotLen*i] *= AIR_CAST(nrrdResample_t, 1.0/wght);
          }
        }
      }
    }
  }
  /* ********
  fprintf(stderr, "%s: sample weights:\n", me);
  for (i=0; i<sizeOut; i++) {
    fprintf(stderr, "%s: %d\n        ", me, i);
    wght = 0;
    for (e=0; e<dotLen; e++) {
      fprintf(stderr, "%d/%g ", index[e + dotLen*i], weight[e + dotLen*i]);
      wght += weight[e + dotLen*i];
    }
    fprintf(stderr, " (sum = %g)\n", wght);
  }
  ******** */

  *weightP = weight;
  *indexP = index;
  /*
  fprintf(stderr, "!%s: dotLen = %d\n", me, dotLen);
  */
  return dotLen;
}
コード例 #18
0
/*
** _nrrdSprintFieldInfo
**
** this prints "<prefix><field>: <info>" into *strP (after allocating it for
** big enough, usually with a stupidly big margin of error), in a form
** suitable to be written to NRRD or other image headers.  This will always
** print something (for valid inputs), even stupid <info>s like
** "(unknown endian)".  It is up to the caller to decide which fields
** are worth writing, via _nrrdFieldInteresting().
**
** NOTE: some of these fields make sense in non-NRRD files (e.g. all
** the per-axis information), but many only make sense in NRRD files.
** This is just one example of NRRD-format-specific stuff that is not
** in formatNRRD.c
*/
void
_nrrdSprintFieldInfo(char **strP, const char *prefix,
                     const Nrrd *nrrd, NrrdIoState *nio, int field) {
  static const char me[]="_nrrdSprintFieldInfo";
  char buff[AIR_STRLEN_MED], *fnb, stmp[AIR_STRLEN_SMALL],
    *strtmp=NULL;
  double colvec[NRRD_SPACE_DIM_MAX];
  const char *fs;
  unsigned int ii, dd,
    uintStrlen = 11,
    size_tStrlen = 33,
    doubleStrlen = 513;
  size_t fslen, fdlen, maxl;
  int endi;

  if (!( strP && prefix
         && nrrd
         && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX)
         && AIR_IN_OP(nrrdField_unknown, field, nrrdField_last) )) {
    return;
  }
  /* As of Sun Dec  2 01:57:48 CST 2012 (revision 5832) the only
     places where this function is called is when it has been guarded
     by "if (_nrrdFieldInteresting())" (except for in formatText.c when
     its called on the dimension field, which is always interesting).
     So, the following:

     if (!_nrrdFieldInteresting(nrrd, nio, field)) {
       *strP = airStrdup("");
     }

     was redundant and confusingly created the appearance of a memory
     leak waiting to happen.  We now let the default switch statement
     set *strP to NULL (all the other cases set it), to smoke out
     errors in how this function is called */

  fs = airEnumStr(nrrdField, field);
  fslen = strlen(prefix) + strlen(fs) + strlen(": ") + 1;
  switch (field) {
  case nrrdField_comment:
  case nrrdField_keyvalue:
    fprintf(stderr, "%s: CONFUSION: why are you calling me on \"%s\"?\n", me,
            airEnumStr(nrrdField, nrrdField_comment));
    *strP = airStrdup("");
    break;
  case nrrdField_content:
    strtmp = airOneLinify(airStrdup(nrrd->content));
    *strP = AIR_CALLOC(fslen + strlen(strtmp), char);
    sprintf(*strP, "%s%s: %s", prefix, fs, strtmp);
    airFree(strtmp); strtmp = NULL;
    break;
  case nrrdField_number:
    *strP = AIR_CALLOC(fslen + size_tStrlen, char);
    sprintf(*strP, "%s%s: %s", prefix, fs,
            airSprintSize_t(stmp, nrrdElementNumber(nrrd)));
    break;
  case nrrdField_type:
    *strP = AIR_CALLOC(fslen + strlen(airEnumStr(nrrdType, nrrd->type)), char);
    sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdType, nrrd->type));
    break;
  case nrrdField_block_size:
    *strP = AIR_CALLOC(fslen + size_tStrlen, char);
    sprintf(*strP, "%s%s: %s", prefix, fs,
            airSprintSize_t(stmp, nrrd->blockSize));
    break;
  case nrrdField_dimension:
    *strP = AIR_CALLOC(fslen + uintStrlen, char);
    sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->dim);
    break;
  case nrrdField_space:
    *strP = AIR_CALLOC(fslen
                       + strlen(airEnumStr(nrrdSpace, nrrd->space)), char);
    sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdSpace, nrrd->space));
    break;
  case nrrdField_space_dimension:
    *strP = AIR_CALLOC(fslen + uintStrlen, char);
    sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->spaceDim);
    break;
    /* ---- begin per-axis fields ---- */
  case nrrdField_sizes:
    *strP = AIR_CALLOC(fslen + nrrd->dim*(size_tStrlen + 1), char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      sprintf(buff, " %s", airSprintSize_t(stmp, nrrd->axis[ii].size));
      strcat(*strP, buff);
    }
    break;
  case nrrdField_spacings:
    *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].spacing);
      strcat(*strP, buff);
    }
    break;
  case nrrdField_thicknesses:
    *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].thickness);
      strcat(*strP, buff);
    }
    break;
  case nrrdField_axis_mins:
    *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].min);
      strcat(*strP, buff);
    }
    break;
  case nrrdField_axis_maxs:
    *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].max);
      strcat(*strP, buff);
    }
    break;
  case nrrdField_space_directions:
    *strP = AIR_CALLOC(fslen
                       + nrrd->dim*nrrd->spaceDim*(doubleStrlen
                                                   + strlen("(,) ")), char);
    sprintf(*strP, "%s%s: ", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim,
                             nrrd->axis[ii].spaceDirection);
      if (ii < nrrd->dim-1) {
        strcat(*strP, " ");
      }
    }
    break;
  case nrrdField_centers:
    fdlen = 0;
    for (ii=0; ii<nrrd->dim; ii++) {
      fdlen += 1 + airStrlen(nrrd->axis[ii].center
                             ? airEnumStr(nrrdCenter, nrrd->axis[ii].center)
                             : NRRD_UNKNOWN);
    }
    *strP = AIR_CALLOC(fslen + fdlen, char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      sprintf(buff, " %s",
              (nrrd->axis[ii].center
               ? airEnumStr(nrrdCenter, nrrd->axis[ii].center)
               : NRRD_UNKNOWN));
      strcat(*strP, buff);
    }
    break;
  case nrrdField_kinds:
    fdlen = 0;
    for (ii=0; ii<nrrd->dim; ii++) {
      fdlen += 1 + airStrlen(nrrd->axis[ii].kind
                             ? airEnumStr(nrrdKind, nrrd->axis[ii].kind)
                             : NRRD_UNKNOWN);
    }
    *strP = AIR_CALLOC(fslen + fdlen, char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      sprintf(buff, " %s",
              (nrrd->axis[ii].kind
               ? airEnumStr(nrrdKind, nrrd->axis[ii].kind)
               : NRRD_UNKNOWN));
      strcat(*strP, buff);
    }
    break;
  case nrrdField_labels:
  case nrrdField_units:
#define LABEL_OR_UNITS (nrrdField_labels == field \
                        ? nrrd->axis[ii].label \
                        : nrrd->axis[ii].units)
    fdlen = 0;
    for (ii=0; ii<nrrd->dim; ii++) {
      /* The "2*" is because at worst every character needs escaping.
         The "+ 3" for the |" "| between each part */
      fdlen += 2*airStrlen(LABEL_OR_UNITS) + 3;
    }
    fdlen += 1; /* for '\0' */
    *strP = AIR_CALLOC(fslen + fdlen, char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->dim; ii++) {
      strcat(*strP, " \"");
      if (airStrlen(nrrd->axis[ii].label)) {
        _nrrdWriteEscaped(NULL, *strP, LABEL_OR_UNITS,
                          "\"", _NRRD_WHITESPACE_NOTAB);
      }
      strcat(*strP, "\"");
    }
#undef LABEL_OR_UNITS
    break;
    /* ---- end per-axis fields ---- */
  case nrrdField_min:
  case nrrdField_max:
    /* we're basically a no-op, now that these fields became meaningless */
    *strP = AIR_CALLOC(fslen + doubleStrlen, char);
    sprintf(*strP, "%s%s: 0.0", prefix, fs);
    strcat(*strP, buff);
    break;
  case nrrdField_old_min:
    *strP = AIR_CALLOC(fslen + doubleStrlen, char);
    sprintf(*strP, "%s%s: ", prefix, fs);
    airSinglePrintf(NULL, buff, "%.17g", nrrd->oldMin);
    strcat(*strP, buff);
    break;
  case nrrdField_old_max:
    *strP = AIR_CALLOC(fslen + doubleStrlen, char);
    sprintf(*strP, "%s%s: ", prefix, fs);
    airSinglePrintf(NULL, buff, "%.17g", nrrd->oldMax);
    strcat(*strP, buff);
    break;
  case nrrdField_endian:
    if (airEndianUnknown != nio->endian) {
      /* we know a specific endianness because either it was recorded as
         part of "unu make -h", or it was set (and data was possibly
         altered) as part of "unu save" */
      endi = nio->endian;
    } else {
      /* we record our current architecture's endian because we're
         going to writing out data */
      endi = airMyEndian();
    }
    *strP = AIR_CALLOC(fslen + strlen(airEnumStr(airEndian, endi)), char);
    sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(airEndian, endi));
    break;
  case nrrdField_encoding:
    *strP = AIR_CALLOC(fslen + strlen(nio->encoding->name), char);
    sprintf(*strP, "%s%s: %s", prefix, fs, nio->encoding->name);
    break;
  case nrrdField_line_skip:
    *strP = AIR_CALLOC(fslen + uintStrlen, char);
    sprintf(*strP, "%s%s: %d", prefix, fs, nio->lineSkip);
    break;
  case nrrdField_byte_skip:
    *strP = AIR_CALLOC(fslen + uintStrlen, char);
    sprintf(*strP, "%s%s: %ld", prefix, fs, nio->byteSkip);
    break;
  case nrrdField_sample_units:
    strtmp = airOneLinify(airStrdup(nrrd->sampleUnits));
    *strP = AIR_CALLOC(fslen + strlen(strtmp), char);
    sprintf(*strP, "%s%s: \"%s\"", prefix, fs, strtmp);
    airFree(strtmp); strtmp = NULL;
    break;
  case nrrdField_space_units:
    fdlen = 0;
    for (ii=0; ii<nrrd->spaceDim; ii++) {
      /* The "2*" is because at worst every character needs escaping.
         See note in formatNRRD.c about how even though its not part
         of the format, we have worst-case scenario of having to
         escape a space units which is nothing but ". The "+ 3" for
         the |" "| between each part */
      fdlen += 2*airStrlen(nrrd->spaceUnits[ii]) + 3;
    }
    fdlen += 1; /* for '\0' */
    *strP = AIR_CALLOC(fslen + fdlen, char);
    sprintf(*strP, "%s%s:", prefix, fs);
    for (ii=0; ii<nrrd->spaceDim; ii++) {
      strcat(*strP, " \"");
      if (airStrlen(nrrd->spaceUnits[ii])) {
        _nrrdWriteEscaped(NULL, *strP, nrrd->spaceUnits[ii],
                          "\"", _NRRD_WHITESPACE_NOTAB);
      }
      strcat(*strP, "\"");
    }
    break;
  case nrrdField_space_origin:
    *strP = AIR_CALLOC(fslen + nrrd->spaceDim*(doubleStrlen
                                               + strlen("(,) ")), char);
    sprintf(*strP, "%s%s: ", prefix, fs);
    _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, nrrd->spaceOrigin);
    break;
  case nrrdField_measurement_frame:
    *strP = AIR_CALLOC(fslen + (nrrd->spaceDim*
                                nrrd->spaceDim*(doubleStrlen
                                                + strlen("(,) "))), char);
    sprintf(*strP, "%s%s: ", prefix, fs);
    for (dd=0; dd<nrrd->spaceDim; dd++) {
      for (ii=0; ii<nrrd->spaceDim; ii++) {
        colvec[ii] = nrrd->measurementFrame[dd][ii];
      }
      _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, colvec);
      if (dd < nrrd->spaceDim-1) {
        strcat(*strP, " ");
      }
    }
    break;
  case nrrdField_data_file:
    /* NOTE: this comes last (nrrdField_data_file is the highest-valued
       member of the nrrdField* enum) because the "LIST" form of the
       data file specification requires that the following lines be
       the filenames */
    /* error checking elsewhere: assumes there is data file info */
    if (nio->dataFNFormat) {
      *strP = AIR_CALLOC(fslen + strlen(nio->dataFNFormat) + 4*uintStrlen,
                         char);
      if (nio->dataFileDim == nrrd->dim-1) {
        sprintf(*strP, "%s%s: %s %d %d %d", prefix, fs, nio->dataFNFormat,
                nio->dataFNMin, nio->dataFNMax, nio->dataFNStep);
      } else {
        sprintf(*strP, "%s%s: %s %d %d %d %u", prefix, fs, nio->dataFNFormat,
                nio->dataFNMin, nio->dataFNMax, nio->dataFNStep,
                nio->dataFileDim);
      }
    } else if (nio->dataFNArr->len > 1) {
コード例 #19
0
ファイル: axis.c プロジェクト: SCIInstitute/Cleaver
/*
** types to pass, one for each dimension:
**           nrrdAxisInfoSize: size_t*
**        nrrdAxisInfoSpacing: double*
**      nrrdAxisInfoThickness: double*
**            nrrdAxisInfoMin: double*
**            nrrdAxisInfoMax: double*
** nrrdAxisInfoSpaceDirection: double*
**         nrrdAxisInfoCenter: int*
**           nrrdAxisInfoKind: int*
**          nrrdAxisInfoLabel: char**
**          nrrdAxisInfoUnits: char**
*/
void
nrrdAxisInfoGet_va(const Nrrd *nrrd, int axInfo, ...) {
  void *buffer[NRRD_DIM_MAX], *ptr;
  _nrrdAxisInfoGetPtrs info;
  unsigned int ai, si;
  va_list ap;
  double svec[NRRD_DIM_MAX][NRRD_SPACE_DIM_MAX];

  if (!( nrrd 
         && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX) 
         && AIR_IN_OP(nrrdAxisInfoUnknown, axInfo, nrrdAxisInfoLast) )) {
    return;
  }

  if (nrrdAxisInfoSpaceDirection != axInfo) {
    info.P = buffer;
    nrrdAxisInfoGet_nva(nrrd, axInfo, info.P);
  } else {
    nrrdAxisInfoGet_nva(nrrd, axInfo, svec);
  }

  va_start(ap, axInfo);
  for (ai=0; ai<nrrd->dim; ai++) {
    ptr = va_arg(ap, void*);
    /*
    printf("!%s(%d): ptr = %lu\n", 
           "nrrdAxisInfoGet", d, (unsigned long)ptr);
    */
    switch (axInfo) {
    case nrrdAxisInfoSize:
      *((size_t*)ptr) = info.ST[ai];
      break;
    case nrrdAxisInfoSpacing:
    case nrrdAxisInfoThickness:
    case nrrdAxisInfoMin:
    case nrrdAxisInfoMax:
      *((double*)ptr) = info.D[ai];
      /* printf("!%s: got double[%d] = %lg\n", "nrrdAxisInfoGet", d,
       *((double*)ptr)); */
      break;
    case nrrdAxisInfoSpaceDirection:
      for (si=0; si<nrrd->spaceDim; si++) {
        ((double*)ptr)[si] = svec[ai][si];
      }
      for (si=nrrd->spaceDim; si<NRRD_SPACE_DIM_MAX; si++) {
        ((double*)ptr)[si] = AIR_NAN;
      }
      break;
    case nrrdAxisInfoCenter:
    case nrrdAxisInfoKind:
      *((int*)ptr) = info.I[ai];
      /* printf("!%s: got int[%d] = %d\n", 
         "nrrdAxisInfoGet", d, *((int*)ptr)); */
      break;
    case nrrdAxisInfoLabel:
    case nrrdAxisInfoUnits:
      /* we DO NOT do the airStrdup() here because this pointer value just
         came from nrrdAxisInfoGet_nva(), which already did the airStrdup() */
      *((char**)ptr) = info.CP[ai];
      /* printf("!%s: got char*[%d] = |%s|\n", "nrrdAxisInfoSet", d, 
       *((char**)ptr)); */
      break;
    }
  }
  va_end(ap);

  return;
}
コード例 #20
0
ファイル: axis.c プロジェクト: SCIInstitute/Cleaver
/*
******** nrrdAxisInfoSet_va()
**
** var args front-end for nrrdAxisInfoSet_nva
**
** types to pass, one for each dimension:
**           nrrdAxisInfoSize: size_t
**        nrrdAxisInfoSpacing: double
**      nrrdAxisInfoThickness: double
**            nrrdAxisInfoMin: double
**            nrrdAxisInfoMax: double
** nrrdAxisInfoSpaceDirection: double*
**         nrrdAxisInfoCenter: int
**           nrrdAxisInfoKind: int
**          nrrdAxisInfoLabel: char*
**          nrrdAxisInfoUnits: char*
*/
void
nrrdAxisInfoSet_va(Nrrd *nrrd, int axInfo, ...) {
  NRRD_TYPE_BIGGEST *buffer[NRRD_DIM_MAX];
  _nrrdAxisInfoSetPtrs info;
  unsigned int ai, si;
  va_list ap;
  double *dp, svec[NRRD_DIM_MAX][NRRD_SPACE_DIM_MAX];

  if (!( nrrd 
         && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX) 
         && AIR_IN_OP(nrrdAxisInfoUnknown, axInfo, nrrdAxisInfoLast) )) {
    return;
  }

  info.P = buffer;
  va_start(ap, axInfo);
  for (ai=0; ai<nrrd->dim; ai++) {
    switch (axInfo) {
    case nrrdAxisInfoSize:
      info.ST[ai] = va_arg(ap, size_t);
      /*
      printf("!%s: got int[%d] = %d\n", "nrrdAxisInfoSet", d, info.I[ai]);
      */
      break;
    case nrrdAxisInfoSpaceDirection:
      dp = va_arg(ap, double*);  /* punting on using info enum */
      /*
      printf("!%s: got dp = %lu\n", "nrrdAxisInfoSet",
             (unsigned long)(dp));
      */
      for (si=0; si<nrrd->spaceDim; si++) {
        /* nrrd->axis[ai].spaceDirection[si] = dp[si]; */
        svec[ai][si] = dp[si];
      }
      for (si=nrrd->spaceDim; si<NRRD_SPACE_DIM_MAX; si++) {
        /* nrrd->axis[ai].spaceDirection[si] = AIR_NAN; */
        svec[ai][si] = dp[si];
      }
      break;
    case nrrdAxisInfoCenter:
    case nrrdAxisInfoKind:
      info.I[ai] = va_arg(ap, int);
      /*
      printf("!%s: got int[%d] = %d\n", 
             "nrrdAxisInfoSet", d, info.I[ai]);
      */
      break;
    case nrrdAxisInfoSpacing:
    case nrrdAxisInfoThickness:
    case nrrdAxisInfoMin:
    case nrrdAxisInfoMax:
      info.D[ai] = va_arg(ap, double);
      /*
      printf("!%s: got double[%d] = %g\n", 
             "nrrdAxisInfoSet", d, info.D[ai]); 
      */
      break;
    case nrrdAxisInfoLabel:
      /* we DO NOT do the airStrdup() here because this pointer value is
         just going to be handed to nrrdAxisInfoSet_nva(), which WILL do the
         airStrdup(); we're not violating the rules for axis labels */
      info.CP[ai] = va_arg(ap, char *);
      /*
      printf("!%s: got char*[%d] = |%s|\n", 
             "nrrdAxisInfoSet", d, info.CP[ai]);
      */
      break;
    case nrrdAxisInfoUnits:
      /* see not above */
      info.CP[ai] = va_arg(ap, char *);
      break;
    }
  }
  va_end(ap);

  if (nrrdAxisInfoSpaceDirection != axInfo) {
    /* now set the quantities which we've gotten from the var args */
    nrrdAxisInfoSet_nva(nrrd, axInfo, info.P);
  } else {
    nrrdAxisInfoSet_nva(nrrd, axInfo, svec);
  }
  
  return;
}
コード例 #21
0
ファイル: write.c プロジェクト: guo2004131/freesurfer
int
nrrdIoStateSet(NrrdIoState *nio, int parm, int value)
{
    char me[]="nrrdIoStateSet", err[BIFF_STRLEN];

    if (!nio)
    {
        sprintf(err, "%s: got NULL pointer", me);
        biffAdd(NRRD, err);
        return 1;
    }
    if (!( AIR_IN_OP(nrrdIoStateUnknown, parm, nrrdIoStateLast) ))
    {
        sprintf(err, "%s: identifier %d not in valid range [%d,%d]", me,
                parm, nrrdIoStateUnknown+1, nrrdIoStateLast-1);
        biffAdd(NRRD, err);
        return 1;
    }
    switch (parm)
    {
    case nrrdIoStateDetachedHeader:
        nio->detachedHeader = !!value;
        break;
    case nrrdIoStateBareText:
        nio->bareText = !!value;
        break;
    case nrrdIoStateCharsPerLine:
        if (value < 40)
        {
            sprintf(err, "%s: %d charsPerLine is awfully small", me, value);
            biffAdd(NRRD, err);
            return 1;
        }
        nio->charsPerLine = value;
        break;
    case nrrdIoStateValsPerLine:
        if (value < 4)
        {
            sprintf(err, "%s: %d valsPerLine is awfully small", me, value);
            biffAdd(NRRD, err);
            return 1;
        }
        nio->valsPerLine = value;
        break;
    case nrrdIoStateSkipData:
        nio->skipData = !!value;
        break;
    case nrrdIoStateKeepNrrdDataFileOpen:
        nio->keepNrrdDataFileOpen = !!value;
        break;
    case nrrdIoStateZlibLevel:
        if (!( AIR_IN_CL(-1, value, 9) ))
        {
            sprintf(err, "%s: zlibLevel %d invalid", me, value);
            biffAdd(NRRD, err);
            return 1;
        }
        nio->zlibLevel = value;
        break;
    case nrrdIoStateZlibStrategy:
        if (!( AIR_IN_OP(nrrdZlibStrategyUnknown, value, nrrdZlibStrategyLast) ))
        {
            sprintf(err, "%s: zlibStrategy %d invalid", me, value);
            biffAdd(NRRD, err);
            return 1;
        }
        nio->zlibStrategy = value;
        break;
    case nrrdIoStateBzip2BlockSize:
        if (!( AIR_IN_CL(-1, value, 9) ))
        {
            sprintf(err, "%s: bzip2BlockSize %d invalid", me, value);
            biffAdd(NRRD, err);
            return 1;
        }
        nio->bzip2BlockSize = value;
        break;
    default:
        fprintf(stderr, "!%s: PANIC: didn't recognize parm %d\n", me, parm);
        exit(1);
    }
    return 0;
}
コード例 #22
0
ファイル: write.c プロジェクト: guo2004131/freesurfer
int
_nrrdFieldInteresting(const Nrrd *nrrd, NrrdIoState *nio, int field)
{
    int ret;
    unsigned int ai;

    if (!( nrrd
            && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX)
            && nio
            && nio->encoding
            && AIR_IN_OP(nrrdField_unknown, field, nrrdField_last) ))
    {
        return 0;
    }

    ret = 0;
    switch (field)
    {
    case nrrdField_comment:
        /* comments and key/value pairs are always handled differently (by
           being printed explicity), so they are never "interesting" */
        break;
    case nrrdField_content:
        ret = !!(airStrlen(nrrd->content));
        break;
    case nrrdField_number:
        /* "number" is entirely redundant with "sizes", which is a
           required field.  Absolutely nothing is lost in eliding "number"
           from the header, so "number" is NEVER interesting.  Should this
           judgement later be found in error, this is the one place where
           the policy change can be implemented */
        break;
    case nrrdField_type:
        /* this is vital */
        ret = 1;
        break;
    case nrrdField_block_size:
        ret = (nrrdTypeBlock == nrrd->type);
        break;
    case nrrdField_dimension:
        /* this is vital */
        ret = 1;
        break;
    case nrrdField_space:
        /* its interesting if its known */
        ret = (nrrdSpaceUnknown != nrrd->space);
        break;
    case nrrdField_space_dimension:
        /* its interesting if its non-zero and if space is not known */
        ret = (nrrd->spaceDim > 0 && nrrdSpaceUnknown == nrrd->space);
        break;
    case nrrdField_sizes:
        /* this is vital */
        ret = 1;
        break;
    case nrrdField_spacings:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= AIR_EXISTS(nrrd->axis[ai].spacing);
        }
        break;
    case nrrdField_thicknesses:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= AIR_EXISTS(nrrd->axis[ai].thickness);
        }
        break;
    case nrrdField_axis_mins:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= AIR_EXISTS(nrrd->axis[ai].min);
        }
        break;
    case nrrdField_axis_maxs:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= AIR_EXISTS(nrrd->axis[ai].max);
        }
        break;
    case nrrdField_space_directions:
        ret = nrrd->spaceDim > 0;
        break;
    case nrrdField_centers:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= (nrrdCenterUnknown != nrrd->axis[ai].center);
        }
        break;
    case nrrdField_kinds:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= (nrrdKindUnknown != nrrd->axis[ai].kind);
        }
        break;
    case nrrdField_labels:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= !!(airStrlen(nrrd->axis[ai].label));
        }
        break;
    case nrrdField_units:
        for (ai=0; ai<nrrd->dim; ai++)
        {
            ret |= !!(airStrlen(nrrd->axis[ai].units));
        }
        break;
    case nrrdField_min:
    case nrrdField_max:
        /* these no longer exist in the Nrrd struct; we never write them */
        ret = AIR_FALSE;
        break;
    case nrrdField_old_min:
        ret = AIR_EXISTS(nrrd->oldMin);
        break;
    case nrrdField_old_max:
        ret = AIR_EXISTS(nrrd->oldMax);
        break;
    case nrrdField_endian:
        ret = nio->encoding->endianMatters && 1 < nrrdElementSize(nrrd);
        break;
    case nrrdField_encoding:
        /* this is vital */
        ret = 1;
        break;
    case nrrdField_line_skip:
        ret = nio->lineSkip > 0;
        break;
    case nrrdField_byte_skip:
        ret = nio->byteSkip != 0;
        break;
    case nrrdField_keyvalue:
        /* comments and key/value pairs are always handled differently (by
           being printed explicity), so they are never "interesting" */
        break;
    case nrrdField_sample_units:
        ret = airStrlen(nrrd->sampleUnits);
        break;
    case nrrdField_space_units:
        for (ai=0; ai<nrrd->spaceDim; ai++)
        {
            ret |= !!(airStrlen(nrrd->spaceUnits[ai]));
        }
        break;
    case nrrdField_space_origin:
        /* we're trusting other validity checks to ensure that
           all the coeffs exist or not, together */
        ret = (nrrd->spaceDim > 0
               && AIR_EXISTS(nrrd->spaceOrigin[0]));
        break;
    case nrrdField_measurement_frame:
        /* we're trusting other validity checks to ensure that
           all the coeffs exist or not, together */
        ret = (nrrd->spaceDim > 0
               && AIR_EXISTS(nrrd->measurementFrame[0][0]));
        break;
    case nrrdField_data_file:
        /* detached header was either requested or is required */
        ret = (nio->detachedHeader
               || nio->dataFNFormat
               || nio->dataFNArr->len > 1);
        break;
    }

    return ret;
}
コード例 #23
0
ファイル: histogram.c プロジェクト: sinkpoint/hodaie-teem
/*
******** nrrdHistoAxis
**
** replace scanlines along one scanline with a histogram of the scanline
**
** this looks at nin->min and nin->max to see if they are both non-NaN.
** If so, it uses these as the range of the histogram, otherwise it
** finds the min and max present in the volume
**
** By its very nature, and by the simplicity of this implemention,
** this can be a slow process due to terrible memory locality.  User
** may want to permute axes before and after this, but that can be
** slow too...  
*/
int
nrrdHistoAxis(Nrrd *nout, const Nrrd *nin, const NrrdRange *_range, 
              unsigned int hax, size_t bins, int type) {
  static const char me[]="nrrdHistoAxis", func[]="histax";
  int map[NRRD_DIM_MAX];
  unsigned int ai, hidx;
  size_t szIn[NRRD_DIM_MAX], szOut[NRRD_DIM_MAX], size[NRRD_DIM_MAX],
    coordIn[NRRD_DIM_MAX], coordOut[NRRD_DIM_MAX];
  size_t I, hI, num;
  double val, count;
  airArray *mop;
  NrrdRange *range;

  if (!(nin && nout)) {
    biffAddf(NRRD, "%s: got NULL pointer", me);
    return 1;
  }
  if (nout == nin) {
    biffAddf(NRRD, "%s: nout==nin disallowed", me);
    return 1;
  }
  if (!(bins > 0)) {
    biffAddf(NRRD, "%s: bins value (" _AIR_SIZE_T_CNV ") invalid", me, bins);
    return 1;
  }
  if (airEnumValCheck(nrrdType, type) || nrrdTypeBlock == type) {
    biffAddf(NRRD, "%s: invalid nrrd type %d", me, type);
    return 1;
  }
  if (!( hax <= nin->dim-1 )) {
    biffAddf(NRRD, "%s: axis %d is not in range [0,%d]",
             me, hax, nin->dim-1);
    return 1;
  }
  mop = airMopNew();
  if (_range) {
    range = nrrdRangeCopy(_range);
    nrrdRangeSafeSet(range, nin, nrrdBlind8BitRangeState);
  } else {
    range = nrrdRangeNewSet(nin, nrrdBlind8BitRangeState);
  }
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, size);
  size[hax] = bins;
  if (nrrdMaybeAlloc_nva(nout, type, nin->dim, size)) {
    biffAddf(NRRD, "%s: failed to alloc output nrrd", me);
    airMopError(mop); return 1;
  }
  
  /* copy axis information */
  for (ai=0; ai<nin->dim; ai++) {
    map[ai] = ai != hax ? (int)ai : -1;
  }
  nrrdAxisInfoCopy(nout, nin, map, NRRD_AXIS_INFO_NONE);
  /* axis hax now has to be set manually */
  nout->axis[hax].size = bins;
  nout->axis[hax].spacing = AIR_NAN; /* min and max convey the information */
  nout->axis[hax].thickness = AIR_NAN;
  nout->axis[hax].min = range->min;
  nout->axis[hax].max = range->max;
  nout->axis[hax].center = nrrdCenterCell;
  if (nin->axis[hax].label) {
    nout->axis[hax].label = (char *)calloc(strlen("histax()")
                                           + strlen(nin->axis[hax].label)
                                           + 1, sizeof(char));
    if (nout->axis[hax].label) {
      sprintf(nout->axis[hax].label, "histax(%s)", nin->axis[hax].label);
    } else {
      biffAddf(NRRD, "%s: couldn't allocate output label", me);
      airMopError(mop); return 1;
    }
  } else {
    nout->axis[hax].label = NULL;
  }
  if (!nrrdStateKindNoop) {
    nout->axis[hax].kind = nrrdKindDomain;
  }

  /* the skinny: we traverse the input samples in linear order, and
     increment the bin in the histogram for the scanline we're in.
     This is not terribly clever, and the memory locality is a
     disaster */
  nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, szIn);
  nrrdAxisInfoGet_nva(nout, nrrdAxisInfoSize, szOut);
  memset(coordIn, 0, NRRD_DIM_MAX*sizeof(size_t));
  num = nrrdElementNumber(nin);
  for (I=0; I<num; I++) {
    /* get input nrrd value and compute its histogram index */
    val = nrrdDLookup[nin->type](nin->data, I);
    if (AIR_EXISTS(val) && AIR_IN_CL(range->min, val, range->max)) {
      hidx = airIndex(range->min, val, range->max, AIR_CAST(unsigned int, bins));
      memcpy(coordOut, coordIn, nin->dim*sizeof(size_t));
      coordOut[hax] = (unsigned int)hidx;
      NRRD_INDEX_GEN(hI, coordOut, szOut, nout->dim);
      count = nrrdDLookup[nout->type](nout->data, hI);
      count = nrrdDClamp[nout->type](count + 1);
      nrrdDInsert[nout->type](nout->data, hI, count);
    }
    NRRD_COORD_INCR(coordIn, szIn, nin->dim, 0);
  }
コード例 #24
0
ファイル: rays.c プロジェクト: ryanfb/teem-parallel
void *
_hooverThreadBody(void *_arg) {
  _hooverThreadArg *arg;
  void *thread;
  int ret,               /* to catch return values from callbacks */
    sampleI,             /* which sample we're on */
    inside,              /* we're inside the volume */
    vI, uI;              /* integral coords in image */
  double tmp,
    mm,                  /* lowest position in index space, for all axes */
    Mx, My, Mz,          /* highest position in index space on each axis */
    u, v,                /* floating-point coords in image */
    uvScale,             /* how to scale (u,v) to go from image to 
                            near plane, according to ortho or perspective */
    lx, ly, lz,          /* half edge-lengths of volume */
    rayLen=0,            /* length of segment formed by ray line intersecting
                            the near and far clipping planes */
    rayT,                /* current position along ray (world-space) */
    rayDirW[3],          /* unit-length ray direction (world-space) */
    rayDirI[3],          /* rayDirW transformed into index space;
                            not unit length, but a unit change in
                            world space along rayDirW translates to
                            this change in index space along rayDirI */
    rayPosW[3],          /* current ray location (world-space) */
    rayPosI[3],          /* current ray location (index-space) */
    rayStartW[3],        /* ray start on near plane (world-space) */
    rayStartI[3],        /* ray start on near plane (index-space) */
    rayStep,             /* distance between samples (world-space) */
    vOff[3], uOff[3];    /* offsets in arg->ec->wU and arg->ec->wV
                            directions towards start of ray */

  arg = (_hooverThreadArg *)_arg;
  if ( (ret = (arg->ctx->threadBegin)(&thread, 
                                      arg->render, 
                                      arg->ctx->user,
                                      arg->whichThread)) ) {
    arg->errCode = ret;
    arg->whichErr = hooverErrThreadBegin;
    return arg;
  }
  lx = arg->ec->volHLen[0];
  ly = arg->ec->volHLen[1];
  lz = arg->ec->volHLen[2];
  if (nrrdCenterNode == arg->ctx->volCentering) {
    mm = 0;
    Mx = arg->ctx->volSize[0]-1;
    My = arg->ctx->volSize[1]-1;
    Mz = arg->ctx->volSize[2]-1;
  } else {
    mm = -0.5;
    Mx = arg->ctx->volSize[0]-0.5;
    My = arg->ctx->volSize[1]-0.5;
    Mz = arg->ctx->volSize[2]-0.5;
  }
  
  if (arg->ctx->cam->orthographic) {
    ELL_3V_COPY(rayDirW, arg->ctx->cam->N);
    rayDirI[0] = AIR_DELTA(-lx, rayDirW[0], lx, mm, Mx);
    rayDirI[1] = AIR_DELTA(-ly, rayDirW[1], ly, mm, My);
    rayDirI[2] = AIR_DELTA(-lz, rayDirW[2], lz, mm, Mz);
    rayLen = arg->ctx->cam->vspFaar - arg->ctx->cam->vspNeer;
    uvScale = 1.0;
  } else {
    uvScale = arg->ctx->cam->vspNeer/arg->ctx->cam->vspDist;
  }

  while (1) {
    /* the work assignment is simply the next scanline to be rendered:
       the result of all this is setting vI */
    if (arg->ctx->workMutex) {
      airThreadMutexLock(arg->ctx->workMutex);
    }
    vI = arg->ctx->workIdx;
    if (arg->ctx->workIdx < arg->ctx->imgSize[1]) {
      arg->ctx->workIdx += 1;
    }
    if (arg->ctx->workMutex) {
      airThreadMutexUnlock(arg->ctx->workMutex);
    }
    if (vI == arg->ctx->imgSize[1]) {
      /* we're done! */
      break;
    }

    if (nrrdCenterCell == arg->ctx->imgCentering) {
      v = uvScale*AIR_AFFINE(-0.5, vI, arg->ctx->imgSize[1]-0.5,
                             arg->ctx->cam->vRange[0],
                             arg->ctx->cam->vRange[1]);
    } else {
      v = uvScale*AIR_AFFINE(0.0, vI, arg->ctx->imgSize[1]-1.0,
                             arg->ctx->cam->vRange[0],
                             arg->ctx->cam->vRange[1]);
    }
    ELL_3V_SCALE(vOff, v, arg->ctx->cam->V);
    for (uI=0; uI<arg->ctx->imgSize[0]; uI++) {
      if (nrrdCenterCell == arg->ctx->imgCentering) {
        u = uvScale*AIR_AFFINE(-0.5, uI, arg->ctx->imgSize[0]-0.5,
                               arg->ctx->cam->uRange[0],
                               arg->ctx->cam->uRange[1]);
      } else {
        u = uvScale*AIR_AFFINE(0.0, uI, arg->ctx->imgSize[0]-1.0,
                               arg->ctx->cam->uRange[0],
                               arg->ctx->cam->uRange[1]);
      }
      ELL_3V_SCALE(uOff, u, arg->ctx->cam->U);
      ELL_3V_ADD3(rayStartW, uOff, vOff, arg->ec->rayZero);
      rayStartI[0] = AIR_AFFINE(-lx, rayStartW[0], lx, mm, Mx);
      rayStartI[1] = AIR_AFFINE(-ly, rayStartW[1], ly, mm, My);
      rayStartI[2] = AIR_AFFINE(-lz, rayStartW[2], lz, mm, Mz);
      if (!arg->ctx->cam->orthographic) {
        ELL_3V_SUB(rayDirW, rayStartW, arg->ctx->cam->from);
        ELL_3V_NORM(rayDirW, rayDirW, tmp);
        rayDirI[0] = AIR_DELTA(-lx, rayDirW[0], lx, mm, Mx);
        rayDirI[1] = AIR_DELTA(-ly, rayDirW[1], ly, mm, My);
        rayDirI[2] = AIR_DELTA(-lz, rayDirW[2], lz, mm, Mz);
        rayLen = ((arg->ctx->cam->vspFaar - arg->ctx->cam->vspNeer)/
                  ELL_3V_DOT(rayDirW, arg->ctx->cam->N));
      }
      if ( (ret = (arg->ctx->rayBegin)(thread,
                                       arg->render,
                                       arg->ctx->user,
                                       uI, vI, rayLen,
                                       rayStartW, rayStartI,
                                       rayDirW, rayDirI)) ) {
        arg->errCode = ret;
        arg->whichErr = hooverErrRayBegin;
        return arg;
      }
      
      sampleI = 0;
      rayT = 0;
      while (1) {
        ELL_3V_SCALE_ADD2(rayPosW, 1.0, rayStartW, rayT, rayDirW);
        ELL_3V_SCALE_ADD2(rayPosI, 1.0, rayStartI, rayT, rayDirI);
        inside = (AIR_IN_CL(mm, rayPosI[0], Mx) &&
                  AIR_IN_CL(mm, rayPosI[1], My) &&
                  AIR_IN_CL(mm, rayPosI[2], Mz));
        rayStep = (arg->ctx->sample)(thread,
                                     arg->render,
                                     arg->ctx->user,
                                     sampleI, rayT,
                                     inside,
                                     rayPosW, rayPosI);
        if (!AIR_EXISTS(rayStep)) {
          /* sampling failed */
          arg->errCode = 0;
          arg->whichErr = hooverErrSample;
          return arg;
        }
        if (!rayStep) {
          /* ray decided to finish itself */
          break;
        } 
        /* else we moved to a new location along the ray */
        rayT += rayStep;
        if (!AIR_IN_CL(0, rayT, rayLen)) {
          /* ray stepped outside near-far clipping region, its done. */
          break;
        }
        sampleI++;
      }
      
      if ( (ret = (arg->ctx->rayEnd)(thread,
                                     arg->render,
                                     arg->ctx->user)) ) {
        arg->errCode = ret;
        arg->whichErr = hooverErrRayEnd;
        return arg;
      }
    }  /* end this scanline */
  } /* end while(1) assignment of scanlines */

  if ( (ret = (arg->ctx->threadEnd)(thread,
                                    arg->render,
                                    arg->ctx->user)) ) {
    arg->errCode = ret;
    arg->whichErr = hooverErrThreadEnd;
    return arg;
  }
  
  /* returning NULL actually indicates that there was NOT an error */
  return NULL;
}
コード例 #25
0
ファイル: axis.c プロジェクト: SCIInstitute/Cleaver
/*
******** nrrdAxisInfoSet_nva()
**
** Simple means of setting fields of the axis array in the nrrd.
**
** type to pass for third argument:
**           nrrdAxisInfoSize: size_t*
**        nrrdAxisInfoSpacing: double*
**      nrrdAxisInfoThickness: double*
**            nrrdAxisInfoMin: double*
**            nrrdAxisInfoMax: double*
** nrrdAxisInfoSpaceDirection: double (*var)[NRRD_SPACE_DIM_MAX]
**         nrrdAxisInfoCenter: int*
**           nrrdAxisInfoKind: int*
**          nrrdAxisInfoLabel: char**
**          nrrdAxisInfoUnits: char**
*/
void
nrrdAxisInfoSet_nva(Nrrd *nrrd, int axInfo, const void *_info) {
  _nrrdAxisInfoSetPtrs info;
  int exists;
  unsigned int ai, si, minsi;
  
  if (!( nrrd 
         && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX) 
         && AIR_IN_OP(nrrdAxisInfoUnknown, axInfo, nrrdAxisInfoLast) 
         && _info )) {
    return;
  }
  info.P = _info;

  for (ai=0; ai<nrrd->dim; ai++) {
    switch (axInfo) {
    case nrrdAxisInfoSize:
      nrrd->axis[ai].size = info.ST[ai];
      break;
    case nrrdAxisInfoSpacing:
      nrrd->axis[ai].spacing = info.D[ai];
      break;
    case nrrdAxisInfoThickness:
      nrrd->axis[ai].thickness = info.D[ai];
      break;
    case nrrdAxisInfoMin:
      nrrd->axis[ai].min = info.D[ai];
      break;
    case nrrdAxisInfoMax:
      nrrd->axis[ai].max = info.D[ai];
      break;
    case nrrdAxisInfoSpaceDirection:
      /* we won't allow setting an invalid direction */
      exists = AIR_EXISTS(info.V[ai][0]);
      minsi = nrrd->spaceDim;
      for (si=0; si<nrrd->spaceDim; si++) {
        nrrd->axis[ai].spaceDirection[si] = info.V[ai][si];
        if (exists ^ AIR_EXISTS(info.V[ai][si])) {
          minsi = 0;
          break;
        }
      }
      for (si=minsi; si<NRRD_SPACE_DIM_MAX; si++) {
        nrrd->axis[ai].spaceDirection[si] = AIR_NAN;
      }
      break;
    case nrrdAxisInfoCenter:
      nrrd->axis[ai].center = info.I[ai];
      break;
    case nrrdAxisInfoKind:
      nrrd->axis[ai].kind = info.I[ai];
      break;
    case nrrdAxisInfoLabel:
      nrrd->axis[ai].label = (char *)airFree(nrrd->axis[ai].label);
      nrrd->axis[ai].label = (char *)airStrdup(info.CP[ai]);
      break;
    case nrrdAxisInfoUnits:
      nrrd->axis[ai].units = (char *)airFree(nrrd->axis[ai].units);
      nrrd->axis[ai].units = (char *)airStrdup(info.CP[ai]);
      break;
    }
  }
  if (nrrdAxisInfoSpaceDirection == axInfo) {
    for (ai=nrrd->dim; ai<NRRD_DIM_MAX; ai++) {
      for (si=0; si<NRRD_SPACE_DIM_MAX; si++) {
        nrrd->axis[ai].spaceDirection[si] = AIR_NAN;
      }
    }    
  }
  return;
}
コード例 #26
0
int
_pushContextCheck(pushContext *pctx) {
  char me[]="_pushContextCheck", err[BIFF_STRLEN];
  unsigned int sidx;
  int nul;
  
  if (!pctx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(PUSH, err); return 1;
  }
  if (!( AIR_IN_CL(1, pctx->numStage, PUSH_STAGE_MAXNUM) )) {
    sprintf(err, "%s: pctx->numStage (%d) outside valid range [1,%d]", me,
            pctx->numStage, PUSH_STAGE_MAXNUM);
    biffAdd(PUSH, err); return 1;
  }
  nul = AIR_FALSE;
  for (sidx=0; sidx<pctx->numStage; sidx++) {
    nul |= !(pctx->process[sidx]);
  }
  if (nul) {
    sprintf(err, "%s: one or more of the process functions was NULL", me);
    biffAdd(PUSH, err); return 1;
  }
  if (!( pctx->numThing >= 1 )) {
    sprintf(err, "%s: pctx->numThing (%d) not >= 1\n", me, pctx->numThing);
    biffAdd(PUSH, err); return 1;
  }
  if (!( pctx->numThread >= 1 )) {
    sprintf(err, "%s: pctx->numThread (%d) not >= 1\n", me, pctx->numThread);
    biffAdd(PUSH, err); return 1;
  }
  if (!( AIR_IN_CL(1, pctx->numThread, PUSH_THREAD_MAXNUM) )) {
    sprintf(err, "%s: pctx->numThread (%d) outside valid range [1,%d]", me,
            pctx->numThread, PUSH_THREAD_MAXNUM);
    biffAdd(PUSH, err); return 1;
  }

  if (nrrdCheck(pctx->nin)) {
    sprintf(err, "%s: got a broken input nrrd", me);
    biffMove(PUSH, err, NRRD); return 1;
  }
  if (!( (3 == pctx->nin->dim && 4 == pctx->nin->axis[0].size) 
         || (4 == pctx->nin->dim && 7 == pctx->nin->axis[0].size) )) {
    sprintf(err, "%s: input doesn't look like 2D or 3D masked tensors", me);
    biffAdd(PUSH, err); return 1;
  }

  if (pctx->npos) {
    if (nrrdCheck(pctx->npos)) {
      sprintf(err, "%s: got a broken position nrrd", me);
      biffMove(PUSH, err, NRRD); return 1;
    }
    if (!( 2 == pctx->npos->dim 
           && 3 == pctx->npos->axis[0].size )) {
      sprintf(err, "%s: position nrrd not 2-D 3-by-N", me);
      biffAdd(PUSH, err); return 1;
    }
  }
  if (pctx->nstn) {
    if (!pctx->npos) {
      sprintf(err, "%s: can't have start/num nrrd w/out position nrrd", me);
      biffAdd(PUSH, err); return 1;
    }
    if (nrrdCheck(pctx->nstn)) {
      sprintf(err, "%s: got a broken start/num nrrd", me);
      biffMove(PUSH, err, NRRD); return 1;
    }
    if (!( 2 == pctx->nstn->dim 
           && nrrdTypeInt == pctx->nstn->type
           && 3 == pctx->nstn->axis[0].size )) {
      sprintf(err, "%s: start/num nrrd not 2-D 3-by-N array of %ss", me,
              airEnumStr(nrrdType, nrrdTypeInt));
      biffAdd(PUSH, err); return 1;
    }
  }
  return 0;
}
コード例 #27
0
ファイル: axis.c プロジェクト: SCIInstitute/Cleaver
/*
******** nrrdAxisInfoGet_nva()
**
** get any of the axis fields into an array
**
** Note that getting axes labels involves implicitly allocating space
** for them, due to the action of airStrdup().  The user is
** responsible for free()ing these strings when done with them.
**
** type to pass for third argument:
**           nrrdAxisInfoSize: size_t*
**        nrrdAxisInfoSpacing: double*
**      nrrdAxisInfoThickness: double*
**            nrrdAxisInfoMin: double*
**            nrrdAxisInfoMax: double*
** nrrdAxisInfoSpaceDirection: double (*var)[NRRD_SPACE_DIM_MAX]
**         nrrdAxisInfoCenter: int*
**           nrrdAxisInfoKind: int*
**          nrrdAxisInfoLabel: char**
**          nrrdAxisInfoUnits: char**
*/
void
nrrdAxisInfoGet_nva(const Nrrd *nrrd, int axInfo, void *_info) {
  _nrrdAxisInfoGetPtrs info;
  unsigned int ai, si;
  
  if (!( nrrd 
         && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX) 
         && AIR_IN_OP(nrrdAxisInfoUnknown, axInfo, nrrdAxisInfoLast) )) {
    return;
  }
  
  info.P = _info;
  for (ai=0; ai<nrrd->dim; ai++) {
    switch (axInfo) {
    case nrrdAxisInfoSize:
      info.ST[ai] = nrrd->axis[ai].size;
      break;
    case nrrdAxisInfoSpacing:
      info.D[ai] = nrrd->axis[ai].spacing;
      break;
    case nrrdAxisInfoThickness:
      info.D[ai] = nrrd->axis[ai].thickness;
      break;
    case nrrdAxisInfoMin:
      info.D[ai] = nrrd->axis[ai].min;
      break;
    case nrrdAxisInfoMax:
      info.D[ai] = nrrd->axis[ai].max;
      break;
    case nrrdAxisInfoSpaceDirection:
      for (si=0; si<nrrd->spaceDim; si++) {
        info.V[ai][si] = nrrd->axis[ai].spaceDirection[si];
      }
      for (si=nrrd->spaceDim; si<NRRD_SPACE_DIM_MAX; si++) {
        info.V[ai][si] = AIR_NAN;
      }
      break;
    case nrrdAxisInfoCenter:
      info.I[ai] = nrrd->axis[ai].center;
      break;
    case nrrdAxisInfoKind:
      info.I[ai] = nrrd->axis[ai].kind;
      break;
    case nrrdAxisInfoLabel:
      /* note airStrdup()! */
      info.CP[ai] = airStrdup(nrrd->axis[ai].label);
      break;
    case nrrdAxisInfoUnits:
      /* note airStrdup()! */
      info.CP[ai] = airStrdup(nrrd->axis[ai].units);
      break;
    }
  }
  if (nrrdAxisInfoSpaceDirection == axInfo) {
    for (ai=nrrd->dim; ai<NRRD_DIM_MAX; ai++) {
      for (si=0; si<NRRD_SPACE_DIM_MAX; si++) {
        info.V[ai][si] = AIR_NAN;
      }
    }
  }
  return;
}
コード例 #28
0
int
_echoRayIntx_Cylinder(RAYINTX_ARGS(Cylinder)) {
  echoPos_t A, B, C, aa, bb, cc, dd, ee, ff, dscr, cylt1, cylt2, t, tmax,
    twot[2], cylp1, cylp2, pos[3], tmp;
  int tidx, radi0, radi1, twocap[2], cap;

  AIR_UNUSED(parm);
  AIR_UNUSED(tstate);

  if (!_echoRayIntx_CubeSolid(&t, &tmax,
                              -1-ECHO_EPSILON, 1+ECHO_EPSILON,
                              -1-ECHO_EPSILON, 1+ECHO_EPSILON,
                              -1-ECHO_EPSILON, 1+ECHO_EPSILON, ray)) {
    return AIR_FALSE;
  }
  switch(obj->axis) {
  case 0:
    radi0 = 1; radi1 = 2;
    break;
  case 1:
    radi0 = 0; radi1 = 2;
    break;
  case 2: default:
    radi0 = 0; radi1 = 1;
    break;
  }
  aa = ray->dir[radi0];
  bb = ray->dir[radi1];
  ee = ray->dir[obj->axis];
  cc = ray->from[radi0];
  dd = ray->from[radi1];
  ff = ray->from[obj->axis];
  A = aa*aa + bb*bb;
  B = 2*(aa*cc + bb*dd);
  C = cc*cc + dd*dd - 1;
  dscr = B*B - 4*A*C;
  if (dscr <= 0) {
    /* infinite ray grazes or misses the infinite cylinder (not
       bounded to [-1,1] along cylinder's axis), so therefore the ray
       grazes or misses the actual cylinder */
    return AIR_FALSE;
  }
  /* else infinite ray intersects the infinite cylinder */
  dscr = sqrt(dscr);
  cylt1 = (-B - dscr)/(2*A);
  cylp1 = ff + cylt1*ee;
  cylt2 = (-B + dscr)/(2*A);
  cylp2 = ff + cylt2*ee;
  if ( (cylp1 <= -1 && cylp2 <= -1)
       || (cylp1 >= 1 && cylp2 >= 1) ) {
    /* both intersections with infinite cylinder lie on ONE side of the
       finite extent, so there can't be an intersection */
    return AIR_FALSE;
  }
  /* else infinite ray DOES intersect finite cylinder; we have to find
     if any of the intersections are in the [neer, faar] interval */
  tidx = 0;
  if (AIR_IN_CL(-1, cylp1, 1)) {
    twot[tidx] = cylt1;
    twocap[tidx] = 0;
    tidx++;
  }
  if (AIR_IN_CL(-1, cylp2, 1)) {
    twot[tidx] = cylt2;
    twocap[tidx] = 0;
    tidx++;
  }
  if (tidx < 2) {
    /* at least one of the two intersections is with the endcaps */
    t = (-ff - 1)/ee;
    ELL_3V_SCALE_ADD2(pos, 1, ray->from, t, ray->dir);
    aa = pos[radi0]; bb = pos[radi1]; cc = aa*aa + bb*bb;
    if (cc <= 1) {
      twot[tidx] = t;
      twocap[tidx] = 1;
      tidx++;
    }
    if (tidx < 2) {
      /* try other endcap */
      t = (-ff + 1)/ee;
      ELL_3V_SCALE_ADD2(pos, 1, ray->from, t, ray->dir);
      aa = pos[radi0]; bb = pos[radi1]; cc = aa*aa + bb*bb;
      if (cc <= 1) {
        twot[tidx] = t;
        twocap[tidx] = 1;
        tidx++;
      }
    }
  }
  if (!tidx) {
    return AIR_FALSE;
  }
  if (2 == tidx && twot[0] > twot[1]) {
    ELL_SWAP2(twot[0], twot[1], aa);
    ELL_SWAP2(twocap[0], twocap[1], cap);
  }
  t = twot[0];
  cap = twocap[0];
  if (!AIR_IN_CL(ray->neer, t, ray->faar)) {
    if (1 == tidx) {
      return AIR_FALSE;
    }
    t = twot[1];
    cap = twocap[1];
    if (!AIR_IN_CL(ray->neer, t, ray->faar)) {
      return AIR_FALSE;
    }
  }
  /* else one of the intxs is in [neer,faar] segment */
  intx->t = t;
  ELL_3V_SCALE_ADD2(pos, 1, ray->from, t, ray->dir);
  switch(obj->axis) {
  case 0:
    ELL_3V_SET(intx->norm,     cap*pos[0], (1-cap)*pos[1], (1-cap)*pos[2]);
    break;
  case 1:
    ELL_3V_SET(intx->norm, (1-cap)*pos[0],     cap*pos[1], (1-cap)*pos[2]);
    break;
  case 2: default:
    ELL_3V_SET(intx->norm, (1-cap)*pos[0], (1-cap)*pos[1],     cap*pos[2]);
    break;
  }
  ELL_3V_NORM(intx->norm, intx->norm, tmp);
  intx->obj = OBJECT(obj);
  /* does NOT set u, v */
  return AIR_TRUE;
}
コード例 #29
0
ファイル: write.c プロジェクト: guo2004131/freesurfer
/*
** _nrrdSprintFieldInfo
**
** this prints "<prefix><field>: <info>" into *strP (after allocating it for
** big enough, usually with a stupidly big margin of error), in a form
** suitable to be written to NRRD or other image headers.  This will always
** print something (for valid inputs), even stupid <info>s like
** "(unknown endian)".  It is up to the caller to decide which fields
** are worth writing, via _nrrdFieldInteresting().
**
** NOTE: some of these fields make sense in non-NRRD files (e.g. all
** the per-axis information), but many only make sense in NRRD files.
** This is just one example of NRRD-format-specific stuff that is not
** in formatNRRD.c
*/
void
_nrrdSprintFieldInfo(char **strP, char *prefix,
                     const Nrrd *nrrd, NrrdIoState *nio, int field)
{
    char me[]="_nrrdSprintFieldInfo", buff[AIR_STRLEN_MED], *fnb;
    double colvec[NRRD_SPACE_DIM_MAX];
    const char *fs;
    unsigned int ii, dd,
             uintStrlen = 11,
             size_tStrlen = 33,
             doubleStrlen = 513;
    int fslen, fdlen, endi, maxl;

    if (!( strP && prefix
            && nrrd
            && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX)
            && AIR_IN_OP(nrrdField_unknown, field, nrrdField_last) ))
    {
        return;
    }
    if (!_nrrdFieldInteresting(nrrd, nio, field))
    {
        *strP = airStrdup("");
    }

    fs = airEnumStr(nrrdField, field);
    fslen = strlen(prefix) + strlen(fs) + strlen(": ") + 1;
    switch (field)
    {
    case nrrdField_comment:
    case nrrdField_keyvalue:
        fprintf(stderr, "%s: CONFUSION: why are you calling me on \"%s\"?\n", me,
                airEnumStr(nrrdField, nrrdField_comment));
        *strP = airStrdup("");
        break;
    case nrrdField_content:
        airOneLinify(nrrd->content);
        *strP = (char *)calloc(fslen + strlen(nrrd->content), sizeof(char));
        sprintf(*strP, "%s%s: %s", prefix, fs, nrrd->content);
        break;
    case nrrdField_number:
        *strP = (char *)calloc(fslen + size_tStrlen, sizeof(char));
        sprintf(*strP, "%s%s: " _AIR_SIZE_T_CNV, prefix, fs,
                nrrdElementNumber(nrrd));
        break;
    case nrrdField_type:
        *strP = (char *)calloc(fslen + strlen(airEnumStr(nrrdType, nrrd->type)),
                               sizeof(char));
        sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdType, nrrd->type));
        break;
    case nrrdField_block_size:
        *strP = (char *)calloc(fslen + size_tStrlen, sizeof(char));
        sprintf(*strP, "%s%s: " _AIR_SIZE_T_CNV, prefix, fs, nrrd->blockSize);
        break;
    case nrrdField_dimension:
        *strP = (char *)calloc(fslen + uintStrlen, sizeof(char));
        sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->dim);
        break;
    case nrrdField_space:
        *strP = (char *)calloc(fslen + strlen(airEnumStr(nrrdSpace, nrrd->space)),
                               sizeof(char));
        sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdSpace, nrrd->space));
        break;
    case nrrdField_space_dimension:
        *strP = (char *)calloc(fslen + uintStrlen, sizeof(char));
        sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->spaceDim);
        break;
    /* ---- begin per-axis fields ---- */
    case nrrdField_sizes:
        *strP = (char *)calloc(fslen + nrrd->dim*(size_tStrlen + 1), sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            sprintf(buff, " " _AIR_SIZE_T_CNV, nrrd->axis[ii].size);
            strcat(*strP, buff);
        }
        break;
    case nrrdField_spacings:
        *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].spacing);
            strcat(*strP, buff);
        }
        break;
    case nrrdField_thicknesses:
        *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].thickness);
            strcat(*strP, buff);
        }
        break;
    case nrrdField_axis_mins:
        *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].min);
            strcat(*strP, buff);
        }
        break;
    case nrrdField_axis_maxs:
        *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].max);
            strcat(*strP, buff);
        }
        break;
    case nrrdField_space_directions:
        *strP = (char *)calloc(fslen +
                               nrrd->dim*nrrd->spaceDim*(doubleStrlen
                                       + strlen("(,) ")),
                               sizeof(char));
        sprintf(*strP, "%s%s: ", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim,
                                   nrrd->axis[ii].spaceDirection);
            if (ii < nrrd->dim-1)
            {
                strcat(*strP, " ");
            }
        }
        break;
    case nrrdField_centers:
        fdlen = 0;
        for (ii=0; ii<nrrd->dim; ii++)
        {
            fdlen += 1 + airStrlen(nrrd->axis[ii].center
                                   ? airEnumStr(nrrdCenter, nrrd->axis[ii].center)
                                   : NRRD_UNKNOWN);
        }
        *strP = (char *)calloc(fslen + fdlen, sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            sprintf(buff, " %s",
                    (nrrd->axis[ii].center
                     ? airEnumStr(nrrdCenter, nrrd->axis[ii].center)
                     : NRRD_UNKNOWN));
            strcat(*strP, buff);
        }
        break;
    case nrrdField_kinds:
        fdlen = 0;
        for (ii=0; ii<nrrd->dim; ii++)
        {
            fdlen += 1 + airStrlen(nrrd->axis[ii].kind
                                   ? airEnumStr(nrrdKind, nrrd->axis[ii].kind)
                                   : NRRD_UNKNOWN);
        }
        *strP = (char *)calloc(fslen + fdlen, sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            sprintf(buff, " %s",
                    (nrrd->axis[ii].kind
                     ? airEnumStr(nrrdKind, nrrd->axis[ii].kind)
                     : NRRD_UNKNOWN));
            strcat(*strP, buff);
        }
        break;
    case nrrdField_labels:
        fdlen = 0;
        for (ii=0; ii<nrrd->dim; ii++)
        {
            fdlen += airStrlen(nrrd->axis[ii].label) + 4;
        }
        *strP = (char *)calloc(fslen + fdlen, sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            strcat(*strP, " \"");
            if (airStrlen(nrrd->axis[ii].label))
            {
                strcat(*strP, nrrd->axis[ii].label);
            }
            strcat(*strP, "\"");
        }
        break;
    case nrrdField_units:
        fdlen = 0;
        for (ii=0; ii<nrrd->dim; ii++)
        {
            fdlen += airStrlen(nrrd->axis[ii].units) + 4;
        }
        *strP = (char *)calloc(fslen + fdlen, sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->dim; ii++)
        {
            strcat(*strP, " \"");
            if (airStrlen(nrrd->axis[ii].units))
            {
                strcat(*strP, nrrd->axis[ii].units);
            }
            strcat(*strP, "\"");
        }
        break;
    /* ---- end per-axis fields ---- */
    case nrrdField_min:
    case nrrdField_max:
        /* we're basically a no-op, now that these fields became meaningless */
        *strP = (char *)calloc(fslen + doubleStrlen, sizeof(char));
        sprintf(*strP, "%s%s: 0.0", prefix, fs);
        strcat(*strP, buff);
        break;
    case nrrdField_old_min:
        *strP = (char *)calloc(fslen + doubleStrlen, sizeof(char));
        sprintf(*strP, "%s%s: ", prefix, fs);
        airSinglePrintf(NULL, buff, "%g", nrrd->oldMin);
        strcat(*strP, buff);
        break;
    case nrrdField_old_max:
        *strP = (char *)calloc(fslen + doubleStrlen, sizeof(char));
        sprintf(*strP, "%s%s: ", prefix, fs);
        airSinglePrintf(NULL, buff, "%g", nrrd->oldMax);
        strcat(*strP, buff);
        break;
    case nrrdField_endian:
        if (airEndianUnknown != nio->endian)
        {
            /* we know a specific endianness because either it was recorded as
               part of "unu make -h", or it was set (and data was possibly
               altered) as part of "unu save" */
            endi = nio->endian;
        }
        else
        {
            /* we record our current architecture's endian because we're
               going to writing out data */
            endi = AIR_ENDIAN;
        }
        *strP = (char *)calloc(fslen + strlen(airEnumStr(airEndian, endi)),
                               sizeof(char));
        sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(airEndian, endi));
        break;
    case nrrdField_encoding:
        *strP = (char *)calloc(fslen + strlen(nio->encoding->name),
                               sizeof(char));
        sprintf(*strP, "%s%s: %s", prefix, fs, nio->encoding->name);
        break;
    case nrrdField_line_skip:
        *strP = (char *)calloc(fslen + uintStrlen, sizeof(char));
        sprintf(*strP, "%s%s: %d", prefix, fs, nio->lineSkip);
        break;
    case nrrdField_byte_skip:
        *strP = (char *)calloc(fslen + uintStrlen, sizeof(char));
        sprintf(*strP, "%s%s: %d", prefix, fs, nio->byteSkip);
        break;
    case nrrdField_sample_units:
        airOneLinify(nrrd->sampleUnits);
        *strP = (char *)calloc(fslen + strlen(nrrd->sampleUnits), sizeof(char));
        sprintf(*strP, "%s%s: \"%s\"", prefix, fs, nrrd->sampleUnits);
        break;
    case nrrdField_space_units:
        fdlen = 0;
        for (ii=0; ii<nrrd->spaceDim; ii++)
        {
            fdlen += airStrlen(nrrd->spaceUnits[ii]) + 4;
        }
        *strP = (char *)calloc(fslen + fdlen, sizeof(char));
        sprintf(*strP, "%s%s:", prefix, fs);
        for (ii=0; ii<nrrd->spaceDim; ii++)
        {
            strcat(*strP, " \"");
            if (airStrlen(nrrd->spaceUnits[ii]))
            {
                strcat(*strP, nrrd->spaceUnits[ii]);
            }
            strcat(*strP, "\"");
        }
        break;
    case nrrdField_space_origin:
        *strP = (char *)calloc(fslen + nrrd->spaceDim*(doubleStrlen
                               + strlen("(,) ")),
                               sizeof(char));
        sprintf(*strP, "%s%s: ", prefix, fs);
        _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, nrrd->spaceOrigin);
        break;
    case nrrdField_measurement_frame:
        *strP = (char *)calloc(fslen + (nrrd->spaceDim*
                                        nrrd->spaceDim*(doubleStrlen
                                                + strlen("(,) "))),
                               sizeof(char));
        sprintf(*strP, "%s%s: ", prefix, fs);
        for (dd=0; dd<nrrd->spaceDim; dd++)
        {
            for (ii=0; ii<nrrd->spaceDim; ii++)
            {
                colvec[ii] = nrrd->measurementFrame[dd][ii];
            }
            _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, colvec);
            if (dd < nrrd->spaceDim-1)
            {
                strcat(*strP, " ");
            }
        }
        break;
    case nrrdField_data_file:
        /* NOTE: this comes last (nrrdField_data_file is the highest-valued
           member of the nrrdField* enum) because the "LIST" form of the
           data file specification requires that the following lines be
           the filenames */
        /* error checking elsewhere: assumes there is data file info */
        if (nio->dataFNFormat)
        {
            *strP = (char *)calloc(fslen + strlen(nio->dataFNFormat) + 4*uintStrlen,
                                   sizeof(char));
            if (nio->dataFileDim == nrrd->dim-1)
            {
                sprintf(*strP, "%s%s: %s %d %d %d", prefix, fs, nio->dataFNFormat,
                        nio->dataFNMin, nio->dataFNMax, nio->dataFNStep);
            }
            else
            {
                sprintf(*strP, "%s%s: %s %d %d %d %d", prefix, fs, nio->dataFNFormat,
                        nio->dataFNMin, nio->dataFNMax, nio->dataFNStep,
                        nio->dataFileDim);
            }
        }
        else if (nio->dataFNArr->len > 1)
        {
            maxl = 0;
            for (ii=0; ii<nio->dataFNArr->len; ii++)
            {
                maxl = AIR_MAX(maxl, (int)strlen(nio->dataFN[ii]));
            }
            *strP = (char *)calloc(fslen + strlen(NRRD_LIST_FLAG)
                                   + uintStrlen + nio->dataFNArr->len * (maxl + 1),
                                   sizeof(char));
            fnb = (char *)calloc(fslen + strlen(NRRD_LIST_FLAG)
                                 + uintStrlen + maxl + 1,
                                 sizeof(char));
            if (nio->dataFileDim == nrrd->dim-1)
            {
                sprintf(*strP, "%s%s: LIST\n", prefix, fs);
            }
            else
            {
                sprintf(*strP, "%s%s: LIST %d\n", prefix, fs, nio->dataFileDim);
            }
            for (ii=0; ii<nio->dataFNArr->len; ii++)
            {
                sprintf(fnb, "%s%s", nio->dataFN[ii],
                        ii<nio->dataFNArr->len-1 ? "\n" : "");
                strcat(*strP, fnb);
            }
            free(fnb);
        }
        else
        {
            /* there is some ambiguity between a "LIST" of length one,
               and a single explicit data filename, but that's harmless */
            *strP = (char *)calloc(fslen + strlen("./")
                                   + strlen(nio->dataFN[0]) + 1,
                                   sizeof(char));
            sprintf(*strP, "%s%s: %s%s", prefix, fs,
                    /* this is a favor to older readers that can deal with
                       this NRRD file because its being saved in a NRRD0003
                       (or below) version, so we don't want to confuse them
                       by not having the old explicit header-relative flag */
                    (_nrrdFormatNRRD_whichVersion(nrrd, nio) < 4 ? "./" : ""),
                    nio->dataFN[0]);
        }
        break;
    default:
        fprintf(stderr, "%s: CONFUSION: field %d unrecognized\n", me, field);
        break;
    }

    return;
}
コード例 #30
0
ファイル: kind.c プロジェクト: sinkpoint/hodaie-teem
/*
******** gageKindCheck
**
** some some basic checking of the gageEntryItem array (the "table") for
** the sorts of mistakes that may be introduced by its hand-coding, although
** theoretically this is good for dynamically-generated gageKinds as well.
*/
int
gageKindCheck(const gageKind *kind) {
  static const char me[]="gageKindCheck";
  int pitem, pindex, alen;
  int ii, pi;
  gageItemEntry *item;

  if (!kind) {
    biffAddf(GAGE, "%s: got NULL pointer", me);
    return 1;
  }
  if (kind->itemMax > GAGE_ITEM_MAX) {
    biffAddf(GAGE, "%s: kind \"%s\" item max %d > GAGE_ITEM_MAX %d", 
             me, kind->name, kind->itemMax, GAGE_ITEM_MAX);
    return 1;
  }
  for (ii=1; ii<=kind->itemMax; ii++) {
    item = kind->table + ii;
    if (ii != item->enumVal) {
      biffAddf(GAGE,
               "%s: \"%s\"-kind \"%s\" (item %d) has enumVal %d (not %d)",
               me, kind->name, airEnumStr(kind->enm, ii),
               ii, item->enumVal, ii);
      return 1;
    }
    alen = item->answerLength;
    if (!(1 <= alen)) {
      if (kind->dynamicAlloc) {
        biffAddf(GAGE, "%s: (dynamic) \"%s\"-kind \"%s\" (item %d) "
                 "answerLength (%d) not set?",
                 me, kind->name, airEnumStr(kind->enm, ii), ii, alen);
      } else {
        biffAddf(GAGE, "%s: \"%s\"-kind \"%s\" (item %d) has invalid "
                 "answerLength %d",
                 me, kind->name, airEnumStr(kind->enm, ii), ii, alen);
      }
      return 1;
    }
    if (!(AIR_IN_CL(0, item->needDeriv, 2))) {
      biffAddf(GAGE,
               "%s: \"%s\"-kind \"%s\" (item %d) has invalid needDeriv %d",
               me, kind->name, airEnumStr(kind->enm, ii),
               ii, item->needDeriv);
      return 1;
    }
    for (pi=0; pi<GAGE_ITEM_PREREQ_MAXNUM; pi++) {
      if (!( 0 <= item->prereq[pi] )) {
        if (kind->dynamicAlloc) {
          biffAddf(GAGE, "%s: (dynamic) \"%s\"-kind \"%s\" (item %d) "
                   "prereq %d (%d) not set?",
                   me, kind->name, airEnumStr(kind->enm, ii), ii,
                   pi, item->prereq[pi]);
        } else {
          biffAddf(GAGE, "%s: \"%s\"-kind \"%s\" (item %d) has invalid "
                   "prereq %d (%d)",
                   me, kind->name, airEnumStr(kind->enm, ii), ii,
                   pi, item->prereq[pi]);
        }
        return 1;
      }
    }
    pitem = item->parentItem;
    pindex = item->parentIndex;
    if (0 != pitem) {
      if (0 == ii) {
        biffAddf(GAGE, "%s: first item (index 0) of \"%s\"-kind can't "
                 "be a sub-item (wanted parent index %d)", 
                 me, kind->name, pitem);
        return 1;
      }
      if (!(AIR_IN_CL(1, pitem, kind->itemMax))) {
        biffAddf(GAGE, "%s: item %d of \"%s\"-kind wants parent item %d "
                 "outside valid range [0..%d]",
                 me, ii, kind->name, pitem, kind->itemMax);
        return 1;
      }
      if (0 != kind->table[pitem].parentItem) {
        biffAddf(GAGE, "%s: item %d of \"%s\"-kind has parent %d which "
                 "wants to have parent %d: can't have sub-sub-items", 
                 me, ii, kind->name, pitem, kind->table[pitem].parentItem);
        return 1;
      }
      if (!( 0 <= pindex
             && ((unsigned int)pindex + alen 
                 <= kind->table[pitem].answerLength) )) {
        biffAddf(GAGE,
                 "%s: item %d of \"%s\"-kind wants index range [%d,%d] "
                 "of parent %d, which isn't in valid range [0,%d]",
                 me, ii, kind->name,
                 pindex, pindex + alen - 1,
                 pitem, kind->table[pitem].answerLength - 1);
        return 1;
      }
    }
  } 
  return 0;
}