void _nrrdMeasureMode(void *ans, int ansType, const void *_line, int lineType, size_t len, double axmin, double axmax) { Nrrd *nline, *nhist; void *line; AIR_UNUSED(axmin); AIR_UNUSED(axmax); line = calloc(len, nrrdTypeSize[lineType]); if (line) { memcpy(line, _line, len*nrrdTypeSize[lineType]); nline = nrrdNew(); if (nrrdWrap_va(nline, line, lineType, 1, len)) { free(biffGetDone(NRRD)); nrrdNix(nline); nrrdDStore[ansType](ans, AIR_NAN); return; } nhist = nrrdNew(); if (nrrdHisto(nhist, nline, NULL, NULL, nrrdStateMeasureModeBins, nrrdTypeInt)) { free(biffGetDone(NRRD)); nrrdNuke(nhist); nrrdNix(nline); nrrdDStore[ansType](ans, AIR_NAN); return; } /* now we pass this histogram off to histo-mode */ _nrrdMeasureHistoMode(ans, ansType, nhist->data, nrrdTypeInt, nrrdStateMeasureModeBins, nhist->axis[0].min, nhist->axis[0].max); nrrdNuke(nhist); nrrdNix(nline); } else { nrrdDStore[ansType](ans, 0); } return; }
int limnpu_vertsMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *hopt = NULL; char *err, *perr; airArray *mop; int pret; limnPolyData *pld; Nrrd *nout; char *out; hestOptAdd(&hopt, NULL, "input", airTypeOther, 1, 1, &pld, NULL, "input polydata filename", NULL, NULL, limnHestPolyDataLMPD); hestOptAdd(&hopt, NULL, "output", airTypeString, 1, 1, &out, NULL, "output nrrd filename"); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); USAGE(myinfo); PARSE(); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNix, airMopAlways); /* NOT nrrdNuke */ if (nrrdWrap_va(nout, pld->xyzw, nrrdTypeFloat, 2, 4, pld->xyzwNum) || nrrdSave(out, nout, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble:%s", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int miteRayEnd(miteThread *mtt, miteRender *mrr, miteUser *muu) { int idx, slen, stageIdx; mite_t *imgData; double A; AIR_UNUSED(mrr); mtt->samples += mtt->raySample; idx = mtt->ui + (muu->nout->axis[1].size)*mtt->vi; imgData = (mite_t*)muu->nout->data; A = 1 - mtt->TT; if (A) { ELL_5V_SET(imgData + 5*idx, mtt->RR/A, mtt->GG/A, mtt->BB/A, A, mtt->ZZ); } else { ELL_5V_SET(imgData + 5*idx, 0, 0, 0, 0, AIR_NAN); } if (mtt->verbose) { /* muu->debug may be over-allocated, but that's harmless */ muu->ndebug->axis[1].size = mtt->raySample; nrrdWrap_va(muu->ndebug, muu->debug, nrrdTypeDouble, 2, AIR_CAST(size_t, muu->ndebug->axis[0].size), AIR_CAST(size_t, mtt->raySample)); airArrayNix(muu->debugArr); slen = 0; for (stageIdx=0; stageIdx<mtt->stageNum; stageIdx++) { slen += strlen(mtt->stage[stageIdx].label) + 2; } slen += strlen("R,G,B,A,Z") + 1; muu->ndebug->axis[0].label = (char *)calloc(slen, sizeof(char)); for (stageIdx=0; stageIdx<mtt->stageNum; stageIdx++) { strcat(muu->ndebug->axis[0].label, mtt->stage[stageIdx].label); strcat(muu->ndebug->axis[0].label, ",,"); } strcat(muu->ndebug->axis[0].label, "R,G,B,A,Z"); } return 0; }
/* ******** limnCameraPathMake ** ** uses limnSplines to do camera paths based on key-frames ** ** output: cameras at all "numFrames" frames are set in the ** PRE-ALLOCATED array of output cameras, "cam". ** ** input: ** keycam: array of keyframe cameras ** time: times associated with the key frames ** ---> both of these arrays are length "numKeys" <--- ** trackWhat: takes values from the limnCameraPathTrack* enum ** quatType: spline to control camera orientations. This is needed for ** tracking at or from, but not needed for limnCameraPathTrackBoth. ** This is the only limnSplineTypeSpec* argument that can be NULL. ** posType: spline to control whichever of from, at, and up are needed for ** the given style of tracking. ** distType: spline to control neer, faar, dist: positions of near clipping, ** far clipping, and image plane, as well as the ** distance between from and at (which is used if not doing ** limnCameraPathTrackBoth) ** viewType: spline to control fov (and aspect, if you're crazy) ** ** NOTE: The "atRelative", "orthographic", and "rightHanded" fields ** are copied from keycam[0] into all output cam[i], but you still need ** to correctly set them for all keycam[i] for limnCameraUpdate to work ** as expected. Also, for the sake of simplicity, this function only works ** with fov and aspect, instead of {u,v}Range, and hence both "fov" and ** "aspect" need to set in *all* the keycams, even if neither of them ** ever changes! */ int limnCameraPathMake(limnCamera *cam, int numFrames, limnCamera *keycam, double *time, int numKeys, int trackWhat, limnSplineTypeSpec *quatType, limnSplineTypeSpec *posType, limnSplineTypeSpec *distType, limnSplineTypeSpec *viewType) { static const char me[]="limnCameraPathMake"; char which[AIR_STRLEN_MED]; airArray *mop; Nrrd *nquat, *nfrom, *natpt, *nupvc, *ndist, *nfova, *ntime, *nsample; double fratVec[3], *quat, *from, *atpt, *upvc, *dist, *fova, W2V[9], N[3], fratDist; limnSpline *timeSpline, *quatSpline, *fromSpline, *atptSpline, *upvcSpline, *distSpline, *fovaSpline; limnSplineTypeSpec *timeType; int ii, E; if (!( cam && keycam && time && posType && distType && viewType )) { biffAddf(LIMN, "%s: got NULL pointer", me); return 1; } if (!( AIR_IN_OP(limnCameraPathTrackUnknown, trackWhat, limnCameraPathTrackLast) )) { biffAddf(LIMN, "%s: trackWhat %d not in valid range [%d,%d]", me, trackWhat, limnCameraPathTrackUnknown+1, limnCameraPathTrackLast-1); return 1; } if (limnCameraPathTrackBoth != trackWhat && !quatType) { biffAddf(LIMN, "%s: need the quaternion limnSplineTypeSpec if not " "doing trackBoth", me); return 1; } /* create and allocate nrrds. For the time being, we're allocating more different nrrds, and filling their contents, than we need to-- nquat is not needed if we're doing limnCameraPathTrackBoth, for example. However, we do make an effort to only do the spline evaluation on the things we actually need to know. */ mop = airMopNew(); airMopAdd(mop, nquat = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nfrom = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, natpt = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nupvc = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, ndist = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nfova = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, ntime = nrrdNew(), (airMopper)nrrdNix, airMopAlways); if (nrrdWrap_va(ntime, time, nrrdTypeDouble, 1, AIR_CAST(size_t, numKeys))) { biffMovef(LIMN, NRRD, "%s: trouble wrapping time values", me); airMopError(mop); return 1; } airMopAdd(mop, nsample = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); timeType = limnSplineTypeSpecNew(limnSplineTypeTimeWarp); airMopAdd(mop, timeType, (airMopper)limnSplineTypeSpecNix, airMopAlways); if (nrrdMaybeAlloc_va(nquat, nrrdTypeDouble, 2, AIR_CAST(size_t, 4), AIR_CAST(size_t, numKeys)) || nrrdMaybeAlloc_va(nfrom, nrrdTypeDouble, 2, AIR_CAST(size_t, 3), AIR_CAST(size_t, numKeys)) || nrrdMaybeAlloc_va(natpt, nrrdTypeDouble, 2, AIR_CAST(size_t, 3), AIR_CAST(size_t, numKeys)) || nrrdMaybeAlloc_va(nupvc, nrrdTypeDouble, 2, AIR_CAST(size_t, 3), AIR_CAST(size_t, numKeys)) || nrrdMaybeAlloc_va(ndist, nrrdTypeDouble, 2, AIR_CAST(size_t, 4), AIR_CAST(size_t, numKeys)) || nrrdMaybeAlloc_va(nfova, nrrdTypeDouble, 2, AIR_CAST(size_t, 2), AIR_CAST(size_t, numKeys))) { biffMovef(LIMN, NRRD, "%s: couldn't allocate buffer nrrds", me); airMopError(mop); return 1; } quat = (double*)(nquat->data); from = (double*)(nfrom->data); atpt = (double*)(natpt->data); upvc = (double*)(nupvc->data); dist = (double*)(ndist->data); fova = (double*)(nfova->data); /* check cameras, and put camera information into nrrds */ for (ii=0; ii<numKeys; ii++) { if (limnCameraUpdate(keycam + ii)) { biffAddf(LIMN, "%s: trouble with camera at keyframe %d\n", me, ii); airMopError(mop); return 1; } if (!( AIR_EXISTS(keycam[ii].fov) && AIR_EXISTS(keycam[ii].aspect) )) { biffAddf(LIMN, "%s: fov, aspect not both defined on keyframe %d", me, ii); airMopError(mop); return 1; } ell_4m_to_q_d(quat + 4*ii, keycam[ii].W2V); if (ii) { if (0 > ELL_4V_DOT(quat + 4*ii, quat + 4*(ii-1))) { ELL_4V_SCALE(quat + 4*ii, -1, quat + 4*ii); } } ELL_3V_COPY(from + 3*ii, keycam[ii].from); ELL_3V_COPY(atpt + 3*ii, keycam[ii].at); ELL_3V_COPY(upvc + 3*ii, keycam[ii].up); ELL_3V_SUB(fratVec, keycam[ii].from, keycam[ii].at); fratDist = ELL_3V_LEN(fratVec); ELL_4V_SET(dist + 4*ii, fratDist, keycam[ii].neer, keycam[ii].dist, keycam[ii].faar); ELL_2V_SET(fova + 2*ii, keycam[ii].fov, keycam[ii].aspect); } /* create splines from nrrds */ if (!( (strcpy(which, "quaternion"), quatSpline = limnSplineCleverNew(nquat, limnSplineInfoQuaternion, quatType)) && (strcpy(which, "from point"), fromSpline = limnSplineCleverNew(nfrom, limnSplineInfo3Vector, posType)) && (strcpy(which, "at point"), atptSpline = limnSplineCleverNew(natpt, limnSplineInfo3Vector, posType)) && (strcpy(which, "up vector"), upvcSpline = limnSplineCleverNew(nupvc, limnSplineInfo3Vector, posType)) && (strcpy(which, "plane distances"), distSpline = limnSplineCleverNew(ndist, limnSplineInfo4Vector, distType)) && (strcpy(which, "field-of-view"), fovaSpline = limnSplineCleverNew(nfova, limnSplineInfo2Vector, viewType)) && (strcpy(which, "time warp"), timeSpline = limnSplineCleverNew(ntime, limnSplineInfoScalar, timeType)) )) { biffAddf(LIMN, "%s: trouble creating %s spline", me, which); airMopError(mop); return 1; } airMopAdd(mop, quatSpline, (airMopper)limnSplineNix, airMopAlways); airMopAdd(mop, fromSpline, (airMopper)limnSplineNix, airMopAlways); airMopAdd(mop, atptSpline, (airMopper)limnSplineNix, airMopAlways); airMopAdd(mop, upvcSpline, (airMopper)limnSplineNix, airMopAlways); airMopAdd(mop, distSpline, (airMopper)limnSplineNix, airMopAlways); airMopAdd(mop, fovaSpline, (airMopper)limnSplineNix, airMopAlways); airMopAdd(mop, timeSpline, (airMopper)limnSplineNix, airMopAlways); /* evaluate splines */ E = AIR_FALSE; if (!E) E |= limnSplineSample(nsample, timeSpline, limnSplineMinT(timeSpline), numFrames, limnSplineMaxT(timeSpline)); quat = NULL; from = NULL; atpt = NULL; upvc = NULL; switch(trackWhat) { case limnCameraPathTrackAt: if (!E) E |= limnSplineNrrdEvaluate(natpt, atptSpline, nsample); if (!E) atpt = (double*)(natpt->data); if (!E) E |= limnSplineNrrdEvaluate(nquat, quatSpline, nsample); if (!E) quat = (double*)(nquat->data); break; case limnCameraPathTrackFrom: if (!E) E |= limnSplineNrrdEvaluate(nfrom, fromSpline, nsample); if (!E) from = (double*)(nfrom->data); if (!E) E |= limnSplineNrrdEvaluate(nquat, quatSpline, nsample); if (!E) quat = (double*)(nquat->data); break; case limnCameraPathTrackBoth: if (!E) E |= limnSplineNrrdEvaluate(nfrom, fromSpline, nsample); if (!E) from = (double*)(nfrom->data); if (!E) E |= limnSplineNrrdEvaluate(natpt, atptSpline, nsample); if (!E) atpt = (double*)(natpt->data); if (!E) E |= limnSplineNrrdEvaluate(nupvc, upvcSpline, nsample); if (!E) upvc = (double*)(nupvc->data); break; } dist = NULL; if (!E) E |= limnSplineNrrdEvaluate(ndist, distSpline, nsample); if (!E) dist = (double*)(ndist->data); fova = NULL; if (!E) E |= limnSplineNrrdEvaluate(nfova, fovaSpline, nsample); if (!E) fova = (double*)(nfova->data); if (E) { biffAddf(LIMN, "%s: trouble evaluating splines", me); airMopError(mop); return 1; } /* copy information from nrrds back into cameras */ for (ii=0; ii<numFrames; ii++) { cam[ii].atRelative = keycam[0].atRelative; cam[ii].orthographic = keycam[0].orthographic; cam[ii].rightHanded = keycam[0].rightHanded; if (limnCameraPathTrackBoth == trackWhat) { ELL_3V_COPY(cam[ii].from, from + 3*ii); ELL_3V_COPY(cam[ii].at, atpt + 3*ii); ELL_3V_COPY(cam[ii].up, upvc + 3*ii); } else { fratDist = (dist + 4*ii)[0]; ell_q_to_3m_d(W2V, quat + 4*ii); ELL_3MV_ROW1_GET(cam[ii].up, W2V); if (cam[ii].rightHanded) { ELL_3V_SCALE(cam[ii].up, -1, cam[ii].up); } ELL_3MV_ROW2_GET(N, W2V); if (limnCameraPathTrackFrom == trackWhat) { ELL_3V_COPY(cam[ii].from, from + 3*ii); ELL_3V_SCALE_ADD2(cam[ii].at, 1.0, cam[ii].from, fratDist, N); } else { ELL_3V_COPY(cam[ii].at, atpt + 3*ii); ELL_3V_SCALE_ADD2(cam[ii].from, 1.0, cam[ii].at, -fratDist, N); } } cam[ii].neer = (dist + 4*ii)[1]; cam[ii].dist = (dist + 4*ii)[2]; cam[ii].faar = (dist + 4*ii)[3]; cam[ii].fov = (fova + 2*ii)[0]; cam[ii].aspect = (fova + 2*ii)[1]; if (limnCameraUpdate(cam + ii)) { biffAddf(LIMN, "%s: trouble with output camera %d\n", me, ii); airMopError(mop); return 1; } } airMopOkay(mop); return 0; }
int NrrdWriter(HxUniformScalarField3* field, const char* filename, int encoding) { // Identify data type int nrrdType = nrrdTypeUnknown; switch ( field->primType() ) { case McPrimType::mc_uint8: nrrdType = nrrdTypeUChar; break; case McPrimType::mc_int8: nrrdType = nrrdTypeChar; break; case McPrimType::mc_uint16: nrrdType = nrrdTypeUShort; break; case McPrimType::mc_int16: nrrdType = nrrdTypeShort; break; case McPrimType::mc_int32: nrrdType = nrrdTypeInt; break; case McPrimType::mc_float: nrrdType = nrrdTypeFloat; break; case McPrimType::mc_double: nrrdType = nrrdTypeDouble; break; default: break; } if(nrrdType == nrrdTypeUnknown) { theMsg->printf("ERROR: unsupported output type: %s for nrrd",field->primType().getName()); return 0; } void* data = field->lattice.dataPtr(); Nrrd *nrrd = nrrdNew(); NrrdIoState *nios = nrrdIoStateNew(); if ( encoding == nrrdEncodingTypeGzip) { if (nrrdEncodingGzip->available() ) { nrrdIoStateEncodingSet( nios, nrrdEncodingGzip ); nrrdIoStateSet( nios, nrrdIoStateZlibLevel, 9 ); } else theMsg->printf("WARNING: Nrrd library does not support Gzip compression encoding.\n Make sure Teem_ZLIB is on in CMAKE when building Nrrd library.\n"); } else if ( encoding == nrrdEncodingTypeBzip2) { if (nrrdEncodingBzip2->available() ) { nrrdIoStateEncodingSet( nios, nrrdEncodingBzip2 ); // nrrdIoStateSet( nios, nrrdIoStateBzip2BlockSize, 9 ); } else theMsg->printf("WARNING: Nrrd library does not support Bzip2 compression encoding.\n Make sure Teem_BZIP2 is on in CMAKE when building Nrrd library.\n"); } else if ( encoding == nrrdEncodingTypeAscii) { nrrdIoStateEncodingSet( nios, nrrdEncodingAscii ); } else { theMsg->printf("ERROR: Unimplemented nrrd encoding type: %d\n",encoding); return 0; } try { if ( nrrdWrap_va( nrrd, data, nrrdType, (size_t)3, (size_t)field->lattice.dimsInt()[0], (size_t)field->lattice.dimsInt()[1], (size_t)field->lattice.dimsInt()[2] ) ) { throw( biffGetDone(NRRD) ); } nrrdSpaceDimensionSet( nrrd, 3 ); // TODO: Would be nice to set space units. How does Amira store this? // if ( writeVolume->MetaKeyExists(CMTK_META_SPACE_UNITS_STRING) ) // { // nrrd->spaceUnits[0] = strdup( writeVolume->m_MetaInformation[CMTK_META_SPACE_UNITS_STRING].c_str() ); // nrrd->spaceUnits[1] = strdup( writeVolume->m_MetaInformation[CMTK_META_SPACE_UNITS_STRING].c_str() ); // nrrd->spaceUnits[2] = strdup( writeVolume->m_MetaInformation[CMTK_META_SPACE_UNITS_STRING].c_str() ); // } int kind[NRRD_DIM_MAX] = { nrrdKindDomain, nrrdKindDomain, nrrdKindDomain }; nrrdAxisInfoSet_nva( nrrd, nrrdAxisInfoKind, kind ); // TODO: Would be nice to write some kind of space if this exists // Fetch bounding box information and voxel size float* bbox = field->bbox(); McVec3f voxelSize = field->getVoxelSize(); // Just deal with space directions orthogonal to data axes // TODO: Fetch transformation and use that double spaceDir[NRRD_DIM_MAX][NRRD_SPACE_DIM_MAX]; for ( int i = 0; i < 3; ++i ) { for ( int j = 0; j < 3; ++j ) { if (i == j) spaceDir[i][j] = (double) voxelSize[i]; else spaceDir[i][j] = 0.0; // Can't assume that memory is zeroed } } nrrdAxisInfoSet_nva( nrrd, nrrdAxisInfoSpaceDirection, spaceDir ); double origin[NRRD_DIM_MAX] = { bbox[0], bbox[2], bbox[4] }; if ( nrrdSpaceOriginSet( nrrd, origin ) ) { throw( biffGetDone(NRRD) ); } nrrdAxisInfoSet_va( nrrd, nrrdAxisInfoLabel, "x", "y", "z" ); if ( nrrdSave( filename, nrrd, nios ) ) { throw( biffGetDone(NRRD) ); } } catch ( char* err ) { theMsg->printf("ERROR: hxNrrdIO library returned error '%s'\n", err); free( err ); return 0; } nrrdIoStateNix( nios ); nrrdNix(nrrd); return 1; }
int main(int argc, char **argv) { char *err, *me, *filename; Nrrd *nin; unsigned int axi; me = argv[0]; if (2 != argc) { fprintf(stderr, "usage: %s <filename>\n", me); return 1; } filename = argv[1]; /* create a nrrd; at this point this is just an empty container */ nin = nrrdNew(); /* read in the nrrd from file */ if (nrrdLoad(nin, filename, NULL)) { err = biffGetDone(NRRD); fprintf(stderr, "%s: trouble reading \"%s\":\n%s", me, filename, err); free(err); return 1; } /* say something about the array */ printf("%s: \"%s\" is a %d-dimensional nrrd of type %s (%d)\n", me, filename, nin->dim, airEnumStr(nrrdType, nin->type), nin->type); for (axi=0; axi<nin->dim; axi++) { printf(" axis[%d] size = %u\n", axi, (unsigned int)nin->axis[axi].size); } printf("%s: the array contains %d elements, each %d bytes in size\n", me, (int)nrrdElementNumber(nin), (int)nrrdElementSize(nin)); /* blow away both the Nrrd struct *and* the memory at nin->data (nrrdNix() frees the struct but not the data, nrrdEmpty() frees the data but not the struct) */ nrrdNuke(nin); { Nrrd *nout; unsigned int sx=640, sy=480, xi, yi, idx; unsigned char *odata, rr, gg, bb; odata = (unsigned char *)(malloc(sx*sy*3)); for (yi=0; yi<sy; yi++) { rr = (unsigned char)(AIR_AFFINE(0, yi, sy, 0, 255)); for (xi=0; xi<sx; xi++) { gg = (unsigned char)(AIR_AFFINE(0, xi, sx, 0, 255)); bb = (unsigned char)(AIR_AFFINE(0, xi+yi, sx+sy, 0, 255)); idx = xi + sx*yi; odata[0 + 3*idx] = rr; odata[1 + 3*idx] = gg; odata[2 + 3*idx] = bb; } } //Saves the contents of the buffer as a png image //Currently upsidedown nout = nrrdNew(); if (nrrdWrap_va(nout, odata, nrrdTypeUChar, 3, (size_t)3, (size_t)sx, (size_t)sy) || nrrdSave("out.png", nout, NULL)) { err = biffGetDone(NRRD); fprintf(stderr, "%s: trouble wrapping image:\n%s", me, err); free(err); return 1; } nrrdNix(nout); free(odata); } return 0; }
int main(int argc, const char *argv[]) { const char *me; hestOpt *hopt; hestParm *hparm; airArray *mop; char **ninStr, *err, *outS, doneStr[13]; Nrrd *nin0, *nin, *nrgb, *nout, *nhist[2], *npreout, *nhproj[3]; float *rgb; float *out, *preout, *hist[2], maxSum, upSample, overSampleScale; unsigned int size0, sX, sY, sH, ninLen, ti, overSampleNum; NrrdResampleContext *rsmc; NrrdKernelSpec *ksp; me = argv[0]; mop = airMopNew(); hopt = NULL; hparm = hestParmNew(); airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); hparm->respFileEnable = AIR_TRUE; hestOptAdd(&hopt, "i", "images", airTypeString, 1, -1, &ninStr, NULL, "input image sequence", &ninLen, NULL, NULL); hestOptAdd(&hopt, "sh", "histo size", airTypeUInt, 1, 1, &sH, "500", "histogram size"); hestOptAdd(&hopt, "k", "kern", airTypeOther, 1, 1, &ksp, "tent", "kernel for upsampling images", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "us", "upsampling", airTypeFloat, 1, 1, &upSample, "1", "amount of upsampling of image"); hestOptAdd(&hopt, "osn", "# oversmp", airTypeUInt, 1, 1, &overSampleNum, "1", "number of sample per (upsampled) pixel"); hestOptAdd(&hopt, "osc", "scaling", airTypeFloat, 1, 1, &overSampleScale, "1", "scaling with oversampling"); hestOptAdd(&hopt, "ms", "max sum", airTypeFloat, 1, 1, &maxSum, "10", "per-hue histogram summation is non-linearly and " "asymptotically clamped to this maximum"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output filename", NULL); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, mchistInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); if (0 == overSampleNum) { fprintf(stderr, "%s: overSampleNum must be > 0\n", me); airMopError(mop); return 1; } nin0 = nrrdNew(); airMopAdd(mop, nin0, (airMopper)nrrdNuke, airMopAlways); if (nrrdLoad(nin0, ninStr[0], NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't load first image:\n%s", me, err); airMopError(mop); return 1; } if (!( (3 == nin0->axis[0].size || 4 == nin0->axis[0].size) && 3 == nin0->dim && nrrdTypeUChar == nin0->type )) { fprintf(stderr, "%s: 1st image not 3D (3-or-4)-by-X-by-Y %s array " "(got %u-D %s array)\n", me, airEnumStr(nrrdType, nrrdTypeUChar), nin0->dim, airEnumStr(nrrdType, nin0->type)); airMopError(mop); return 1; } rsmc = nrrdResampleContextNew(); airMopAdd(mop, rsmc, (airMopper)nrrdResampleContextNix, airMopAlways); size0 = AIR_CAST(unsigned int, nin0->axis[0].size); sX = AIR_CAST(unsigned int, upSample*nin0->axis[1].size); sY = AIR_CAST(unsigned int, upSample*nin0->axis[2].size); nrgb = nrrdNew(); airMopAdd(mop, nrgb, (airMopper)nrrdNuke, airMopAlways); if (nrrdResampleDefaultCenterSet(rsmc, nrrdCenterCell) || nrrdResampleInputSet(rsmc, nin0) || nrrdResampleKernelSet(rsmc, 1, ksp->kernel, ksp->parm) || nrrdResampleKernelSet(rsmc, 2, ksp->kernel, ksp->parm) || nrrdResampleSamplesSet(rsmc, 1, sX) || nrrdResampleSamplesSet(rsmc, 2, sY) || nrrdResampleRangeFullSet(rsmc, 1) || nrrdResampleRangeFullSet(rsmc, 2) || nrrdResampleTypeOutSet(rsmc, nrrdTypeFloat) || nrrdResampleRenormalizeSet(rsmc, AIR_TRUE) || nrrdResampleExecute(rsmc, nrgb)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error resampling slice:\n%s", me, err); airMopError(mop); return 1; } nhist[0] = nrrdNew(); airMopAdd(mop, nhist[0], (airMopper)nrrdNuke, airMopAlways); nhist[1] = nrrdNew(); airMopAdd(mop, nhist[1], (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(nhist[0], nrrdTypeFloat, 2, AIR_CAST(size_t, sH), AIR_CAST(size_t, sH)) || nrrdMaybeAlloc_va(nhist[1], nrrdTypeFloat, 2, AIR_CAST(size_t, sH), AIR_CAST(size_t, sH))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating histos:\n%s", me, err); airMopError(mop); return 1; } nhist[0]->axis[0].min = nhist[0]->axis[1].min = 0.0; nhist[0]->axis[0].max = nhist[0]->axis[1].max = 1.0; nhist[1]->axis[0].min = nhist[1]->axis[1].min = 0.0; nhist[1]->axis[0].max = nhist[1]->axis[1].max = 1.0; nhproj[0] = nrrdNew(); airMopAdd(mop, nhproj[0], (airMopper)nrrdNix, airMopAlways); nhproj[1] = nrrdNew(); airMopAdd(mop, nhproj[1], (airMopper)nrrdNix, airMopAlways); nhproj[2] = nrrdNew(); airMopAdd(mop, nhproj[2], (airMopper)nrrdNix, airMopAlways); printf("working ... "); hist[0] = AIR_CAST(float *, nhist[0]->data); hist[1] = AIR_CAST(float *, nhist[1]->data); nin = nrrdNew(); airMopAdd(mop, nin, (airMopper)nrrdNuke, airMopAlways); npreout = nrrdNew(); airMopAdd(mop, npreout, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(npreout, nrrdTypeFloat, 3, AIR_CAST(size_t, 3), AIR_CAST(size_t, sH), AIR_CAST(size_t, ninLen))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating pre-output:\n%s", me, err); airMopError(mop); return 1; } preout = AIR_CAST(float *, npreout->data); for (ti=0; ti<ninLen; ti++) { printf("%s", airDoneStr(0, ti, ninLen, doneStr)); fflush(stdout); if (nrrdLoad(nin, ninStr[ti], NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't load image[%u]:\n%s", me, ti, err); airMopError(mop); return 1; } if (!nrrdSameSize(nin0, nin, AIR_TRUE)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: nin[%u] not like nin[0]:\n%s", me, ti, err); airMopError(mop); return 1; } if (nrrdResampleInputSet(rsmc, nin) || nrrdResampleExecute(rsmc, nrgb)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble resampling nin[%u]:\n%s", me, ti, err); airMopError(mop); return 1; } if (nrrdWrap_va(nhproj[0], preout + 0*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH)) || nrrdWrap_va(nhproj[1], preout + 1*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH)) || nrrdWrap_va(nhproj[2], preout + 2*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble wrapping output[%u]:\n%s", me, ti, err); airMopError(mop); return 1; } rgb = AIR_CAST(float *, nrgb->data); imageProc(nhproj, nhist, sH, rgb, size0, sX*sY, overSampleNum, overSampleScale); preout += 3*sH; } printf("%s\n", airDoneStr(0, ti, ninLen, doneStr)); fflush(stdout); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(nout, nrrdTypeFloat, 3, AIR_CAST(size_t, 3), AIR_CAST(size_t, sH), AIR_CAST(size_t, ninLen))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating output:\n%s", me, err); airMopError(mop); return 1; } out = AIR_CAST(float *, nout->data); preout = AIR_CAST(float *, npreout->data); for (ti=0; ti<ninLen; ti++) { unsigned int hi; float hh, vv, ss, scl; for (hi=0; hi<sH; hi++) { hh = AIR_AFFINE(0, hi, sH, 0, 1); if (!preout[hi + 2*sH]) { ELL_3V_SET(out + 3*hi, 0, 0, 0); } else { ss = preout[hi + 2*sH]; scl = ss/(maxSum + ss); vv = scl*preout[hi + 1*sH]; dyeHSVtoRGB(out + 0 + 3*hi, out + 1 + 3*hi, out + 2 + 3*hi, hh, preout[hi + 0*sH], vv); } } out += 3*sH; preout += 3*sH; } if (nrrdSave(outS, nout, NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error saving output:\n%s", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }