int main(int argc, char * argv[]) { FSLIO *fslio; void *buffer; char *f1name; double ***vol; int x,y,z,t; /*** process commandline parameters */ if (argc < 2) { pusage(argv[0]); exit(1); } /************************* PRINT ***************************/ if (!strncmp(argv[1],"print",5)) { if (argc != 3) { fprintf(stderr, "\nError, print command takes one parameter: print <dataset>\n"); exit(1); } f1name = argv[2]; /** open nifti dataset */ fslio = FslInit(); buffer = FslReadAllVolumes(fslio,f1name); if (buffer == NULL) { fprintf(stderr, "\nError opening and reading %s.\n",f1name); exit(1); } nifti_image_infodump(fslio->niftiptr); exit(0); } /************************* PEEK ***************************/ if (!strncmp(argv[1],"peek",4)) { if (argc != 7) { fprintf(stderr, "\nError, peek command takes five parameters: peek <dataset> X Y Z T\n"); exit(1); } /**** get inputs */ f1name = argv[2]; x = atoi(argv[3]); y = atoi(argv[4]); z = atoi(argv[5]); t = atoi(argv[6]); /** open nifti dataset header */ fslio = FslReadHeader(f1name); if (fslio == NULL) { fprintf(stderr, "\nError, could not read header info for %s.\n",f1name); exit(1); } /**** check inputs */ if ( (x<0) || (x>=fslio->niftiptr->nx) ) { fprintf(stderr, "\nError: x index (%d) out of range [0..%d]\n",x,fslio->niftiptr->nx-1); exit(1); } if ( (y<0) || (y>=fslio->niftiptr->ny) ) { fprintf(stderr, "\nError: y index (%d) out of range [0..%d]\n",y,fslio->niftiptr->ny-1); exit(1); } if ( (z<0) || (z>=fslio->niftiptr->nz) ) { fprintf(stderr, "\nError: z index (%d) out of range [0..%d]\n",z,fslio->niftiptr->nz-1); exit(1); } if ( (t<0) || (t>=fslio->niftiptr->nt) ) { fprintf(stderr, "\nError: t index (%d) out of range [0..%d]\n",t,fslio->niftiptr->nt-1); exit(1); } /*** get volume data as scaled doubles */ vol = FslGetVolumeAsScaledDouble(fslio,t); if (vol == NULL) { fprintf(stderr, "\nError accessing %s\n",f1name); exit(1); } else { fprintf(stderr, "\nLocation %d %d %d %d: %.4f\n",x,y,z,t,vol[z][y][x]); exit(0); } } fprintf(stderr, "\nError, unrecognized command %s\n",argv[1]); pusage(argv[0]); exit(1); }
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); }
int main (int argc, char *argv[]) { char TEMP_STR[256]; nifti_set_debug_level(3); int Errors=0; { PrintTest("NOT REALLY AN ERROR, JUST TESTING THE ERROR TEST REPORTING MECHANISM",1,NIFTITEST_FALSE,&Errors); PrintTest("NOT REALLY AN ERROR, JUST TESTING THE ERROR COUNTING MECHANISM",Errors==1,NIFTITEST_FALSE,&Errors); Errors=0; } { const char write_image_filename[6][64]={ "ATestReferenceImageForReadingAndWriting.nii", "ATestReferenceImageForReadingAndWriting.hdr", "ATestReferenceImageForReadingAndWriting.img", "ATestReferenceImageForReadingAndWriting.nii.gz", "ATestReferenceImageForReadingAndWriting.hdr.gz", "ATestReferenceImageForReadingAndWriting.img.gz" }; printf("======= Testing All Nifti Valid Names ======\n"); fflush(stdout); unsigned int filenameindex; for(filenameindex=0;filenameindex<6; filenameindex++) { char buf[512]; int CompressedTwoFile = strstr(write_image_filename[filenameindex],".img.gz") != 0 || strstr(write_image_filename[filenameindex],".hdr.gz") != 0; printf("======= Testing with filename: %s ======\n",write_image_filename[filenameindex]); fflush(stdout); nifti_image * reference_image = generate_reference_image(write_image_filename[filenameindex],&Errors); /* * Add an extension to test extension reading */ { static char ext[] = "THIS IS A TEST"; sprintf(buf,"nifti_add_extension %s",write_image_filename[filenameindex]); PrintTest(buf, nifti_add_extension(reference_image, ext,sizeof(ext), NIFTI_ECODE_COMMENT) == -1, NIFTITEST_FALSE,&Errors); sprintf(buf,"valid_nifti_extension %s",write_image_filename[filenameindex]); PrintTest("valid_nifti_extensions", valid_nifti_extensions(reference_image) == 0, NIFTITEST_FALSE,&Errors); } PrintTest("Create reference image",reference_image==0,NIFTITEST_TRUE,&Errors); nifti_image_write ( reference_image ) ; /* * test nifti_copy_extension */ { nifti_image *nim = nifti_simple_init_nim(); PrintTest("nifti_copy_extension", nifti_copy_extensions(nim,reference_image), NIFTITEST_FALSE,&Errors); nifti_image_free(nim); nim = nifti_copy_nim_info(reference_image); PrintTest("nifti_copy_nim_info", nim == 0, NIFTITEST_FALSE,&Errors); PrintTest("nifti_nim_is_valid", nifti_nim_is_valid(nim,0) == 0, NIFTITEST_FALSE,&Errors); nifti_image_free(nim); } { nifti_image * reloaded_image = nifti_image_read(reference_image->fname,1); PrintTest("Reload of image ",reloaded_image==0,NIFTITEST_TRUE,&Errors); { /* * if the file is named '.img', '.hdr', '.img.gz', or '.hdr.gz', then * the header extensions won't be saved with the file. * The test will fail if it finds an extension in a 2-file NIfTI, or * fails to find one in a '.nii' or '.nii.gz' file. */ int result = valid_nifti_extensions(reloaded_image); sprintf(buf,"reload valid_nifti_extensions %s",write_image_filename[filenameindex]); PrintTest(buf, CompressedTwoFile ? result != 0 : result == 0, NIFTITEST_FALSE,&Errors); } nifti_image_infodump(reloaded_image); compare_reference_image_values(reference_image,reloaded_image,&Errors); nifti_image_free(reloaded_image); } { nifti_brick_list NB_orig, NB_select; nifti_image * nim_orig, * nim_select; int blist[5] = { 7, 0, 5, 5, 9 }; /* * test some error paths in the nifti_image_read_bricks */ nim_orig = nifti_image_read_bricks(reference_image->fname,0,blist, &NB_orig); PrintTest("invalid arg bricked image read 1",nim_orig != 0,NIFTITEST_FALSE,&Errors); nim_orig = nifti_image_read_bricks(reference_image->fname, 0, NULL, &NB_orig); PrintTest("Reload of bricked image",nim_orig == 0,NIFTITEST_FALSE,&Errors); nifti_free_NBL(&NB_orig); nifti_image_free(nim_orig); nim_select = nifti_image_read_bricks(reference_image->fname, 5, blist, &NB_select); PrintTest("Reload of bricked image with blist",nim_orig == 0,NIFTITEST_FALSE,&Errors); nifti_free_NBL(&NB_select); nifti_image_free(nim_select); } /* * test nifti_update_dims_from_array */ PrintTest("nifti_update_dims_from_array -- valid dims", nifti_update_dims_from_array(reference_image) != 0, NIFTITEST_FALSE,&Errors); reference_image->dim[0] = 8; PrintTest("nifti_update_dims_from_array -- invalid dims", nifti_update_dims_from_array(reference_image) == 0, NIFTITEST_FALSE,&Errors); { nifti_1_header x = nifti_convert_nim2nhdr(reference_image); char buf[512]; sprintf(buf,"nifti_hdr_looks_good %s",reference_image->fname); PrintTest(buf, !nifti_hdr_looks_good(&x), NIFTITEST_FALSE,&Errors); } nifti_image_free(reference_image); } /* * check nifti_findimgname */ { char *imgname = nifti_findimgname("ATestReferenceImageForReadingAndWriting.hdr",2); PrintTest("nifti_findimgname", imgname == 0 || strcmp(imgname,"ATestReferenceImageForReadingAndWriting.img") != 0, NIFTITEST_FALSE,&Errors); free(imgname); } { int IsNiftiFile; IsNiftiFile = is_nifti_file(write_image_filename[0]); PrintTest("is_nifti_file0", IsNiftiFile != 1,NIFTITEST_FALSE,&Errors); IsNiftiFile = is_nifti_file(write_image_filename[1]); PrintTest("is_nifti_file1", IsNiftiFile != 2,NIFTITEST_FALSE,&Errors); IsNiftiFile = is_nifti_file(write_image_filename[3]); PrintTest("is_nifti_file2", IsNiftiFile != 1,NIFTITEST_FALSE,&Errors); IsNiftiFile = is_nifti_file(write_image_filename[4]); PrintTest("is_nifti_file2", IsNiftiFile != 2,NIFTITEST_FALSE,&Errors); } } { /* * test writing and reading an ascii file */ nifti_image * reference_image = generate_reference_image("TestAsciiImage.nia",&Errors); reference_image->nifti_type = 3; nifti_image_write(reference_image); nifti_image * reloaded_image = nifti_image_read("TestAsciiImage.nia",1); PrintTest("Read/Write Ascii image", reloaded_image == 0,NIFTITEST_FALSE,&Errors); nifti_image_free(reference_image); nifti_image_free(reloaded_image); } { enum { NUM_FILE_NAMES=8 }; const char * FILE_NAMES[NUM_FILE_NAMES]={ "myimage", "myimage.tif", "myimage.tif.gz", "myimage.nii", "myimage.img.gz", ".nii", ".myhiddenimage", ".myhiddenimage.nii" }; const char * KNOWN_FILE_BASENAMES[NUM_FILE_NAMES]={ "myimage", "myimage.tif", "myimage.tif.gz", "myimage", "myimage", "", ".myhiddenimage", ".myhiddenimage" }; const int KNOWN_nifti_validfilename[NUM_FILE_NAMES]={ 1, 1, 1, 1, 1, 0, 1, 1 }; const int KNOWN_nifti_is_complete_filename[NUM_FILE_NAMES]={ 0, 0, 0, 1, 1, 0, 0, 1 }; unsigned int fni; for(fni=0;fni<NUM_FILE_NAMES;fni++) { printf("\nTesting \"%s\" filename\n",FILE_NAMES[fni]); { int KnownValid=nifti_validfilename(FILE_NAMES[fni]); snprintf(TEMP_STR,256,"nifti_validfilename(\"%s\")=%d",FILE_NAMES[fni],KnownValid); PrintTest(TEMP_STR,KnownValid != KNOWN_nifti_validfilename[fni],NIFTITEST_FALSE,&Errors); } { int KnownValid=nifti_is_complete_filename(FILE_NAMES[fni]); snprintf(TEMP_STR,256,"nifti_is_complete_filename(\"%s\")=%d",FILE_NAMES[fni],KnownValid); PrintTest(TEMP_STR,KnownValid != KNOWN_nifti_is_complete_filename[fni],NIFTITEST_FALSE,&Errors); } { char * basename=nifti_makebasename(FILE_NAMES[fni]); snprintf(TEMP_STR,256,"nifti_makebasename(\"%s\")=\"%s\"",FILE_NAMES[fni],basename); PrintTest(TEMP_STR,strcmp(basename,KNOWN_FILE_BASENAMES[fni]) != 0,NIFTITEST_FALSE,&Errors); free(basename); } } /* * the following 2 calls aren't tested, because all they do is display * compile-time information -- no way to fail unless writing to stdout fails. */ nifti_disp_lib_hist(); nifti_disp_lib_version(); /* * the following exercises error path code in nifti_image_read_bricks */ PrintTest( "nifti_image_read_bricks 1", nifti_image_read_bricks((char *)0,-1,(const int *)0,(nifti_brick_list *)0) != 0, NIFTITEST_FALSE, &Errors); PrintTest( "nifti_image_read_bricks 1", nifti_image_read_bricks("NOFILE.NOFILE",-1,(const int *)0,(nifti_brick_list *)0) != 0, NIFTITEST_FALSE, &Errors); } /* * call nifti_datatype_string with all possible values */ #define nifti_datatype_test(constant,string) \ { \ char buf[64]; \ sprintf(buf,"nifti_datatype_string %s",string); \ PrintTest( \ buf, \ strcmp(nifti_datatype_string(constant),string) != 0, \ NIFTITEST_FALSE, \ &Errors); \ } nifti_datatype_test(DT_UNKNOWN,"UNKNOWN"); nifti_datatype_test(DT_BINARY, "BINARY"); nifti_datatype_test(DT_INT8, "INT8"); nifti_datatype_test(DT_UINT8, "UINT8"); nifti_datatype_test(DT_INT16, "INT16"); nifti_datatype_test(DT_UINT16, "UINT16"); nifti_datatype_test(DT_INT32, "INT32"); nifti_datatype_test(DT_UINT32, "UINT32"); nifti_datatype_test(DT_INT64, "INT64"); nifti_datatype_test(DT_UINT64, "UINT64"); nifti_datatype_test(DT_FLOAT32, "FLOAT32"); nifti_datatype_test(DT_FLOAT64, "FLOAT64"); nifti_datatype_test(DT_FLOAT128, "FLOAT128"); nifti_datatype_test(DT_COMPLEX64, "COMPLEX64"); nifti_datatype_test(DT_COMPLEX128, "COMPLEX128"); nifti_datatype_test(DT_COMPLEX256, "COMPLEX256"); nifti_datatype_test(DT_RGB24, "RGB24"); #define nifti_is_inttype_test(constant,rval) \ { \ char buf[64]; \ sprintf(buf,"nifti_datatype_string %d",constant); \ PrintTest( \ buf, \ nifti_is_inttype(constant) != rval, \ NIFTITEST_FALSE, \ &Errors); \ } nifti_is_inttype_test(DT_UNKNOWN,0); nifti_is_inttype_test(DT_BINARY,0); nifti_is_inttype_test(DT_INT8,1); nifti_is_inttype_test(DT_UINT8,1); nifti_is_inttype_test(DT_INT16,1); nifti_is_inttype_test(DT_UINT16,1); nifti_is_inttype_test(DT_INT32,1); nifti_is_inttype_test(DT_UINT32,1); nifti_is_inttype_test(DT_INT64,1); nifti_is_inttype_test(DT_UINT64,1); nifti_is_inttype_test(DT_FLOAT32,0); nifti_is_inttype_test(DT_FLOAT64,0); nifti_is_inttype_test(DT_FLOAT128,0); nifti_is_inttype_test(DT_COMPLEX64,0); nifti_is_inttype_test(DT_COMPLEX128,0); nifti_is_inttype_test(DT_COMPLEX256,0); nifti_is_inttype_test(DT_RGB24,1); #define nifti_units_string_test(constant,string) \ { \ char buf[64]; \ sprintf(buf,"nifti_units_string_test %s",string); \ PrintTest( \ buf, \ strcmp(nifti_units_string(constant),string) != 0, \ NIFTITEST_FALSE, \ &Errors); \ } nifti_units_string_test(NIFTI_UNITS_METER,"m"); nifti_units_string_test(NIFTI_UNITS_MM,"mm"); nifti_units_string_test(NIFTI_UNITS_MICRON,"um"); nifti_units_string_test(NIFTI_UNITS_SEC,"s"); nifti_units_string_test(NIFTI_UNITS_MSEC,"ms"); nifti_units_string_test(NIFTI_UNITS_USEC,"us"); nifti_units_string_test(NIFTI_UNITS_HZ,"Hz"); nifti_units_string_test(NIFTI_UNITS_PPM,"ppm"); nifti_units_string_test(NIFTI_UNITS_RADS,"rad/s"); #define nifti_intent_string_test(constant,string) \ { \ char buf[64]; \ sprintf(buf,"nifti_intent_string %s",string); \ PrintTest( \ buf, \ strcmp(nifti_intent_string(constant),string) != 0, \ NIFTITEST_FALSE, \ &Errors); \ } nifti_intent_string_test(NIFTI_INTENT_CORREL,"Correlation statistic"); nifti_intent_string_test(NIFTI_INTENT_TTEST,"T-statistic"); nifti_intent_string_test(NIFTI_INTENT_FTEST,"F-statistic"); nifti_intent_string_test(NIFTI_INTENT_ZSCORE,"Z-score"); nifti_intent_string_test(NIFTI_INTENT_CHISQ,"Chi-squared distribution"); nifti_intent_string_test(NIFTI_INTENT_BETA,"Beta distribution"); nifti_intent_string_test(NIFTI_INTENT_BINOM,"Binomial distribution"); nifti_intent_string_test(NIFTI_INTENT_GAMMA,"Gamma distribution"); nifti_intent_string_test(NIFTI_INTENT_POISSON,"Poisson distribution"); nifti_intent_string_test(NIFTI_INTENT_NORMAL,"Normal distribution"); nifti_intent_string_test(NIFTI_INTENT_FTEST_NONC,"F-statistic noncentral"); nifti_intent_string_test(NIFTI_INTENT_CHISQ_NONC,"Chi-squared noncentral"); nifti_intent_string_test(NIFTI_INTENT_LOGISTIC,"Logistic distribution"); nifti_intent_string_test(NIFTI_INTENT_LAPLACE,"Laplace distribution"); nifti_intent_string_test(NIFTI_INTENT_UNIFORM,"Uniform distribition"); nifti_intent_string_test(NIFTI_INTENT_TTEST_NONC,"T-statistic noncentral"); nifti_intent_string_test(NIFTI_INTENT_WEIBULL,"Weibull distribution"); nifti_intent_string_test(NIFTI_INTENT_CHI,"Chi distribution"); nifti_intent_string_test(NIFTI_INTENT_INVGAUSS,"Inverse Gaussian distribution"); nifti_intent_string_test(NIFTI_INTENT_EXTVAL,"Extreme Value distribution"); nifti_intent_string_test(NIFTI_INTENT_PVAL,"P-value"); nifti_intent_string_test(NIFTI_INTENT_LOGPVAL,"Log P-value"); nifti_intent_string_test(NIFTI_INTENT_LOG10PVAL,"Log10 P-value"); nifti_intent_string_test(NIFTI_INTENT_ESTIMATE,"Estimate"); nifti_intent_string_test(NIFTI_INTENT_LABEL,"Label index"); nifti_intent_string_test(NIFTI_INTENT_NEURONAME,"NeuroNames index"); nifti_intent_string_test(NIFTI_INTENT_GENMATRIX,"General matrix"); nifti_intent_string_test(NIFTI_INTENT_SYMMATRIX,"Symmetric matrix"); nifti_intent_string_test(NIFTI_INTENT_DISPVECT,"Displacement vector"); nifti_intent_string_test(NIFTI_INTENT_VECTOR,"Vector"); nifti_intent_string_test(NIFTI_INTENT_POINTSET,"Pointset"); nifti_intent_string_test(NIFTI_INTENT_TRIANGLE,"Triangle"); nifti_intent_string_test(NIFTI_INTENT_QUATERNION,"Quaternion"); nifti_intent_string_test(NIFTI_INTENT_DIMLESS,"Dimensionless number"); nifti_intent_string_test(-200,"Unknown"); #define nifti_slice_string_test(constant,string) \ { \ char buf[64]; \ sprintf(buf,"nifti_slice_string_test %s",string); \ PrintTest( \ buf, \ strcmp(nifti_slice_string(constant),string) != 0, \ NIFTITEST_FALSE, \ &Errors); \ } nifti_slice_string_test(NIFTI_SLICE_SEQ_INC,"sequential_increasing"); nifti_slice_string_test(NIFTI_SLICE_SEQ_DEC,"sequential_decreasing"); nifti_slice_string_test(NIFTI_SLICE_ALT_INC,"alternating_increasing"); nifti_slice_string_test(NIFTI_SLICE_ALT_DEC,"alternating_decreasing"); nifti_slice_string_test(NIFTI_SLICE_ALT_INC2,"alternating_increasing_2"); nifti_slice_string_test(NIFTI_SLICE_ALT_DEC2,"alternating_decreasing_2"); #define nifti_orientation_string_test(constant,string) \ { \ char buf[64]; \ sprintf(buf,"nifti_orientation_string_test %s",string); \ PrintTest( \ buf, \ strcmp(nifti_orientation_string(constant),string) != 0, \ NIFTITEST_FALSE, \ &Errors); \ } nifti_orientation_string_test(NIFTI_L2R,"Left-to-Right"); nifti_orientation_string_test(NIFTI_R2L,"Right-to-Left"); nifti_orientation_string_test(NIFTI_P2A,"Posterior-to-Anterior"); nifti_orientation_string_test(NIFTI_A2P,"Anterior-to-Posterior"); nifti_orientation_string_test(NIFTI_I2S,"Inferior-to-Superior"); nifti_orientation_string_test(NIFTI_S2I,"Superior-to-Inferior"); #define nifti_datatype_sizes_test(constant,Nbyper,Swapsize) \ { \ int nbyper; \ int swapsize; \ char buf[64]; \ sprintf(buf,"nifti_datatype_sizes_test %d",constant); \ nifti_datatype_sizes(constant,&nbyper,&swapsize); \ PrintTest( \ buf, \ nbyper != Nbyper || swapsize != Swapsize, \ NIFTITEST_FALSE, \ &Errors); \ } nifti_datatype_sizes_test(DT_UINT8,1,0); nifti_datatype_sizes_test(DT_UINT16,2,2); nifti_datatype_sizes_test(DT_RGB24,3,0); nifti_datatype_sizes_test(DT_FLOAT32,4,4); nifti_datatype_sizes_test(DT_COMPLEX64,8,4); nifti_datatype_sizes_test(DT_UINT64,8,8); nifti_datatype_sizes_test(DT_FLOAT128,16,16); nifti_datatype_sizes_test(DT_COMPLEX128,16,8); nifti_datatype_sizes_test(DT_COMPLEX256,32,16); { mat44 R; unsigned i,j; for(i = 0; i < 4; i++) for(j = 0; j < 4; j++) R.m[i][j] = (i == j ? 1 : 0); float qb; float qc; float qd; float qx; float qy; float qz; float dx; float dy; float dz; float qfac; nifti_mat44_to_quatern(R,&qb,&qc,&qd,&qx,&qy,&qz,&dx,&dy,&dz,&qfac); PrintTest("nifti_mat44_to_quatern", qb != 0.000000 || qc != 0.000000 || qd != 0.000000 || qx != 0.000000 || qy != 0.000000 || qd != 0.000000 || dx != 1.000000 || dy != 1.000000 || dz != 1.000000 || qfac != 1.000000, NIFTITEST_FALSE,&Errors); } { mat44 x = nifti_make_orthog_mat44(0.14,0.0,0.0, 0.0,0.9,0.0, 0.0,0.0,1.1); PrintTest("nifti_make_orthog_mat44", x.m[0][0] != 1.0 || x.m[1][1] != 1.0 || x.m[2][2] != 1.0 || x.m[3][3] != 1.0, NIFTITEST_FALSE,&Errors); } { static char x[16] = { 'a','b','c','d','e','f','g','h', 'H','G','F','E','D','C','B','A' }; nifti_swap_Nbytes(1,16,(void *)x); PrintTest("nifti_swap_16bytes", x[0] != 'A' || x[1] != 'B' || x[2] != 'C' || x[3] != 'D' || x[4] != 'E' || x[5] != 'F' || x[6] != 'G' || x[7] != 'H' || x[8] != 'h' || x[9] != 'g' || x[10] != 'f' || x[11] != 'e' || x[12] != 'd' || x[13] != 'c' || x[14] != 'b' || x[15] != 'a', NIFTITEST_FALSE,&Errors); } { static char x[8] = { 'a','b','c','d','D','C','B','A' }; nifti_swap_Nbytes(1,8,(void *)x); PrintTest("nifti_swap_8bytes", x[0] != 'A' || x[1] != 'B' || x[2] != 'C' || x[3] != 'D' || x[4] != 'd' || x[5] != 'c' || x[6] != 'b' || x[7] != 'a', NIFTITEST_FALSE,&Errors); } { /* * test nifti_simple_init_nim */ nifti_image *nim = nifti_simple_init_nim(); PrintTest("nifti_simple_init_nim", nim == 0,NIFTITEST_FALSE,&Errors); nifti_image_free(nim); nim = 0; /* * test nifti_image_open */ znzFile f = nifti_image_open("ATestReferenceImageForReadingAndWriting.hdr","r",&nim); PrintTest("nifti_image_open", nim == 0 || f == 0, NIFTITEST_FALSE,&Errors); PrintTest("nifti_image_load", nifti_image_load(nim) == -1, NIFTITEST_FALSE,&Errors); nifti_image_unload(nim); PrintTest("nifti_image_unload", nim->data != 0, NIFTITEST_FALSE,&Errors); znzclose(f); nifti_image_free(nim); } /* * call various functions from nifti_stats */ printf("\n\nTOTAL ERRORS=%d\n",Errors); return Errors; }
int main( int argc , char *argv[] ) { nifti_image *nim ; int iarg=1 , outmode=1 , ll ; if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf("Usage: nifti1_test [-n2|-n1|-na|-a2] infile [prefix]\n" "\n" " If prefix is given, then the options mean:\n" " -a2 ==> write an ANALYZE 7.5 file pair: prefix.hdr/prefix.img\n" " -n2 ==> write a NIFTI-1 file pair: prefix.hdr/prefix.img\n" " -n1 ==> write a NIFTI-1 single file: prefix.nii\n" " -na ==> write a NIFTI-1 ASCII+binary file: prefix.nia\n" " The default is '-n1'.\n" "\n" " If prefix is not given, then the header info from infile\n" " file is printed to stdout.\n" "\n" " Please note that the '.nia' format is NOT part of the\n" " NIFTI-1 specification, but is provided mostly for ease\n" " of visualization (e.g., you can edit a .nia file and\n" " change some header fields, then rewrite it as .nii)\n" ) ; printf("\nsizeof(nifti_1_header)=%u\n",(unsigned int)sizeof(nifti_1_header)) ; exit(0) ; } if( argv[1][0] == '-' ){ if( argv[1][1] == 'a' ){ outmode = 0 ; } else if( argv[1][1] == 'n' ){ switch( argv[1][2] ){ case '1': outmode = 1 ; break ; default: outmode = 2 ; break ; case 'a': outmode = 3 ; break ; } } iarg++ ; } if( iarg >= argc ){ fprintf(stderr,"** ERROR: no input file on command line!?\n"); exit(1); } nim = nifti_image_read( argv[iarg++] , 1 ) ; if( nim == NULL ) exit(1) ; if( iarg >= argc ){ nifti_image_infodump(nim); exit(0); } nim->nifti_type = outmode ; if( nim->fname != NULL ) free(nim->fname) ; if( nim->iname != NULL ) free(nim->iname) ; ll = strlen(argv[iarg]) ; nim->fname = (char *)calloc(1,ll+6) ; strcpy(nim->fname,argv[iarg]) ; nim->iname = (char *)calloc(1,ll+6) ; strcpy(nim->iname,argv[iarg]) ; if( nim->nifti_type == 1 ){ strcat(nim->fname,".nii") ; strcat(nim->iname,".nii") ; } else if ( nim->nifti_type == 3 ){ strcat(nim->fname,".nia") ; strcat(nim->iname,".nia") ; } else { strcat(nim->fname,".hdr") ; strcat(nim->iname,".img") ; } nifti_image_write( nim ) ; exit(0) ; }