Esempio n. 1
0
/* regrid using a minc volume */
void regrid_minc(char *in_fn, int buffer_size,
                 VIO_Volume * totals, VIO_Volume * weights, int v_size,
                 double regrid_floor, double regrid_ceil)
{
   Loop_Data ld;
   Loop_Options *loop_opt;
   int      mincid;

   /* Open the file to get some information */
   mincid = miopen(in_fn, NC_NOWRITE);
   ld.file_ndims = get_minc_ndims(mincid);
   get_minc_spatial_dims(mincid, ld.space_to_dim, ld.dim_to_space);
   get_minc_voxel_to_world(mincid, ld.voxel_to_world);

   /* alloc space for data_buf */
   ld.data_buf = (double *)malloc(sizeof(double) * v_size);

   ld.floor = regrid_floor;
   ld.ceil = regrid_ceil;

   ld.totals = totals;
   ld.weights = weights;

   /* set up and do voxel_loop */
   loop_opt = create_loop_options();
   set_loop_first_input_mincid(loop_opt, mincid);
   set_loop_verbose(loop_opt, verbose);
   set_loop_buffer_size(loop_opt, (long)1024 * buffer_size);
   voxel_loop(1, &in_fn, 0, NULL, NULL, loop_opt, regrid_loop, (void *)&ld);
   free_loop_options(loop_opt);

   /* tidy up */
   free(ld.data_buf);
   }
Esempio n. 2
0
/* get info from a model file (steps, starts, etc */
int get_model_file_info(char *dst, char *key, char *nextArg)
{
   int      mincid;
   char    *fname;

   /* Get pointer to volume definition structure */
   Volume_Definition *vd = (Volume_Definition *) dst;

   /* Check for following argument */
   if(nextArg == NULL){
      (void)fprintf(stderr, "\"%s\" option requires an additional argument\n", key);
      exit(EXIT_FAILURE);
      }
   fname = nextArg;

   /* check that the file exists */
   if(!file_exists(fname)){
      fprintf(stderr, "Couldn't find -like file %s.\n\n", fname);
      exit(EXIT_FAILURE);
      }

   /* get volume definition from input filename */
   mincid = miopen(fname, NC_NOWRITE);
   get_vol_def(mincid, vd);

   /* Close the file */
   miclose(mincid);

   return TRUE;
   }
