Пример #1
0
int
unrrdu_joinMain(int argc, char **argv, char *me, hestParm *hparm) {
  hestOpt *opt = NULL;
  char *out, *err, *label;
  Nrrd **nin;
  Nrrd *nout;
  int incrDim, pret;
  unsigned int ninLen, axis;
  double mm[2], spc;
  airArray *mop;

  hparm->respFileEnable = AIR_TRUE;

  hestOptAdd(&opt, "i,input", "nin0", airTypeOther, 1, -1, &nin, NULL,
             "everything to be joined together",
             &ninLen, NULL, nrrdHestNrrd);
  OPT_ADD_AXIS(axis, "axis to join along");
  hestOptAdd(&opt, "incr", NULL, airTypeInt, 0, 0, &incrDim, NULL,
             "in situations where the join axis is *not* among the existing "
             "axes of the input nrrds, then this flag signifies that the join "
             "axis should be *inserted*, and the output dimension should "
             "be one greater than input dimension.  Without this flag, the "
             "nrrds are joined side-by-side, along an existing axis.");
  hestOptAdd(&opt, "l,label", "label", airTypeString, 1, 1, &label, "",
             "label to associate with join axis");
  hestOptAdd(&opt, "mm,minmax", "min max", airTypeDouble, 2, 2, mm, "nan nan",
             "min and max values along join axis");
  hestOptAdd(&opt, "sp,spacing", "spc", airTypeDouble, 1, 1, &spc, "nan",
             "spacing between samples along join axis");
  OPT_ADD_NOUT(out, "output nrrd");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_joinInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);

  if (nrrdJoin(nout, AIR_CAST(const Nrrd**, nin), ninLen, axis, incrDim)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error joining nrrds:\n%s", me, err);
    airMopError(mop);
    return 1;
  }
