示例#1
0
文件: tinfo.c 项目: rblake/seg3d2
int
main(int argc, char *argv[]) {
  Nrrd *hvol, *info;
  char *iStr, *dStr, *oStr;
  int dim;

  me = argv[0];
  if (argc != 4)
    usage();
  iStr = argv[1];
  dStr = argv[2];
  oStr = argv[3];

  if (nrrdLoad(hvol=nrrdNew(), iStr, NULL)) {
    fprintf(stderr, "%s: trouble reading hvol:\n%s\n", me, biffGet(NRRD));
    usage();
  }
  if (1 != sscanf(dStr, "%d", &dim)) {
    fprintf(stderr, "%s: trouble parsing %s as an int\n", me, dStr);
    usage();
  }
  if (baneOpacInfo(info = nrrdNew(), hvol, dim, nrrdMeasureHistoMean)) {
    fprintf(stderr, "%s: trouble calculting %d-D opacity info:\n%s\n",
            me, dim, biffGet(BANE));
    exit(1);
  }
  if (nrrdSave(oStr, info, NULL)) {
    fprintf(stderr, "%s: trouble saving nrrd to %s:\n%s\n", me, oStr,
            biffGet(NRRD));
    exit(1);
  }
  nrrdNuke(hvol);
  nrrdNuke(info);
  exit(0);
}
示例#2
0
/*
******** meetPullVolNix
**
** this frees stuff allocated meetPullVolParse and meetPullVolLoadMulti
*/
meetPullVol *
meetPullVolNix(meetPullVol *mpv) {

  if (mpv) {
    if (!mpv->leeching && mpv->nin) {
      nrrdNuke(mpv->nin);
    }
    if (mpv->numSS) {
      unsigned int ssi;
      if (mpv->ninSS) {
        /* need this check because the mpv may not have benefitted
           from meetPullVolLoadMulti, so it might be incomplete */
        for (ssi=0; ssi<mpv->numSS; ssi++) {
          if (!mpv->leeching) {
            nrrdNuke(mpv->ninSS[ssi]);
          }
        }
        airFree(mpv->ninSS);
      }
      airFree(mpv->posSS);
    }
    airFree(mpv->fileName);
    airFree(mpv->volName);
    airFree(mpv);
  }
  return NULL;
}
示例#3
0
int
main(int argc, char *argv[]) {
  Nrrd *map, *ppm;
  NrrdRange *range;

  AIR_UNUSED(argc);
  me = argv[0];

  if (limnEnvMapFill(map=nrrdNew(), cb, limnQN16checker, NULL)) {
    fprintf(stderr, "%s: trouble:\n%s", me, biffGet(LIMN));
    exit(1);
  }
  range = nrrdRangeNew(0, 1);
  if (nrrdQuantize(ppm=nrrdNew(), map, range, 8)) {
    fprintf(stderr, "%s: trouble:\n%s", me, biffGet(NRRD));
    exit(1);
  }
  if (nrrdSave("map.ppm", ppm, NULL)) {
    fprintf(stderr, "%s: trouble:\n%s", me, biffGet(NRRD));
    exit(1);
  }

  nrrdNuke(map);
  nrrdNuke(ppm);
  nrrdRangeNix(range);
  exit(0);
}
示例#4
0
int
_alanPerIteration(alanContext *actx, int iter) {
  char me[]="_alanPerIteration", fname[AIR_STRLEN_MED];
  Nrrd *nslc, *nimg;
  
  if (!(actx->saveInterval || actx->frameInterval)) {
    if (actx->verbose && !(iter % 100)) {
      fprintf(stderr, "%s: iter = %d, averageChange = %g\n",
              me, iter, actx->averageChange);
    }
  }
  if (actx->saveInterval && !(iter % actx->saveInterval)) {
    sprintf(fname, "%06d.nrrd", actx->constFilename ? 0 : iter);
    nrrdSave(fname, actx->_nlev[(iter+1) % 2], NULL);
    fprintf(stderr, "%s: iter = %d, averageChange = %g, saved %s\n",
            me, iter, actx->averageChange, fname);
  }
  if (actx->frameInterval && !(iter % actx->frameInterval)) {
    nrrdSlice(nslc=nrrdNew(), actx->_nlev[(iter+1) % 2], 0, 0);
    nrrdQuantize(nimg=nrrdNew(), nslc, NULL, 8);
    sprintf(fname, (2 == actx->dim ? "%06d.png" : "%06d.nrrd"),
            actx->constFilename ? 0 : iter);
    nrrdSave(fname, nimg, NULL);
    fprintf(stderr, "%s: iter = %d, averageChange = %g, saved %s\n",
            me, iter, actx->averageChange, fname);
    nrrdNuke(nslc);
    nrrdNuke(nimg);
  }
  return 0;
}
示例#5
0
/*
******** ell_Nm_wght_pseudo_inv()
**
** determines a weighted least squares solution via
** P = (A^T * W * A)^(-1) * A^T * W
*/
int
ell_Nm_wght_pseudo_inv(Nrrd *ninv, Nrrd *nA, Nrrd *nW) {
  static const char me[]="ell_Nm_wght_pseudo_inv";
  Nrrd *nAt, *nAtW, *nAtWA, *nAtWAi;
  int ret=0;

  if (!( ninv && !ell_Nm_check(nA, AIR_FALSE)
         && !ell_Nm_check(nW, AIR_FALSE) )) {
    biffAddf(ELL, "%s: NULL or invalid args", me);
    return 1;
  }
  nAt = nrrdNew();
  nAtW = nrrdNew();
  nAtWA = nrrdNew();
  nAtWAi = nrrdNew();
  if (ell_Nm_tran(nAt, nA)
      || ell_Nm_mul(nAtW, nAt, nW)
      || ell_Nm_mul(nAtWA, nAtW, nA)
      || ell_Nm_inv(nAtWAi, nAtWA)
      || ell_Nm_mul(ninv, nAtWAi, nAtW)) {
    biffAddf(ELL, "%s: trouble", me);
    ret = 1; goto seeya;
  }

 seeya:
  nrrdNuke(nAt); nrrdNuke(nAtW); nrrdNuke(nAtWA); nrrdNuke(nAtWAi);
  return ret;
}
示例#6
0
alanContext *
alanContextNix(alanContext *actx) {

  if (actx) {
    actx->_nlev[0] = nrrdNuke(actx->_nlev[0]);
    actx->_nlev[1] = nrrdNuke(actx->_nlev[1]);
    actx->nparm = nrrdNuke(actx->nparm);
    actx->nten = nrrdNuke(actx->nten);
    free(actx);
  }
  return NULL;
}
示例#7
0
echoThreadState *
echoThreadStateNix(echoThreadState *state) {

  if (state) {
    state->thread = airThreadNix(state->thread);
    nrrdNuke(state->njitt);
    nrrdNuke(state->nperm);
    state->permBuff = AIR_CAST(unsigned int *, airFree(state->permBuff));
    state->chanBuff = AIR_CAST(echoCol_t *, airFree(state->chanBuff));
    airFree(state);
  }
  return NULL;
}
示例#8
0
int
main(int argc, char *argv[]) {
  char *me, *ninName, *noutName, *err;
  Nrrd *nin;

  me = argv[0];
  if (3 != argc) {
    /*                       0   1     2   (3) */
    fprintf(stderr, "usage: %s <nin> <nout>\n", me);
    exit(1);
  }
  ninName = argv[1];
  noutName = argv[2];
  if (nrrdLoad(nin=nrrdNew(), ninName, NULL)) {
    fprintf(stderr, "%s: couldn't open nrrd \"%s\":\n%s", me, ninName,
            err = biffGetDone(NRRD));
    free(err); exit(1);
  }
  if (nrrdSave(noutName, nin, NULL)) {
    fprintf(stderr, "%s: trouble saving nrrd to \"%s\":\n%s", me, noutName,
            err = biffGetDone(NRRD));
    free(err); exit(1);
  }
  nrrdNuke(nin);
  exit(0);
}
示例#9
0
文件: minmax.c 项目: rblake/seg3d2
int
main(int argc, char **argv) {
  char *me, *err;
  Nrrd *nrrd;
  NrrdRange *range;

  me = argv[0];
  if (2 != argc)
    usage(me);

  nrrdStateVerboseIO = 10;
  
  if (nrrdLoad(nrrd=nrrdNew(), argv[1], NULL)) {
    fprintf(stderr, "%s: trouble loading \"%s\":\n%s", 
            me, argv[1], err = biffGet(NRRD));
    free(err);
    exit(1);
  }

  range = nrrdRangeNewSet(nrrd, nrrdBlind8BitRangeState);

  printf("%s: min = %g; max = %g, hasNonExist = %d\n", me,
         range->min, range->max, range->hasNonExist);

  nrrdNuke(nrrd);

  exit(0);
}
示例#10
0
int
main(int argc, char **argv) {
  char *me, *err, *key="strong bad", *value;
  Nrrd *nrrd;
  NrrdIoState *io;

  me = argv[0];
  if (2 != argc)
    usage(me);

  io = nrrdIoStateNew();
  nrrdStateVerboseIO = 10;
  
  if (nrrdLoad(nrrd=nrrdNew(), argv[1], NULL)) {
    fprintf(stderr, "%s: trouble loading \"%s\":\n%s", 
            me, argv[1], err = biffGetDone(NRRD));
    free(err);
    exit(1);
  }

  if ((value = nrrdKeyValueGet(nrrd, key))) {
    fprintf(stderr, "%s: '%s':='%s' (%d)\n", me, key, value, 
            (int)strlen(value));
  } else {
    fprintf(stderr, "%s: value not found for key: %s\n", me, key);
  }
  
  nrrdIoStateNix(io);
  nrrdNuke(nrrd);

  exit(0);
}
示例#11
0
文件: clip.c 项目: CIBC-Internal/teem
int
_baneClipAnswer_Percentile(int *countP, Nrrd *hvol, double *clipParm) {
  static const char me[]="_baneClipAnswer_Percentile";
  Nrrd *ncopy;
  int *hits, clip;
  size_t num, sum, out, outsofar, hi;

  if (nrrdCopy(ncopy=nrrdNew(), hvol)) {
    biffMovef(BANE, NRRD, "%s: couldn't create copy of histovol", me);
    return 1;
  }
  hits = (int *)ncopy->data;
  num = nrrdElementNumber(ncopy);
  qsort(hits, num, sizeof(int), nrrdValCompare[nrrdTypeInt]);
  sum = 0;
  for (hi=0; hi<num; hi++) {
    sum += hits[hi];
  }
  out = (size_t)(sum*clipParm[0]/100);
  outsofar = 0;
  hi = num-1;
  do {
    outsofar += hits[hi--];
  } while (outsofar < out);
  clip = hits[hi];
  nrrdNuke(ncopy);

  *countP = clip;
  return 0;
}
示例#12
0
Nrrd* LBLReader::Convert(int t, int c, bool get_max)
{
	int64_t pos = m_path_name.find_last_of('.');
	if (pos == -1)
		return 0;
	wstring str_name = m_path_name.substr(0, pos);
	wostringstream strs;
	strs << str_name /*<< "_t" << t << "_c" << c*/ << ".lbl";
	str_name = strs.str();
	FILE* lbl_file = 0;
	if (!WFOPEN(&lbl_file, str_name.c_str(), L"rb"))
		return 0;

	Nrrd *output = nrrdNew();
	NrrdIoState *nio = nrrdIoStateNew();
	nrrdIoStateSet(nio, nrrdIoStateSkipData, AIR_TRUE);
	if (nrrdRead(output, lbl_file, nio))
	{
		fclose(lbl_file);
		return 0;
	}
	nio = nrrdIoStateNix(nio);
	rewind(lbl_file);
	if (output->dim != 3 ||
		(output->type != nrrdTypeInt &&
		output->type != nrrdTypeUInt))
	{
		nrrdNuke(output);
		fclose(lbl_file);
		return 0;
	}
	int slice_num = int(output->axis[2].size);
	int x_size = int(output->axis[0].size);
	int y_size = int(output->axis[1].size);
	int data_size = slice_num * x_size * y_size;
	output->data = new unsigned int[data_size];

	if (nrrdRead(output, lbl_file, NULL))
	{
		nrrdNuke(output);
		fclose(lbl_file);
		return 0;
	}

	fclose(lbl_file);
	return output;
}
/*
** this is called *after* pushOutputGet
**
** should nix everything created by the many _push*Setup() functions
*/
int
pushFinish(pushContext *pctx) {
  char me[]="pushFinish", err[BIFF_STRLEN];
  unsigned int ii, tidx;

  if (!pctx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(PUSH, err); return 1;
  }

  if (pctx->verbose > 1) {
    fprintf(stderr, "%s: finishing workers\n", me);
  }
  pctx->finished = AIR_TRUE;
  if (pctx->numThread > 1) {
    airThreadBarrierWait(pctx->stageBarrierA);
  }
  for (tidx=pctx->numThread; tidx>0; tidx--) {
    if (tidx-1) {
      airThreadJoin(pctx->task[tidx-1]->thread,
                    &(pctx->task[tidx-1]->returnPtr));
    }
    pctx->task[tidx-1]->thread = airThreadNix(pctx->task[tidx-1]->thread);
    pctx->task[tidx-1] = _pushTaskNix(pctx->task[tidx-1]);
  }
  pctx->task = (pushTask **)airFree(pctx->task);

  pctx->nten = nrrdNuke(pctx->nten);
  pctx->ninv = nrrdNuke(pctx->ninv);
  pctx->nmask = nrrdNuke(pctx->nmask);
  pctx->gctx = gageContextNix(pctx->gctx);
  pctx->fctx = tenFiberContextNix(pctx->fctx);
  for (ii=0; ii<pctx->numBin; ii++) {
    pushBinDone(pctx->bin + ii);
  }
  pctx->bin = (pushBin *)airFree(pctx->bin);
  pctx->binsEdge = pctx->numBin = 0;

  if (pctx->numThread > 1) {
    pctx->binMutex = airThreadMutexNix(pctx->binMutex);
    pctx->stageBarrierA = airThreadBarrierNix(pctx->stageBarrierA);
    pctx->stageBarrierB = airThreadBarrierNix(pctx->stageBarrierB);
  }

  return 0;
}
/*
** _gageStandardNixer()
**
*********************************************************
** as of about Wed Apr 20 19:32:54 EDT 2005, this is moot
*********************************************************
**
** the usual/default nixer used in gage, which is a simple wrapper
** around nrrdNuke at this point, although other things could be
** implemented later ...
**
** The "kind" and "_info" pointers are ignored.
**
** Nixers must gracefully handle being handed a NULL npad.
**
** The intention is that nixers cannot generate errors, so the return
** is void, and no nixer should accumulate errors in biff.  This nixer
** is a shining example of this.
*/
void
_gageStandardNixer (Nrrd *npad, gageKind *kind, gagePerVolume *pvl) {

  AIR_UNUSED(kind);
  if (npad != pvl->nin) {
    nrrdNuke(npad);
  }
}
示例#15
0
void
demoIO(char *filename)
{
  char me[]="demoIO", newname[]="foo.nrrd", *err, *key, *val;
  int kvn, kvi;
  Nrrd *nin;

  /* create a nrrd; at this point this is just an empty container */
  nin = nrrdNew();

  /* read in the nrrd from file */
  if (nrrdLoad(nin, filename, NULL))
  {
    err = biffGetDone(NRRD);
    fprintf(stderr, "%s: trouble reading \"%s\":\n%s", me, filename, err);
    free(err);
    return;
  }

  /* say something about the array */
  printf("%s: \"%s\" is a %d-dimensional nrrd of type %d (%s)\n",
         me, filename, nin->dim, nin->type,
         airEnumStr(nrrdType, nin->type));
  printf("%s: the array contains %d elements, each %d bytes in size\n",
         me, (int)nrrdElementNumber(nin), (int)nrrdElementSize(nin));

  /* print out the key/value pairs present */
  kvn = nrrdKeyValueSize(nin);
  if (kvn)
  {
    for (kvi=0; kvi<kvn; kvi++)
    {
      nrrdKeyValueIndex(nin, &key, &val, kvi);
      printf("%s: key:value %d = %s:%s\n", me, kvi, key, val);
      free(key);
      free(val);
      key = val = NULL;
    }
  }

  /* modify key/value pairs, and write out the nrrd to a different file */
  nrrdKeyValueClear(nin);
  nrrdKeyValueAdd(nin, "new key", "precious value");
  if (nrrdSave(newname, nin, NULL))
  {
    err = biffGetDone(NRRD);
    fprintf(stderr, "%s: trouble writing \"%s\":\n%s", me, newname, err);
    free(err);
    return;
  }

  /* blow away both the Nrrd struct *and* the memory at nin->data
     (nrrdNix() frees the struct but not the data,
     nrrdEmpty() frees the data but not the struct) */
  nrrdNuke(nin);

  return;
}
示例#16
0
int main(int argc, char * argv[])
{
	Nrrd *nin = nrrdNew();
	Nrrd *nquantized = nrrdNew();
	char *biffErr;

	if(argc < 4) {
		fprintf(stderr,"Usage: %s centerx centery nrrd\n",argv[0]);
		return 1;
	}

	cx = atoi(argv[1]);
	cy = atoi(argv[2]);

	if(nrrdLoad(nin, argv[3], NULL)) {
		biffErr = biffGetDone(NRRD);
		fprintf(stderr, "Error reading file: %s\n", biffErr);
		free(biffErr);
		return 1;
	}

	printf("Read %d-dimensional nrrd of type %d (%s)\n",
			nin->dim, nin->type, airEnumStr(nrrdType, nin->type));

	printf("Axis dimensions: %d x %d x %d\n", nin->axis[0].size,
			nin->axis[1].size, nin->axis[2].size);

	NrrdRange *range = nrrdRangeNewSet(nin, 0);
	printf("min: %g\tmax: %g\n", range->min, range->max);

	if(nrrdQuantize(nquantized, nin, range, 8)) {
		biffErr = biffGetDone(NRRD);
		fprintf(stderr, "Error quantizing: %s\n", biffErr);
		return 1;
	}

	process_slices(nquantized);

	nrrdRangeNix(range);
	nrrdNuke(nin);
	nrrdNuke(nquantized);

	return 0;
}
示例#17
0
coilContext *
coilContextNix(coilContext *cctx) {

  if (cctx) {
    /* thread machinery destroyed with coilFinish() */
    cctx->nvol = nrrdNuke(cctx->nvol);
    airFree(cctx);
  }
  return NULL;
}
示例#18
0
文件: measure.c 项目: rblake/seg3d2
void
_nrrdMeasureMode(void *ans, int ansType,
                 const void *_line, int lineType, size_t len, 
                 double axmin, double axmax) {
  Nrrd *nline, *nhist;
  void *line;

  AIR_UNUSED(axmin);
  AIR_UNUSED(axmax);
  line = calloc(len, nrrdTypeSize[lineType]);
  if (line) {
    memcpy(line, _line, len*nrrdTypeSize[lineType]);

    nline = nrrdNew();
    if (nrrdWrap_va(nline, line, lineType, 1, len)) {
      free(biffGetDone(NRRD));
      nrrdNix(nline);
      nrrdDStore[ansType](ans, AIR_NAN);
      return;
    }
    nhist = nrrdNew();
    if (nrrdHisto(nhist, nline, NULL, NULL,
                  nrrdStateMeasureModeBins, nrrdTypeInt)) {
      free(biffGetDone(NRRD));
      nrrdNuke(nhist);
      nrrdNix(nline);
      nrrdDStore[ansType](ans, AIR_NAN);
      return;
    }
    
    /* now we pass this histogram off to histo-mode */
    _nrrdMeasureHistoMode(ans, ansType,
                          nhist->data, nrrdTypeInt, nrrdStateMeasureModeBins,
                          nhist->axis[0].min, nhist->axis[0].max);
    nrrdNuke(nhist);
    nrrdNix(nline);
  } else {
    nrrdDStore[ansType](ans, 0);
  }
  return;
}
示例#19
0
int
main(int argc, char **argv) {
  char *me, *err;
  Nrrd *nrrd;
  NrrdIoState *nio;
  char hstr[] = "NRRD0001\n"
    "# Complete NRRD file format specification at:\n"
    "# http://teem.sourceforge.net/nrrd/format.html\n"
    "# one comment\n"
    "# two comment\n"
    "# three comment\n"
    "type: float\n"
    "dimension: 2\n"
    "sizes: 91 114\n"
    "centerings: node node\n"
    "endian: big\n"
    "encoding: raw\n"
    "bingo:=bob\n"
    "foo:=super duper fancy bar with corona\n"
    /* "data file: tmp.raw\n" */;
  char *wstr;
  AIR_UNUSED(argc);
  me = argv[0];

  nrrdStateVerboseIO = 10;

  nio = nrrdIoStateNew();
  nrrd = nrrdNew();

  nio->path = airStrdup(".");
  if (nrrdStringRead(nrrd, hstr, nio)) {
    fprintf(stderr, "%s: trouble reading string:\n%s", 
            me, err = biffGet(NRRD));
    free(err);
    exit(1);
  }
  fprintf(stderr, "%s: nrrd->data = %p\n", me, nrrd->data);

  nrrdSave("out.nrrd", nrrd, NULL);
  if (nrrdStringWrite(&wstr, nrrd, NULL)) {
    fprintf(stderr, "%s: trouble writing string:\n%s", 
            me, err = biffGet(NRRD));
    free(err);
    exit(1);
  }
  fprintf(stderr, "%s: |%s|\n", me, wstr);

  free(wstr);
  nrrdIoStateNix(nio);
  nrrdNuke(nrrd);

  exit(0);
}
示例#20
0
int
main(int argc, char *argv[]) {
  Nrrd *info, *pos;
  float sigma, gthresh;
  char *iStr, *oStr, *sigStr, *gthStr;

  me = argv[0];
  if (argc != 5) {
    usage();
  }
  iStr = argv[1];
  sigStr = argv[2];
  gthStr = argv[3];
  oStr = argv[4];

  if (1 != sscanf(sigStr, "%g", &sigma) ||
      1 != sscanf(gthStr, "%g", &gthresh)) {
    fprintf(stderr, "%s: couldn't parse %s and %s as floats\n", me, 
            sigStr, gthStr);
    usage();
  }

  if (nrrdLoad(info=nrrdNew(), iStr, NULL)) {
    fprintf(stderr, "%s: trouble reading \"%s\" :\n%s\n", me, 
            iStr, biffGet(NRRD));
    exit(1);
  }
  if (banePosCalc(pos = nrrdNew(), sigma, gthresh, info)) {
    fprintf(stderr, "%s: trouble calculating %s:\n%s\n", me,
            2 == info->dim ? "p(v,g)" : "p(v)", biffGet(BANE));
    exit(1);
  }
  if (nrrdSave(oStr, pos, NULL)) {
    fprintf(stderr, "%s: trouble writing output to \"%s\"\n", me, oStr);
    exit(1);
  }
  nrrdNuke(info);
  nrrdNuke(pos);
  exit(0);
}
示例#21
0
void WriteFile(Nrrd *nData, int type, char *Outfile){
    if(type == 0){
        if(nrrdSave(Outfile, nData, NULL)) {
            exit(1);
        }
    }
    else{
        Nrrd *ntmp = nrrdNew();
        nrrdQuantize(ntmp, nData, NULL, 8);
        nrrdSave(Outfile, ntmp, NULL);
    }
    nrrdNuke(nData);
    return;
}
示例#22
0
int
main(int argc, char *argv[]) {
  char *bStr, *pStr, *oStr;
  Nrrd *b, *p, *o;

  me = argv[0];
  if (argc != 4) 
    usage();
  bStr = argv[1];
  pStr = argv[2];
  oStr = argv[3];
  if (nrrdLoad(b=nrrdNew(), bStr, NULL)) {
    fprintf(stderr, "%s: trouble reading %s:\n%s\n", me, bStr, biffGet(NRRD));
    usage();
  }

  if (nrrdLoad(p=nrrdNew(), pStr, NULL)) {
    fprintf(stderr, "%s: trouble reading %s:\n%s\n", me, pStr, biffGet(NRRD));
    usage();
  }
  
  if (baneOpacCalc(o = nrrdNew(), b, p)) {
    fprintf(stderr, "%s: trouble calculating opac:\n%s", me, biffGet(BANE));
    exit(1);
  }

  if (nrrdSave(oStr, o, NULL)) {
    fprintf(stderr, "%s: trouble writing %s:\n%s\n", me, oStr, biffGet(NRRD));
    exit(1);
  }

  nrrdNuke(o);
  nrrdNuke(b);
  nrrdNuke(p);
  exit(0);
}
示例#23
0
void
alanContextInit(alanContext *actx) {
  if (actx) {
    actx->verbose = 0;
    actx->wrap = AIR_FALSE;
    actx->textureType = alanTextureTypeUnknown;
    actx->dim = 0;
    ELL_3V_SET(actx->size, 0, 0, 0);
    actx->oversample = 0;
    actx->homogAniso = AIR_FALSE;
    actx->numThreads = 1;
    actx->frameInterval = 10;
    actx->saveInterval = 100;
    actx->maxIteration = 1000000;
    actx->minAverageChange = 0.00002f;
    actx->maxPixelChange = 6;
    actx->K = AIR_NAN;
    actx->F = AIR_NAN;
    actx->deltaX = 1.25;
    actx->alpha = 16;
    actx->beta = 12;
    actx->deltaT = 1.0;
    actx->react = 1.0;
    actx->initA = actx->initB = 0;
    actx->diffA = actx->diffB = 0;
    actx->perIteration = NULL;
    actx->randRange = 3;
    actx->_nlev[0] = nrrdNuke(actx->_nlev[0]);
    actx->_nlev[1] = nrrdNuke(actx->_nlev[1]);
    actx->nlev = actx->_nlev[0];
    actx->nparm = nrrdNuke(actx->nparm);
    actx->nten = nrrdNuke(actx->nten);
    actx->constFilename = AIR_FALSE;
  }
  return;
}
/*
** _gageStandardPadder()
**
*********************************************************
** as of about Wed Apr 20 19:32:54 EDT 2005, this is moot
*********************************************************
**
** the usual/default padder used in gage, basically just a simple
** wrapper around nrrdPad_va(), but similar in spirit to nrrdSimplePad().
**
** The "kind" is needed to learn the baseDim for this kind of volume.
** The "_info" pointer is ignored.
**
** Any padder used in gage must, if it generates biff errors, 
** accumulate them under the GAGE key.  This padder is a shining
** example of this.
*/
Nrrd *
_gageStandardPadder(Nrrd *nin, gageKind *kind, 
                    int padding, gagePerVolume *pvl) {
  Nrrd *npad;
  char me[]="_gageStandardPadder", err[BIFF_STRLEN];

  int i, baseDim;
  ptrdiff_t amin[NRRD_DIM_MAX], amax[NRRD_DIM_MAX];

  AIR_UNUSED(pvl);

  if (!(nin && kind)) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(GAGE, err); return NULL;
  }

  baseDim = kind->baseDim;
  if (!( padding >= 0 )) {
    sprintf(err, "%s: given padding %d invalid", me, padding);
    biffAdd(GAGE, err); return NULL;
  }
  if (0 == padding) {
    /* we can use the original volume if we promise not to blow it away,
       see _gageStandardNixer() */
    return nin;
  } else {
    npad = nrrdNew();
    for (i=0; i<baseDim; i++) {
      amin[i] = 0;
      amax[i] = nin->axis[i].size - 1;
    }
    amin[0 + baseDim] = -padding;
    amin[1 + baseDim] = -padding;
    amin[2 + baseDim] = -padding;
    amax[0 + baseDim] = nin->axis[0 + baseDim].size - 1 + padding;
    amax[1 + baseDim] = nin->axis[1 + baseDim].size - 1 + padding;
    amax[2 + baseDim] = nin->axis[2 + baseDim].size - 1 + padding;
    if (nrrdPad_va(npad, nin, amin, amax, nrrdBoundaryBleed)) {
      sprintf(err, "%s: trouble padding input volume", me);
      biffMove(GAGE, err, NRRD); 

      nrrdNuke(npad);
      return NULL;
    }
  }
  return npad;
}
示例#25
0
int
alanTensorSet(alanContext *actx, Nrrd *nten, int oversample) {
  static const char me[]="alanTensorSet";

  if (!( actx && nten )) {
    biffAddf(ALAN, "%s: got NULL pointer", me);
    return 1;
  }
  DIM_SET;
  if (!( oversample > 0 )) {
    biffAddf(ALAN, "%s: oversample %d invalid", me, oversample);
    return 1;
  }
  if (2 == actx->dim) {
    if (!( 3 == nten->dim && 4 == nten->axis[0].size )) {
      biffAddf(ALAN, "%s: didn't get 3-D (4,X,Y) nrrd", me);
      return 1;
    }
  } else {
    if (!( 4 == nten->dim && 7 == nten->axis[0].size )) {
      biffAddf(ALAN, "%s: didn't get 4-D (7,X,Y,Z) nrrd", me);
      return 1;
    }
  }

  if (1 != oversample) {
    biffAddf(ALAN, "%s: sorry, can only handle oversample==1 now", me);
    return 1;
  }

  actx->nten = nrrdNuke(actx->nten);
  actx->nten = nrrdNew();
  if (nrrdConvert(actx->nten, nten, alan_nt)) {
    biffMovef(ALAN, NRRD, "%s: trouble converting tensors to alan_t", me);
    return 1;
  }
  actx->size[0] = AIR_UINT(oversample*nten->axis[1].size);
  actx->size[1] = AIR_UINT(oversample*nten->axis[2].size);
  if (3 == actx->dim) {
    actx->size[2] = AIR_UINT(oversample*nten->axis[3].size);
  } else {
    actx->size[2] = 1;
  }

  return 0;
}
示例#26
0
int
main(int argc, char *argv[]) {
  Nrrd *info;
  float sigma;

  AIR_UNUSED(argc);
  if (nrrdLoad(info=nrrdNew(), argv[1], NULL)) {
    fprintf(stderr, "trouble:\n%s\n", biffGet(BANE));
  }
  if (baneSigmaCalc(&sigma, info)) {
    fprintf(stderr, "trouble:\n%s\n", biffGet(BANE));
  }
  printf("%g\n", sigma);

  nrrdNuke(info);
  return 0;
}
示例#27
0
文件: clip.c 项目: CIBC-Internal/teem
int
_baneClipAnswer_TopN(int *countP, Nrrd *hvol, double *clipParm) {
  static const char me[]="_baneClipAnwer_TopN";
  Nrrd *copy;
  int *hits, tmp;
  size_t num;

  if (nrrdCopy(copy=nrrdNew(), hvol)) {
    biffMovef(BANE, NRRD, "%s: couldn't create copy of histovol", me);
    return 1;
  }
  hits = (int *)copy->data;
  num = nrrdElementNumber(copy);
  qsort(hits, num, sizeof(int), nrrdValCompare[nrrdTypeInt]);
  tmp = AIR_CLAMP(0, (int)clipParm[0], (int)num-1);
  *countP = hits[num-tmp-1];
  nrrdNuke(copy);

  return 0;
}
示例#28
0
/*
** this should only nix things created by pullContextNew, or the things
** (vols and ispecs) that were explicitly added to this context
*/
pullContext *
pullContextNix(pullContext *pctx) {
  unsigned int ii;
  
  if (pctx) {
    for (ii=0; ii<pctx->volNum; ii++) {
      pctx->vol[ii] = pullVolumeNix(pctx->vol[ii]);
    }
    pctx->volNum = 0;
    for (ii=0; ii<=PULL_INFO_MAX; ii++) {
      if (pctx->ispec[ii]) {
        pctx->ispec[ii] = pullInfoSpecNix(pctx->ispec[ii]);
      }
    }
    pctx->energySpec = pullEnergySpecNix(pctx->energySpec);
    /* handled elsewhere: bin, task, iterBarrierA, iterBarrierB */
    pctx->noutPos = nrrdNuke(pctx->noutPos);
    airFree(pctx);
  }
  return NULL;
}
示例#29
0
int
_nrrdHestIterParse(void *ptr, char *str, char err[AIR_STRLEN_HUGE]) {
  char me[]="_nrrdHestIterParse", *nerr;
  Nrrd *nrrd;
  NrrdIter **iterP;
  airArray *mop;
  double val;
  int ret;

  if (!(ptr && str)) {
    sprintf(err, "%s: got NULL pointer", me);
    return 1;
  }
  iterP = (NrrdIter **)ptr;
  mop = airMopNew();
  *iterP = nrrdIterNew();
  airMopAdd(mop, *iterP, (airMopper)nrrdIterNix, airMopOnError);

  /* the challenge here is determining if a given string represents a
     filename or a number.  Obviously there are cases where it could
     be both, so we'll assume its a filename first.  Because: there
     are different ways of writing the same number, such as "3" -->
     "+3", "3.1" --> "3.10", so someone accidently using the file when
     they mean to use the number has easy ways of changing the number
     representation, since these trivial transformations will probably
     not all result in valid filenames. Another problem is that one
     really wants a general robust test to see if a given string is a
     valid number representation AND NOTHING BUT THAT, and sscanf() is
     not that test.  In any case, if there are to be improved smarts
     about this matter, they need to be implemented below and nowhere
     else. */

  nrrd = nrrdNew();
  ret = nrrdLoad(nrrd, str, NULL);
  if (!ret) {
    /* first attempt at nrrdLoad() was SUCCESSFUL */
    nrrdIterSetOwnNrrd(*iterP, nrrd);
  } else {
    /* so it didn't load as a nrrd- if its because fopen() failed,
       then we'll try it as a number.  If its for another reason,
       then we complain */
    nrrdNuke(nrrd);
    if (2 != ret) {
      /* it failed because of something besides the fopen(), so complain */
      nerr = biffGetDone(NRRD);
      airStrcpy(err, AIR_STRLEN_HUGE, nerr);
      airMopError(mop); return 1;
    } else {
      /* fopen() failed, so it probably wasn't meant to be a filename */
      free(biffGetDone(NRRD));
      ret = airSingleSscanf(str, "%lf", &val);
      if (_nrrdLooksLikeANumber(str)
          || (1 == ret && (!AIR_EXISTS(val)
                           || AIR_ABS(AIR_PI - val) < 0.0001))) {
        /* either it patently looks like a number, or,
           it already parsed as a number and it is a special value */
        if (1 == ret) {
          nrrdIterSetValue(*iterP, val);
        } else {
          /* oh, this is bad. */
          fprintf(stderr, "%s: PANIC, is it a number or not?", me);
          exit(1);
        }
      } else {
        /* it doesn't look like a number, but the fopen failed, so
           we'll let it fail again and pass back the error messages */
        if (nrrdLoad(nrrd = nrrdNew(), str, NULL)) {
          nerr = biffGetDone(NRRD);
          airStrcpy(err, AIR_STRLEN_HUGE, nerr);
          airMopError(mop); return 1;
        } else {
          /* what the hell? */
          fprintf(stderr, "%s: PANIC, is it a nrrd or not?", me);
          exit(1);
        }
      }
    }
  }
  airMopAdd(mop, iterP, (airMopper)airSetNull, airMopOnError);
  airMopOkay(mop);
  return 0;
}
示例#30
0
/*
******** nrrdSpatialResample()
**
** general-purpose array-resampler: resamples a nrrd of any type
** (except block) and any dimension along any or all of its axes, with
** any combination of up- or down-sampling along the axes, with any
** kernel (specified by callback), with potentially a different kernel
** for each axis.  Whether or not to resample along axis d is
** controlled by the non-NULL-ity of info->kernel[ai].  Where to sample
** on the axis is controlled by info->min[ai] and info->max[ai]; these
** specify a range of "positions" aka "world space" positions, as 
** determined by the per-axis min and max of the input nrrd, which must
** be set for every resampled axis.
** 
** we cyclically permute those axes being resampled, and never touch
** the position (in axis ordering) of axes along which we are not
** resampling.  This strategy is certainly not the most intelligent
** one possible, but it does mean that the axis along which we're
** currently resampling-- the one along which we'll have to look at
** multiple adjecent samples-- is that resampling axis which is
** currently most contiguous in memory.  It may make sense to precede
** the resampling with an axis permutation which bubbles all the
** resampled axes to the front (most contiguous) end of the axis list,
** and then puts them back in place afterwards, depending on the cost
** of such axis permutation overhead.
*/
int
nrrdSpatialResample(Nrrd *nout, const Nrrd *nin,
                    const NrrdResampleInfo *info) {
  char me[]="nrrdSpatialResample", func[]="resample", err[BIFF_STRLEN];
  nrrdResample_t
    *array[NRRD_DIM_MAX],      /* intermediate copies of the input data
                                  undergoing resampling; we don't need a full-
                                  fledged nrrd for these.  Only about two of
                                  these arrays will be allocated at a time;
                                  intermediate results will be free()d when not
                                  needed */
    *_inVec,                   /* current input vector being resampled;
                                  not necessarily contiguous in memory
                                  (if strideIn != 1) */
    *inVec,                    /* buffer for input vector; contiguous */
    *_outVec;                  /* output vector in context of volume;
                                  never contiguous */
  double tmpF;
  double ratio,                /* factor by which or up or downsampled */
    ratios[NRRD_DIM_MAX];      /* record of "ratio" for all resampled axes,
                                  used to compute new spacing in output */

  Nrrd *floatNin;              /* if the input nrrd type is not nrrdResample_t,
                                  then we convert it and keep it here */
  unsigned int ai,
    pi,                        /* current pass */
    topLax,
    permute[NRRD_DIM_MAX],     /* how to permute axes of last pass to get
                                  axes for current pass */
    ax[NRRD_DIM_MAX+1][NRRD_DIM_MAX],  /* axis ordering on each pass */
    passes;                    /* # of passes needed to resample all axes */
  int i, s, e,
    topRax,                    /* the lowest index of an axis which is
                                  resampled.  If all axes are being resampled,
                                  then this is 0.  If for some reason the
                                  "x" axis (fastest stride) is not being
                                  resampled, but "y" is, then topRax is 1 */
    botRax,                    /* index of highest axis being resampled */
    typeIn, typeOut;           /* types of input and output of resampling */
  size_t sz[NRRD_DIM_MAX+1][NRRD_DIM_MAX];
                               /* how many samples along each
                                  axis, changing on each pass */

  /* all these variables have to do with the spacing of elements in
     memory for the current pass of resampling, and they (except
     strideIn) are re-set at the beginning of each pass */
  nrrdResample_t
    *weight;                  /* sample weights */
  unsigned int ci[NRRD_DIM_MAX+1],
    co[NRRD_DIM_MAX+1];
  int 
    sizeIn, sizeOut,          /* lengths of input and output vectors */
    dotLen,                   /* # input samples to dot with weights to get
                                 one output sample */
    doRound,                  /* actually do rounding on output: we DO NOT
                                 round when info->round but the output 
                                 type is not integral */
    *index;                   /* dotLen*sizeOut 2D array of input indices */
  size_t 
    I,                        /* swiss-army int */
    strideIn,                 /* the stride between samples in the input
                                 "scanline" being resampled */
    strideOut,                /* stride between samples in output 
                                 "scanline" from resampling */
    L, LI, LO, numLines,      /* top secret */
    numOut;                   /* # of _samples_, total, in output volume;
                                 this is for allocating the output */
  airArray *mop;              /* for cleaning up */
  
  if (!(nout && nin && info)) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(NRRD, err); return 1;
  }
  if (nrrdBoundaryUnknown == info->boundary) {
    sprintf(err, "%s: need to specify a boundary behavior", me);
    biffAdd(NRRD, err); return 1;
  }

  typeIn = nin->type;
  typeOut = nrrdTypeDefault == info->type ? typeIn : info->type;

  if (_nrrdResampleCheckInfo(nin, info)) {
    sprintf(err, "%s: problem with arguments", me);
    biffAdd(NRRD, err); return 1;
  }
  
  _nrrdResampleComputePermute(permute, ax, sz,
                              &topRax, &botRax, &passes,
                              nin, info);
  topLax = topRax ? 0 : 1;

  /* not sure where else to put this:
     (want to put it before 0 == passes branch)
     We have to assume some centering when doing resampling, and it would
     be stupid to not record it in the outgoing nrrd, since the value of
     nrrdDefaultCenter could always change. */
  for (ai=0; ai<nin->dim; ai++) {
    if (info->kernel[ai]) {
      nout->axis[ai].center = _nrrdCenter(nin->axis[ai].center);
    }
  }

  if (0 == passes) {
    /* actually, no resampling was desired.  Copy input to output,
       but with the clamping that we normally do at the end of resampling */
    nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, sz[0]);
    if (nrrdMaybeAlloc_nva(nout, typeOut, nin->dim, sz[0])) {
      sprintf(err, "%s: couldn't allocate output", me);
      biffAdd(NRRD, err); return 1;
    }
    numOut = nrrdElementNumber(nout);
    for (I=0; I<numOut; I++) {
      tmpF = nrrdDLookup[nin->type](nin->data, I);
      tmpF = nrrdDClamp[typeOut](tmpF);
      nrrdDInsert[typeOut](nout->data, I, tmpF);
    }
    nrrdAxisInfoCopy(nout, nin, NULL, NRRD_AXIS_INFO_NONE);
    /* HEY: need to create textual representation of resampling parameters */
    if (nrrdContentSet_va(nout, func, nin, "")) {
      sprintf(err, "%s:", me);
      biffAdd(NRRD, err); return 1;
    }
    if (nrrdBasicInfoCopy(nout, nin,
                          NRRD_BASIC_INFO_DATA_BIT
                          | NRRD_BASIC_INFO_TYPE_BIT
                          | NRRD_BASIC_INFO_BLOCKSIZE_BIT
                          | NRRD_BASIC_INFO_DIMENSION_BIT
                          | NRRD_BASIC_INFO_CONTENT_BIT
                          | NRRD_BASIC_INFO_COMMENTS_BIT
                          | (nrrdStateKeyValuePairsPropagate
                             ? 0
                             : NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT))) {
      sprintf(err, "%s:", me);
      biffAdd(NRRD, err); return 1;
    }
    return 0;
  }

  mop = airMopNew();
  /* convert input nrrd to nrrdResample_t if necessary */
  if (nrrdResample_nrrdType != typeIn) {
    if (nrrdConvert(floatNin = nrrdNew(), nin, nrrdResample_nrrdType)) {
      sprintf(err, "%s: couldn't create float copy of input", me);
      biffAdd(NRRD, err); airMopError(mop); return 1;
    }
    array[0] = (nrrdResample_t*)floatNin->data;
    airMopAdd(mop, floatNin, (airMopper)nrrdNuke, airMopAlways);
  } else {
    floatNin = NULL;
    array[0] = (nrrdResample_t*)nin->data;
  }
  
  /* compute strideIn; this is actually the same for every pass
     because (strictly speaking) in every pass we are resampling
     the same axis, and axes with lower indices are constant length */
  strideIn = 1;
  for (ai=0; ai<(unsigned int)topRax; ai++) { /* HEY scrutinize casts */
    strideIn *= nin->axis[ai].size;
  }
  /*
  printf("%s: strideIn = " _AIR_SIZE_T_CNV "\n", me, strideIn);
  */

  /* go! */
  for (pi=0; pi<passes; pi++) {
    /*
    printf("%s: --- pass %d --- \n", me, pi);
    */
    numLines = strideOut = 1;
    for (ai=0; ai<nin->dim; ai++) {
      if (ai < (unsigned int)botRax) {   /* HEY scrutinize cast */
        strideOut *= sz[pi+1][ai];
      }
      if (ai != (unsigned int)topRax) {  /* HEY scrutinize cast */
        numLines *= sz[pi][ai];
      }
    }
    sizeIn = sz[pi][topRax];
    sizeOut = sz[pi+1][botRax];
    numOut = numLines*sizeOut;
    /* for the rest of the loop body, d is the original "dimension"
       for the axis being resampled */
    ai = ax[pi][topRax];
    /*
    printf("%s(%d): numOut = " _AIR_SIZE_T_CNV "\n", me, pi, numOut);
    printf("%s(%d): numLines = " _AIR_SIZE_T_CNV "\n", me, pi, numLines);
    printf("%s(%d): stride: In=%d, Out=%d\n", me, pi, 
           (int)strideIn, (int)strideOut);
    printf("%s(%d): sizeIn = %d\n", me, pi, sizeIn);
    printf("%s(%d): sizeOut = %d\n", me, pi, sizeOut);
    */

    /* we can free the input to the previous pass 
       (if its not the given data) */
    if (pi > 0) {
      if (pi == 1) {
        if (array[0] != nin->data) {
          airMopSub(mop, floatNin, (airMopper)nrrdNuke);
          floatNin = nrrdNuke(floatNin);
          array[0] = NULL;
          /*
          printf("%s: pi %d: freeing array[0]\n", me, pi);
          */
        }
      } else {
        airMopSub(mop, array[pi-1], airFree);
        array[pi-1] = (nrrdResample_t*)airFree(array[pi-1]);
        /*
        printf("%s: pi %d: freeing array[%d]\n", me, pi, pi-1);
        */
      }
    }

    /* allocate output volume */
    array[pi+1] = (nrrdResample_t*)calloc(numOut, sizeof(nrrdResample_t));
    if (!array[pi+1]) {
      sprintf(err, "%s: couldn't create array of " _AIR_SIZE_T_CNV 
              " nrrdResample_t's for output of pass %d",
              me, numOut, pi);
      biffAdd(NRRD, err); airMopError(mop); return 1;
    }
    airMopAdd(mop, array[pi+1], airFree, airMopAlways);
    /*
    printf("%s: allocated array[%d]\n", me, pi+1);
    */

    /* allocate contiguous input scanline buffer, we alloc one more
       than needed to provide a place for the pad value.  That is, in
       fact, the over-riding reason to copy a scanline to a local
       array: so that there is a simple consistent (non-branchy) way
       to incorporate the pad values */
    inVec = (nrrdResample_t *)calloc(sizeIn+1, sizeof(nrrdResample_t));
    airMopAdd(mop, inVec, airFree, airMopAlways);
    inVec[sizeIn] = AIR_CAST(nrrdResample_t, info->padValue);

    dotLen = _nrrdResampleMakeWeightIndex(&weight, &index, &ratio,
                                          nin, info, ai);
    if (!dotLen) {
      sprintf(err, "%s: trouble creating weight and index vector arrays", me);
      biffAdd(NRRD, err); airMopError(mop); return 1;
    }
    ratios[ai] = ratio;
    airMopAdd(mop, weight, airFree, airMopAlways);
    airMopAdd(mop, index, airFree, airMopAlways);

    /* the skinny: resample all the scanlines */
    _inVec = array[pi];
    _outVec = array[pi+1];
    memset(ci, 0, (NRRD_DIM_MAX+1)*sizeof(int));
    memset(co, 0, (NRRD_DIM_MAX+1)*sizeof(int));
    for (L=0; L<numLines; L++) {
      /* calculate the index to get to input and output scanlines,
         according the coordinates of the start of the scanline */
      NRRD_INDEX_GEN(LI, ci, sz[pi], nin->dim);
      NRRD_INDEX_GEN(LO, co, sz[pi+1], nin->dim);
      _inVec = array[pi] + LI;
      _outVec = array[pi+1] + LO;
      
      /* read input scanline into contiguous array */
      for (i=0; i<sizeIn; i++) {
        inVec[i] = _inVec[i*strideIn];
      }

      /* do the weighting */
      for (i=0; i<sizeOut; i++) {
        tmpF = 0.0;
        /*
        fprintf(stderr, "%s: i = %d (tmpF=0)\n", me, (int)i);
        */
        for (s=0; s<dotLen; s++) {
          tmpF += inVec[index[s + dotLen*i]]*weight[s + dotLen*i];
          /*
          fprintf(stderr, "  tmpF += %g*%g == %g\n",
                  inVec[index[s + dotLen*i]], weight[s + dotLen*i], tmpF);
          */
        }
        _outVec[i*strideOut] = tmpF;
        /*
        fprintf(stderr, "--> out[%d] = %g\n",
                i*strideOut, _outVec[i*strideOut]);
        */
      }
 
      /* update the coordinates for the scanline starts.  We don't
         use the usual NRRD_COORD macros because we're subject to
         the unusual constraint that ci[topRax] and co[permute[topRax]]
         must stay exactly zero */
      e = topLax;
      ci[e]++; 
      co[permute[e]]++;
      while (L < numLines-1 && ci[e] == sz[pi][e]) {
        ci[e] = co[permute[e]] = 0;
        e++;
        e += e == topRax;
        ci[e]++; 
        co[permute[e]]++;
      }
    }

    /* pass-specific clean up */
    airMopSub(mop, weight, airFree);
    airMopSub(mop, index, airFree);
    airMopSub(mop, inVec, airFree);
    weight = (nrrdResample_t*)airFree(weight);
    index = (int*)airFree(index);
    inVec = (nrrdResample_t*)airFree(inVec);
  }

  /* clean up second-to-last array and scanline buffers */
  if (passes > 1) {
    airMopSub(mop, array[passes-1], airFree);
    array[passes-1] = (nrrdResample_t*)airFree(array[passes-1]);
    /*
    printf("%s: now freeing array[%d]\n", me, passes-1);
    */
  } else if (array[passes-1] != nin->data) {
    airMopSub(mop, floatNin, (airMopper)nrrdNuke);
    floatNin = nrrdNuke(floatNin);
  }
  array[passes-1] = NULL;
  
  /* create output nrrd and set axis info */
  if (nrrdMaybeAlloc_nva(nout, typeOut, nin->dim, sz[passes])) {
    sprintf(err, "%s: couldn't allocate final output nrrd", me);
    biffAdd(NRRD, err); airMopError(mop); return 1;
  }
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopOnError);
  nrrdAxisInfoCopy(nout, nin, NULL, 
                   (NRRD_AXIS_INFO_SIZE_BIT
                    | NRRD_AXIS_INFO_MIN_BIT
                    | NRRD_AXIS_INFO_MAX_BIT
                    | NRRD_AXIS_INFO_SPACING_BIT
                    | NRRD_AXIS_INFO_SPACEDIRECTION_BIT  /* see below */
                    | NRRD_AXIS_INFO_THICKNESS_BIT
                    | NRRD_AXIS_INFO_KIND_BIT));
  for (ai=0; ai<nin->dim; ai++) {
    if (info->kernel[ai]) {
      /* we do resample this axis */
      nout->axis[ai].spacing = nin->axis[ai].spacing/ratios[ai];
      /* no way to usefully update thickness: we could be doing blurring
         but maintaining the number of samples: thickness increases, or
         we could be downsampling, in which the relationship between the
         sampled and the skipped regions of space becomes complicated:
         no single scalar can represent it, or we could be upsampling,
         in which the notion of "skip" could be rendered meaningless */
      nout->axis[ai].thickness = AIR_NAN;
      nout->axis[ai].min = info->min[ai];
      nout->axis[ai].max = info->max[ai];
      /*
        HEY: this is currently a bug: all this code was written long
        before there were space directions, so min/max are always 
        set, regardless of whethere there are incoming space directions
        which then disallows output space directions on the same axes
      _nrrdSpaceVecScale(nout->axis[ai].spaceDirection,
                         1.0/ratios[ai], nin->axis[ai].spaceDirection);
      */
      nout->axis[ai].kind = _nrrdKindAltered(nin->axis[ai].kind, AIR_TRUE);
    } else {
      /* this axis remains untouched */
      nout->axis[ai].min = nin->axis[ai].min;
      nout->axis[ai].max = nin->axis[ai].max;
      nout->axis[ai].spacing = nin->axis[ai].spacing;
      nout->axis[ai].thickness = nin->axis[ai].thickness;
      nout->axis[ai].kind = nin->axis[ai].kind;
    }
  }
  /* HEY: need to create textual representation of resampling parameters */
  if (nrrdContentSet_va(nout, func, nin, "")) {
    sprintf(err, "%s:", me);
    biffAdd(NRRD, err); return 1;
  }

  /* copy the resampling final result into the output nrrd, maybe
     rounding as we go to make sure that 254.9999 is saved as 255
     in uchar output, and maybe clamping as we go to insure that
     integral results don't have unexpected wrap-around. */
  if (info->round) {
    if (nrrdTypeInt == typeOut ||
        nrrdTypeUInt == typeOut ||
        nrrdTypeLLong == typeOut ||
        nrrdTypeULLong == typeOut) {
      fprintf(stderr, "%s: WARNING: possible erroneous output with "
              "rounding of %s output type due to int-based implementation "
              "of rounding\n", me, airEnumStr(nrrdType, typeOut));
    }
    doRound = nrrdTypeIsIntegral[typeOut];
  } else {
    doRound = AIR_FALSE;
  }
  numOut = nrrdElementNumber(nout);
  for (I=0; I<numOut; I++) {
    tmpF = array[passes][I];
    if (doRound) {
      tmpF = AIR_CAST(nrrdResample_t, AIR_ROUNDUP(tmpF));
    }
    if (info->clamp) {
      tmpF = nrrdDClamp[typeOut](tmpF);
    }
    nrrdDInsert[typeOut](nout->data, I, tmpF);
  }

  if (nrrdBasicInfoCopy(nout, nin,
                        NRRD_BASIC_INFO_DATA_BIT
                        | NRRD_BASIC_INFO_TYPE_BIT
                        | NRRD_BASIC_INFO_BLOCKSIZE_BIT
                        | NRRD_BASIC_INFO_DIMENSION_BIT
                        | NRRD_BASIC_INFO_CONTENT_BIT
                        | NRRD_BASIC_INFO_COMMENTS_BIT
                        | (nrrdStateKeyValuePairsPropagate
                           ? 0
                           : NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT))) {
    sprintf(err, "%s:", me);
    biffAdd(NRRD, err); return 1;
  }

  /* enough already */
  airMopOkay(mop);
  return 0;
}