Esempio n. 3
0
MNCAPI int minc_format_convert(const char *input,const char *output)
{
    int old_fd;
    int new_fd;
    int flags;
    struct mi2opts opts;
    
    old_fd = miopen((char *)input, NC_NOWRITE);
    if (old_fd < 0) {
        perror(input);
        return MI_ERROR;
    }

    flags = NC_CLOBBER|MI2_CREATE_V2;

    memset(&opts,0,sizeof(struct mi2opts));
    opts.struct_version = MI2_OPTS_V1;

    new_fd = micreatex((char *)output, flags, &opts);
    if (new_fd < 0) {
        perror(output);
        exit MI_ERROR;
    }

    micopy(old_fd, new_fd);

    miclose(old_fd);
    miclose(new_fd);
    
    return MI_NOERROR;
}
Esempio n. 4
0
MNCAPI int
minc_get_world_transform(char *path, double transform[MINC_3D][MINC_3D+1])
{
    int i, j;
    double dircos[MINC_3D];
    double step, start;
    char *dimensions[] = { MIxspace, MIyspace, MIzspace };
    int length;
    int fd;
    int varid;
    int old_ncopts;

    old_ncopts =get_ncopts();
    set_ncopts(0);

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
	set_ncopts(old_ncopts);
        return (MINC_STATUS_ERROR);
    }

    /* Zero the matrix */
    for (i = 0; i < MINC_3D; i++) {
        for (j = 0; j < MINC_3D + 1; j++) {
          transform[i][j] = 0.0;
        }
        transform[i][i] = 1.0;
    }

   for (j = 0; j < MINC_3D; j++) {

      /* Set default values */
      step = 1.0;
      start = 0.0;
      for (i = 0; i < MINC_3D; i++) {
         dircos[i] = 0.0;
      }
      dircos[j] = 1.0;

      varid = ncvarid(fd, dimensions[j]);
      miattget(fd, varid, MIstart, NC_DOUBLE, 1, &start, &length);
      miattget(fd, varid, MIstep, NC_DOUBLE, 1, &step, &length);
      miattget(fd, varid, MIdirection_cosines, NC_DOUBLE, 3, dircos, &length);

      normalize_vector(dircos);

      /* Put them in the matrix.
       */
      for (i = 0; i < MINC_3D; i++) {
         transform[i][j] = step * dircos[i];
         transform[i][MINC_3D] += start * dircos[i];
      }

   }

   set_ncopts(old_ncopts);
   return (MINC_STATUS_OK);
}
int main(int argc, char *argv[])
{
   char **input_files;
   char *output_file;
   char *arg_string;
   int num_input_files;
   int inmincid;
   Loop_Options *loop_options;
   Program_Data program_data;

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc < 3)) {
      (void) fprintf(stderr, 
                     "\nUsage: %s [options] <in1.mnc> [...] <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr,
                     "       %s -help\n\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }
   input_files = &argv[1];
   num_input_files = argc - 2;
   output_file = argv[argc-1];

   /* Open the first input file and get the vector length */
   inmincid = miopen(input_files[0], NC_NOWRITE);
   if (get_vector_length(inmincid) > 1) {
      (void) fprintf(stderr, "Input file %s is not a scalar file\n",
                     input_files[0]);
      exit(EXIT_FAILURE);
   }

   /* Set up looping options */
   loop_options = create_loop_options();
   set_loop_clobber(loop_options, clobber);
   set_loop_verbose(loop_options, verbose);
#if MINC2
   set_loop_v2format(loop_options, v2format);
#endif /* MINC2 */
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_output_vector_size(loop_options, num_input_files);
   set_loop_buffer_size(loop_options, (long) buffer_size * 1024);
   set_loop_first_input_mincid(loop_options, inmincid);
   set_loop_accumulate(loop_options, TRUE, 0, NULL, NULL);

   /* Do loop */
   voxel_loop(num_input_files, input_files, 1, &output_file, 
              arg_string, loop_options,
              do_makevector, (void *) &program_data);

   exit(EXIT_SUCCESS);
}
Esempio n. 6
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : get_volume_info
@INPUT      : infile - input file name
@OUTPUT     : volume_info - input volume information
@RETURNS    : Id of icv created
@DESCRIPTION: Routine to read volume information for a file.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : August 22, 1993 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static int get_volume_info(char *infile, Volume_Info *volume_info)
{
   int icvid, mincid;

   /* Create and set up icv for input */
   icvid = miicv_create();
   setup_input_icv(icvid);

   /* Open the image file */
   mincid = miopen(infile, NC_NOWRITE);

   /* Attach the icv to the file */
   (void) miicv_attach(icvid, mincid, ncvarid(mincid, MIimage));

   /* Get dimension information */
   get_dimension_info(infile, icvid, volume_info);

   /* Get the volume min and max */
   (void) miicv_inqdbl(icvid, MI_ICV_NORM_MIN, &volume_info->minimum);
   (void) miicv_inqdbl(icvid, MI_ICV_NORM_MAX, &volume_info->maximum);

   return icvid;
}
Esempio n. 7
0
int main(int argc, char *argv[])
{
   char *infile, *outfile;
   char *arg_string;
   Loop_Options *loop_options;
   int inmincid;
   Lookup_Data lookup_data;

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 3)) {
      (void) fprintf(stderr, "\nUsage: %s [options] <in.mnc> <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr,   "       %s -help\n\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }
   infile = argv[1];
   outfile = argv[2];

   /* Get the appropriate lookup table */
   if ((lookup_file != NULL) || (lookup_string != NULL)) {
      lookup_data.lookup_table = read_lookup_table(lookup_file, lookup_string);
   }
   else {
      switch (lookup_type) {
      case LU_GRAY:
         lookup_data.lookup_table = &gray_lookup;
         break;
      case LU_HOTMETAL:
         lookup_data.lookup_table = &hotmetal_lookup;
         break;
      case LU_SPECTRAL:
         lookup_data.lookup_table = &spectral_lookup;
         break;
      case LU_TABLE:
         break;
      default:
         fprintf(stderr, "Unknown lookup type: %d\n", lookup_type);
         break;
      }
   }

   /* Get the null value */
   lookup_data.null_value = 
      get_null_value(lookup_data.lookup_table->vector_length, 
                     null_value_string);

   /* Open the input file and get the range */
   inmincid = miopen(infile, NC_NOWRITE);
   if (!discrete_lookup && (lookup_range[0] == DEFAULT_RANGE)) {
      get_full_range(inmincid, lookup_range);
   }
   if (lookup_min != DEFAULT_RANGE)
      lookup_range[0] = lookup_min;
   if (lookup_max != DEFAULT_RANGE)
      lookup_range[1] = lookup_max;

   /* Set up lookup information */
   lookup_data.invert = invert_table;
   lookup_data.range[0] = lookup_range[0];
   lookup_data.range[1] = lookup_range[1];
   lookup_data.discrete = discrete_lookup;

   /* Set up looping options */
   loop_options = create_loop_options();
   set_loop_clobber(loop_options, clobber);
   set_loop_verbose(loop_options, verbose);
#if MINC2
   set_loop_v2format(loop_options, minc2_format);
#endif /* MINC2 */
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_convert_input_to_scalar(loop_options, TRUE);
   set_loop_output_vector_size(loop_options, 
                               lookup_data.lookup_table->vector_length);
   set_loop_buffer_size(loop_options, (long) buffer_size * 1024);
   set_loop_first_input_mincid(loop_options, inmincid);

   /* Do loop */
   voxel_loop(1, &infile, 1, &outfile, arg_string, loop_options,
              do_lookup, (void *) &lookup_data);

   /* Free stuff */
   if (lookup_data.null_value != NULL) free(lookup_data.null_value);
   if (lookup_data.lookup_table->free_data) {
      free(lookup_data.lookup_table->table);
      free(lookup_data.lookup_table);
   }

   exit(EXIT_SUCCESS);
}
Esempio n. 8
0
int
main(int argc, char **argv)
{
    /* NIFTI stuff */
    nifti_image *nii_ptr;
    nifti_image nii_rec;
    int nii_dimids[MAX_NII_DIMS];
    int nii_dir[MAX_NII_DIMS];
    int nii_map[MAX_NII_DIMS];
    unsigned long nii_lens[MAX_NII_DIMS];
    int nii_ndims;
    static int nifti_filetype;
    static int nifti_datatype;
    static int nifti_signed = 1;

    /* MINC stuff */
    int mnc_fd;                 /* MINC file descriptor */
    nc_type mnc_type;           /* MINC data type as read */
    int mnc_ndims;              /* MINC image dimension count */
    int mnc_dimids[MAX_VAR_DIMS]; /* MINC image dimension identifiers */
    long mnc_dlen;              /* MINC dimension length value */
    double mnc_dstep;           /* MINC dimension step value */
    int mnc_icv;                /* MINC image conversion variable */
    int mnc_vid;                /* MINC Image variable ID */
    long mnc_start[MAX_VAR_DIMS]; /* MINC data starts */
    long mnc_count[MAX_VAR_DIMS]; /* MINC data counts */
    int mnc_signed;             /* MINC if output voxels are signed */
    double real_range[2];       /* MINC real range (min, max) */
    double input_valid_range[2]; /* MINC valid range (min, max) */
    double output_valid_range[2]; /* Valid range of output data. */
    double nifti_slope;         /* Slope to be applied to output voxels. */
    double nifti_inter;         /* Intercept to be applied to output voxels. */
    double total_valid_range;   /* Overall valid range (max - min). */
    double total_real_range;    /* Overall real range (max - min). */

    /* Other stuff */
    char out_str[1024];         /* Big string for filename */
    char att_str[1024];         /* Big string for attribute values */
    int i;                      /* Generic loop counter the first */
    int j;                      /* Generic loop counter the second */
    char *str_ptr;              /* Generic ASCIZ string pointer */
    int r;                      /* Result code. */
    static int vflag = 0;       /* Verbose flag (default is quiet) */

    static ArgvInfo argTable[] = {
        {NULL, ARGV_HELP, NULL, NULL,
         "Output voxel data type specification"},
        {"-byte", ARGV_CONSTANT, (char *)DT_INT8, (char *)&nifti_datatype,
         "Write voxel data in 8-bit signed integer format."},
        {"-short", ARGV_CONSTANT, (char *)DT_INT16, (char *)&nifti_datatype,
         "Write voxel data in 16-bit signed integer format."},
        {"-int", ARGV_CONSTANT, (char *)DT_INT32, (char *)&nifti_datatype,
         "Write voxel data in 32-bit signed integer format."},
        {"-float", ARGV_CONSTANT, (char *)DT_FLOAT32, (char *)&nifti_datatype,
         "Write voxel data in 32-bit floating point format."},
        {"-double", ARGV_CONSTANT, (char *)DT_FLOAT64, (char *)&nifti_datatype,
         "Write voxel data in 64-bit floating point format."},
        {"-signed", ARGV_CONSTANT, (char *)1, (char *)&nifti_signed,
         "Write integer voxel data in signed format."},
        {"-unsigned", ARGV_CONSTANT, (char *)0, (char *)&nifti_signed,
         "Write integer voxel data in unsigned format."},
        {NULL, ARGV_HELP, NULL, NULL,
         "Output file format specification"},
        {"-dual", ARGV_CONSTANT, (char *)FT_NIFTI_DUAL, 
         (char *)&nifti_filetype,
         "Write NIfTI-1 two-file format (.img and .hdr)"},
        {"-ASCII", ARGV_CONSTANT, (char *)FT_NIFTI_ASCII, 
         (char *)&nifti_filetype,
         "Write NIfTI-1 ASCII header format (.nia)"},
        {"-nii", ARGV_CONSTANT, (char *)FT_NIFTI_SINGLE, 
         (char *)&nifti_filetype,
         "Write NIfTI-1 one-file format (.nii)"},
        {"-analyze", ARGV_CONSTANT, (char *)FT_ANALYZE, 
         (char *)&nifti_filetype,
         "Write an Analyze two-file format file (.img and .hdr)"},
        {NULL, ARGV_HELP, NULL, NULL,
         "Other options"},
        {"-quiet", ARGV_CONSTANT, (char *)0, 
         (char *)&vflag,
         "Quiet operation"},
        {"-verbose", ARGV_CONSTANT, (char *)1, 
         (char *)&vflag,
         "Quiet operation"},
        {NULL, ARGV_END, NULL, NULL, NULL}
    };

    ncopts = 0;                 /* Clear global netCDF error reporting flag */

    /* Default NIfTI file type is "NII", single binary file
     */
    nifti_filetype = FT_UNSPECIFIED;
    nifti_datatype = DT_UNKNOWN;

    if (ParseArgv(&argc, argv, argTable, 0) || (argc < 2)) {
        fprintf(stderr, "Too few arguments\n");
        return usage();
    }

    if (!nifti_signed) {
        switch (nifti_datatype) {
        case DT_INT8:
            nifti_datatype = DT_UINT8;
            break;
        case DT_INT16:
            nifti_datatype = DT_UINT16;
            break;
        case DT_INT32:
            nifti_datatype = DT_UINT32;
            break;
        }
    }
    switch (nifti_datatype){
    case DT_INT8:
    case DT_UINT8:
        mnc_type = NC_BYTE;
        break;
    case DT_INT16:
    case DT_UINT16:
        mnc_type = NC_SHORT;
        break;
    case DT_INT32:
    case DT_UINT32:
        mnc_type = NC_INT;
        break;
    case DT_FLOAT32:
        mnc_type = NC_FLOAT;
        break;
    case DT_FLOAT64:
        mnc_type = NC_DOUBLE;
        break;
    }

    if (argc == 2) {
        strcpy(out_str, argv[1]);
        str_ptr = strrchr(out_str, '.');
        if (str_ptr != NULL && !strcmp(str_ptr, ".mnc")) {
            *str_ptr = '\0';
        }
    }
    else if (argc == 3) {
        strcpy(out_str, argv[2]);
        str_ptr = strrchr(out_str, '.');
        if (str_ptr != NULL) {
            /* See if a recognized file extension was specified.  If so,
             * we trim it off and set the output file type if none was
             * specified.  If the extension is not recognized, assume
             * that we will form the filename by just adding the right
             * extension for the selected output format.
             */
            if (!strcmp(str_ptr, ".nii")) {
                if (nifti_filetype == FT_UNSPECIFIED) {
                    nifti_filetype = FT_NIFTI_SINGLE;
                }
                *str_ptr = '\0';
            }
            else if (!strcmp(str_ptr, ".img") || 
                     !strcmp(str_ptr, ".hdr")) {
                if (nifti_filetype == FT_UNSPECIFIED) {
                    nifti_filetype = FT_NIFTI_DUAL;
                }
                *str_ptr = '\0';
            }
            else if (!strcmp(str_ptr, ".nia")) {
                if (nifti_filetype == FT_UNSPECIFIED) {
                    nifti_filetype = FT_NIFTI_ASCII;
                }
                *str_ptr = '\0';
            }
        }
    }
    else {
        fprintf(stderr, "Filename argument required\n");
        return usage();
    }

    /* Open the MINC file.  It needs to exist.
     */
    mnc_fd = miopen(argv[1], NC_NOWRITE);
    if (mnc_fd < 0) {
        fprintf(stderr, "Can't find input file '%s'\n", argv[1]);
        return (-1);
    }

    /* Find the MINC image variable.  If we can't find it, there is no
     * further processing possible...
     */
    mnc_vid = ncvarid(mnc_fd, MIimage);
    if (mnc_vid < 0) {
        fprintf(stderr, "Can't locate the image variable (mnc_vid=%d)\n", mnc_vid);
        return (-1);
    }

    /* Find out about the MINC image variable - specifically, how many
     * dimensions, and which dimensions.
     */
    r = ncvarinq(mnc_fd, mnc_vid, NULL, NULL, &mnc_ndims, mnc_dimids, NULL);
    if (r < 0) {
        fprintf(stderr, "Can't read information from image variable\n");
        return (-1);
    }
    if (mnc_ndims > MAX_NII_DIMS) {
        fprintf(stderr, "NIfTI-1 files may contain at most %d dimensions\n", 
                MAX_NII_DIMS);
        return (-1);
    }

    /* Initialize the NIfTI structure 
     */
    nii_ptr = &nii_rec;

    init_nifti_header(nii_ptr);

    /* For now we just use the mnc2nii command line as the description
     * field.  Probably we should use something better, perhaps a
     * combination of some other standard MINC fields that might
     * provide more information.
     */
    str_ptr = nii_ptr->descrip;
    for (i = 0; i < argc; i++) {
        char *arg_ptr = argv[i];

        if ((str_ptr - nii_ptr->descrip) >= MAX_NII_DESCRIP) {
            break;
        }

        if (i != 0) {
            *str_ptr++ = ' ';
        }

        while (*arg_ptr != '\0' && 
               (str_ptr - nii_ptr->descrip) < MAX_NII_DESCRIP) {
            *str_ptr++ = *arg_ptr++;
        }
        *str_ptr = '\0';
    }

    nii_ptr->fname = malloc(strlen(out_str) + 4 + 1);
    nii_ptr->iname = malloc(strlen(out_str) + 4 + 1);
    strcpy(nii_ptr->fname, out_str);
    strcpy(nii_ptr->iname, out_str);

    switch (nifti_filetype) {
    case FT_ANALYZE:
        strcat(nii_ptr->fname, ".hdr");
        strcat(nii_ptr->iname, ".img");
        break;
    case FT_NIFTI_SINGLE:
        strcat(nii_ptr->fname, ".nii");
        strcat(nii_ptr->iname, ".nii");
        break;
    case FT_NIFTI_DUAL:
        strcat(nii_ptr->fname, ".hdr");
        strcat(nii_ptr->iname, ".img");
        break;
    case FT_NIFTI_ASCII:
        strcat(nii_ptr->fname, ".nia");
        strcat(nii_ptr->iname, ".nia");
        break;
    default:
        fprintf(stderr, "Unknown output file type %d\n", nifti_filetype);
        return (-1);
    }

    /* Get real voxel range for the input file.
     */
    miget_image_range(mnc_fd, real_range);

    /* Get the actual valid voxel value range.
     */
    miget_valid_range(mnc_fd, mnc_vid, input_valid_range);

    /* Find the default range for the output type. Our output file
     * will use the full legal range of the output type if it is
     * an integer.
     */

    if (nifti_datatype == DT_UNKNOWN) {
        nii_ptr->datatype = DT_FLOAT32; /* Default */
        mnc_type = NC_FLOAT;
        mnc_signed = 1;
    }
    else {
        nii_ptr->datatype = nifti_datatype;
        mnc_signed = nifti_signed;
    }

    if (vflag) {
        fprintf(stderr, "MINC type %d signed %d\n", mnc_type, mnc_signed);
    }

    miget_default_range(mnc_type, mnc_signed, output_valid_range);

    total_valid_range = input_valid_range[1] - input_valid_range[0];
    total_real_range = real_range[1] - real_range[0];

    if ((output_valid_range[1] - output_valid_range[0]) > total_valid_range) {
        /* Empirically, forcing the valid range to be the nearest power
         * of two greater than the existing valid range seems to improve
         * the behavior of the conversion. This is at least in part because
         * of the limited precision of the NIfTI-1 voxel scaling fields.
         */
        double new_range = nearest_power_of_two(total_valid_range);
        if (new_range - 1.0 >= total_valid_range) {
            new_range -= 1.0;
        }

        if (output_valid_range[1] > total_valid_range) {
            output_valid_range[0] = 0;
            output_valid_range[1] = new_range;
        }
        else {
            output_valid_range[1] = output_valid_range[0] + new_range;
        }
    }
    else {
        /* The new range can't fully represent the input range. Use the 
         * full available range, and warn the user that they may have a
         * problem.
         */
        printf("WARNING: Range of input exceeds range of output format.\n");
    }

    if (vflag) {
        printf("Real range: %f %f Input valid range: %f %f Output valid range: %f %f\n",
               real_range[0], real_range[1],
               input_valid_range[0], input_valid_range[1],
               output_valid_range[0], output_valid_range[1]);
    }

    /* If the output type is not floating point, we may need to scale the
     * voxel values.
     */

    if (mnc_type != NC_FLOAT && mnc_type != NC_DOUBLE) {

        /* Figure out how to map pixel values into the range of the 
         * output datatype.
         */
        nifti_slope = ((real_range[1] - real_range[0]) / 
                       (output_valid_range[1] - output_valid_range[0]));

        if (nifti_slope == 0.0) {
            nifti_slope = 1.0;
        }
        nifti_inter = real_range[0] - (output_valid_range[0] * nifti_slope);

        /* One problem with NIfTI-1 is the limited precision of the 
         * scl_slope and scl_inter fields (they are just 32-bits). So
         * we look for possible issues and warn about that here.
         */
        if (nifti_inter != (float) nifti_inter || 
            nifti_slope != (float) nifti_slope) {
            double epsilon_i = nifti_inter - (float) nifti_inter;
            double epsilon_s = nifti_slope - (float) nifti_slope;

            /* If the loss in precision is more than one part per thousand
             * of the real range, flag this as a problem!
             */
            if ((epsilon_i > total_real_range / 1.0e3) ||
                (epsilon_s > total_real_range / 1.0e3)) {
                fprintf(stderr, "ERROR: Slope and intercept cannot be represented in the NIfTI-1 header.\n");
                fprintf(stderr, "      slope %f (%f), intercept %f (%f)\n", 
                        nifti_slope, (float) nifti_slope,
                        nifti_inter, (float) nifti_inter);
                return (-1);
            }
        }
    }
    else {
        nifti_slope = 0.0;
    }

    nii_ptr->scl_slope = nifti_slope;
    nii_ptr->scl_inter = nifti_inter;

    nii_ptr->nvox = 1;          /* Initial value for voxel count */

    /* Find all of the dimensions of the MINC file, in the order they 
     * will be listed in the NIfTI-1/Analyze file.  We use this to build
     * a map for restructuring the data according to the normal rules
     * of NIfTI-1.
     */
    nii_ndims = 0;
    for (i = 0; i < MAX_NII_DIMS; i++) {
        if (dimnames[i] == NULL) {
            nii_dimids[nii_ndims] = -1;
            continue;
        }

        nii_dimids[nii_ndims] = ncdimid(mnc_fd, dimnames[i]);
        if (nii_dimids[nii_ndims] == -1) {
            continue;
        }

        /* Make sure the dimension is actually used to define the image.
         */
        for (j = 0; j < mnc_ndims; j++) {
            if (nii_dimids[nii_ndims] == mnc_dimids[j]) {
                nii_map[nii_ndims] = j;
                break;
            }
        }

        if (j < mnc_ndims) {
            mnc_dlen = 1;
            mnc_dstep = 0;

            ncdiminq(mnc_fd, nii_dimids[nii_ndims], NULL, &mnc_dlen);
            ncattget(mnc_fd, ncvarid(mnc_fd, dimnames[i]), MIstep, &mnc_dstep);

            if (mnc_dstep < 0) {
                nii_dir[nii_ndims] = -1;
                mnc_dstep = -mnc_dstep;
            }
            else {
                nii_dir[nii_ndims] = 1;
            }

            nii_lens[nii_ndims] = mnc_dlen;
            nii_ndims++;
        }

        nii_ptr->dim[dimmap[i]] = (int) mnc_dlen;
        nii_ptr->nvox *= mnc_dlen;

        nii_ptr->pixdim[dimmap[i]] = (float) mnc_dstep;
    }

    /* Here we do some "post-processing" of the results. Make certain that
     * the nt value is never zero, and make certain that ndim is set to
     * 4 if there is a time dimension and 5 if there is a vector dimension
     */

    if (nii_ptr->dim[3] > 1 && nii_ndims < 4) {
        nii_ndims = 4;
    }

    if (nii_ptr->dim[4] > 1) {
        nii_ptr->intent_code = NIFTI_INTENT_VECTOR;
        nii_ndims = 5;
    }

    nii_ptr->ndim = nii_ndims; /* Total number of dimensions in file */
    nii_ptr->nx = nii_ptr->dim[0];
    nii_ptr->ny = nii_ptr->dim[1];
    nii_ptr->nz = nii_ptr->dim[2];
    nii_ptr->nt = nii_ptr->dim[3];
    nii_ptr->nu = nii_ptr->dim[4];

    nii_ptr->dx = nii_ptr->pixdim[0];
    nii_ptr->dy = nii_ptr->pixdim[1];
    nii_ptr->dz = nii_ptr->pixdim[2];
    nii_ptr->dt = nii_ptr->pixdim[3];
    nii_ptr->du = 1; /* MINC files don't define a sample size for a vector_dimension */

    nii_ptr->nifti_type = nifti_filetype;

    /* Load the direction_cosines and start values into the NIfTI-1 
     * sform structure.
     *
     */
    for (i = 0; i < MAX_SPACE_DIMS; i++) {
        int id = ncvarid(mnc_fd, mnc_spatial_names[i]);
        double start;
        double step;
        double dircos[MAX_SPACE_DIMS];
        int tmp;

        if (id < 0) {
            continue;
        }

        /* Set default values */
        start = 0.0;
        step = 1.0;
        dircos[DIM_X] = dircos[DIM_Y] = dircos[DIM_Z] = 0.0;
        dircos[i] = 1.0;

        miattget(mnc_fd, id, MIstart, NC_DOUBLE, 1, &start, &tmp);
        miattget(mnc_fd, id, MIstep, NC_DOUBLE, 1, &step, &tmp);
        miattget(mnc_fd, id, MIdirection_cosines, NC_DOUBLE, MAX_SPACE_DIMS, 
                 dircos, &tmp);
        ncdiminq(mnc_fd, ncdimid(mnc_fd, mnc_spatial_names[i]), NULL, 
                 &mnc_dlen);

        if (step < 0) {
            step = -step;
            start = start - step * (mnc_dlen - 1);
        }

        nii_ptr->sto_xyz.m[0][i] = step * dircos[0];
        nii_ptr->sto_xyz.m[1][i] = step * dircos[1];
        nii_ptr->sto_xyz.m[2][i] = step * dircos[2];

        nii_ptr->sto_xyz.m[0][3] += start * dircos[0];
        nii_ptr->sto_xyz.m[1][3] += start * dircos[1];
        nii_ptr->sto_xyz.m[2][3] += start * dircos[2];

        miattgetstr(mnc_fd, id, MIspacetype, sizeof(att_str), att_str);

        /* Try to set the S-transform code correctly.
         */
        if (!strcmp(att_str, MI_TALAIRACH)) {
            nii_ptr->sform_code = NIFTI_XFORM_TALAIRACH;
        }
        else if (!strcmp(att_str, MI_CALLOSAL)) {
            /* TODO: Not clear what do do here... */
            nii_ptr->sform_code = NIFTI_XFORM_SCANNER_ANAT;
        }
        else {                  /* MI_NATIVE or unknown */
            nii_ptr->sform_code = NIFTI_XFORM_SCANNER_ANAT;
        }
    }

    /* So the last row is right... */
    nii_ptr->sto_xyz.m[3][0] = 0.0;
    nii_ptr->sto_xyz.m[3][1] = 0.0;
    nii_ptr->sto_xyz.m[3][2] = 0.0;
    nii_ptr->sto_xyz.m[3][3] = 1.0;

    nii_ptr->sto_ijk = nifti_mat44_inverse(nii_ptr->sto_xyz);

    nifti_datatype_sizes(nii_ptr->datatype, 
                         &nii_ptr->nbyper, &nii_ptr->swapsize);


    if (vflag) {
        nifti_image_infodump(nii_ptr);
    }

    /* Now load the actual MINC data. */

    nii_ptr->data = malloc(nii_ptr->nbyper * nii_ptr->nvox);
    if (nii_ptr->data == NULL) {
        fprintf(stderr, "Out of memory.\n");
        return (-1);
    }

    mnc_icv = miicv_create();
    miicv_setint(mnc_icv, MI_ICV_TYPE, mnc_type);
    miicv_setstr(mnc_icv, MI_ICV_SIGN, (mnc_signed) ? MI_SIGNED : MI_UNSIGNED);
    miicv_setdbl(mnc_icv, MI_ICV_VALID_MAX, output_valid_range[1]);
    miicv_setdbl(mnc_icv, MI_ICV_VALID_MIN, output_valid_range[0]);
    miicv_setdbl(mnc_icv, MI_ICV_IMAGE_MAX, real_range[1]);
    miicv_setdbl(mnc_icv, MI_ICV_IMAGE_MIN, real_range[0]);
    miicv_setdbl(mnc_icv, MI_ICV_DO_NORM, TRUE);
    miicv_setdbl(mnc_icv, MI_ICV_USER_NORM, TRUE);

    miicv_attach(mnc_icv, mnc_fd, mnc_vid);

    /* Read in the entire hyperslab from the file.
     */
    for (i = 0; i < mnc_ndims; i++) {
        ncdiminq(mnc_fd, mnc_dimids[i], NULL, &mnc_count[i]);
        mnc_start[i] = 0;
    }

    r = miicv_get(mnc_icv, mnc_start, mnc_count, nii_ptr->data);
    if (r < 0) {
        fprintf(stderr, "Read error\n");
        return (-1);
    }

    /* Shut down the MINC stuff now that it has done its work. 
     */
    miicv_detach(mnc_icv);
    miicv_free(mnc_icv);
    miclose(mnc_fd);

    if (vflag) {
        /* Debugging stuff - just to check the contents of these arrays.
         */
        for (i = 0; i < nii_ndims; i++) {
            printf("%d: %ld %d %d\n", 
                   i, nii_lens[i], nii_map[i], nii_dir[i]);
        }
        printf("bytes per voxel %d\n", nii_ptr->nbyper);
        printf("# of voxels %ld\n", nii_ptr->nvox);
    }

    /* Rearrange the data to correspond to the NIfTI dimension ordering.
     */
    restructure_array(nii_ndims,
                      nii_ptr->data,
                      nii_lens,
                      nii_ptr->nbyper,
                      nii_map,
                      nii_dir);

    if (vflag) {
        /* More debugging stuff - check coordinate transform.
         */
        test_xform(nii_ptr->sto_xyz, 0, 0, 0);
        test_xform(nii_ptr->sto_xyz, 10, 0, 0);
        test_xform(nii_ptr->sto_xyz, 0, 10, 0);
        test_xform(nii_ptr->sto_xyz, 0, 0, 10);
        test_xform(nii_ptr->sto_xyz, 10, 10, 10);
    }

    if (vflag) {
        fprintf(stdout, "Writing NIfTI-1 file...");
    }
    nifti_image_write(nii_ptr);
    if (vflag) {
        fprintf(stdout, "done.\n");
    }

    return (0);
}
Esempio n. 9
0
int
test_icv_read(char *filename, int xsize, int ysize, double image_min,
              double image_max, nc_type datatype, char *signtype)
{
   int icv, cdfid, img, ndims;
   static long coord[MAX_VAR_DIMS];
   static long count[MAX_VAR_DIMS];
   int dim[MAX_VAR_DIMS];
   long dim_size;
   unsigned char *image;
   int i;
   double min, max;
   int n;

   min = DBL_MAX;
   max = -DBL_MAX;

   image = malloc(xsize * ysize * nctypelen(datatype));
   if (image == NULL) {
       return (ERROR_STATUS);
   }

   /* Create the icv */
   icv=miicv_create();
   (void) miicv_setint(icv, MI_ICV_XDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_YDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_ZDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_ADIM_SIZE, xsize);
   (void) miicv_setint(icv, MI_ICV_BDIM_SIZE, ysize);
   (void) miicv_setint(icv, MI_ICV_KEEP_ASPECT, FALSE);
   (void) miicv_setint(icv, MI_ICV_DO_DIM_CONV, TRUE);
   (void) miicv_setint(icv, MI_ICV_TYPE, datatype);
   (void) miicv_setstr(icv, MI_ICV_SIGN, signtype);
   (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, image_max);
   (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, image_min);

   /* Open the file, attach the image variable */
   cdfid=miopen(filename, NC_NOWRITE);

   /* Attach image variable */
   img=ncvarid(cdfid, MIimage);
   (void) miicv_attach(icv, cdfid, img);

   /* Get the number of dimensions and modify count and coord */
   (void) ncvarinq(cdfid, img, NULL, NULL, &ndims, dim, NULL);
   if (ndims!=3) {
      (void) fprintf(stderr, "File must have 3 dimensions\n");
      return ERROR_STATUS;
   }
   (void) ncdiminq(cdfid, dim[0], NULL, &dim_size);
   count[0]=1;
   count[1]=ysize;
   count[2]=xsize;
   coord[1]=0;
   coord[2]=0;

   /* Get the data */
   for (i=0; i<dim_size; i++) {
      coord[0]=i;
      (void) miicv_get(icv, coord, count, image);

      switch (datatype) {
      case NC_BYTE:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned char uc = *(((unsigned char *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed char sc = *(((signed char *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_SHORT:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned short uc = *(((unsigned short *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed short sc = *(((signed short *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_INT:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned int uc = *(((unsigned int *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed int sc = *(((signed int *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_FLOAT:
          for (n = 0; n < xsize*ysize; n++) {
              float sc = *(((float *)image) + n);
              if (sc > max) {
                  max = sc;
              }
              if (sc < min) {
                  min = sc;
              }
          }
          break;
      case NC_DOUBLE:
          for (n = 0; n < xsize*ysize; n++) {
              double sc = *(((double *)image) + n);
              if (sc > max) {
                  max = sc;
              }
              if (sc < min) {
                  min = sc;
              }
          }
          break;
      }
      printf("%d %s %s %f %f\n", i, signtype, nctypename(datatype), min, max);
   }

   /* Close the file and free the icv */
   (void) miclose(cdfid);
   (void) miicv_free(icv);

   free(image);
   return (NORMAL_STATUS);
}
Esempio n. 10
0
MNCAPI int
minc_load_data(char *path, void *dataptr, int datatype,
               long *ct, long *cz, long *cy, long *cx,
               double *dt, double *dz, double *dy, double *dx,
               void **infoptr)
{
    int fd;                     /* MINC file descriptor */
    nc_type nctype;             /* netCDF type */
    char *signstr;              /* MI_SIGNED or MI_UNSIGNED */
    int length;
    int dim_id[MI_S_NDIMS];
    long dim_len[MI_S_NDIMS];
    int i, j;                   /* Generic loop counters */
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    int icv;                    /* MINC image conversion variable */
    long start[MI_S_NDIMS];
    long count[MI_S_NDIMS];
    size_t ucount[MI_S_NDIMS];
    int dir[MI_S_NDIMS];        /* Dimension "directions" */
    int map[MI_S_NDIMS];        /* Dimension mapping */
    int old_ncopts;             /* For storing the old state of ncopts */
    double *p_dtmp;
    long *p_ltmp;
    struct file_info *p_file;
    struct att_info *p_att;
    int r;                      /* Generic return code */
    
    *infoptr = NULL;

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
        return (MINC_STATUS_ERROR);
    }

    old_ncopts =get_ncopts();
    set_ncopts(0);

    for (i = 0; i < MI_S_NDIMS; i++) {
        dim_id[i] = ncdimid(fd, minc_dimnames[i]);
        if (dim_id[i] >= 0) {
            ncdiminq(fd, dim_id[i], NULL, &dim_len[i]);
            var_id = ncvarid(fd, minc_dimnames[i]);
            ncattinq(fd, var_id, MIstep, &nctype, &length);

            switch (i) {
            case MI_S_T:
                p_ltmp = ct;
                p_dtmp = dt;
                break;
            case MI_S_X:
                p_ltmp = cx;
                p_dtmp = dx;
                break;
            case MI_S_Y:
                p_ltmp = cy;
                p_dtmp = dy;
                break;
            case MI_S_Z:
                p_ltmp = cz;
                p_dtmp = dz;
                break;
            default:
                return (MINC_STATUS_ERROR);
            }
                
            if (nctype == NC_DOUBLE && length == 1) {
                ncattget(fd, var_id, MIstep, p_dtmp);
            }
            else {
                *p_dtmp = 0;    /* Unknown/not set */
            }
            *p_ltmp = dim_len[i];
        }
        else {
            dim_len[i] = 0;
        }
    }

    set_ncopts(old_ncopts);

    var_id = ncvarid(fd, MIimage);

    ncvarinq(fd, var_id, NULL, &nctype, &var_ndims, var_dims, NULL);

    if (var_ndims != 3 && var_ndims != 4) {
        return (MINC_STATUS_ERROR);
    }

    /* We want the data to wind up in t, x, y, z order. */

    for (i = 0; i < MI_S_NDIMS; i++) {
        map[i] = -1;
    }

    for (i = 0; i < var_ndims; i++) {
        if (var_dims[i] == dim_id[MI_S_T]) {
            map[MI_S_T] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_X]) {
            map[MI_S_X] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Y]) {
            map[MI_S_Y] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Z]) {
            map[MI_S_Z] = i;
        }
    }

    icv = miicv_create();

    minc_simple_to_nc_type(datatype, &nctype, &signstr);
    miicv_setint(icv, MI_ICV_TYPE, nctype);
    miicv_setstr(icv, MI_ICV_SIGN, signstr);
    miicv_attach(icv, fd, var_id);

    for (i = 0; i < var_ndims; i++) {
        start[i] = 0;
    }

    for (i = 0; i < MI_S_NDIMS; i++) {
        if (map[i] >= 0) {
            count[map[i]] = dim_len[i];
        }
    }

    r = miicv_get(icv, start, count, dataptr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    if (map[MI_S_T] >= 0) {
        if (*dt < 0) {
            dir[MI_S_T] = -1;
            *dt = -*dt;
        }
        else {
            dir[MI_S_T] = 1;
        }
    }

    if (map[MI_S_X] >= 0) {
        if (*dx < 0) {
            dir[MI_S_X] = -1;
            *dx = -*dx;
        }
        else {
            dir[MI_S_X] = 1;
        }
    }

    if (map[MI_S_Y] >= 0) {
        if (*dy < 0) {
            dir[MI_S_Y] = -1;
            *dy = -*dy;
        }
        else {
            dir[MI_S_Y] = 1;
        }
    }

    if (map[MI_S_Z] >= 0) {
        if (*dz < 0) {
            dir[MI_S_Z] = -1;
            *dz = -*dz;
        }
        else {
            dir[MI_S_Z] = 1;
        }
    }

    if (var_ndims == 3) {
        for (i = 1; i < MI_S_NDIMS; i++) {
            map[i-1] = map[i];
            dir[i-1] = dir[i];
        }
    }

    j = 0;
    for (i = 0; i < MI_S_NDIMS; i++) {
        if (dim_len[i] > 0) {
            ucount[j++] = dim_len[i];
        }
    }

    restructure_array(var_ndims, dataptr, ucount, nctypelen(nctype),
                      map, dir);

    miicv_detach(icv);
    miicv_free(icv);

    old_ncopts =get_ncopts();
    set_ncopts(0);

    /* Generate the complete infoptr array.
     * This is essentially an in-memory copy of the variables and attributes
     * in the file.
     */

    p_file = (struct file_info *) malloc(sizeof (struct file_info));

    ncinquire(fd, &p_file->file_ndims, &p_file->file_nvars,
              &p_file->file_natts, NULL);

    p_file->file_atts = (struct att_info *) malloc(sizeof (struct att_info) * 
                                                   p_file->file_natts);

    p_file->file_vars = (struct var_info *) malloc(sizeof (struct var_info) *
                                                   p_file->file_nvars);

    for (i = 0; i < p_file->file_natts; i++) {
        p_att = &p_file->file_atts[i];

        ncattname(fd, NC_GLOBAL, i, p_att->att_name);
        ncattinq(fd, NC_GLOBAL, 
                 p_att->att_name, 
                 &p_att->att_type, 
                 &p_att->att_len);

        p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));

        ncattget(fd, NC_GLOBAL, p_att->att_name, p_att->att_val);
    }

    for (i = 0; i < p_file->file_nvars; i++) {
        struct var_info *p_var = &p_file->file_vars[i];

        ncvarinq(fd, i, 
                 p_var->var_name, 
                 &p_var->var_type, 
                 &p_var->var_ndims, 
                 p_var->var_dims,
                 &p_var->var_natts);

        p_var->var_atts = malloc(p_var->var_natts *
                                 sizeof (struct att_info));

        if (ncdimid(fd, p_var->var_name) >= 0) {
            /* It's a dimension variable, have to treat it specially... */
        }

        for (j = 0; j < p_var->var_natts; j++) {
            p_att = &p_var->var_atts[j];

            ncattname(fd, i, j, p_att->att_name);
            ncattinq(fd, i, 
                     p_att->att_name, 
                     &p_att->att_type, 
                     &p_att->att_len);

            p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));
            ncattget(fd, i, p_att->att_name, p_att->att_val);
        }
    }

    *infoptr = p_file;

    set_ncopts(old_ncopts);

    miclose(fd);

    return (MINC_STATUS_OK);
}
Esempio n. 11
0
MNCAPI int
minc_file_size(char *path,
               long *ct, long *cz, long *cy, long *cx,
               long *cvoxels, long *cbytes)
{
    int fd;
    nc_type nctype;
    int dim_id[MI_S_NDIMS];
    long dim_len[MI_S_NDIMS];
    int i;
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    long voxel_count;
    long byte_count;
    int old_ncopts;

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
        return (MINC_STATUS_ERROR);
    }
    
    old_ncopts =get_ncopts();
    set_ncopts(0);

    for (i = 0; i < MI_S_NDIMS; i++) {
        dim_id[i] = ncdimid(fd, minc_dimnames[i]);
        if (dim_id[i] >= 0) {
            ncdiminq(fd, dim_id[i], NULL, &dim_len[i]);
        }
        else {
            dim_len[i] = 0;
        }
    }

    set_ncopts(old_ncopts);

    if (ct != NULL) {
        *ct = dim_len[MI_S_T];
    }
    if (cz != NULL) {
        *cz = dim_len[MI_S_Z];
    }
    if (cy != NULL) {
        *cy = dim_len[MI_S_Y];
    }
    if (cx != NULL) {
        *cx = dim_len[MI_S_X];
    }

    var_id = ncvarid(fd, MIimage);

    if (cvoxels != NULL || cbytes != NULL) {
        ncvarinq(fd, var_id, NULL, &nctype, &var_ndims, var_dims, NULL);

        voxel_count = 1;

        for (i = 0; i < var_ndims; i++) {
            long length;
            ncdiminq(fd, var_dims[i], NULL, &length);
            voxel_count *= length;
        }

        byte_count = voxel_count * nctypelen(nctype);

        if (cvoxels != NULL) {
            *cvoxels = voxel_count;
        }
        if (cbytes != NULL) {
            *cbytes = byte_count;
        }
    }
    return (MINC_STATUS_OK);
}
Esempio n. 12
0
int main(int argc, char *argv[])
{
   char *infile, *outfile;
   char *arg_string;
   int inmincid;
   int input_vector_length;
   int ivalue;
   Loop_Options *loop_options;
   Program_Data program_data;

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 3)) {
      (void) fprintf(stderr, "\nUsage: %s [options] <in.mnc> <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr,   "       %s -help\n\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }
   infile = argv[1];
   outfile = argv[2];

   /* Check for conflicting options */
   if ((conversion_type != CONV_DEFAULT) && 
       (linear_coefficients.numvalues > 0)) {
      (void) fprintf(stderr, 
                     "Do not specify -linear with other conversion options\n");
      exit(EXIT_FAILURE);
   }

   /* Set up conversion information */
   if (conversion_type == CONV_DEFAULT) conversion_type = CONV_MAGNITUDE;
   program_data.conversion_type = conversion_type;
   program_data.num_coefficients = 0;
   program_data.linear_coefficients = NULL;

   /* Check for coefficients for linear combination */
   if (linear_coefficients.numvalues > 0) {
      conversion_type = CONV_LINEAR;
      program_data.conversion_type = conversion_type;
      program_data.num_coefficients = linear_coefficients.numvalues;
      program_data.linear_coefficients = 
         malloc(linear_coefficients.numvalues * 
                sizeof(*program_data.linear_coefficients));
      for (ivalue=0; ivalue < linear_coefficients.numvalues; ivalue++) {
         program_data.linear_coefficients[ivalue] =
            linear_coefficients.values[ivalue];
      }
   }

   /* Open the input file and get the vector length */
   inmincid = miopen(infile, NC_NOWRITE);
   input_vector_length = get_vector_length(inmincid);
   if (input_vector_length < 0) {
       fprintf(stderr, str_wrong_dimension_order);
       exit(EXIT_FAILURE);
   }
   if (input_vector_length < 1) input_vector_length = 1;

   /* Check that this length is okay */
   if ((conversion_type == CONV_GREY) && 
       (input_vector_length != 3) && (input_vector_length > 1)) {
      (void) fprintf(stderr, "Input file does not contain RGB data\n");
      exit(EXIT_FAILURE);
   }
   if ((conversion_type == CONV_LINEAR) && 
       (input_vector_length != program_data.num_coefficients) && 
       (input_vector_length > 1)) {
      (void) fprintf(stderr, 
         "Input vector length does not match number of linear coefficients\n");
      exit(EXIT_FAILURE);
   }

   /* Set up looping options */
   loop_options = create_loop_options();
   set_loop_clobber(loop_options, clobber);
   set_loop_verbose(loop_options, verbose);
#if MINC2
   set_loop_v2format(loop_options, v2format);
#endif /* MINC2 */
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_output_vector_size(loop_options, 1);
   set_loop_buffer_size(loop_options, (long) buffer_size * 1024);
   set_loop_first_input_mincid(loop_options, inmincid);

   /* Do loop */
   voxel_loop(1, &infile, 1, &outfile, arg_string, loop_options,
              do_makescalar, (void *) &program_data);

   /* Free stuff */
   if (program_data.linear_coefficients != NULL) {
      free(program_data.linear_coefficients);
   }
   if (linear_coefficients.values != NULL) {
      free(linear_coefficients.values);
   }

   exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[])
{
   char *pname;
   char *filename, *tempfile, *newfile;
   char string[1024];
   char *variable_name, *attribute_name;
   int created_tempfile;
   int done_redef;
   int iatt;
   int mincid, varid;
   int variable_exists, attribute_exists;
   nc_type attribute_type, new_type;
   int attribute_length, new_length;
   void *new_value;
   int total_length, alloc_length, ival;
   char *zeros;
   int old_ncopts;

   /* Parse the command line */
   pname=argv[0];
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 2)) {
      (void) fprintf(stderr, "\nUsage: %s [<options>] <file.mnc>\n", 
                     pname);
      (void) fprintf(stderr,   "       %s [-help]\n\n", pname);
      exit(EXIT_FAILURE);
   }
   filename = argv[1];

   /* Create temp file name. First try looking for minc extension, then
      a compression extension. Chop off the unwanted extension. */
   (void) strncpy(string, filename, sizeof(string)-1);
   tempfile = strstr(string, MINC_EXTENSION);
   if (tempfile != NULL) {
      tempfile += strlen(MINC_EXTENSION);
      if (*tempfile == '\0')
         tempfile = NULL;
   }
   else {
      tempfile = strstr(string, GZIP_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, BZIP_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, BZIP2_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, COMPRESS_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, PACK_EXTENSION);
      if (tempfile == NULL)
         tempfile = strstr(string, ZIP_EXTENSION);
   }
   if (tempfile != NULL) {
      *tempfile = '\0';
      tempfile = string;
   }

   /* If tempfile == NULL, then either we have a minc file or we don't know 
      how to edit the file in place. Check that it is a minc file. */
   if (tempfile == NULL) {
      newfile = miexpand_file(filename, tempfile, TRUE, &created_tempfile);
      if (created_tempfile) {
         if (newfile != NULL) {
            (void) remove(newfile);
            free(newfile);
         }
         (void) fprintf(stderr, "Cannot edit file \"%s\" in place.\n",
                        filename);
         exit(EXIT_FAILURE);
      }
   }

   /* Expand the file. */
   newfile = miexpand_file(filename, tempfile, FALSE, &created_tempfile);
   if (newfile == NULL) {
      (void) fprintf(stderr, "Error decompressing file \"%s\"\n",
                     filename);
      exit(EXIT_FAILURE);
   }

   /* If a new file was created, get rid of the old one */
   if (created_tempfile) {
      (void) remove(filename);
   }

   /* Open the file */
   mincid = miopen(newfile, NC_WRITE);

   /* Loop through attribute list, modifying values */
   done_redef = FALSE;
   ncopts = NC_VERBOSE;
   zeros = NULL;
   alloc_length = 0;
   for (iatt=0; iatt < attribute_list_size; iatt++) {

      /* Get variable and attribute name */
      variable_name = attribute_list[iatt].variable;
      attribute_name = attribute_list[iatt].attribute;

      /* Check for attribute existence */
      if (strlen(variable_name) == 0) {
         varid = NC_GLOBAL;
         variable_exists = TRUE;
      }
      else {
         old_ncopts = ncopts; ncopts = 0;
         varid = ncvarid(mincid, variable_name);
         ncopts = old_ncopts;
         variable_exists = (varid != MI_ERROR);
      }
      attribute_type = NC_CHAR;
      attribute_length = 0;
      if (variable_exists) {
         old_ncopts = ncopts; ncopts = 0;
         attribute_exists = 
            (ncattinq(mincid, varid, attribute_name,
                      &attribute_type, &attribute_length) != MI_ERROR);
         ncopts = old_ncopts;
      }
      else
         attribute_exists = FALSE;

      /* Are we inserting or deleting? */
      switch (attribute_list[iatt].action) {
      case Insert_attribute:
      case Append_attribute:
         if (attribute_list[iatt].value != NULL) {
            new_type = NC_CHAR;
            new_length = strlen(attribute_list[iatt].value)+1;
            new_value = (void *) attribute_list[iatt].value;
         }
         else {
            new_type = NC_DOUBLE;
            new_length = attribute_list[iatt].num_doubles;
            new_value = (void *) attribute_list[iatt].double_values;
         }

         /* For append we have to copy the entire attribute, if it 
          * already exists.
          */
         if (attribute_list[iatt].action == Append_attribute &&
             attribute_exists) {
             char *tmp_value;

             /* Verify that the existing type matches the newly
              * requested type.  Don't allow a -dappend on a 
              * string attribute, for example.
              */
             if (new_type != attribute_type) {
                 fprintf(stderr, 
                         "Can't append %s data to %s attribute %s:%s.\n",
                         (new_type == NC_DOUBLE) ? "double" : "string",
                         (attribute_type == NC_DOUBLE) ? "double" : "string",
                         variable_name, attribute_name);
                 exit(EXIT_FAILURE);
             }

             new_type = attribute_type;
             tmp_value = malloc((attribute_length + new_length) * nctypelen(new_type));
             ncattget(mincid, varid, attribute_name, tmp_value);

             /* For string attributes, remove any trailing null
              * character before appending.
              */
             if (new_type == NC_CHAR && tmp_value[attribute_length-1] == 0) {
                 attribute_length--;
             }

             memcpy(tmp_value + attribute_length * nctypelen(new_type),
                    new_value,
                    new_length * nctypelen(new_type));
             new_length += attribute_length;
             new_value = (void *) tmp_value;
         }

         total_length = attribute_length*nctypelen(attribute_type);
         if (!attribute_exists ||
             (total_length < new_length*nctypelen(new_type))) {
            if (! done_redef) {
               done_redef = TRUE;
               (void) ncredef(mincid);
            }
         }
         else if (!done_redef && attribute_exists && (total_length > 0)) {
            if (total_length > alloc_length) {
               if (zeros != NULL) free(zeros);
               zeros = malloc(total_length);
               alloc_length = total_length;
               for (ival=0; ival < alloc_length; ival++)
                  zeros[ival] = '\0';
            }
            (void) ncattput(mincid, varid, attribute_name, NC_CHAR,
                            total_length, zeros);
            (void) ncsync(mincid);
            
         }
         if (!variable_exists) {
            old_ncopts = ncopts; ncopts = 0;
            varid = micreate_group_variable(mincid, variable_name);
            ncopts = old_ncopts;
            if (varid == MI_ERROR) {
               varid = ncvardef(mincid, variable_name, NC_INT,
                                0, NULL);
            }
            variable_exists = (varid != MI_ERROR);
         }
         if (variable_exists) {
            (void) ncattput(mincid, varid, attribute_name,
                            new_type, new_length, new_value);
         }

         break;

      case Delete_attribute:

         if (attribute_exists) {
            if (! done_redef) {
               done_redef = TRUE;
               (void) ncredef(mincid);
            }
            (void) ncattdel(mincid, varid, attribute_name);
         }
              
         break;

      default:
          (void) fprintf(stderr, "Program error: unknown action %d\n",
                         (int) attribute_list[iatt].action);
          exit(EXIT_FAILURE);
      }

   }
   ncopts = NC_VERBOSE | NC_FATAL;

   /* Close the file */
   (void) miclose(mincid);

   /* Free stuff */
   free(newfile);
   if (zeros != NULL) free(zeros);

   exit(EXIT_SUCCESS);
}
Esempio n. 14
0
int main(int argc, char *argv[])
{
   char **infiles, *outfiles[3];
   int nfiles, nout;
   char *arg_string;
   Norm_Data norm_data;
   Average_Data average_data;
   Loop_Options *loop_options;
   double *vol_mean, vol_total, nvols, global_mean, total_weight;
   int ifile, iweight;
   int weights_specified;
   int first_mincid, dimid, varid, dim[MAX_VAR_DIMS];
   int ndims;
   long start, count;
   int old_ncopts;
   int strlength;
   char dimname[MAX_NC_NAME];

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc < 2)) {
      (void) fprintf(stderr, 
      "\nUsage: %s [options] [<in1.mnc> ...] <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr, 
        "       %s -help\n\n", argv[0]);
      exit(EXIT_FAILURE);
   }
   outfiles[0] = outfiles[1] = outfiles[2] = NULL;
   outfiles[0] = argv[argc-1];
   nout = 1;
   if( sdfile != NULL )
	   outfiles[nout++] = sdfile;
   if( weightfile != NULL )
	   outfiles[nout++] = weightfile;

   first_mincid = MI_ERROR;

   /* Get the list of input files either from the command line or
      from a file, or report an error if both are specified */
   nfiles = argc - 2;
   if (filelist == NULL) {
      infiles = &argv[1];
   }
   else if (nfiles <= 0) {
      infiles = read_file_names(filelist, &nfiles);
      if (infiles == NULL) {
         (void) fprintf(stderr, 
                        "Error reading in file names from file \"%s\"\n",
                        filelist);
         exit(EXIT_FAILURE);
      }
   }
   else {
      (void) fprintf(stderr, 
                     "Do not specify both -filelist and input file names\n");
      exit(EXIT_FAILURE);
   }

   /* Make sure that we have something to process */
   if (nfiles == 0) {
      (void) fprintf(stderr, "No input files specified\n");
      exit(EXIT_FAILURE);
   }

   /* Set default value of copy_all_header */
   if (copy_all_header == DEFAULT_BOOLEAN) {
      copy_all_header = (nfiles <= 1);
   }

   /* Are we averaging over a dimension? */
   average_data.averaging_over_dimension = (averaging_dimension != NULL);

   /* Check for weights and width-weighting */
   weights_specified = weights.numvalues > 0;
   if (weights_specified && width_weighted) {
      (void) fprintf(stderr, 
         "%s: Please do not specify weights and width-weighting.\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }

   /* Default is no weighting */
   average_data.num_weights = 0;
   average_data.weights = NULL;

   /* Check for weights */
   if (weights_specified) {
      if (averaging_dimension == NULL) {
         if (weights.numvalues != nfiles) {
            (void) fprintf(stderr, 
               "%s: Number of weights does not match number of files.\n",
                           argv[0]);
            exit(EXIT_FAILURE);
         }
      }
      else {
         if (nfiles > 1) {
            (void) fprintf(stderr,
               "%s: Only one input file allowed with -weights and -avgdim.\n",
                           argv[0]);
            exit(EXIT_FAILURE);
         }

         /* Check that the dimension size matches the number of weights */
         first_mincid = miopen(infiles[0], NC_NOWRITE);
         dimid = ncdimid(first_mincid, averaging_dimension);
         (void) ncdiminq(first_mincid, dimid, NULL, &count);
         if (weights.numvalues != count) {
            (void) fprintf(stderr,
               "%s: Number of weights does not match size of dimension.\n",
                           argv[0]);
         }
      }

      /* Save the weights */
      average_data.num_weights = weights.numvalues;
      average_data.weights = 
         malloc(sizeof(*average_data.weights) * average_data.num_weights);
      for (iweight=0; iweight < average_data.num_weights; iweight++) {
         average_data.weights[iweight] = weights.values[iweight];
      }

      free(weights.values);
   }

   /* Check for width weighting */
   if (width_weighted) {

      /* Check for errors */
      if (averaging_dimension == NULL) {
         (void) fprintf(stderr, 
                        "%s: Please specify -avgdim with -width_weighted.\n",
                        argv[0]);
         exit(EXIT_FAILURE);
      }
      if (nfiles > 1) {
         (void) fprintf(stderr,
                        "%s: Use -width_weighted with only one input file.\n",
                        argv[0]);
         exit(EXIT_FAILURE);
      }

      /* Open the file */
      first_mincid = miopen(infiles[0], NC_NOWRITE);

      /* Get the dimension id */
      dimid = ncdimid(first_mincid, averaging_dimension);

      /* Look for the width variable */
      strlength = MAX_NC_NAME - strlen(WIDTH_SUFFIX) - 1;
      (void) strncpy(dimname, averaging_dimension, strlength);
      dimname[strlength] = '\0';
      (void) strcat(dimname, WIDTH_SUFFIX);
      old_ncopts = ncopts; ncopts = 0;
      varid = ncvarid(first_mincid, dimname);
      (void) ncvarinq(first_mincid, varid, NULL, NULL, &ndims, dim, NULL);
      ncopts = old_ncopts;
      if (varid != MI_ERROR) {

         /* Check that things match up */
         if ((ndims != 1) || (dim[0] != dimid)) {
            (void) fprintf(stderr,
                "%s: Dimension width variable does not match avgdim.\n",
                           argv[0]);
         }

         /* Get the size of the dimension */
         (void) ncdiminq(first_mincid, dim[0], NULL, &count);
         average_data.num_weights = count;
         average_data.weights = 
            malloc(sizeof(*average_data.weights) * average_data.num_weights);

         /* Read in the widths */
         start = 0;
         (void) mivarget(first_mincid, varid, &start, &count, NC_DOUBLE, NULL,
                         average_data.weights);

      }
   }    /* If width_weighted */

   /* Check that weights sum to non-zero. We don't need to normalize them,
      since a running sum is done in the averaging. */
   if (average_data.num_weights > 0) {
      total_weight = 0.0;
      for (iweight=0; iweight < average_data.num_weights; iweight++) {
         total_weight += average_data.weights[iweight];
      }
      if (total_weight == 0.0) {
         (void) fprintf(stderr, "%s: Weights sum to zero.\n", argv[0]);
         exit(EXIT_FAILURE);
      }
   }

   /* If we don't have weights, each input will get a weight of 1 */
   if (average_data.num_weights == 0)
       total_weight = nfiles;

   /* Check the cumulative weight thresholding */
   if (weight_thresh > 0.0 && weight_thresh_fraction > 0.0){
      (void) fprintf(stderr, 
                     "Do not specify both -min_weight -min_weight_fraction\n");
      exit(EXIT_FAILURE);
   }
   else if( weight_thresh_fraction > 0.0 ){
       weight_thresh = weight_thresh_fraction * total_weight;
   }
   average_data.weight_thresh = weight_thresh;
   

   /* Check for binarization */
   if (binarize) {
      if (normalize == TRUE) {
         (void) fprintf(stderr, 
            "%s: Normalization and binarization cannot both be specified\n",
                        argv[0]);
         exit(EXIT_FAILURE);
      }
      normalize = FALSE;
      if (binvalue != -DBL_MAX) {
         binrange[0] = binvalue - 0.5;
         binrange[1] = binvalue + 0.5;
      }
      if (binrange[0] > binrange[1]) {
         (void) fprintf(stderr, 
         "%s: Please specify a binarization range with min less than max\n",
                        argv[0]);
         exit(EXIT_FAILURE);
      }
      average_data.binrange[0] = binrange[0];
      average_data.binrange[1] = binrange[1];
   }
   average_data.binarize = binarize;

   /* Store the ignore above/below values */
   average_data.ignore_below = ignore_below;
   average_data.ignore_above = ignore_above;

   /* Check for no specification of normalization */
#ifdef NO_DEFAULT_NORM
   if (normalize == -1) {
      (void) fprintf(stderr, "\n%s: %s\n\n%s\n%s\n%s\n%s\n%s\n\n", argv[0],
"Please specify either -norm or -nonorm.",
"The default setting for normalization is being changed from \"-norm\" to",
"\"-nonorm\". To prevent undetected problems with data, this program will ",
"not work unless one of these flags is explicitly given on the command-line",
"(ie. no default is permitted). The new default will come into effect some",
"time in the future."
                     );
      exit(EXIT_FAILURE);
   }
#endif

   /* Do normalization if needed */
   average_data.norm_factor = 
      malloc(sizeof(*average_data.norm_factor) * nfiles);
   if (normalize) {
      vol_mean = malloc(sizeof(*vol_mean) * nfiles);
      loop_options = create_loop_options();
      set_loop_verbose(loop_options, FALSE);
#if MINC2
      set_loop_v2format(loop_options, minc2_format);
#endif /* MINC2 */
      set_loop_accumulate(loop_options, TRUE, 0, NULL, NULL);
      set_loop_buffer_size(loop_options, (long) 1024 * max_buffer_size_in_kb);
      set_loop_check_dim_info(loop_options, check_dimensions);
      vol_total = 0.0;
      nvols = 0;
      if (verbose) {
         (void) fprintf(stderr, "Normalizing:");
         (void) fflush(stderr);
      }
      for (ifile=0; ifile < nfiles; ifile++) {
         norm_data.threshold_set = FALSE;
         norm_data.sum0 = 0.0;
         norm_data.sum1 = 0.0;
         if (verbose) {
            (void) fprintf(stderr, ".");
            (void) fflush(stderr);
         }
         if (first_mincid != MI_ERROR) {
            set_loop_first_input_mincid(loop_options, first_mincid);
            first_mincid = MI_ERROR;
         }
         voxel_loop(1, &infiles[ifile], 0, NULL, NULL, loop_options,
                    do_normalization, (void *) &norm_data);
         if (norm_data.sum0 > 0.0) {
            vol_mean[ifile] = norm_data.sum1 / norm_data.sum0;
            vol_total += vol_mean[ifile];
            nvols++;
         }
         else {
            vol_mean[ifile] = 0.0;
         }
         if (debug) {
            (void) fprintf(stderr, "Volume %d mean = %.15g\n",
                           ifile, vol_mean[ifile]);
         }
      }
      free_loop_options(loop_options);
      if (verbose) {
         (void) fprintf(stderr, "Done\n");
         (void) fflush(stderr);
      }
      if (nvols > 0)
         global_mean = vol_total / nvols;
      else
         global_mean = 0.0;
      for (ifile=0; ifile < nfiles; ifile++) {
         if (vol_mean[ifile] > 0.0)
            average_data.norm_factor[ifile] = global_mean / vol_mean[ifile];
         else
            average_data.norm_factor[ifile] = 0.0;
         if (debug) {
            (void) fprintf(stderr, "Volume %d norm factor = %.15g\n", 
                           ifile, average_data.norm_factor[ifile]);
         }
      }
      free(vol_mean);
   }
   else {
      for (ifile=0; ifile < nfiles; ifile++) {
         average_data.norm_factor[ifile] = 1.0;
      }
   }

   /* Do averaging */
   average_data.need_sd = (sdfile != NULL);
   average_data.need_weight = (weightfile != NULL);
   loop_options = create_loop_options();
   if (first_mincid != MI_ERROR) {
      set_loop_first_input_mincid(loop_options, first_mincid);
      first_mincid = MI_ERROR;
   }
   set_loop_verbose(loop_options, verbose);
   set_loop_clobber(loop_options, clobber);
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_accumulate(loop_options, TRUE, 1, start_average, finish_average);
   set_loop_copy_all_header(loop_options, copy_all_header);
   set_loop_dimension(loop_options, averaging_dimension);
   set_loop_buffer_size(loop_options, (long) 1024 * max_buffer_size_in_kb);
   set_loop_check_dim_info(loop_options, check_dimensions);
   voxel_loop(nfiles, infiles, nout, outfiles, arg_string, loop_options,
              do_average, (void *) &average_data);
   free_loop_options(loop_options);

   /* Free stuff */
   free(average_data.weights);
   free(average_data.norm_factor);

   exit(EXIT_SUCCESS);
}
Esempio n. 15
0
int main(int argc, char *argv[])
{
   char *filename;
   int mincid, imgid, icvid, ndims, dims[MAX_VAR_DIMS];
   nc_type datatype;
   int is_signed;
   long start[MAX_VAR_DIMS], count[MAX_VAR_DIMS], end[MAX_VAR_DIMS];
   long size;
   int idim;
   void *data;
   double temp;

   /* Check arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 2)) {
      (void) fprintf(stderr, "\nUsage: %s [<options>] <mincfile>\n", argv[0]);
      (void) fprintf(stderr,   "       %s -help\n\n", argv[0]);
      exit(EXIT_FAILURE);
   }
   filename = argv[1];

   /* Check that a normalization option was specified */
   if (normalize_output == VIO_BOOL_DEFAULT) {
      (void) fprintf(stderr, 
                     "Please specify either -normalize or -nonormalize\n");
      (void) fprintf(stderr, "Usually -normalize is most appropriate\n");
      exit(EXIT_FAILURE);
   }

   /* Open the file */
   mincid = miopen(filename, NC_NOWRITE);

   /* Inquire about the image variable */
   imgid = ncvarid(mincid, MIimage);
   (void) ncvarinq(mincid, imgid, NULL, NULL, &ndims, dims, NULL);
   (void)miget_datatype(mincid, imgid, &datatype, &is_signed);

   /* Check if arguments set */

   /* Get output data type */
   if (output_datatype == INT_MAX) output_datatype = datatype;

   /* Get output sign */ 
   if (output_signed == INT_MAX) {
      if (output_datatype == datatype)
         output_signed = is_signed;
      else 
         output_signed = (output_datatype != NC_BYTE);
   }

   /* Get output range */
   if (valid_range[0] == DBL_MAX) {
      if ((output_datatype == datatype) && (output_signed == is_signed)) {
         (void) miget_valid_range(mincid, imgid, valid_range);
      }
      else {
         (void) miget_default_range(output_datatype, output_signed, 
                                    valid_range);
      }
   }
   if (valid_range[0] > valid_range[1]) {
      temp = valid_range[0];
      valid_range[0] = valid_range[1];
      valid_range[1] = temp;
   }

   /* Set up image conversion */
   icvid = miicv_create();
   (void) miicv_setint(icvid, MI_ICV_TYPE, output_datatype);
   (void) miicv_setstr(icvid, MI_ICV_SIGN, (output_signed ? 
                                            MI_SIGNED : MI_UNSIGNED));
   (void) miicv_setdbl(icvid, MI_ICV_VALID_MIN, valid_range[0]);
   (void) miicv_setdbl(icvid, MI_ICV_VALID_MAX, valid_range[1]);
   if ((output_datatype == NC_FLOAT) || (output_datatype == NC_DOUBLE)) {
      (void) miicv_setint(icvid, MI_ICV_DO_NORM, TRUE);
      (void) miicv_setint(icvid, MI_ICV_USER_NORM, TRUE);
   }
   else if (normalize_output) {
      (void) miicv_setint(icvid, MI_ICV_DO_NORM, TRUE);
   }
   (void) miicv_attach(icvid, mincid, imgid);

   /* Set input file start, count and end vectors for reading a slice
      at a time */
   for (idim=0; idim < ndims; idim++) {
      (void) ncdiminq(mincid, dims[idim], NULL, &end[idim]);
   }
   (void) miset_coords(ndims, (long) 0, start);
   (void) miset_coords(ndims, (long) 1, count);
   size = nctypelen(output_datatype);
   for (idim=ndims-2; idim < ndims; idim++) {
      count[idim] = end[idim];
      size *= count[idim];
   }

   /* Allocate space */
   data = malloc(size);

   /* Loop over input slices */

   while (start[0] < end[0]) {

      /* Read in the slice */
      (void) miicv_get(icvid, start, count, data);

      /* Write out the slice */
      if (fwrite(data, sizeof(char), (size_t) size, stdout) != size) {
         (void) fprintf(stderr, "Error writing data.\n");
         exit(EXIT_FAILURE);
      }

      /* Increment start counter */
      idim = ndims-1;
      start[idim] += count[idim];
      while ( (idim>0) && (start[idim] >= end[idim])) {
         start[idim] = 0;
         idim--;
         start[idim] += count[idim];
      }

   }       /* End loop over slices */

   /* Clean up */
   (void) miclose(mincid);
   (void) miicv_free(icvid);
   free(data);

   exit(EXIT_SUCCESS);
}