/* ----------------------------- MNI Header ----------------------------------- @NAME : save_volume_slice @INPUT : icvid - id of icv to write volume_info - volume information (minimum and maximum are ignored) slice_num - number of slice to write image - image to write slice_min - minimum real value for slice slice_max - maximum real value for slice @OUTPUT : (nothing) @RETURNS : (nothing) @DESCRIPTION: Routine to write out a slice. @METHOD : @GLOBALS : @CALLS : @CREATED : August 26, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ static void save_volume_slice(int icvid, Volume_Info *volume_info, int slice_num, unsigned char *image, double slice_min, double slice_max) { int mincid; long start[MAX_VAR_DIMS], count[MAX_VAR_DIMS]; /* Get the minc file id */ (void) miicv_inqint(icvid, MI_ICV_CDFID, &mincid); /* Set up the start and count variables for writinging the volume */ (void) miset_coords(3, 0, start); start[0] = slice_num; count[0] = 1; count[1] = volume_info->nrows; count[2] = volume_info->ncolumns; /* Write out the slice min and max */ (void) mivarput1(mincid, ncvarid(mincid, MIimagemin), start, NC_DOUBLE, NULL, &slice_min); (void) mivarput1(mincid, ncvarid(mincid, MIimagemax), start, NC_DOUBLE, NULL, &slice_max); /* Write out the volume */ (void) miicv_put(icvid, start, count, image); }
/* ----------------------------- MNI Header ----------------------------------- @NAME : save_volume_slice @INPUT : icvid - id of icv to write volume_info - volume information (minimum and maximum are ignored) slice_num - number of slice to write image - image to write slice_min - minimum real value for slice slice_max - maximum real value for slice @OUTPUT : (nothing) @RETURNS : (nothing) @DESCRIPTION: Routine to write out a slice. @METHOD : @GLOBALS : @CALLS : @CREATED : August 26, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ void save_volume_slice(int icvid, Volume_Info *volume_info, int slice_num[], unsigned char *image, double slice_min, double slice_max) { int mincid; long start[MAX_VAR_DIMS], count[MAX_VAR_DIMS]; int idim, ndims; /* Get the minc file id */ (void) miicv_inqint(icvid, MI_ICV_CDFID, &mincid); ndims = volume_info->number_of_dimensions; /* Set up the start and count variables for writing the volume */ (void) miset_coords(MAX_VAR_DIMS, 0, start); for(idim=0; idim<ndims-2; idim++){ start[idim] = slice_num[idim]; count[idim] = 1; } count[ndims-2] = volume_info->length[ndims-2]; count[ndims-1] = volume_info->length[ndims-1]; /* Write out the slice min and max */ (void) mivarput1(mincid, ncvarid(mincid, MIimagemin), start, NC_DOUBLE, NULL, &slice_min); (void) mivarput1(mincid, ncvarid(mincid, MIimagemax), start, NC_DOUBLE, NULL, &slice_max); /* Write out the volume */ (void) miicv_put(icvid, start, count, image); }
/* ----------------------------- MNI Header ----------------------------------- @NAME : WriteImages @INPUT : TempFile - where the images come from Image - where they're going Slices - vector containing list of slices to write Frames - vector containing list of frames to write NumSlices - the number of elements of Slices[] actually used NumFrames - the number of elements of Frames[] actually used @OUTPUT : @RETURNS : an error code as defined in mierrors.h ERR_NONE = all went well ERR_IN_TEMP = ran out of data reading the temp file ERR_OUT_MINC = some problem writing to MINC file (this should not happen!!!) also sets ErrMsg in the event of an error @DESCRIPTION: Reads images sequentially from TempFile, and writes them into the image variable specified by *Image at the slice/frame locations specified by Slices[] and Frames[]. Smart enough to handle files with no time dimension, but assumes there is always a z dimension. @METHOD : @GLOBALS : @CALLS : @CREATED : 93-6-3, Greg Ward @MODIFIED : ---------------------------------------------------------------------------- */ int WriteImages (FILE *TempFile, ImageInfoRec *Image, long Slices[], long Frames[], long NumSlices, long NumFrames) { int slice, frame; long Start [MAX_NC_DIMS], Count [MAX_NC_DIMS]; double *Buffer; Boolean DoFrames; Boolean DoSlices; Boolean Success; int RetVal; Buffer = (double *) calloc (Image->ImageSize, sizeof (double)); /* * First ensure that we will always read an *entire* image, but only * one slice/frame at a time (no matter how many slices/frames we * may be reading) */ Start [Image->HeightDim] = 0; Count [Image->HeightDim] = Image->Height; Start [Image->WidthDim] = 0; Count [Image->WidthDim] = Image->Width; /* * Handle files with missing frames or slices. See the function * ReadImages in the file mireadimages.c for a detailed explanation. */ if (NumFrames > 0) { Count [Image->FrameDim] = 1; DoFrames = TRUE; } else { DoFrames = FALSE; NumFrames = 1; } /* Exact same code as for frames, but changed to slices */ if (NumSlices > 0) { Count [Image->SliceDim] = 1; DoSlices = TRUE; } else { DoSlices = FALSE; NumSlices = 1; } #ifdef DEBUG printf ("Ready to start writing.\n"); printf ("NumFrames = %ld, DoFrames = %d\n", NumFrames, (int) DoFrames); printf ("NumSlices = %ld, DoSlices = %d\n", NumSlices, (int) DoSlices); #endif for (slice = 0; slice < NumSlices; slice++) { if (DoSlices) { Start [Image->SliceDim] = Slices [slice]; } /* * Loop through all frames, reading/writing one image each time. * Note that NumFrames will be one even if DoFrames is false; * so this loop WILL always execute, but it and the functions it calls * (particularly PutMaxMin) act slightly differently depending on * the value of DoFrames, */ for (frame = 0; frame < NumFrames; frame++) { Success = ReadNextImage (Buffer, Image->ImageSize, TempFile); if (!Success) { sprintf (ErrMsg, "Error reading from temporary file at slice %d, frame %d", slice, frame); return (ERR_IN_TEMP); } PutMaxMin (Image, Buffer, Slices [slice], Frames [frame], DoSlices, DoFrames); if (DoFrames) { Start [Image->FrameDim] = Frames [frame]; } RetVal = miicv_put (Image->ICV, Start, Count, Buffer); if (RetVal == MI_ERROR) { sprintf (ErrMsg, "INTERNAL BUG: Fail on miicv_put: Error code %d", ncerr); return (ERR_OUT_MINC); } } /* for frame */ } /* for slice */ /* * Use the MIcomplete attribute to signal that we are done writing */ miattputstr (Image->CDF, Image->ID, MIcomplete, MI_TRUE); free (Buffer); return (ERR_NONE); } /* WriteImages */
int main(int argc, char **argv) { int icv, cdfid, img, max, min, dimvar; static int dim[MAX_VAR_DIMS]; static struct { long len; char *name;} diminfo[] = { { 7, MIzspace }, { 9, MIyspace }, { 2, MIxspace } }; /* static struct { long len; char *name;} diminfo[]= {3, MIzspace, 4, MIyspace, 5, MIxspace}; */ static int numdims=sizeof(diminfo)/sizeof(diminfo[0]); static long coord[]={0,0,0}; static long count[]={3,4,5}; double dvalue; short int ivalue[]={ 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 311, 313, 315, 317, 319, 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349 }; int i, j, k; int cflag = 0; #if MINC2 if (argc == 2 && !strcmp(argv[1], "-2")) { cflag = MI2_CREATE_V2; } #endif /* MINC2 */ icv=miicv_create(); miicv_setint(icv, MI_ICV_XDIM_DIR, MI_ICV_NEGATIVE); miicv_setint(icv, MI_ICV_YDIM_DIR, MI_ICV_NEGATIVE); miicv_setint(icv, MI_ICV_ZDIM_DIR, MI_ICV_NEGATIVE); miicv_setint(icv, MI_ICV_NUM_IMGDIMS, 3); miicv_setint(icv, MI_ICV_DIM_SIZE+0, 5); miicv_setint(icv, MI_ICV_DIM_SIZE+1, 4); miicv_setint(icv, MI_ICV_DIM_SIZE+2, 3); miicv_setint(icv, MI_ICV_DO_DIM_CONV, TRUE); miicv_setint(icv, MI_ICV_KEEP_ASPECT, FALSE); miicv_setint(icv, MI_ICV_DO_NORM, TRUE); cdfid=micreate("test.mnc", NC_CLOBBER | cflag); for (i=0; i<numdims; i++) { dim[i]=ncdimdef(cdfid, diminfo[i].name, diminfo[i].len); dimvar=micreate_std_variable(cdfid, diminfo[i].name, NC_DOUBLE, 0, &dim[i]); miattputdbl(cdfid, dimvar, MIstep, 0.8); miattputdbl(cdfid, dimvar, MIstart, 22.0); } img=micreate_std_variable(cdfid, MIimage, NC_SHORT, numdims, dim); max=micreate_std_variable(cdfid, MIimagemax, NC_DOUBLE, 1, dim); min=micreate_std_variable(cdfid, MIimagemin, NC_DOUBLE, 1, dim); ncendef(cdfid); for (i=0; i<diminfo[0].len; i++) { dvalue = 200; coord[0]=i; ncvarput1(cdfid, max, coord, &dvalue); dvalue = -dvalue; ncvarput1(cdfid, min, coord, &dvalue); } coord[0]=0; miicv_attach(icv, cdfid, img); miicv_inqdbl(icv, MI_ICV_ADIM_START, &dvalue); printf("adim start = %g", dvalue); miicv_inqdbl(icv, MI_ICV_ADIM_STEP, &dvalue); printf(", step = %g\n", dvalue); miicv_inqdbl(icv, MI_ICV_BDIM_START, &dvalue); printf("bdim start = %g", dvalue); miicv_inqdbl(icv, MI_ICV_BDIM_STEP, &dvalue); printf(", step = %g\n", dvalue); miicv_inqdbl(icv, MI_ICV_NORM_MAX, &dvalue); printf("norm : max = %g", dvalue); miicv_inqdbl(icv, MI_ICV_NORM_MIN, &dvalue); printf(", min = %g\n", dvalue); miicv_put(icv, coord, count, ivalue); miicv_get(icv, coord, count, ivalue); for (i=0; i<3; i++) { for (j=0; j<4; j++) { for (k=0; k<5; k++) { printf("%5d",ivalue[i*20+j*5+k]); } printf("\n"); } } miclose(cdfid); miicv_free(icv); return 0; }
int main(int argc, char **argv) { int icv, cdfid, img, max, min; static char *typenm[]={"short", "double"}; static char *boolnm[] = {"true", "false"}; static nc_type intypes[] = {NC_SHORT, NC_DOUBLE}; static int norms[] = {TRUE, FALSE}; static nc_type outtypes[] = {NC_SHORT, NC_DOUBLE}; static int maxpresent[] = {TRUE, FALSE}; static int valpresent[] = {TRUE, FALSE}; static int dim[MAX_VAR_DIMS]; static struct { long len; char *name;} diminfo[] = { { 3, MIzspace }, { 1, MIyspace }, { 1, MIxspace } }; static int numdims=sizeof(diminfo)/sizeof(diminfo[0]); static long coord[]={0,0,0}; static long count[]={1,1,1}; static double max_values[] = {0.4, 0.6, 0.8}; double dvalue; short int ivalue; int i, intype, inorm, outtype, imax, ival; int cflag = 0; char filename[256]; #if MINC2 if (argc == 2 && !strcmp(argv[1], "-2")) { cflag = MI2_CREATE_V2; } #endif /* MINC2 */ snprintf(filename, sizeof(filename), "test_icv_range-%d.mnc", getpid()); for (intype=0; intype<MAX_IN_TYPES; intype++) { for (inorm=0; inorm<MAX_NORM; inorm++) { icv=miicv_create(); miicv_setint(icv, MI_ICV_TYPE, intypes[intype]); miicv_setint(icv, MI_ICV_DO_NORM, norms[inorm]); miicv_setdbl(icv, MI_ICV_VALID_MAX, 20000.0); miicv_setdbl(icv, MI_ICV_VALID_MIN, 0.0); for (outtype=0; outtype<MAX_OUT_TYPES; outtype++) { for (imax=0; imax<MAX_MAX; imax++) { for (ival=0; ival<MAX_VAL; ival++) { printf( "in : %s, out : %s, norm : %s, imgmax : %s, valid : %s\n", typenm[intype], typenm[outtype], boolnm[inorm], boolnm[imax], boolnm[ival]); cdfid=micreate(filename, NC_CLOBBER | cflag); for (i=0; i<numdims; i++) dim[i]=ncdimdef(cdfid, diminfo[i].name, diminfo[i].len); img=micreate_std_variable(cdfid, MIimage, outtypes[outtype], numdims, dim); if (maxpresent[imax]) { max=micreate_std_variable(cdfid, MIimagemax, NC_DOUBLE, 1, dim); min=micreate_std_variable(cdfid, MIimagemin, NC_DOUBLE, 1, dim); } if (valpresent[ival]) { dvalue = 32000; ncattput(cdfid, img, MIvalid_max, NC_DOUBLE, 1, &dvalue); dvalue = 0; ncattput(cdfid, img, MIvalid_min, NC_DOUBLE, 1, &dvalue); } ncendef(cdfid); if (maxpresent[imax]) { for (i=0; i<3; i++) { dvalue = max_values[i]; coord[0]=i; ncvarput1(cdfid, max, coord, &dvalue); dvalue = -dvalue; ncvarput1(cdfid, min, coord, &dvalue); } coord[0]=0; } miicv_attach(icv, cdfid, img); if (intypes[intype]==NC_DOUBLE) { dvalue = 0.2; miicv_put(icv, coord, count, &dvalue); } else { ivalue = 12500; miicv_put(icv, coord, count, &ivalue); } dvalue = 0; mivarget1(cdfid, img, coord, NC_DOUBLE, MI_SIGNED, &dvalue); printf(" file value = %g\n", dvalue); if (intypes[intype]==NC_DOUBLE) { miicv_get(icv, coord, count, &dvalue); } else { miicv_get(icv, coord, count, &ivalue); dvalue=ivalue; } printf(" icv value = %g\n", dvalue); miclose(cdfid); } } } miicv_free(icv); } } unlink(filename); return 0; }
MNCAPI int minc_save_data(int fd, void *dataptr, int datatype, long st, long sz, long sy, long sx, long ct, long cz, long cy, long cx) { nc_type nctype; char *signstr; int i; int var_id; int var_ndims; int var_dims[MAX_NC_DIMS]; int icv; long start[MI_S_NDIMS]; long count[MI_S_NDIMS]; int old_ncopts; int r; double min, max; long slice_size; long index; int dtbytes; /* Length of datatype in bytes */ old_ncopts =get_ncopts(); set_ncopts(0); var_id = ncvarid(fd, MIimage); ncvarinq(fd, var_id, NULL, NULL, &var_ndims, var_dims, NULL); set_ncopts(old_ncopts); if (var_ndims < 2 || var_ndims > 4) { return (MINC_STATUS_ERROR); } r = minc_simple_to_nc_type(datatype, &nctype, &signstr); if (r == MINC_STATUS_ERROR) { return (MINC_STATUS_ERROR); } dtbytes = nctypelen(nctype); /* Update the image-min and image-max values */ if (ct > 0) { slice_size = cz * cy * cx; index = st; for (i = 0; i < ct; i++) { find_minmax((char *) dataptr + (dtbytes * slice_size * i), slice_size, datatype, &min, &max); mivarput1(fd, ncvarid(fd, MIimagemin), &index, NC_DOUBLE, MI_SIGNED, &min); mivarput1(fd, ncvarid(fd, MIimagemax), &index, NC_DOUBLE, MI_SIGNED, &max); index++; } } else { slice_size = cy * cx; index = sz; for (i = 0; i < cz; i++) { find_minmax((char *) dataptr + (dtbytes * slice_size * i), slice_size, datatype, &min, &max); mivarput1(fd, ncvarid(fd, MIimagemin), &index, NC_DOUBLE, MI_SIGNED, &min); mivarput1(fd, ncvarid(fd, MIimagemax), &index, NC_DOUBLE, MI_SIGNED, &max); index++; } } /* We want the data to wind up in t, x, y, z order. */ icv = miicv_create(); if (icv < 0) { return (MINC_STATUS_ERROR); } r = miicv_setint(icv, MI_ICV_TYPE, nctype); if (r < 0) { return (MINC_STATUS_ERROR); } r = miicv_setstr(icv, MI_ICV_SIGN, signstr); if (r < 0) { return (MINC_STATUS_ERROR); } r = miicv_setint(icv, MI_ICV_DO_NORM, 1); if (r < 0) { return (MINC_STATUS_ERROR); } r = miicv_setint(icv, MI_ICV_DO_FILLVALUE, 1); if (r < 0) { return (MINC_STATUS_ERROR); } r = miicv_attach(icv, fd, var_id); if (r < 0) { return (MINC_STATUS_ERROR); } i = 0; switch (var_ndims) { case 4: count[i] = ct; start[i] = st; i++; /* fall through */ case 3: count[i] = cz; start[i] = sz; i++; /* fall through */ case 2: count[i] = cy; start[i] = sy; i++; count[i] = cx; start[i] = sx; i++; break; } r = miicv_put(icv, start, count, dataptr); if (r < 0) { return (MINC_STATUS_ERROR); } miicv_detach(icv); miicv_free(icv); return (MINC_STATUS_OK); }