void CNiftiFile::setupForm( FormID formID, const float matrix[4][4] ) { assert( ndim > 1 ); qform_code = 0; sform_code = 0; //create space tranformation matrix - transforms the space when reading _NOT_ the data for( int y = 0; y < 4; y++ ) for( int x = 0; x < 4; x++ ) { qto_xyz.m[y][x] = matrix[y][x] * ( myDealer.swap[y] ? 1 : -1 ); //no voxelsize for qto_xyz - is done by pixdim directly sto_xyz.m[y][x] = matrix[y][x] * pixdim[y+1] * ( myDealer.swap[y] ? 1 : -1 ); } //generate matching quaternions nifti_mat44_to_quatern( qto_xyz, &quatern_b, &quatern_c, &quatern_d, &qoffset_x, &qoffset_y, &qoffset_z, NULL, NULL, NULL, &qfac ); #ifndef __OPTIMIZE__ int icod = 0, jcod = 0, kcod = 0; nifti_mat44_to_orientation( sto_xyz, &icod, &jcod, &kcod ); fprintf( stderr, "icod %d jcod %d kcod %d\n", icod, jcod, kcod ); nifti_mat44_to_orientation( qto_xyz, &icod, &jcod, &kcod ); fprintf( stderr, "icod %d jcod %d kcod %d qfac %f\n", icod, jcod, kcod, qfac ); #endif }
unsigned char * reOrient(unsigned char* img, struct nifti_1_header *h, vec3i orientVec, mat33 orient, vec3 minMM) //e.g. [-1,2,3] means reflect x axis, [2,1,3] means swap x and y dimensions { size_t nvox = h->dim[1] * h->dim[2] * h->dim[3]; if (nvox < 1) return img; vec3i outDim= {0,0,0}; vec3i outInc= {0,0,0}; for (int i = 0; i < 3; i++) { //set dimension, pixdim and outDim.v[i] = h->dim[abs(orientVec.v[i])]; if (abs(orientVec.v[i]) == 1) outInc.v[i] = 1; if (abs(orientVec.v[i]) == 2) outInc.v[i] = h->dim[1]; if (abs(orientVec.v[i]) == 3) outInc.v[i] = h->dim[1]*h->dim[2]; if (orientVec.v[i] < 0) outInc.v[i] = -outInc.v[i]; //flip } //for each dimension int nvol = 1; //convert all non-spatial volumes from source to destination for (int vol = 4; vol < 8; vol++) { if (h->dim[vol] > 1) nvol = nvol * h->dim[vol]; } reOrientImg(img, outDim, outInc, h->bitpix / 8, nvol); //now change the header.... vec3 outPix= {h->pixdim[abs(orientVec.v[0])],h->pixdim[abs(orientVec.v[1])],h->pixdim[abs(orientVec.v[2])]}; for (int i = 0; i < 3; i++) { h->dim[i+1] = outDim.v[i]; h->pixdim[i+1] = outPix.v[i]; } mat44 s = sFormMat(h); mat33 mat; //computer transform LOAD_MAT33(mat, s.m[0][0],s.m[0][1],s.m[0][2], s.m[1][0],s.m[1][1],s.m[1][2], s.m[2][0],s.m[2][1],s.m[2][2]); mat = matMul33( mat, orient); s = setMat44Vec(mat, minMM); //add offset mat2sForm(h,s); h->qform_code = h->sform_code; //apply to the quaternion as well float dumdx, dumdy, dumdz; nifti_mat44_to_quatern( s , &h->quatern_b, &h->quatern_c, &h->quatern_d,&h->qoffset_x, &h->qoffset_y, &h->qoffset_z, &dumdx, &dumdy, &dumdz,&h->pixdim[0]) ; return img; } //reOrient()
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; }
/* *************************************************************** */ nifti_image *reg_io_nrdd2nifti(Nrrd *nrrdImage) { // Check if the file can be converted if(nrrdImage->dim>7){ fprintf(stderr, "[NiftyReg ERROR] reg_io_nrdd2nifti - The Nifti format only support 7 dimensions\n"); exit(1); } // Need first to extract the input image dimension int dim[8]={1,1,1,1,1,1,1,1}; dim[0]=nrrdImage->dim; int vectorIncrement=0; if(nrrdImage->axis[0].kind==nrrdKindVector) vectorIncrement=1; for(int i=0;i<(dim[0]<7?dim[0]:7);++i) dim[i+1]=(int)nrrdImage->axis[i+vectorIncrement].size; if(vectorIncrement==1){ dim[0]=5; dim[4]=1; dim[5]=nrrdImage->axis[0].size; } // The nifti_image pointer is created nifti_image *niiImage=NULL; // The nifti image is generated based on the nrrd image datatype switch(nrrdImage->type){ case nrrdTypeUChar: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_UINT8,true); break; case nrrdTypeChar: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_INT8,true); break; case nrrdTypeUShort: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_UINT16,true); break; case nrrdTypeShort: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_INT16,true); break; case nrrdTypeUInt: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_UINT32,true); break; case nrrdTypeInt: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_INT32,true); break; case nrrdTypeFloat: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_FLOAT32,true); break; case nrrdTypeDouble: niiImage=nifti_make_new_nim(dim,NIFTI_TYPE_FLOAT64,true); break; default: fprintf(stderr, "[NiftyReg ERROR] reg_io_nrdd2nifti - The data type is not supported\n"); exit(1); } // The data are copied over from the nrrd to the nifti structure memcpy(niiImage->data, nrrdImage->data, niiImage->nvox*niiImage->nbyper); // We set the spacing information for every axis double spaceDir[NRRD_SPACE_DIM_MAX], spacing; for(int i=0;i<7;++i){ nrrdSpacingCalculate(nrrdImage,i+vectorIncrement,&spacing,spaceDir); if(spacing==spacing) niiImage->pixdim[i+1]=(float)spacing; else niiImage->pixdim[i+1]=1.0f; } niiImage->dx=niiImage->pixdim[1]; niiImage->dy=niiImage->pixdim[2]; niiImage->dz=niiImage->pixdim[3]; niiImage->dt=niiImage->pixdim[4]; niiImage->du=niiImage->pixdim[5]; niiImage->dv=niiImage->pixdim[6]; niiImage->dw=niiImage->pixdim[7]; // Set the slope and intersection niiImage->scl_inter=0; niiImage->scl_slope=1; // Set the min and max intensities niiImage->cal_min=reg_tools_getMinValue(niiImage); niiImage->cal_max=reg_tools_getMaxValue(niiImage); // The space orientation is extracted and converted into a matrix mat44 qform_orientation_matrix; reg_mat44_eye(&qform_orientation_matrix); if(nrrdImage->space==nrrdSpaceRightAnteriorSuperior || nrrdImage->space==nrrdSpaceRightAnteriorSuperiorTime || nrrdImage->space==nrrdSpace3DRightHanded || nrrdImage->space==nrrdSpace3DRightHandedTime ){ qform_orientation_matrix.m[0][0]=1.f; // NIFTI_L2R qform_orientation_matrix.m[1][1]=1.f; // NIFTI_P2A qform_orientation_matrix.m[2][2]=1.f; // NIFTI_I2S niiImage->qform_code=1; } else if(nrrdImage->space==nrrdSpaceLeftAnteriorSuperior || nrrdImage->space==nrrdSpaceLeftAnteriorSuperiorTime || nrrdImage->space==nrrdSpace3DLeftHanded || nrrdImage->space==nrrdSpace3DLeftHandedTime ){ qform_orientation_matrix.m[0][0]=-1.f; //NIFTI_R2L qform_orientation_matrix.m[1][1]=1.f; // NIFTI_P2A qform_orientation_matrix.m[2][2]=1.f; // NIFTI_I2S niiImage->qform_code=1; } else if(nrrdImage->space!=nrrdSpaceScannerXYZ && nrrdImage->space!=nrrdSpaceScannerXYZTime ){ niiImage->qform_code=0; fprintf(stderr, "[NiftyReg WARNING] reg_io_nrdd2nifti - nrrd space value unrecognised: the Nifti qform is set to identity\n"); } if(niiImage->qform_code>0){ // The origin is set // Note that x and y origin are negated to fit with ITK conversion if(niiImage->ndim>=1) qform_orientation_matrix.m[0][3]=niiImage->qoffset_x=-nrrdImage->spaceOrigin[0]; if(niiImage->ndim>=2) qform_orientation_matrix.m[1][3]=niiImage->qoffset_y=-nrrdImage->spaceOrigin[1]; if(niiImage->ndim>=3) qform_orientation_matrix.m[2][3]=niiImage->qoffset_z=nrrdImage->spaceOrigin[2]; // Flipp the orientation to fit ITK's filters qform_orientation_matrix.m[0][0] *= -1.0f; qform_orientation_matrix.m[1][1] *= -1.0f; // Extract the quaternions and qfac values nifti_mat44_to_quatern(qform_orientation_matrix, &niiImage->quatern_b, &niiImage->quatern_c, &niiImage->quatern_d, &niiImage->qoffset_x, &niiImage->qoffset_y, &niiImage->qoffset_z, &niiImage->dx, &niiImage->dy, &niiImage->dz, &niiImage->qfac); // Set the qform matrices niiImage->qto_xyz=nifti_quatern_to_mat44(niiImage->quatern_b, niiImage->quatern_c, niiImage->quatern_d, niiImage->qoffset_x, niiImage->qoffset_y, niiImage->qoffset_z, niiImage->dx, niiImage->dy, niiImage->dz, niiImage->qfac); } else{ // diagonal matrix is assumed niiImage->qto_xyz=qform_orientation_matrix; niiImage->qto_xyz.m[0][0]=niiImage->dx; niiImage->qto_xyz.m[1][1]=niiImage->dy; if(niiImage->ndim>2) niiImage->qto_xyz.m[2][2]=niiImage->dz; } niiImage->qto_ijk=nifti_mat44_inverse(niiImage->qto_xyz); // The sform has to be set if required // Check if the spaceDirection array is set // The check is performed in the dim in case you are dealing with a vector if(nrrdImage->axis[1].spaceDirection[0]!=std::numeric_limits<double>::quiet_NaN()){ niiImage->sform_code=1; reg_mat44_eye(&niiImage->sto_xyz); for(int i=0;i<(niiImage->ndim<3?niiImage->ndim:3);++i){ for(int j=0;j<(niiImage->ndim<3?niiImage->ndim:3);++j){ niiImage->sto_xyz.m[i][j]=(float)nrrdImage->axis[i+vectorIncrement].spaceDirection[j]; } niiImage->sto_xyz.m[i][3]=(float)nrrdImage->spaceOrigin[i]; } // The matrix is flipped to go from nrrd to nifti // and follow the ITK style for(unsigned int i=0;i<2;++i) for(unsigned int j=0;j<4;++j) niiImage->sto_xyz.m[i][j]*=-1.0f; niiImage->sto_ijk=nifti_mat44_inverse(niiImage->sto_xyz); } // Set the space unit if it is defined if(nrrdImage->spaceUnits[1]!=NULL){ if(strcmp(nrrdImage->spaceUnits[1],"m")==0) niiImage->xyz_units=NIFTI_UNITS_METER; else if(strcmp(nrrdImage->spaceUnits[1],"mm")==0) niiImage->xyz_units=NIFTI_UNITS_MM; else if(strcmp(nrrdImage->spaceUnits[1],"um")==0) niiImage->xyz_units=NIFTI_UNITS_MICRON; } // Set the time unit if it is defined if(nrrdImage->axis[3].size>1){ if(nrrdImage->spaceUnits[4]!=NULL){ if(strcmp(nrrdImage->spaceUnits[4],"sec")) niiImage->time_units=NIFTI_UNITS_SEC; else if(strcmp(nrrdImage->spaceUnits[4],"msec")) niiImage->time_units=NIFTI_UNITS_MSEC; } } // Check if the nrrd image was a NiftyReg velocity field parametrisation if(vectorIncrement == 1){ // The intensity array has to be reoriented switch(niiImage->datatype){ case NIFTI_TYPE_FLOAT32: reg_convertVectorField_nrrd_to_nifti<float>(nrrdImage,niiImage); break; case NIFTI_TYPE_FLOAT64: reg_convertVectorField_nrrd_to_nifti<double>(nrrdImage,niiImage); break; default: fprintf(stderr, "[NiftyReg ERROR] - reg_convertVectorField_nrrd_to_nifti - unsupported datatype\n"); exit(1); } // The orientation flag are re-organised niiImage->ndim=5; niiImage->dim[4]=niiImage->nt=1; niiImage->dim[5]=niiImage->nu=nrrdImage->axis[0].size; niiImage->intent_code=NIFTI_INTENT_VECTOR; // Check if the image is a stationary field from NiftyReg if(nrrdImage->axis[0].label!=NULL){ std::string str=nrrdImage->axis[0].label; size_t it; if((it=str.find("NREG_VEL_STEP "))!=std::string::npos){ str=str.substr(it+13); memset(niiImage->intent_name, 0, 16); strcpy(niiImage->intent_name,"NREG_VEL_STEP"); niiImage->intent_p1=atof(str.c_str()); } if(str.find("NREG_CPP_FILE")!=std::string::npos){ memset(niiImage->intent_name, 0, 16); strcpy(niiImage->intent_name,"NREG_CPP_FILE"); } } } // returns the new nii image return niiImage; }