/* ******* nrrdInit ** ** initializes a nrrd to default state. All nrrd functions in the ** business of initializing a nrrd struct use this function. Mostly ** just sets values to 0, NaN, "", NULL, or Unknown */ void nrrdInit(Nrrd *nrrd) { int ii; if (nrrd) { nrrdBasicInfoInit(nrrd, NRRD_BASIC_INFO_NONE); for (ii=0; ii<NRRD_DIM_MAX; ii++) { _nrrdAxisInfoInit(nrrd->axis + ii); } } return; }
void nrrdPeripheralInit(Nrrd *nrrd) { nrrdBasicInfoInit(nrrd, 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 | NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT); return; }
int nrrdArithUnaryOp(Nrrd *nout, int op, const Nrrd *nin) { static const char me[]="nrrdArithUnaryOp"; size_t N, I; int size[NRRD_DIM_MAX]; double (*insert)(void *v, size_t I, double d), (*lookup)(const void *v, size_t I), (*uop)(double), val; if (!(nout && nin)) { biffAddf(NRRD, "%s: got NULL pointer", me); return 1; } if (nrrdTypeBlock == nin->type) { biffAddf(NRRD, "%s: can't operate on type %s", me, airEnumStr(nrrdType, nrrdTypeBlock)); return 1; } if (airEnumValCheck(nrrdUnaryOp, op)) { biffAddf(NRRD, "%s: unary op %d invalid", me, op); return 1; } if (nout != nin) { if (nrrdCopy(nout, nin)) { biffAddf(NRRD, "%s:", me); return 1; } } nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, size); uop = _nrrdUnaryOp[op]; N = nrrdElementNumber(nin); lookup = nrrdDLookup[nin->type]; insert = nrrdDInsert[nin->type]; for (I=0; I<N; I++) { val = lookup(nin->data, I); insert(nout->data, I, uop(val)); } if (nrrdContentSet_va(nout, airEnumStr(nrrdUnaryOp, op), nin, "")) { biffAddf(NRRD, "%s:", me); return 1; } nrrdBasicInfoInit(nout, NRRD_BASIC_INFO_ALL ^ (NRRD_BASIC_INFO_OLDMIN_BIT | NRRD_BASIC_INFO_OLDMAX_BIT)); return 0; }
int _nrrdCopy(Nrrd *nout, const Nrrd *nin, int bitflag) { char me[]="_nrrdCopy", err[BIFF_STRLEN]; size_t size[NRRD_DIM_MAX]; if (!(nin && nout)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(NRRD, err); return 1; } if (nout == nin) { /* its not the case that we have nothing to do- the semantics of copying cannot be achieved if the input and output nrrd are the same; this is an error */ sprintf(err, "%s: nout==nin disallowed", me); biffAdd(NRRD, err); return 1; } if (!nrrdElementSize(nin)) { sprintf(err, "%s: input nrrd reports zero element size!", me); biffAdd(NRRD, err); return 1; } nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, size); if (nin->data) { if (nrrdMaybeAlloc_nva(nout, nin->type, nin->dim, size)) { sprintf(err, "%s: couldn't allocate data", me); biffAdd(NRRD, err); return 1; } memcpy(nout->data, nin->data, nrrdElementNumber(nin)*nrrdElementSize(nin)); } else { /* someone is trying to copy structs without data, fine fine fine */ if (nrrdWrap_nva(nout, NULL, nin->type, nin->dim, size)) { sprintf(err, "%s: couldn't allocate data", me); biffAdd(NRRD, err); return 1; } } nrrdAxisInfoCopy(nout, nin, NULL, NRRD_AXIS_INFO_SIZE_BIT); /* if nin->data non-NULL (second branch above), this will harmlessly unset and set type and dim */ nrrdBasicInfoInit(nout, NRRD_BASIC_INFO_DATA_BIT | bitflag); if (nrrdBasicInfoCopy(nout, nin, NRRD_BASIC_INFO_DATA_BIT | bitflag)) { sprintf(err, "%s: trouble copying basic info", me); biffAdd(NRRD, err); return 1; } return 0; }
/* ** _nrrdApply2DSetUp() ** ** some error checking and initializing needed for 2D LUTS and regular ** maps. The intent is that if this succeeds, then there is no need ** for any further error checking. ** ** The only thing this function DOES is allocate the output nrrd, and ** set meta information. The rest is just error checking. ** ** The given NrrdRange has to be fleshed out by the caller: it can't ** be NULL, and both range->min and range->max must exist. */ int _nrrdApply2DSetUp(Nrrd *nout, const Nrrd *nin, const NrrdRange *range0, const NrrdRange *range1, const Nrrd *nmap, int kind, int typeOut, int rescale0, int rescale1) { char me[]="_nrrdApply2DSetUp", err[BIFF_STRLEN], *mapcnt; char nounStr[][AIR_STRLEN_SMALL]={"2D lut", "2D regular map"}; char verbStr[][AIR_STRLEN_SMALL]={"lut2", "rmap2"}; int mapAxis, copyMapAxis0=AIR_FALSE, axisMap[NRRD_DIM_MAX]; unsigned int dim, entLen; size_t size[NRRD_DIM_MAX]; double domMin, domMax; if (nout == nin) { sprintf(err, "%s: due to laziness, nout==nin always disallowed", me); biffAdd(NRRD, err); return 1; } if (airEnumValCheck(nrrdType, typeOut)) { sprintf(err, "%s: invalid requested output type %d", me, typeOut); biffAdd(NRRD, err); return 1; } if (nrrdTypeBlock == nin->type || nrrdTypeBlock == typeOut) { sprintf(err, "%s: input or requested output type is %s, need scalar", me, airEnumStr(nrrdType, nrrdTypeBlock)); biffAdd(NRRD, err); return 1; } if (!(2 == nin->axis[0].size)) { sprintf(err, "%s: input axis[0] must have size 2 (not " _AIR_SIZE_T_CNV ")", me, nin->axis[0].size); biffAdd(NRRD, err); return 1; } if (!(nin->dim > 1)) { sprintf(err, "%s: input dimension must be > 1 (not %u)", me, nin->dim); biffAdd(NRRD, err); return 1; } if (rescale0 && !(range0 && AIR_EXISTS(range0->min) && AIR_EXISTS(range0->max))) { sprintf(err, "%s: want axis 0 rescaling but didn't get range, or " "not both range->{min,max} exist", me); biffAdd(NRRD, err); return 1; } if (rescale1 && !(range1 && AIR_EXISTS(range1->min) && AIR_EXISTS(range1->max))) { sprintf(err, "%s: want axis 1 rescaling but didn't get range, or " "not both range->{min,max} exist", me); biffAdd(NRRD, err); return 1; } mapAxis = nmap->dim - 2; if (!(0 == mapAxis || 1 == mapAxis)) { sprintf(err, "%s: dimension of %s should be 2 or 3, not %d", me, nounStr[kind], nmap->dim); biffAdd(NRRD, err); return 1; } copyMapAxis0 = (1 == mapAxis); domMin = _nrrdApplyDomainMin(nmap, AIR_FALSE, mapAxis); domMax = _nrrdApplyDomainMax(nmap, AIR_FALSE, mapAxis); if (!( domMin < domMax )) { sprintf(err, "%s: (axis %d) domain min (%g) not less than max (%g)", me, mapAxis, domMin, domMax); biffAdd(NRRD, err); return 1; } domMin = _nrrdApplyDomainMin(nmap, AIR_FALSE, mapAxis+1); domMax = _nrrdApplyDomainMax(nmap, AIR_FALSE, mapAxis+1); if (!( domMin < domMax )) { sprintf(err, "%s: (axis %d) domain min (%g) not less than max (%g)", me, mapAxis+1, domMin, domMax); biffAdd(NRRD, err); return 1; } if (nrrdHasNonExist(nmap)) { sprintf(err, "%s: %s nrrd has non-existent values", me, nounStr[kind]); biffAdd(NRRD, err); return 1; } entLen = mapAxis ? nmap->axis[0].size : 1; if (mapAxis + nin->dim - 1 > NRRD_DIM_MAX) { sprintf(err, "%s: input nrrd dim %d through non-scalar %s exceeds " "NRRD_DIM_MAX %d", me, nin->dim, nounStr[kind], NRRD_DIM_MAX); biffAdd(NRRD, err); return 1; } if (mapAxis) { size[0] = entLen; axisMap[0] = -1; } for (dim=1; dim<nin->dim; dim++) { size[dim-1+mapAxis] = nin->axis[dim].size; axisMap[dim-1+mapAxis] = dim; } /* fprintf(stderr, "##%s: pre maybe alloc: nout->data = %p\n", me, nout->data); for (dim=0; dim<mapAxis + nin->dim - 1; dim++) { fprintf(stderr, " size[%d] = %d\n", dim, (int)size[dim]); } fprintf(stderr, " nout->dim = %u; nout->type = %d = %s; sizes = %u,%u\n", nout->dim, nout->type, airEnumStr(nrrdType, nout->type), AIR_CAST(unsigned int, nout->axis[0].size), AIR_CAST(unsigned int, nout->axis[1].size)); fprintf(stderr, " typeOut = %d = %s\n", typeOut, airEnumStr(nrrdType, typeOut)); */ if (nrrdMaybeAlloc_nva(nout, typeOut, nin->dim - 1 + mapAxis, size)) { sprintf(err, "%s: couldn't allocate output nrrd", me); biffAdd(NRRD, err); return 1; } /* fprintf(stderr, " nout->dim = %d; nout->type = %d = %s\n", nout->dim, nout->type, airEnumStr(nrrdType, nout->type)); for (dim=0; dim<nout->dim; dim++) { fprintf(stderr, " size[%d] = %d\n", dim, (int)nout->axis[dim].size); } fprintf(stderr, "##%s: post maybe alloc: nout->data = %p\n", me, nout->data); */ if (nrrdAxisInfoCopy(nout, nin, axisMap, NRRD_AXIS_INFO_NONE)) { sprintf(err, "%s: trouble copying axis info", me); biffAdd(NRRD, err); return 1; } if (copyMapAxis0) { _nrrdAxisInfoCopy(nout->axis + 0, nmap->axis + 0, NRRD_AXIS_INFO_SIZE_BIT); } mapcnt = _nrrdContentGet(nmap); if (nrrdContentSet_va(nout, verbStr[kind], nin, "%s", mapcnt)) { sprintf(err, "%s:", me); biffAdd(NRRD, err); free(mapcnt); return 1; } free(mapcnt); nrrdBasicInfoInit(nout, (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)); return 0; }
int nrrdHistoDraw(Nrrd *nout, const Nrrd *nin, size_t sy, int showLog, double max) { static const char me[]="nrrdHistoDraw", func[]="dhisto"; char cmt[AIR_STRLEN_MED]; unsigned int k, sx, x, y, maxhitidx, E, numticks, *Y, *logY, tick, *ticks; double hits, maxhits, usemaxhits; unsigned char *pgmData; airArray *mop; if (!(nin && nout && sy > 0)) { biffAddf(NRRD, "%s: invalid args", me); return 1; } if (nout == nin) { biffAddf(NRRD, "%s: nout==nin disallowed", me); return 1; } if (nrrdHistoCheck(nin)) { biffAddf(NRRD, "%s: input nrrd not a histogram", me); return 1; } sx = AIR_CAST(unsigned int, nin->axis[0].size); nrrdBasicInfoInit(nout, NRRD_BASIC_INFO_DATA_BIT); if (nrrdPGM(nout, sx, sy)) { biffAddf(NRRD, "%s: failed to allocate histogram image", me); return 1; } /* perhaps I should be using nrrdAxisInfoCopy */ nout->axis[0].spacing = nout->axis[1].spacing = AIR_NAN; nout->axis[0].thickness = nout->axis[1].thickness = AIR_NAN; nout->axis[0].min = nin->axis[0].min; nout->axis[0].max = nin->axis[0].max; nout->axis[0].center = nout->axis[1].center = nrrdCenterCell; nout->axis[0].label = (char *)airStrdup(nin->axis[0].label); nout->axis[1].label = (char *)airFree(nout->axis[1].label); pgmData = (unsigned char *)nout->data; maxhits = maxhitidx = 0; for (x=0; x<sx; x++) { hits = nrrdDLookup[nin->type](nin->data, x); if (maxhits < hits) { maxhits = hits; maxhitidx = x; } } if (AIR_EXISTS(max) && max > 0) { usemaxhits = max; } else { usemaxhits = maxhits; } nout->axis[1].min = usemaxhits; nout->axis[1].max = 0; numticks = (unsigned int)log10(usemaxhits + 1); mop = airMopNew(); ticks = (unsigned int*)calloc(numticks, sizeof(unsigned int)); airMopMem(mop, &ticks, airMopAlways); Y = (unsigned int*)calloc(sx, sizeof(unsigned int)); airMopMem(mop, &Y, airMopAlways); logY = (unsigned int*)calloc(sx, sizeof(unsigned int)); airMopMem(mop, &logY, airMopAlways); if (!(ticks && Y && logY)) { biffAddf(NRRD, "%s: failed to allocate temp arrays", me); airMopError(mop); return 1; } for (k=0; k<numticks; k++) { ticks[k] = airIndex(0, log10(pow(10,k+1) + 1), log10(usemaxhits+1), AIR_CAST(unsigned int, sy)); } for (x=0; x<sx; x++) { hits = nrrdDLookup[nin->type](nin->data, x); Y[x] = airIndex(0, hits, usemaxhits, AIR_CAST(unsigned int, sy)); logY[x] = airIndex(0, log10(hits+1), log10(usemaxhits+1), AIR_CAST(unsigned int, sy)); /* printf("%d -> %d,%d", x, Y[x], logY[x]); */ } for (y=0; y<sy; y++) { tick = 0; for (k=0; k<numticks; k++) tick |= ticks[k] == y; for (x=0; x<sx; x++) { pgmData[x + sx*(sy-1-y)] = (2 == showLog /* HACK: draw log curve, but not log tick marks */ ? (y >= logY[x] ? 0 /* above log curve */ : (y >= Y[x] ? 128 /* below log curve, above normal curve */ : 255 /* below log curve, below normal curve */ ) ) : (!showLog ? (y >= Y[x] ? 0 : 255) : (y >= logY[x] /* above log curve */ ? (!tick ? 0 /* not on tick mark */ : 255) /* on tick mark */ : (y >= Y[x] /* below log curve, above normal curve */ ? (!tick ? 128 /* not on tick mark */ : 0) /* on tick mark */ :255 /* below log curve, below normal curve */ ) ) ) ); } } E = AIR_FALSE; sprintf(cmt, "min value: %g\n", nout->axis[0].min); if (!E) E |= nrrdCommentAdd(nout, cmt); sprintf(cmt, "max value: %g\n", nout->axis[0].max); if (!E) E |= nrrdCommentAdd(nout, cmt); sprintf(cmt, "max hits: %g, in bin %d, around value %g\n", maxhits, maxhitidx, nrrdAxisInfoPos(nout, 0, maxhitidx)); if (!E) E |= nrrdCommentAdd(nout, cmt); if (!E) E |= nrrdContentSet_va(nout, func, nin, "%d", sy); if (E) { biffAddf(NRRD, "%s:", me); airMopError(mop); return 1; } /* bye */ airMopOkay(mop); return 0; }
int nrrdArithIterTernaryOpSelect(Nrrd *nout, int op, NrrdIter *inA, NrrdIter *inB, NrrdIter *inC, unsigned int which) { static const char me[]="nrrdArithIterTernaryOpSelect"; char *contA, *contB, *contC; size_t N, I, size[NRRD_DIM_MAX]; int type; double (*insert)(void *v, size_t I, double d), (*top)(double a, double b, double c), valA, valB, valC; const Nrrd *nin; if (!(nout && inA && inB && inC)) { biffAddf(NRRD, "%s: got NULL pointer", me); return 1; } if (airEnumValCheck(nrrdTernaryOp, op)) { biffAddf(NRRD, "%s: ternary op %d invalid", me, op); return 1; } if (!( 0 == which || 1 == which || 2 == which )) { biffAddf(NRRD, "%s: which %u not valid, want 0, 1, or 2", me, which); return 1; } nin = (0 == which ? _NRRD_ITER_NRRD(inA) : (1 == which ? _NRRD_ITER_NRRD(inB) : _NRRD_ITER_NRRD(inC))); if (!nin) { biffAddf(NRRD, "%s: selected input %u is a fixed value", me, which); return 1; } type = nin->type; nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, size); if (_nrrdMaybeAllocMaybeZero_nva(nout, type, nin->dim, size, AIR_FALSE /* zero when no realloc */)) { biffAddf(NRRD, "%s: couldn't allocate output nrrd", me); return 1; } nrrdBasicInfoCopy(nout, nin, (NRRD_BASIC_INFO_DATA_BIT | NRRD_BASIC_INFO_TYPE_BIT | NRRD_BASIC_INFO_DIMENSION_BIT | NRRD_BASIC_INFO_CONTENT_BIT | NRRD_BASIC_INFO_COMMENTS_BIT | (nrrdStateKeyValuePairsPropagate ? 0 : NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT))); nrrdBasicInfoInit(nout, NRRD_BASIC_INFO_ALL ^ (NRRD_BASIC_INFO_OLDMIN_BIT | NRRD_BASIC_INFO_OLDMAX_BIT)); top = _nrrdTernaryOp[op]; /* fprintf(stderr, "%!s: inA->left = %d, inB->left = %d\n", me, (int)(inA->left), (int)(inB->left)); */ N = nrrdElementNumber(nin); insert = nrrdDInsert[type]; for (I=0; I<N; I++) { /* HEY: there is a loss of precision issue here with 64-bit ints */ valA = nrrdIterValue(inA); valB = nrrdIterValue(inB); valC = nrrdIterValue(inC); /* if (!(I % 1000)) { fprintf(stderr, "!%s: %d: top(%g,%g,%g) = %g\n", me, (int)I, valA, valB, valC, top(valA, valB, valC)); } */ insert(nout->data, I, top(valA, valB, valC)); } contA = nrrdIterContent(inA); contB = nrrdIterContent(inB); contC = nrrdIterContent(inC); if (_nrrdContentSet_va(nout, airEnumStr(nrrdTernaryOp, op), contA, "%s,%s", contB, contC)) { biffAddf(NRRD, "%s:", me); free(contA); free(contB); free(contC); return 1; } if (nout != nin) { nrrdAxisInfoCopy(nout, nin, NULL, NRRD_AXIS_INFO_NONE); } free(contA); free(contB); free(contC); return 0; }
/* ******** nrrdArithTerneryOp ** ** HEY: UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED UNTESTED ** ** this is a simplified version of nrrdArithIterTernaryOp, written after ** that, in a hurry, to operate directly on three nrrds, instead with ** the NrrdIter nonsense */ int nrrdArithTernaryOp(Nrrd *nout, int op, const Nrrd *ninA, const Nrrd *ninB, const Nrrd *ninC) { static const char me[]="nrrdArithTernaryOp"; char *contA, *contB, *contC; size_t N, I, size[NRRD_DIM_MAX]; double (*ins)(void *v, size_t I, double d), (*lupA)(const void *v, size_t I), (*lupB)(const void *v, size_t I), (*lupC)(const void *v, size_t I), (*top)(double a, double b, double c), valA, valB, valC; if (!( nout && !nrrdCheck(ninA) && !nrrdCheck(ninB) && !nrrdCheck(ninC) )) { biffAddf(NRRD, "%s: NULL pointer or invalid args", me); return 1; } if (!( nrrdSameSize(ninA, ninB, AIR_TRUE) && nrrdSameSize(ninA, ninC, AIR_TRUE) )) { biffAddf(NRRD, "%s: size mismatch between arguments", me); return 1; } if (airEnumValCheck(nrrdTernaryOp, op)) { biffAddf(NRRD, "%s: ternary op %d invalid", me, op); return 1; } nrrdAxisInfoGet_nva(ninA, nrrdAxisInfoSize, size); if (!( nout == ninA || nout == ninB || nout == ninC)) { if (_nrrdMaybeAllocMaybeZero_nva(nout, ninA->type, ninA->dim, size, AIR_FALSE /* zero when no realloc */)) { biffAddf(NRRD, "%s: couldn't allocate output nrrd", me); return 1; } if (nrrdAxisInfoCopy(nout, ninA, NULL, NRRD_AXIS_INFO_NONE)) { biffAddf(NRRD, "%s:", me); return 1; } nrrdBasicInfoCopy(nout, ninA, (NRRD_BASIC_INFO_DATA_BIT | NRRD_BASIC_INFO_TYPE_BIT | NRRD_BASIC_INFO_DIMENSION_BIT | NRRD_BASIC_INFO_CONTENT_BIT | NRRD_BASIC_INFO_COMMENTS_BIT | (nrrdStateKeyValuePairsPropagate ? 0 : NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT))); } nrrdBasicInfoInit(nout, NRRD_BASIC_INFO_ALL ^ (NRRD_BASIC_INFO_OLDMIN_BIT | NRRD_BASIC_INFO_OLDMAX_BIT)); top = _nrrdTernaryOp[op]; N = nrrdElementNumber(ninA); lupA = nrrdDLookup[ninA->type]; lupB = nrrdDLookup[ninB->type]; lupC = nrrdDLookup[ninC->type]; ins = nrrdDInsert[nout->type]; for (I=0; I<N; I++) { /* HEY: there is a loss of precision issue here with 64-bit ints */ valA = lupA(ninA->data, I); valB = lupB(ninB->data, I); valC = lupC(ninC->data, I); ins(nout->data, I, top(valA, valB, valC)); } contA = _nrrdContentGet(ninA); contB = _nrrdContentGet(ninB); contC = _nrrdContentGet(ninC); if (_nrrdContentSet_va(nout, airEnumStr(nrrdTernaryOp, op), contA, "%s,%s", contB, contC)) { biffAddf(NRRD, "%s:", me); free(contA); free(contB); free(contC); return 1; } free(contA); free(contB); free(contC); return 0; }