Пример #2
0
int
unrrdu_projectMain(int argc, const char **argv, const char *me,
                   hestParm *hparm) {
    hestOpt *opt = NULL;
    char *out, *err;
    Nrrd *nin, *nout;
    unsigned int axis;
    int measr, pret, type;
    airArray *mop;

    OPT_ADD_AXIS(axis, "axis to project along");
    hestOptAdd(&opt, "m,measure", "measr", airTypeEnum, 1, 1, &measr, NULL,
               "How to \"measure\" a scanline, by summarizing all its values "
               "with a single scalar. " NRRD_MEASURE_DESC,
               NULL, nrrdMeasure);
    hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &type, "default",
               "type to use for output. By default (not using this option), "
               "the output type is determined auto-magically",
               NULL, NULL, &unrrduHestMaybeTypeCB);
    OPT_ADD_NIN(nin, "input nrrd");
    OPT_ADD_NOUT(out, "output nrrd");

    mop = airMopNew();
    airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

    USAGE(_unrrdu_projectInfoL);
    PARSE();
    airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

    nout = nrrdNew();
    airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);

    if (nrrdProject(nout, nin, axis, measr, type)) {
        airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
        fprintf(stderr, "%s: error projecting nrrd:\n%s", me, err);
        airMopError(mop);
        return 1;
    }

    SAVE(out, nout, NULL);

    airMopOkay(mop);
    return 0;
}
Пример #3
0
int
unrrdu_axsplitMain(int argc, const char **argv, const char *me,
                   hestParm *hparm) {
  hestOpt *opt = NULL;
  char *out, *err;
  Nrrd *nin, *nout;
  int pret;
  size_t size[2];
  unsigned int axis;
  airArray *mop;

  OPT_ADD_AXIS(axis, "dimension (axis index) to split at");
  hestOptAdd(&opt, "s,size", "fast, slow sizes", airTypeSize_t, 2, 2,
             size, NULL,
             "fast and slow axis sizes to produce as result of splitting "
             "given axis.");
  OPT_ADD_NIN(nin, "input nrrd");
  OPT_ADD_NOUT(out, "output nrrd");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_axsplitInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);

  if (nrrdAxesSplit(nout, nin, axis, size[0], size[1])) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error splitting axis:\n%s", me, err);
    airMopError(mop);
    return 1;
  }

  SAVE(out, nout, NULL);

  airMopOkay(mop);
  return 0;
}
Пример #4
0
int
unrrdu_axinsertMain(int argc, char **argv, char *me, hestParm *hparm) {
  hestOpt *opt = NULL;
  char *out, *err, *label;
  Nrrd *nin, *nout;
  int pret;
  unsigned int axis;
  airArray *mop;

  OPT_ADD_AXIS(axis, "dimension (axis index) at which to insert the new axis");
  hestOptAdd(&opt, "l,label", "label", airTypeString, 1, 1, &label, "",
             "label to associate with new axis");
  OPT_ADD_NIN(nin, "input nrrd");
  OPT_ADD_NOUT(out, "output nrrd");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_axinsertInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);

  if (nrrdAxesInsert(nout, nin, axis)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error inserting axis:\n%s", me, err);
    airMopError(mop);
    return 1;
  }
  if (strlen(label)) {
    nout->axis[axis].label = (char *)airFree(nout->axis[axis].label);
    nout->axis[axis].label = airStrdup(label);
  }

  SAVE(out, nout, NULL);

  airMopOkay(mop);
  return 0;
}
Пример #5
0
int
unrrdu_histaxMain(int argc, const char **argv, const char *me,
                  hestParm *hparm) {
  hestOpt *opt = NULL;
  char *out, *err;
  Nrrd *nin, *nout;
  char *minStr, *maxStr;
  int type, pret, blind8BitRange;
  unsigned int axis, bins;
  airArray *mop;
  NrrdRange *range;

  OPT_ADD_AXIS(axis, "axis to histogram along");
  hestOptAdd(&opt, "b,bin", "bins", airTypeUInt, 1, 1, &bins, NULL,
             "# of bins in histogram");
  OPT_ADD_TYPE(type, "output type", "uchar");
  /* HEY copy and paste from unrrdu/quantize.c */
  hestOptAdd(&opt, "min,minimum", "value", airTypeString, 1, 1,
             &minStr, "nan",
             "The value to map to zero, given explicitly as a regular number, "
             "*or*, if the number is given with a \"" NRRD_MINMAX_PERC_SUFF
             "\" suffix, this "
             "minimum is specified in terms of the percentage of samples in "
             "input that are lower. "
             "\"0" NRRD_MINMAX_PERC_SUFF "\" means the "
             "lowest input value is used, "
             "\"1" NRRD_MINMAX_PERC_SUFF "\" means that the "
             "1% of the lowest values are all mapped to zero. "
             "By default (not using this option), the lowest input value is "
             "used.");
  hestOptAdd(&opt, "max,maximum", "value", airTypeString, 1, 1,
             &maxStr, "nan",
             "The value to map to the highest unsigned integral value, given "
             "explicitly as a regular number, "
             "*or*, if the number is given with "
             "a \"" NRRD_MINMAX_PERC_SUFF "\" suffix, "
             "this maximum is specified "
             "in terms of the percentage of samples in input that are higher. "
             "\"0" NRRD_MINMAX_PERC_SUFF "\" means the highest input value is "
             "used, which is also the default "
             "behavior (same as not using this option).");
  hestOptAdd(&opt, "blind8", "bool", airTypeBool, 1, 1, &blind8BitRange,
             nrrdStateBlind8BitRange ? "true" : "false",
             "Whether to know the range of 8-bit data blindly "
             "(uchar is always [0,255], signed char is [-128,127]).");
  OPT_ADD_NIN(nin, "input nrrd");
  OPT_ADD_NOUT(out, "output nrrd");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_histaxInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  range = nrrdRangeNew(AIR_NAN, AIR_NAN);
  airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways);
  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdRangePercentileFromStringSet(range, nin, minStr, maxStr,
                                       10*bins /* HEY magic */,
                                       blind8BitRange)
      || nrrdHistoAxis(nout, nin, range, axis, bins, type)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error doing axis histogramming:\n%s", me, err);
    airMopError(mop);
    return 1;
  }

  SAVE(out, nout, NULL);

  airMopOkay(mop);
  return 0;
}
Пример #6
0
int
unrrdu_sselectMain(int argc, const char **argv, const char *me,
                   hestParm *hparm) {
  hestOpt *opt = NULL;
  char *err;
  Nrrd *nin, *noutAbove, *noutBelow, *nline;
  unsigned int axis;
  double thresh;
  int pret;
  airArray *mop;
  char *outS[2];

  OPT_ADD_NIN(nin, "input nrrd");
  OPT_ADD_AXIS(axis, "axis to slice along");
  hestOptAdd(&opt, "s,selector", "nline", airTypeOther, 1, 1, &nline, NULL,
             "the 1-D nrrd of values to compare with threshold",
             NULL, NULL, nrrdHestNrrd);
  hestOptAdd(&opt, "th", "thresh", airTypeDouble, 1, 1, &thresh,
             NULL, "threshold on selector line");
  hestOptAdd(&opt, "o,output", "above below", airTypeString, 2, 2,
             outS, "- x",
             "outputs for slices corresponding to values "
             "above (first) and below (second) given threshold. "
             "Use \"x\" to say that no output is desired.");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_sselectInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  if (!strcmp(outS[0], "x") && !strcmp(outS[1], "x")) {
    fprintf(stderr, "%s: need to save either above or below slices "
            "(can't use \"x\" for both)\n", me);
    airMopError(mop);
    return 1;
  }
  if (strcmp(outS[0], "x")) {
    noutAbove = nrrdNew();
    airMopAdd(mop, noutAbove, (airMopper)nrrdNuke, airMopAlways);
  } else {
    noutAbove = NULL;
  }
  if (strcmp(outS[1], "x")) {
    noutBelow = nrrdNew();
    airMopAdd(mop, noutBelow, (airMopper)nrrdNuke, airMopAlways);
  } else {
    noutBelow = NULL;
  }

  if (nrrdSliceSelect(noutAbove, noutBelow, nin, axis,
                      nline, thresh)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error selecting slices nrrd:\n%s", me, err);
    airMopError(mop);
    return 1;
  }

  if (noutAbove) {
    SAVE(outS[0], noutAbove, NULL);
  }
  if (noutBelow) {
    SAVE(outS[1], noutBelow, NULL);
  }

  airMopOkay(mop);
  return 0;
}
Пример #7
0
int
unrrdu_diceMain(int argc, const char **argv, const char *me,
                hestParm *hparm) {
  hestOpt *opt = NULL;
  char *base, *err, fnout[AIR_STRLEN_MED], /* file name out */
    fffname[AIR_STRLEN_MED],  /* format for filename */
    *ftmpl;                   /* format template */
  Nrrd *nin, *nout;
  int pret, fit;
  unsigned int axis, start, pos, top, size, sanity;
  airArray *mop;

  OPT_ADD_AXIS(axis, "axis to slice along");
  OPT_ADD_NIN(nin, "input nrrd");
  hestOptAdd(&opt, "s,start", "start", airTypeUInt, 1, 1, &start, "0",
             "integer value to start numbering with");
  hestOptAdd(&opt, "ff,format", "form", airTypeString, 1, 1, &ftmpl, "",
             "a printf-style format to use for generating all "
             "filenames.  Use this to override the number of characters "
             "used to represent the slice position, or the file format "
             "of the output, e.g. \"-ff %03d.ppm\" for 000.ppm, "
             "001.ppm, etc. By default (not using this option), slices "
             "are saved in NRRD format (or PNM or PNG where possible) "
             "with shortest possible filenames.");
  /* the fact that we're using unsigned int instead of size_t is
     its own kind of sanity check */
  hestOptAdd(&opt, "l,limit", "max#", airTypeUInt, 1, 1, &sanity, "9999",
             "a sanity check on how many slice files should be saved "
             "out, to prevent accidentally dicing the wrong axis "
             "or the wrong array. Can raise this value if needed.");
  hestOptAdd(&opt, "o,output", "prefix", airTypeString, 1, 1, &base, NULL,
             "output filename prefix (excluding info set via \"-ff\"), "
             "basically to set path of output files (so be sure to end "
             "with \"/\".");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_diceInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  if (!( axis < nin->dim )) {
    fprintf(stderr, "%s: given axis (%u) outside range [0,%u]\n",
            me, axis, nin->dim-1);
    airMopError(mop);
    return 1;
  }
  if (nin->axis[axis].size > sanity) {
    char stmp[AIR_STRLEN_SMALL];
    fprintf(stderr, "%s: axis %u size %s > sanity limit %u; "
            "increase via \"-l\"\n", me,
            axis, airSprintSize_t(stmp, nin->axis[axis].size), sanity);
    airMopError(mop);
    return 1;
  }
  size = AIR_UINT(nin->axis[axis].size);

  /* HEY: this should use nrrdSaveMulti(), and if there's additional
     smarts here, they should be moved into nrrdSaveMulti() */
  if (airStrlen(ftmpl)) {
    if (!( _nrrdContainsPercentThisAndMore(ftmpl, 'd')
           || _nrrdContainsPercentThisAndMore(ftmpl, 'u') )) {
      fprintf(stderr, "%s: given filename format \"%s\" doesn't seem to "
              "have the converstion specification to print an integer\n",
              me, ftmpl);
      airMopError(mop);
      return 1;
    }
    sprintf(fffname, "%%s%s", ftmpl);
  } else {
    unsigned int dignum=0, tmps;
    tmps = top = start + size - 1;
    do {
      dignum++;
      tmps /= 10;
    } while (tmps);
    /* sprintf the number of digits into the string that will be used
       to sprintf the slice number into the filename */
    sprintf(fffname, "%%s%%0%uu.nrrd", dignum);
  }
  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);

  for (pos=0; pos<size; pos++) {
    if (nrrdSlice(nout, nin, axis, pos)) {
      airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: error slicing nrrd:%s\n", me, err);
      airMopError(mop);
      return 1;
    }
    if (0 == pos && !airStrlen(ftmpl)) {
      /* See if these slices would be better saved as PNG or PNM images.
         Altering the file name will tell nrrdSave() to use a different
         file format.  We wait till now to check this so that we can
         work from the actual slice */
      if (nrrdFormatPNG->fitsInto(nout, nrrdEncodingRaw, AIR_FALSE)) {
        strcpy(fffname + strlen(fffname) - 4, "png");
      } else {
        fit = nrrdFormatPNM->fitsInto(nout, nrrdEncodingRaw, AIR_FALSE);
        if (2 == fit) {
          strcpy(fffname + strlen(fffname) - 4, "pgm");
        } else if (3 == fit) {
          strcpy(fffname + strlen(fffname) - 4, "ppm");
        }
      }
    }
    sprintf(fnout, fffname, base, pos+start);
    fprintf(stderr, "%s: %s ...\n", me, fnout);
    if (nrrdSave(fnout, nout, NULL)) {
      airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: error writing nrrd to \"%s\":%s\n",
              me, fnout, err);
      airMopError(mop);
      return 1;
    }
  }

  airMopOkay(mop);
  return 0;
}
Пример #8
0
int
unrrdu_diceMain(int argc, char **argv, char *me, hestParm *hparm) {
  hestOpt *opt = NULL;
  char *base, *err, fnout[AIR_STRLEN_MED], /* file name out */
    fffname[AIR_STRLEN_MED],  /* format for filename */
    *ftmpl;                   /* format template */
  Nrrd *nin, *nout;
  int top, pret, start, fit;
  unsigned int axis;
  size_t pos;
  airArray *mop;

  OPT_ADD_AXIS(axis, "axis to slice along");
  OPT_ADD_NIN(nin, "input nrrd");
  hestOptAdd(&opt, "s,start", "start", airTypeInt, 1, 1, &start, "0",
             "integer value to start numbering with");
  hestOptAdd(&opt, "ff,format", "form", airTypeString, 1, 1, &ftmpl, "",
             "a printf-style format to use for generating all "
             "filenames.  Use this to override the number of characters "
             "used to represent the slice position, or the file format "
             "of the output, e.g. \"-ff %03d.ppm\" for 000.ppm, "
             "001.ppm, etc. By default (not using this option), slices "
             "are saved in NRRD format (or PNM or PNG where possible) "
             "with shortest possible filenames.");
  hestOptAdd(&opt, "o,output", "prefix", airTypeString, 1, 1, &base, NULL,
             "output filename prefix (excluding info set via \"-ff\"), "
             "basically to set path of output files (so be sure to end "
             "with \"/\".");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_diceInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  if (start < 0) {
    fprintf(stderr, "%s: given start index (%d) less than zero\n", me, start);
    airMopError(mop);
    return 1;
  }
  if (!( axis < nin->dim )) {
    fprintf(stderr, "%s: given axis (%u) outside range [0,%u]\n",
            me, axis, nin->dim-1);
    airMopError(mop);
    return 1;
  }
  
  /* HEY: this should use nrrdSaveMulti(), and if there's additional
     smarts here, they should be moved into nrrdSaveMulti() */
  if (airStrlen(ftmpl)) {
    if (!( _nrrdContainsPercentThisAndMore(ftmpl, 'd') 
           || _nrrdContainsPercentThisAndMore(ftmpl, 'u') )) {
      fprintf(stderr, "%s: given filename format \"%s\" doesn't seem to "
              "have the converstion specification to print an integer\n",
              me, ftmpl);
      airMopError(mop);
      return 1;
    }
    sprintf(fffname, "%%s%s", ftmpl);
  } else {
    top = start + nin->axis[axis].size-1;
    if (top > 9999999) {
      sprintf(fffname, "%%s%%08d.nrrd");
    } else if (top > 999999) {
      sprintf(fffname, "%%s%%07d.nrrd");
    } else if (top > 99999) {
      sprintf(fffname, "%%s%%06d.nrrd");
    } else if (top > 9999) {
      sprintf(fffname, "%%s%%05d.nrrd");
    } else if (top > 999) {
      sprintf(fffname, "%%s%%04d.nrrd");
    } else if (top > 99) {
      sprintf(fffname, "%%s%%03d.nrrd");
    } else if (top > 9) {
      sprintf(fffname, "%%s%%02d.nrrd");
    } else {
      sprintf(fffname, "%%s%%01d.nrrd");
    }
  }
  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);

  for (pos=0; pos<nin->axis[axis].size; pos++) {
    if (nrrdSlice(nout, nin, axis, pos)) {
      airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: error slicing nrrd:%s\n", me, err);
      airMopError(mop);
      return 1;
    }
    if (0 == pos && !airStrlen(ftmpl)) {
      /* See if these slices would be better saved as PNG or PNM images.
         Altering the file name will tell nrrdSave() to use a different
         file format. */
      if (nrrdFormatPNG->fitsInto(nout, nrrdEncodingRaw, AIR_FALSE)) {
        strcpy(fffname + strlen(fffname) - 4, "png");
      } else {
        fit = nrrdFormatPNM->fitsInto(nout, nrrdEncodingRaw, AIR_FALSE);
        if (2 == fit) {
          strcpy(fffname + strlen(fffname) - 4, "pgm");
        } else if (3 == fit) {
          strcpy(fffname + strlen(fffname) - 4, "ppm");
        }
      }
    }
    sprintf(fnout, fffname, base, pos+start);
    fprintf(stderr, "%s: %s ...\n", me, fnout);
    if (nrrdSave(fnout, nout, NULL)) {
      airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: error writing nrrd to \"%s\":%s\n",
              me, fnout, err);
      airMopError(mop);
      return 1;
    }
  }

  airMopOkay(mop);
  return 0;
}
Пример #9
0
int
unrrdu_shuffleMain(int argc, char **argv, char *me, hestParm *hparm) {
  hestOpt *opt = NULL;
  char *out, *err;
  Nrrd *nin, *nout;
  unsigned int di, axis, permLen, *perm, *iperm, *whichperm;
  size_t *realperm;
  int inverse, pret;
  airArray *mop;

  /* so that long permutations can be read from file */
  hparm->respFileEnable = AIR_TRUE;

  hestOptAdd(&opt, "p,permute", "slc0 slc1", airTypeUInt, 1, -1, &perm, NULL,
             "new slice ordering", &permLen);
  hestOptAdd(&opt, "inv,inverse", NULL, airTypeInt, 0, 0, &inverse, NULL,
             "use inverse of given permutation");
  OPT_ADD_AXIS(axis, "axis to shuffle along");
  OPT_ADD_NIN(nin, "input nrrd");
  OPT_ADD_NOUT(out, "output nrrd");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_shuffleInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
  
  /* we have to do error checking on axis in order to do error
     checking on length of permutation */
  if (!( axis < nin->dim )) {
    fprintf(stderr, "%s: axis %d not in valid range [0,%d]\n", 
            me, axis, nin->dim-1);
    airMopError(mop);
    return 1;
  }
  if (!( permLen == nin->axis[axis].size )) {
    fprintf(stderr, "%s: permutation length (%u) != axis %d's size ("
            _AIR_SIZE_T_CNV ")\n",
            me, permLen, axis, nin->axis[axis].size);
    airMopError(mop);
    return 1;
  }
  if (inverse) {
    iperm = (unsigned int*)calloc(permLen, sizeof(unsigned int));
    airMopAdd(mop, iperm, airFree, airMopAlways);
    if (nrrdInvertPerm(iperm, perm, permLen)) {
      fprintf(stderr,
              "%s: couldn't compute inverse of given permutation\n", me);
      airMopError(mop);
      return 1;
    }
    whichperm = iperm;
  } else {
    whichperm = perm;
  }
  
  realperm = (size_t*)calloc(permLen, sizeof(size_t));
  airMopAdd(mop, realperm, airFree, airMopAlways);
  for (di=0; di<permLen; di++) {
    realperm[di] = whichperm[di];
  }
  if (nrrdShuffle(nout, nin, axis, realperm)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error shuffling nrrd:\n%s", me, err);
    airMopError(mop);
    return 1;
  }

  SAVE(out, nout, NULL);

  airMopOkay(mop);
  return 0;
}
Пример #10
0
int
unrrdu_axinfoMain(int argc, char **argv, char *me, hestParm *hparm) {
  hestOpt *opt = NULL;
  char *out, *err, *label, *units, *centerStr;
  Nrrd *nin, *nout;
  int pret, center;
  unsigned int axis;
  double mm[2], spc;
  airArray *mop;

  OPT_ADD_AXIS(axis, "dimension (axis index) to modify");
  hestOptAdd(&opt, "l,label", "label", airTypeString, 1, 1, &label, "",
             "label to associate with axis");
  hestOptAdd(&opt, "u,units", "units", airTypeString, 1, 1, &units, "",
             "units of measurement");
  hestOptAdd(&opt, "mm,minmax", "min max", airTypeDouble, 2, 2, mm, "nan nan",
             "min and max values along axis");
  hestOptAdd(&opt, "sp,spacing", "spacing", airTypeDouble, 1, 1, &spc, "nan",
             "spacing between samples along axis");
  /* HEY: this is currently a fundamental (but only rarely annoying)
     problem in hest.  Because there is functionally no difference
     between whether an option's information comes from the default
     string or from the command-line, there is no real way to tell
     hest, "hey, its just fine for this option to not be used, and
     if its not used, DON'T DO ANYTHING".  The games of setting strings
     to "" and floats/doubles to NaN are ways of compensating for
     this.  However, there is no analogous trick for airEnums.
  hestOptAdd(&opt, "c,center", "center", airTypeEnum, 1, 1, &cent, "unknown",
             "centering of axis: \"cell\" or \"node\"", 
             NULL, nrrdCenter);
  */
  /* but this hack will do for now */
  hestOptAdd(&opt, "c,center", "center", airTypeString, 1, 1, &centerStr, "",
             "axis centering: \"cell\" or \"node\".  Not using this option "
             "leaves the centering as it is on input");

  OPT_ADD_NIN(nin, "input nrrd");
  OPT_ADD_NOUT(out, "output nrrd");

  mop = airMopNew();
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);

  USAGE(_unrrdu_axinfoInfoL);
  PARSE();
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);

  if (!( axis < nin->dim )) {
    fprintf(stderr, "%s: axis %u not in valid range [0,%u]\n", 
            me, axis, nin->dim-1);
    airMopError(mop);
    return 1;
  }
  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
  if (nrrdCopy(nout, nin)) {
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: error copying input:\n%s", me, err);
    airMopError(mop);
    return 1;
  }
  
  if (strlen(label)) {
    nout->axis[axis].label = (char *)airFree(nout->axis[axis].label);
    nout->axis[axis].label = airStrdup(label);
  }
  if (strlen(units)) {
    nout->axis[axis].units = (char *)airFree(nout->axis[axis].units);
    nout->axis[axis].units = airStrdup(units);
  }
  if (AIR_EXISTS(mm[0])) {
    nout->axis[axis].min = mm[0];
  }
  if (AIR_EXISTS(mm[1])) {
    nout->axis[axis].max = mm[1];
  }
  if (AIR_EXISTS(spc)) {
    nout->axis[axis].spacing = spc;
  }
  /* see above
  if (nrrdCenterUnknown != cent) {
    nout->axis[axis].center = cent;
  }
  */
  if (airStrlen(centerStr)) {
    if (!(center = airEnumVal(nrrdCenter, centerStr))) {
      fprintf(stderr, "%s: couldn't parse \"%s\" as %s", me,
              centerStr, nrrdCenter->name);
      airMopError(mop);
      return 1;
    }
    nout->axis[axis].center = center;
  }

  SAVE(out, nout, NULL);

  airMopOkay(mop);
  return 0;
}