int main(int argc, char *argv[]) { int i; Nrrd *nrrd; double diff, idx, idx2, idx3, idx4, lo, hi, pos, pos2, pos3, pos4; AIR_UNUSED(argc); AIR_UNUSED(argv); if (nrrdAlloc_va(nrrd=nrrdNew(), nrrdTypeFloat, 2, AIR_CAST(size_t, 4), AIR_CAST(size_t, 4))) { printf("trouble:\n%s\n", biffGet(NRRD)); exit(1); } nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoMin, 10.0, 10.0); nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoMax, 12.0, 12.0); nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoCenter, nrrdCenterNode, nrrdCenterCell); idx = 0; printf("\n"); pos = nrrdAxisInfoPos(nrrd, 0, idx); printf("pos(0, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 0, pos)); pos = nrrdAxisInfoPos(nrrd, 1, idx); printf("pos(1, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 1, pos)); idx = 1; printf("\n"); pos = nrrdAxisInfoPos(nrrd, 0, idx); printf("pos(0, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 0, pos)); pos = nrrdAxisInfoPos(nrrd, 1, idx); printf("pos(1, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 1, pos)); idx = 2; printf("\n"); pos = nrrdAxisInfoPos(nrrd, 0, idx); printf("pos(0, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 0, pos)); pos = nrrdAxisInfoPos(nrrd, 1, idx); printf("pos(1, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 1, pos)); idx = 0; idx2 = 0; printf("\n"); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 0, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 0, lo, hi); printf("range(0, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 1, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 1, lo, hi); printf("range(1, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); idx = 0; idx2 = 1; printf("\n"); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 0, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 0, lo, hi); printf("range(0, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 1, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 1, lo, hi); printf("range(1, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); idx = 1; idx2 = 0; printf("\n"); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 0, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 0, lo, hi); printf("range(0, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 1, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 1, lo, hi); printf("range(1, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoMin, 12.0, 12.0); nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoMax, 10.0, 10.0); printf("\n(axis min,max flipped)\n"); idx = 0; printf("\n"); pos = nrrdAxisInfoPos(nrrd, 0, idx); printf("pos(0, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 0, pos)); pos = nrrdAxisInfoPos(nrrd, 1, idx); printf("pos(1, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 1, pos)); idx = 1; printf("\n"); pos = nrrdAxisInfoPos(nrrd, 0, idx); printf("pos(0, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 0, pos)); pos = nrrdAxisInfoPos(nrrd, 1, idx); printf("pos(1, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 1, pos)); idx = 2; printf("\n"); pos = nrrdAxisInfoPos(nrrd, 0, idx); printf("pos(0, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 0, pos)); pos = nrrdAxisInfoPos(nrrd, 1, idx); printf("pos(1, %g) == %g --> %g\n", idx, pos, nrrdAxisInfoIdx(nrrd, 1, pos)); idx = 0; idx2 = 0; printf("\n"); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 0, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 0, lo, hi); printf("range(0, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 1, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 1, lo, hi); printf("range(1, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); idx = 0; idx2 = 2; printf("\n"); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 0, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 0, lo, hi); printf("range(0, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 1, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 1, lo, hi); printf("range(1, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); idx = 2; idx2 = 0; printf("\n"); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 0, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 0, lo, hi); printf("range(0, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrdAxisInfoPosRange(&lo, &hi, nrrd, 1, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 1, lo, hi); printf("range(1, %g -- %g) == (%g -- %g) --> (%g -- %g)\n", idx, idx2, lo, hi, idx3, idx4); nrrd->axis[0].center = nrrdCenterCell; nrrd->axis[0].size = 4; nrrd->axis[0].min = -4; nrrd->axis[0].max = 4; pos = 0; pos2 = 1; nrrdAxisInfoIdxRange(&idx, &idx2, nrrd, 0, pos, pos2); nrrdAxisInfoPosRange(&pos3, &pos4, nrrd, 0, idx, idx2); printf("min, max = %g, %g\n", nrrd->axis[0].min, nrrd->axis[0].max); printf("pos, pos2 = %g, %g\n", pos, pos2); printf("idx, idx2 = %g, %g\n", idx, idx2); printf("pos3, pos4 = %g, %g\n", pos3, pos4); exit(1); /* and now for random-ness */ airSrandMT((int)airTime()); nrrd->axis[0].center = nrrdCenterNode; nrrd->axis[0].center = nrrdCenterCell; for (i=0; i<=1000000; i++) { nrrd->axis[0].min = frand(-3.0, 3.0); nrrd->axis[0].max = frand(-3.0, 3.0); idx = frand(-3.0, 3.0); pos = nrrdAxisInfoPos(nrrd, 0, idx); diff = idx - nrrdAxisInfoIdx(nrrd, 0, pos); if (AIR_ABS(diff) > 0.00000001) { printf("PANIC 0\n"); exit(2); } pos = frand(-3.0, 3.0); idx = nrrdAxisInfoIdx(nrrd, 0, pos); diff = pos - nrrdAxisInfoPos(nrrd, 0, idx); if (AIR_ABS(diff) > 0.00000001) { printf("PANIC 1\n"); exit(2); } nrrd->axis[0].min = (int)frand(-3.0, 3.0); nrrd->axis[0].max = (int)frand(-3.0, 3.0); idx = (int)frand(-10.0, 10.0); idx2 = (int)frand(-10.0, 10.0); nrrdAxisInfoPosRange(&pos, &pos2, nrrd, 0, idx, idx2); nrrdAxisInfoIdxRange(&idx3, &idx4, nrrd, 0, pos, pos2); diff = AIR_ABS(idx - idx3) + AIR_ABS(idx2 - idx4); if (AIR_ABS(diff) > 0.00000001) { printf("PANIC 2\n"); exit(2); } pos = (int)frand(-3.0, 3.0); pos2 = (int)frand(-3.0, 3.0); nrrdAxisInfoIdxRange(&idx, &idx2, nrrd, 0, pos, pos2); nrrdAxisInfoPosRange(&pos3, &pos4, nrrd, 0, idx, idx2); diff = AIR_ABS(pos - pos3) + AIR_ABS(pos2 - pos4); if (AIR_ABS(diff) > 0.00000001) { printf("min, max = %g, %g\n", nrrd->axis[0].min, nrrd->axis[0].max); printf("pos, pos2 = %g, %g\n", pos, pos2); printf("idx, idx2 = %g, %g\n", idx, idx2); printf("pos3, pos4 = %g, %g\n", pos3, pos4); printf("PANIC (%d) 3 %g\n", (int)nrrd->axis[0].size, diff); exit(2); } } exit(0); }
/* ******** nrrdCrop() ** ** select some sub-volume inside a given nrrd, producing an output ** nrrd with the same dimensions, but with equal or smaller sizes ** along each axis. */ int nrrdCrop(Nrrd *nout, const Nrrd *nin, size_t *min, size_t *max) { char me[]="nrrdCrop", func[] = "crop", err[BIFF_STRLEN], buff1[NRRD_DIM_MAX*30], buff2[AIR_STRLEN_SMALL]; unsigned int ai; size_t I, lineSize, /* #bytes in one scanline to be copied */ typeSize, /* size of data type */ cIn[NRRD_DIM_MAX], /* coords for line start, in input */ cOut[NRRD_DIM_MAX], /* coords for line start, in output */ szIn[NRRD_DIM_MAX], szOut[NRRD_DIM_MAX], idxIn=0, idxOut=0, /* linear indices for input and output */ numLines; /* number of scanlines in output nrrd */ char *dataIn, *dataOut; /* errors */ if (!(nout && nin && min && max)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(NRRD, err); return 1; } if (nout == nin) { sprintf(err, "%s: nout==nin disallowed", me); biffAdd(NRRD, err); return 1; } for (ai=0; ai<nin->dim; ai++) { if (!(min[ai] <= max[ai])) { sprintf(err, "%s: axis %d min (" _AIR_SIZE_T_CNV ") not <= max (" _AIR_SIZE_T_CNV ")", me, ai, min[ai], max[ai]); biffAdd(NRRD, err); return 1; } if (!( min[ai] < nin->axis[ai].size && max[ai] < nin->axis[ai].size )) { sprintf(err, "%s: axis %d min (" _AIR_SIZE_T_CNV ") or max (" _AIR_SIZE_T_CNV ") out of bounds [0," _AIR_SIZE_T_CNV "]", me, ai, min[ai], max[ai], nin->axis[ai].size-1); biffAdd(NRRD, err); return 1; } } /* this shouldn't actually be necessary .. */ if (!nrrdElementSize(nin)) { sprintf(err, "%s: nrrd reports zero element size!", me); biffAdd(NRRD, err); return 1; } /* allocate */ nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, szIn); numLines = 1; for (ai=0; ai<nin->dim; ai++) { szOut[ai] = max[ai] - min[ai] + 1; if (ai) { numLines *= szOut[ai]; } } nout->blockSize = nin->blockSize; if (nrrdMaybeAlloc_nva(nout, nin->type, nin->dim, szOut)) { sprintf(err, "%s:", me); biffAdd(NRRD, err); return 1; } lineSize = szOut[0]*nrrdElementSize(nin); /* the skinny */ typeSize = nrrdElementSize(nin); dataIn = (char *)nin->data; dataOut = (char *)nout->data; memset(cOut, 0, NRRD_DIM_MAX*sizeof(unsigned int)); /* printf("!%s: nin->dim = %d\n", me, nin->dim); printf("!%s: min = %d %d %d\n", me, min[0], min[1], min[2]); printf("!%s: szIn = %d %d %d\n", me, szIn[0], szIn[1], szIn[2]); printf("!%s: szOut = %d %d %d\n", me, szOut[0], szOut[1], szOut[2]); printf("!%s: lineSize = %d\n", me, lineSize); printf("!%s: typeSize = %d\n", me, typeSize); printf("!%s: numLines = %d\n", me, (int)numLines); */ for (I=0; I<numLines; I++) { for (ai=0; ai<nin->dim; ai++) { cIn[ai] = cOut[ai] + min[ai]; } NRRD_INDEX_GEN(idxOut, cOut, szOut, nin->dim); NRRD_INDEX_GEN(idxIn, cIn, szIn, nin->dim); /* printf("!%s: %5d: cOut=(%3d,%3d,%3d) --> idxOut = %5d\n", me, (int)I, cOut[0], cOut[1], cOut[2], (int)idxOut); printf("!%s: %5d: cIn=(%3d,%3d,%3d) --> idxIn = %5d\n", me, (int)I, cIn[0], cIn[1], cIn[2], (int)idxIn); */ memmove(dataOut + idxOut*typeSize, dataIn + idxIn*typeSize, lineSize); /* the lowest coordinate in cOut[] will stay zero, since we are copying one (1-D) scanline at a time */ NRRD_COORD_INCR(cOut, szOut, nin->dim, 1); } if (nrrdAxisInfoCopy(nout, nin, NULL, (NRRD_AXIS_INFO_SIZE_BIT | NRRD_AXIS_INFO_MIN_BIT | NRRD_AXIS_INFO_MAX_BIT ))) { sprintf(err, "%s:", me); biffAdd(NRRD, err); return 1; } for (ai=0; ai<nin->dim; ai++) { nrrdAxisInfoPosRange(&(nout->axis[ai].min), &(nout->axis[ai].max), nin, ai, min[ai], max[ai]); /* do the safe thing first */ nout->axis[ai].kind = _nrrdKindAltered(nin->axis[ai].kind, AIR_FALSE); /* try cleverness */ if (!nrrdStateKindNoop) { if (nout->axis[ai].size == nin->axis[ai].size) { /* we can safely copy kind; the samples didn't change */ nout->axis[ai].kind = nin->axis[ai].kind; } else if (nrrdKind4Color == nin->axis[ai].kind && 3 == szOut[ai]) { nout->axis[ai].kind = nrrdKind3Color; } else if (nrrdKind4Vector == nin->axis[ai].kind && 3 == szOut[ai]) { nout->axis[ai].kind = nrrdKind3Vector; } else if ((nrrdKind4Vector == nin->axis[ai].kind || nrrdKind3Vector == nin->axis[ai].kind) && 2 == szOut[ai]) { nout->axis[ai].kind = nrrdKind2Vector; } else if (nrrdKindRGBAColor == nin->axis[ai].kind && 0 == min[ai] && 2 == max[ai]) { nout->axis[ai].kind = nrrdKindRGBColor; } else if (nrrdKind2DMaskedSymMatrix == nin->axis[ai].kind && 1 == min[ai] && max[ai] == szIn[ai]-1) { nout->axis[ai].kind = nrrdKind2DSymMatrix; } else if (nrrdKind2DMaskedMatrix == nin->axis[ai].kind && 1 == min[ai] && max[ai] == szIn[ai]-1) { nout->axis[ai].kind = nrrdKind2DMatrix; } else if (nrrdKind3DMaskedSymMatrix == nin->axis[ai].kind && 1 == min[ai] && max[ai] == szIn[ai]-1) { nout->axis[ai].kind = nrrdKind3DSymMatrix; } else if (nrrdKind3DMaskedMatrix == nin->axis[ai].kind && 1 == min[ai] && max[ai] == szIn[ai]-1) { nout->axis[ai].kind = nrrdKind3DMatrix; } } } strcpy(buff1, ""); for (ai=0; ai<nin->dim; ai++) { sprintf(buff2, "%s[" _AIR_SIZE_T_CNV "," _AIR_SIZE_T_CNV "]", (ai ? "x" : ""), min[ai], max[ai]); strcat(buff1, buff2); } if (nrrdContentSet_va(nout, func, nin, "%s", buff1)) { sprintf(err, "%s:", me); biffAdd(NRRD, err); return 1; } if (nrrdBasicInfoCopy(nout, nin, NRRD_BASIC_INFO_DATA_BIT | NRRD_BASIC_INFO_TYPE_BIT | NRRD_BASIC_INFO_BLOCKSIZE_BIT | NRRD_BASIC_INFO_DIMENSION_BIT | NRRD_BASIC_INFO_SPACEORIGIN_BIT | NRRD_BASIC_INFO_CONTENT_BIT | NRRD_BASIC_INFO_COMMENTS_BIT | (nrrdStateKeyValuePairsPropagate ? 0 : NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT))) { sprintf(err, "%s:", me); biffAdd(NRRD, err); return 1; } /* copy origin, then shift it along the spatial axes */ _nrrdSpaceVecCopy(nout->spaceOrigin, nin->spaceOrigin); for (ai=0; ai<nin->dim; ai++) { if (AIR_EXISTS(nin->axis[ai].spaceDirection[0])) { _nrrdSpaceVecScaleAdd2(nout->spaceOrigin, 1.0, nout->spaceOrigin, min[ai], nin->axis[ai].spaceDirection); } } return 0; }