int unrrdu_flipMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int pret; unsigned int axis; airArray *mop; OPT_ADD_AXIS(axis, "axis to flip along"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_flipInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdFlip(nout, nin, axis)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error flipping nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_shuffleMain(int argc, const char **argv, const 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 )) { char stmp[AIR_STRLEN_SMALL]; fprintf(stderr, "%s: permutation length (%u) != axis %d's size (%s)\n", me, permLen, axis, airSprintSize_t(stmp, nin->axis[axis].size)); airMopError(mop); return 1; } if (inverse) { iperm = AIR_CALLOC(permLen, 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 {
int unrrdu_axdeleteMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout, *ntmp; int pret, _axis; unsigned axis; airArray *mop; hestOptAdd(&opt, "a,axis", "axis", airTypeInt, 1, 1, &_axis, NULL, "dimension (axis index) of the axis to remove"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_axdeleteInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (-1 == _axis) { ntmp = nrrdNew(); airMopAdd(mop, ntmp, (airMopper)nrrdNuke, airMopAlways); if (nrrdCopy(nout, nin)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error copying axis:\n%s", me, err); airMopError(mop); return 1; } for (axis=0; axis<nout->dim && nout->axis[axis].size > 1; axis++); while (axis<nout->dim) { if (nrrdAxesDelete(ntmp, nout, axis) || nrrdCopy(nout, ntmp)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error deleting axis:\n%s", me, err); airMopError(mop); return 1; } for (axis=0; axis<nout->dim && nout->axis[axis].size > 1; axis++); } } else { if (nrrdAxesDelete(nout, nin, _axis)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error deleting axis:\n%s", me, err); airMopError(mop); return 1; } } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_ccfindMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err, *valS; Nrrd *nin, *nout, *nval=NULL; airArray *mop; int type, pret; unsigned int conny; hestOptAdd(&opt, "v,values", "filename", airTypeString, 1, 1, &valS, "", "Giving a filename here allows you to save out the values " "associated with each connect component. This can be used " "later with \"ccmerge -d\". By default, no record of the " "original CC values is kept."); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &type, "default", "type to use for output, to store the CC ID values. By default " "(not using this option), the type used will be the smallest of " "uchar, ushort, or int, that can represent all the CC ID values. " "Using this option allows one to specify the integral type to " "be used.", NULL, NULL, &unrrduHestMaybeTypeCB); hestOptAdd(&opt, "c,connect", "connectivity", airTypeUInt, 1, 1, &conny, NULL, "what kind of connectivity to use: the number of coordinates " "that vary in order to traverse the neighborhood of a given " "sample. In 2D: \"1\": 4-connected, \"2\": 8-connected"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_ccfindInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdCCFind(nout, airStrlen(valS) ? &nval : NULL, nin, type, conny)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error doing connected components:\n%s", me, err); airMopError(mop); return 1; } if (nval) { airMopAdd(mop, nval, (airMopper)nrrdNuke, airMopAlways); } if (airStrlen(valS)) { SAVE(valS, nval, NULL); } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_spliceMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout, *nslice; unsigned int axis; int pret; long int _pos[2]; size_t pos; airArray *mop; OPT_ADD_AXIS(axis, "axis to splice along"); hestOptAdd(&opt, "p,position", "pos", airTypeOther, 1, 1, _pos, NULL, "position to splice at:\n " "\b\bo <int> gives 0-based index\n " "\b\bo M-<int> give index relative " "to the last sample on the axis (M == #samples-1).", NULL, NULL, &unrrduHestPosCB); hestOptAdd(&opt, "s,slice", "nslice", airTypeOther, 1, 1, &(nslice), NULL, "slice nrrd. This the slice to be inserted in \"nin\"", NULL, NULL, nrrdHestNrrd); OPT_ADD_NIN(nin, "input nrrd. This the nrrd into which the slice will " "be inserted"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_spliceInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); if (!( axis < nin->dim )) { fprintf(stderr, "%s: axis %u not in range [0,%u]\n", me, axis, nin->dim-1); return 1; } if (_pos[0] == -1) { fprintf(stderr, "%s: m+<int> specification format meaningless here\n", me); return 1; } pos = _pos[0]*(nin->axis[axis].size-1) + _pos[1]; nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdSplice(nout, nin, nslice, axis, pos)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error splicing nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_histaxMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int type, bins, pret, blind8BitRange; unsigned int axis; double min, max; airArray *mop; NrrdRange *range; OPT_ADD_AXIS(axis, "axis to histogram along"); hestOptAdd(&opt, "b,bin", "bins", airTypeInt, 1, 1, &bins, NULL, "# of bins in histogram"); OPT_ADD_TYPE(type, "output type", "uchar"); hestOptAdd(&opt, "min,minimum", "value", airTypeDouble, 1, 1, &min, "nan", "Value at low end of histogram. Defaults to lowest value " "found in input nrrd."); hestOptAdd(&opt, "max,maximum", "value", airTypeDouble, 1, 1, &max, "nan", "Value at high end of histogram. Defaults to highest value " "found in input nrrd."); 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); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); range = nrrdRangeNew(min, max); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range, nin, blind8BitRange); if (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; }
int unrrdu_dhistoMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int pret, nolog, notick; unsigned int size; airArray *mop; double max; hestOptAdd(&opt, "h,height", "height", airTypeUInt, 1, 1, &size, NULL, "height of output image (horizontal size is determined by " "number of bins in input histogram)."); hestOptAdd(&opt, "nolog", NULL, airTypeInt, 0, 0, &nolog, NULL, "do not show the log-scaled histogram with decade tick-marks"); hestOptAdd(&opt, "notick", NULL, airTypeInt, 0, 0, ¬ick, NULL, "do not draw the log decade tick marks"); hestOptAdd(&opt, "max,maximum", "max # hits", airTypeDouble, 1, 1, &max, "nan", "constrain the top of the drawn histogram to be at this " "number of hits. This will either scale the drawn histogram " "downward or clip its top, depending on whether the given max " "is higher or lower than the actual maximum bin count. By " "not using this option (the default), the actual maximum bin " "count is used"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_dhistoInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdHistoDraw(nout, nin, size, nolog ? AIR_FALSE : (notick ? 2 : AIR_TRUE), max)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error drawing histogram nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_axmergeMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout[2]; int *axes, pret, ni; unsigned int ii, jj, axesLen; airArray *mop; hestOptAdd(&opt, "a,axis", "ax0", airTypeInt, 1, -1, &axes, NULL, "axis (or axes) to merge. Each axis index identified is the " "lower of the pair of axes that will be merged. Saying \"-a 2\" " "means to merge axis 2 and axis 3 into axis 2. If multiple " "merges are to be done, the indices listed here are for " "the axes prior to any merging.", &axesLen); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_axmergeInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); airMopAdd(mop, nout[0]=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nout[1]=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); if (axesLen > 1) { /* sort merge axes into ascending order */ qsort(axes, axesLen, sizeof(*axes), nrrdValCompare[nrrdTypeInt]); } ni = 0; for (ii=0; ii<axesLen; ii++) { if (nrrdAxesMerge(nout[ni], !ii ? nin : nout[1-ni], axes[ii])) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error merging axes:\n%s", me, err); airMopError(mop); return 1; } for (jj=ii+1; jj<axesLen; jj++) { axes[jj] -= 1; } ni = 1-ni; } SAVE(out, nout[1-ni], NULL); airMopOkay(mop); return 0; }
int unrrdu_gammaMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; double min, max, gamma; airArray *mop; int pret, blind8BitRange; NrrdRange *range; hestOptAdd(&opt, "g,gamma", "gamma", airTypeDouble, 1, 1, &gamma, NULL, "gamma > 1.0 brightens; gamma < 1.0 darkens. " "Negative gammas invert values (like in xv). "); hestOptAdd(&opt, "min,minimum", "value", airTypeDouble, 1, 1, &min, "nan", "Value to implicitly map to 0.0 prior to calling pow(). " "Defaults to lowest value found in input nrrd."); hestOptAdd(&opt, "max,maximum", "value", airTypeDouble, 1, 1, &max, "nan", "Value to implicitly map to 1.0 prior to calling pow(). " "Defaults to highest value found in input nrrd."); 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_gammaInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); range = nrrdRangeNew(min, max); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range, nin, blind8BitRange); if (nrrdArithGamma(nout, nin, range, gamma)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error doing gamma:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_distMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int pret; int E, typeOut, invert, sign; double thresh; airArray *mop; hestOptAdd(&opt, "th,thresh", "val", airTypeDouble, 1, 1, &thresh, NULL, "threshold value to separate inside from outside"); hestOptAdd(&opt, "t,type", "type", airTypeEnum, 1, 1, &typeOut, "float", "type to save output in", NULL, nrrdType); hestOptAdd(&opt, "sgn", NULL, airTypeInt, 0, 0, &sign, NULL, "also compute signed (negative) distances inside objects, " "instead of leaving them as zero"); hestOptAdd(&opt, "inv", NULL, airTypeInt, 0, 0, &invert, NULL, "values *below* threshold are considered interior to object. " "By default (not using this option), values above threshold " "are considered interior. "); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_distInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (sign) { E = nrrdDistanceL2Signed(nout, nin, typeOut, NULL, thresh, !invert); } else { E = nrrdDistanceL2(nout, nin, typeOut, NULL, thresh, !invert); } if (E) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error doing distance transform:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 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; }
int unrrdu_permuteMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; unsigned int *perm, permLen; int pret; airArray *mop; hestOptAdd(&opt, "p,permute", "ax0 ax1", airTypeUInt, 1, -1, &perm, NULL, "new axis ordering", &permLen); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_permuteInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (!( permLen == nin->dim )) { fprintf(stderr,"%s: # axes in permutation (%u) != nrrd dim (%d)\n", me, permLen, nin->dim); airMopError(mop); return 1; } if (nrrdAxesPermute(nout, nin, perm)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error permuting nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_untileMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; unsigned int axes[3]; int pret; size_t size[2]; airArray *mop; hestOptAdd(&opt, "a,axis", "axMerge ax0 ax1", airTypeUInt, 3, 3, axes, NULL, "the slow parts of axes ax0 and ax1 are merged into a (new) " "axis axMerge, with the axis ax0 part being faster than ax1."); hestOptAdd(&opt, "s,size", "size0 size1", airTypeSize_t, 2, 2, size, NULL, "the slow parts of axes ax0 and ax1 are taken to have size " "size0 and size1, respectively, and axis axMerge will have " "size size0*size1."); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_untileInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdUntile2D(nout, nin, axes[1], axes[2], axes[0], size[0], size[1])) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error tiling nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_convertMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int type, pret, E, doClamp; airArray *mop; OPT_ADD_TYPE(type, "type to convert to", NULL); OPT_ADD_NIN(nin, "input nrrd"); hestOptAdd(&opt, "clamp", NULL, airTypeInt, 0, 0, &doClamp, NULL, "clamp input values to representable range of values of " "output type, to avoid wrap-around problems"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_convertInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (doClamp) { E = nrrdClampConvert(nout, nin, type); } else { E = nrrdConvert(nout, nin, type); } if (E) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error converting nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 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; }
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; }
int unrrdu_tileMain(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 axes[3]; airArray *mop; hestOptAdd(&opt, "a,axis", "axSplit ax0 ax1", airTypeUInt, 3, 3, axes, NULL, "axSplit is divided and merged with ax0 and ax1"); hestOptAdd(&opt, "s,size", "fast slow", airTypeSize_t, 2, 2, size, NULL, "fast and slow axis sizes to produce as result of splitting " "the axSplit axis."); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_tileInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdTile2D(nout, nin, axes[1], axes[2], axes[0], size[0], size[1])) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error tiling nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_unblockMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int type, pret; size_t blockSize; airArray *mop; OPT_ADD_TYPE(type, "type to unblock to", NULL); hestOptAdd(&opt, "bs", "blocksize", airTypeSize_t, 1, 1, &blockSize, "0", "Useful only if *output* type is also block: the size of " "blocks in output nrrd"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_unblockInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); nout->blockSize = blockSize; airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdUnblock(nout, nin, type)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error unblocking nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_ccadjMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; airArray *mop; int pret; unsigned int conny; hestOptAdd(&opt, "c,connect", "connectivity", airTypeUInt, 1, 1, &conny, NULL, "what kind of connectivity to use: the number of coordinates " "that vary in order to traverse the neighborhood of a given " "sample. In 2D: \"1\": 4-connected, \"2\": 8-connected"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_ccadjInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdCCAdjacency(nout, nin, conny)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error finding adjacencies:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_swapMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int pret; unsigned int ax[2]; airArray *mop; hestOptAdd(&opt, "a,axis", "axisA axisB", airTypeUInt, 2, 2, ax, NULL, "the two axes to switch (0-based numbering)"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_swapInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdAxesSwap(nout, nin, ax[0], ax[1])) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error swapping nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_reshapeMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int pret; size_t *size; unsigned int sizeLen; airArray *mop; hestOptAdd(&opt, "s,size", "sz0 sz1 ", airTypeSize_t, 1, -1, &size, NULL, "new axes sizes", &sizeLen); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_reshapeInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdReshape_nva(nout, nin, sizeLen, size)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error reshaping nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_substMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; int pret; Nrrd *nin, *nsubst, *nout; airArray *mop; hestOptAdd(&opt, "s,subst", "subst", airTypeOther, 1, 1, &nsubst, NULL, "substition table to map input nrrd through", NULL, NULL, nrrdHestNrrd); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_substInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdApply1DSubstitution(nout, nin, nsubst)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble applying SUBST:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_fftMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *_nin, *nout; int pret; airArray *mop; int sign, rigor, rescale, realInput; char *wispath; FILE *fwise; unsigned int *axes, axesLen; hestOptAdd(&opt, NULL, "dir", airTypeEnum, 1, 1, &sign, NULL, "forward (\"forw\", \"f\") or backward/inverse " "(\"back\", \"b\") transform ", NULL, direction_enm); hestOptAdd(&opt, "a,axes", "ax0", airTypeUInt, 1, -1, &axes, NULL, "the one or more axes that should be transformed", &axesLen); hestOptAdd(&opt, "pr,planrigor", "pr", airTypeEnum, 1, 1, &rigor, "est", "rigor with which fftw plan is constructed. Options include:\n " "\b\bo \"e\", \"est\", \"estimate\": only an estimate\n " "\b\bo \"m\", \"meas\", \"measure\": standard amount of " "measurements of system properties\n " "\b\bo \"p\", \"pat\", \"patient\": slower, more measurements\n " "\b\bo \"x\", \"ex\", \"exhaustive\": slowest, most measurements", NULL, nrrdFFTWPlanRigor); hestOptAdd(&opt, "r,rescale", "bool", airTypeBool, 1, 1, &rescale, "true", "scale fftw output (by sqrt(1/N)) so that forward and backward " "transforms will get back to original values"); hestOptAdd(&opt, "w,wisdom", "filename", airTypeString, 1, 1, &wispath, "", "A filename here is used to read in fftw wisdom (if the file " "exists already), and is used to save out updated wisdom " "after the transform. By default (not using this option), " "no wisdom is read or saved. Note: no wisdom is gained " "(that is, learned by FFTW) with planning rigor \"estimate\"."); OPT_ADD_NIN(_nin, "input nrrd"); hestOptAdd(&opt, "ri,realinput", NULL, airTypeInt, 0, 0, &realInput, NULL, "input is real-valued, so insert new length-2 axis 0 " "and set complex component to 0.0. Axes to transform " "(indicated by \"-a\") will be incremented accordingly."); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); if (nrrdFFTWEnabled) { USAGE(_unrrdu_fftInfoL_yes); } else { USAGE(_unrrdu_fftInfoL_no); } PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (realInput) { ptrdiff_t minPad[NRRD_DIM_MAX], maxPad[NRRD_DIM_MAX]; unsigned int axi; Nrrd *ntmp; ntmp = nrrdNew(); airMopAdd(mop, ntmp, (airMopper)nrrdNuke, airMopAlways); if (nrrdAxesInsert(ntmp, _nin, 0)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error creating complex axis:\n%s", me, err); airMopError(mop); return 1; } nin = nrrdNew(); airMopAdd(mop, nin, (airMopper)nrrdNuke, airMopAlways); minPad[0] = 0; maxPad[0] = 1; for (axi=1; axi<ntmp->dim; axi++) { minPad[axi] = 0; maxPad[axi] = AIR_CAST(ptrdiff_t, ntmp->axis[axi].size-1); } if (nrrdPad_nva(nin, ntmp, minPad, maxPad, nrrdBoundaryPad, 0.0)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error padding out complex axis:\n%s", me, err); airMopError(mop); return 1; } /* increment specified axes to transform */ for (axi=0; axi<axesLen; axi++) { axes[axi]++; } /* ntmp is really done with, we can free up the space now; this is one of the rare times we want airMopSub */ airMopSub(mop, ntmp, (airMopper)nrrdNuke); nrrdNuke(ntmp); } else { /* input is apparently already complex */ nin = _nin; } if (airStrlen(wispath) && nrrdFFTWEnabled) { fwise = fopen(wispath, "r"); if (fwise) { if (nrrdFFTWWisdomRead(fwise)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error with fft wisdom:\n%s", me, err); airMopError(mop); return 1; } fclose(fwise); } else { fprintf(stderr, "%s: (\"%s\" couldn't be opened, will try to save " "wisdom afterwards)", me, wispath); } } if (nrrdFFT(nout, nin, axes, axesLen, sign, rescale, rigor)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error with fft:\n%s", me, err); airMopError(mop); return 1; } if (airStrlen(wispath) && nrrdFFTWEnabled) { if (!(fwise = fopen(wispath, "w"))) { fprintf(stderr, "%s: couldn't open %s for writing: %s\n", me, wispath, strerror(errno)); airMopError(mop); return 1; } if (nrrdFFTWWisdomWrite(fwise)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error with fft wisdom:\n%s", me, err); airMopError(mop); return 1; } fclose(fwise); } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_rmapMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nmap, *nout; airArray *mop; NrrdRange *range=NULL; int typeOut, rescale, pret, blind8BitRange; double min, max; hestOptAdd(&opt, "m,map", "map", airTypeOther, 1, 1, &nmap, NULL, "regular map to map input nrrd through", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "r,rescale", NULL, airTypeInt, 0, 0, &rescale, NULL, "rescale the input values from the input range to the " "map domain. The map domain is either explicitly " "defined by the axis min,max along axis 0 or 1, or, it " "is implicitly defined as zero to the length of " "that axis minus one."); hestOptAdd(&opt, "min,minimum", "value", airTypeDouble, 1, 1, &min, "nan", "Low end of input range. Defaults to lowest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\") or if the map domain is only " "implicitly defined"); hestOptAdd(&opt, "max,maximum", "value", airTypeDouble, 1, 1, &max, "nan", "High end of input range. Defaults to highest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\") or if the map domain is only " "implicitly defined"); 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]). " "Explicitly setting this is useful " "only with rescaling (\"-r\") or if the map domain is only " "implicitly defined"); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &typeOut, "default", "specify the type (\"int\", \"float\", etc.) of the " "output nrrd. " "By default (not using this option), the output type " "is the map's type.", 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_rmapInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); /* here is a big difference between unu and nrrd: we enforce rescaling any time that the map domain is implicit. This is how the pre-1.6 functionality is recreated. Also, whenever there is rescaling we pass a NrrdRange to reflect the (optional) user range specification, instead of letting nrrdApply1DRegMap find the input range itself (by passing a NULL NrrdRange). */ if (!( AIR_EXISTS(nmap->axis[nmap->dim - 1].min) && AIR_EXISTS(nmap->axis[nmap->dim - 1].max) )) { rescale = AIR_TRUE; } if (rescale) { range = nrrdRangeNew(min, max); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range, nin, blind8BitRange); } if (nrrdTypeDefault == typeOut) { typeOut = nmap->type; } if (nrrdApply1DRegMap(nout, nin, range, nmap, typeOut, rescale)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble applying map:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_cropMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; unsigned int ai; int minLen, maxLen, pret; long int *minOff, *maxOff; size_t min[NRRD_DIM_MAX], max[NRRD_DIM_MAX]; airArray *mop; OPT_ADD_BOUND("min,minimum", minOff, "low corner of bounding box.\n " "\b\bo <int> gives 0-based index\n " "\b\bo M, M+<int>, M-<int> give index relative " "to the last sample on the axis (M == #samples-1).", minLen); OPT_ADD_BOUND("max,maximum", maxOff, "high corner of bounding box. Besides " "the specification styles described above, there's also:\n " "\b\bo m+<int> give index relative to minimum.", maxLen); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_cropInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); if (!( minLen == (int)nin->dim && maxLen == (int)nin->dim )) { fprintf(stderr, "%s: # min coords (%d) or max coords (%d) != nrrd dim (%d)\n", me, minLen, maxLen, nin->dim); airMopError(mop); return 1; } for (ai=0; ai<nin->dim; ai++) { if (-1 == minOff[0 + 2*ai]) { fprintf(stderr, "%s: can't use m+<int> specification for axis %d min\n", me, ai); airMopError(mop); return 1; } } for (ai=0; ai<nin->dim; ai++) { min[ai] = minOff[0 + 2*ai]*(nin->axis[ai].size-1) + minOff[1 + 2*ai]; if (-1 == maxOff[0 + 2*ai]) { max[ai] = min[ai] + maxOff[1 + 2*ai]; } else { max[ai] = maxOff[0 + 2*ai]*(nin->axis[ai].size-1) + maxOff[1 + 2*ai]; } /* fprintf(stderr, "%s: ai %2d: min = %4d, max = %4d\n", me, ai, min[ai], max[ai]); */ } nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdCrop(nout, nin, min, max)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error cropping nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_1opMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout, *ntmp=NULL; int op, pret, type; airArray *mop; hestOptAdd(&opt, NULL, "operator", airTypeEnum, 1, 1, &op, NULL, "Unary operator. Possibilities include:\n " "\b\bo \"-\": negative (multiply by -1.0)\n " "\b\bo \"r\": reciprocal (1.0/value)\n " "\b\bo \"sin\", \"cos\", \"tan\", \"asin\", \"acos\", \"atan\": " "same as in C\n " "\b\bo \"exp\", \"log\", \"log10\", \"log1p\": same as in C\n " "\b\bo \"log2\": log base 2\n " "\b\bo \"sqrt\", \"cbrt\", \"ceil\", \"floor\": same as in C\n " "\b\bo \"erf\": error function (integral of Gaussian)\n " "\b\bo \"rup\", \"rdn\": round up or down to integral value\n " "\b\bo \"abs\": absolute value\n " "\b\bo \"sgn\": -1, 0, 1 if value is <0, ==0, or >0\n " "\b\bo \"exists\": 1 iff not NaN or +/-Inf, 0 otherwise\n " "\b\bo \"rand\": random value in [0.0,1.0), no relation to input", NULL, nrrdUnaryOp); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &type, "default", "convert input nrrd to this type prior to " "doing operation. Useful when desired output is float " "(e.g., with log1p), but input is integral. By default " "(not using this option), the types of " "the input nrrds are left unchanged.", 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_1opInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdTypeDefault != type) { /* they requested conversion to another type prior to the 1op */ airMopAdd(mop, ntmp=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); if (nrrdConvert(ntmp, nin, type)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error converting input nrrd:\n%s", me, err); airMopError(mop); return 1; } } else { ntmp = nin; } if (nrrdUnaryOpRand == op || nrrdUnaryOpNormalRand == op) { airSrandMT(AIR_CAST(unsigned int, airTime())); } if (nrrdArithUnaryOp(nout, op, ntmp)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error doing unary operation:\n%s", me, err); airMopError(mop); return 1; } /* if we had to create ntmp with nrrdConvert, it will be mopped, otherwise ntmp is an alias for nin, which will also be mopped */ SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_imapMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nmap, *nacl, *nout; airArray *mop; NrrdRange *range=NULL; unsigned int aclLen; int typeOut, rescale, pret, blind8BitRange; double min, max; hestOptAdd(&opt, "m,map", "map", airTypeOther, 1, 1, &nmap, NULL, "irregular map to map input nrrd through", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "l,length", "aclLen", airTypeUInt, 1, 1, &aclLen, "0", "length of accelerator array, used to try to speed-up " "task of finding between which pair of control points " "a given value lies. Not terribly useful for small maps " "(about 10 points or less). Use 0 to turn accelorator off. "); hestOptAdd(&opt, "r,rescale", NULL, airTypeInt, 0, 0, &rescale, NULL, "rescale the input values from the input range to the " "map domain"); hestOptAdd(&opt, "min,minimum", "value", airTypeDouble, 1, 1, &min, "nan", "Low end of input range. Defaults to lowest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\")"); hestOptAdd(&opt, "max,maximum", "value", airTypeDouble, 1, 1, &max, "nan", "High end of input range. Defaults to highest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\")"); 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]). " "Explicitly setting this is useful only with rescaling (\"-r\")"); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &typeOut, "default", "specify the type (\"int\", \"float\", etc.) of the " "output nrrd. " "By default (not using this option), the output type " "is the map's type.", 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_imapInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (aclLen) { nacl = nrrdNew(); airMopAdd(mop, nacl, (airMopper)nrrdNuke, airMopAlways); if (nrrd1DIrregAclGenerate(nacl, nmap, aclLen)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble generating accelerator:\n%s", me, err); airMopError(mop); return 1; } } else { nacl = NULL; } if (rescale) { range = nrrdRangeNew(min, max); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range, nin, blind8BitRange); } if (nrrdTypeDefault == typeOut) { typeOut = nmap->type; } /* some very non-exhaustive tests seemed to indicate that the accelerator does not in fact reliably speed anything up. This of course depends on the size of the imap (# points), but chances are most imaps will have only a handful of points, in which case the binary search in _nrrd1DIrregFindInterval() will finish quickly ... */ if (nrrdApply1DIrregMap(nout, nin, range, nmap, nacl, typeOut, rescale)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble applying map:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_lutMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nlut, *nout; airArray *mop; int typeOut, rescale, pret, blind8BitRange; double min, max; NrrdRange *range=NULL; hestOptAdd(&opt, "m,map", "lut", airTypeOther, 1, 1, &nlut, NULL, "lookup table to map input nrrd through", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "r,rescale", NULL, airTypeInt, 0, 0, &rescale, NULL, "rescale the input values from the input range to the " "lut domain. The lut domain is either explicitly " "defined by the axis min,max along axis 0 or 1, or, it " "is implicitly defined as zero to the length of that axis " "minus one."); hestOptAdd(&opt, "min,minimum", "value", airTypeDouble, 1, 1, &min, "nan", "Low end of input range. Defaults to lowest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\")"); hestOptAdd(&opt, "max,maximum", "value", airTypeDouble, 1, 1, &max, "nan", "High end of input range. Defaults to highest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\")"); 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]). " "Explicitly setting this is useful only with rescaling (\"-r\")"); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &typeOut, "default", "specify the type (\"int\", \"float\", etc.) of the " "output nrrd. " "By default (not using this option), the output type " "is the lut's type.", 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_lutInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); /* see comment rmap.c */ if (!( AIR_EXISTS(nlut->axis[nlut->dim - 1].min) && AIR_EXISTS(nlut->axis[nlut->dim - 1].max) )) { rescale = AIR_TRUE; } if (rescale) { range = nrrdRangeNew(min, max); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range, nin, blind8BitRange); } if (nrrdTypeDefault == typeOut) { typeOut = nlut->type; } if (nrrdApply1DLut(nout, nin, range, nlut, typeOut, rescale)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble applying LUT:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 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; }
int unrrdu_resampleMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int type, bb, pret, norenorm, older, E, defaultCenter, verbose; unsigned int scaleLen, ai, samplesOut; airArray *mop; float *scale; double padVal; NrrdResampleInfo *info; NrrdResampleContext *rsmc; NrrdKernelSpec *unuk; mop = airMopNew(); info = nrrdResampleInfoNew(); airMopAdd(mop, info, (airMopper)nrrdResampleInfoNix, airMopAlways); hparm->elideSingleOtherDefault = AIR_FALSE; hestOptAdd(&opt, "old", NULL, airTypeInt, 0, 0, &older, NULL, "instead of using the new nrrdResampleContext implementation, " "use the old nrrdSpatialResample implementation"); hestOptAdd(&opt, "s,size", "sz0", airTypeOther, 1, -1, &scale, NULL, "For each axis, information about how many samples in output:\n " "\b\bo \"=\": leave this axis completely untouched: no " "resampling whatsoever\n " "\b\bo \"x<float>\": multiply the number of input samples by " "<float>, and round to the nearest integer, to get the number " "of output samples. Use \"x1\" to resample the axis but leave " "the number of samples unchanged\n " "\b\bo \"<int>\": exact number of output samples", &scaleLen, NULL, &unrrduHestScaleCB); hestOptAdd(&opt, "k,kernel", "kern", airTypeOther, 1, 1, &unuk, "cubic:0,0.5", "The kernel to use for resampling. " "Kernels logically live in the input index space for upsampling, " "and in the output index space for downsampling. " "Possibilities include:\n " "\b\bo \"box\": nearest neighbor interpolation\n " "\b\bo \"cheap\": nearest neighbor interpolation for upsampling, " "and non-blurring sub-sampling (pick subset of input samples) " "on downsampling\n " "\b\bo \"tent\": linear interpolation\n " "\b\bo \"cubic:B,C\": Mitchell/Netravali BC-family of " "cubics:\n " "\t\t\"cubic:1,0\": B-spline; maximal blurring\n " "\t\t\"cubic:0,0.5\": Catmull-Rom; good interpolating kernel\n " "\b\bo \"quartic:A\": 1-parameter family of " "interpolating quartics (\"quartic:0.0834\" is most accurate)\n " "\b\bo \"hann:R\": Hann (cosine bell) windowed sinc, radius R\n " "\b\bo \"black:R\": Blackman windowed sinc, radius R\n " "\b\bo \"gauss:S,C\": Gaussian blurring, with standard deviation " "S and cut-off at C standard deviations", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&opt, "nrn", NULL, airTypeInt, 0, 0, &norenorm, NULL, "don't do per-pass kernel weight renormalization. " "Doing the renormalization is not a big performance hit, and " "is sometimes needed to avoid \"grating\" on non-integral " "down-sampling. Disabling the renormalization is needed for " "correct results with artificially narrow kernels. "); hestOptAdd(&opt, "b,boundary", "behavior", airTypeEnum, 1, 1, &bb, "bleed", "How to handle samples beyond the input bounds:\n " "\b\bo \"pad\": use some specified value\n " "\b\bo \"bleed\": extend border values outward\n " "\b\bo \"wrap\": wrap-around to other side", NULL, nrrdBoundary); hestOptAdd(&opt, "v,value", "value", airTypeDouble, 1, 1, &padVal, "0.0", "for \"pad\" boundary behavior, pad with this value"); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &type, "default", "type to save OUTPUT as. By default (not using this option), " "the output type is the same as the input type", NULL, NULL, &unrrduHestMaybeTypeCB); hestOptAdd(&opt, "cheap", NULL, airTypeInt, 0, 0, &(info->cheap), NULL, "DEPRECATED: the \"-k cheap\" option is the new (and more " "reliable) way to access this functionality. \"-cheap\" is " "only here for legacy use in combination with \"-old\".\n " "When downsampling (reducing number of samples), don't " "try to do correct filtering by scaling kernel to match " "new (stretched) index space; keep it in old index space. " "When used in conjunction with \"-k box\", this can implement " "subsampling which chooses every Nth value. "); hestOptAdd(&opt, "c,center", "center", airTypeEnum, 1, 1, &defaultCenter, (nrrdCenterCell == nrrdDefaultCenter ? "cell" : "node"), "(not available with \"-old\") " "default centering of axes when input nrrd " "axes don't have a known centering: \"cell\" or \"node\" ", NULL, nrrdCenter); hestOptAdd(&opt, "verbose", NULL, airTypeInt, 0, 0, &verbose, NULL, "(not available with \"-old\") " "turn on verbosity "); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_resampleInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (scaleLen != nin->dim) { fprintf(stderr, "%s: # sampling sizes (%d) != input nrrd dimension (%d)\n", me, scaleLen, nin->dim); airMopError(mop); return 1; } if (!older) { rsmc = nrrdResampleContextNew(); rsmc->verbose = verbose; airMopAdd(mop, rsmc, (airMopper)nrrdResampleContextNix, airMopAlways); E = AIR_FALSE; if (!E) E |= nrrdResampleDefaultCenterSet(rsmc, defaultCenter); if (!E) E |= nrrdResampleNrrdSet(rsmc, nin); for (ai=0; ai<nin->dim; ai++) { switch((int)scale[0 + 2*ai]) { case 0: /* no resampling */ if (!E) E |= nrrdResampleKernelSet(rsmc, ai, NULL, NULL); break; case 1: /* scaling of input # samples */ if (!E) E |= nrrdResampleKernelSet(rsmc, ai, unuk->kernel, unuk->parm); samplesOut = AIR_ROUNDUP(scale[1 + 2*ai]*nin->axis[ai].size); if (!E) E |= nrrdResampleSamplesSet(rsmc, ai, samplesOut); break; case 2: /* explicit # of samples */ if (!E) E |= nrrdResampleKernelSet(rsmc, ai, unuk->kernel, unuk->parm); samplesOut = (size_t)scale[1 + 2*ai]; if (!E) E |= nrrdResampleSamplesSet(rsmc, ai, samplesOut); break; } if (!E) E |= nrrdResampleRangeFullSet(rsmc, ai); } if (!E) E |= nrrdResampleBoundarySet(rsmc, bb); if (!E) E |= nrrdResampleTypeOutSet(rsmc, type); if (!E) E |= nrrdResamplePadValueSet(rsmc, padVal); if (!E) E |= nrrdResampleRenormalizeSet(rsmc, !norenorm); if (!E) E |= nrrdResampleExecute(rsmc, nout); if (E) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error resampling nrrd:\n%s", me, err); airMopError(mop); return 1; } } else { for (ai=0; ai<nin->dim; ai++) { /* this may be over-written below */ info->kernel[ai] = unuk->kernel; switch((int)scale[0 + 2*ai]) { case 0: /* no resampling */ info->kernel[ai] = NULL; break; case 1: /* scaling of input # samples */ info->samples[ai] = AIR_ROUNDUP(scale[1 + 2*ai]*nin->axis[ai].size); break; case 2: /* explicit # of samples */ info->samples[ai] = (size_t)scale[1 + 2*ai]; break; } memcpy(info->parm[ai], unuk->parm, NRRD_KERNEL_PARMS_NUM*sizeof(double)); if (info->kernel[ai] && (!( AIR_EXISTS(nin->axis[ai].min) && AIR_EXISTS(nin->axis[ai].max))) ) { nrrdAxisInfoMinMaxSet(nin, ai, (nin->axis[ai].center ? nin->axis[ai].center : nrrdDefaultCenter)); } info->min[ai] = nin->axis[ai].min; info->max[ai] = nin->axis[ai].max; } info->boundary = bb; info->type = type; info->padValue = padVal; info->renormalize = !norenorm; if (nrrdSpatialResample(nout, nin, info)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error resampling nrrd:\n%s", me, err); airMopError(mop); return 1; } } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }