c_nifti 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/COPYING +621 -0
  7. data/COPYING.lesser +166 -0
  8. data/Gemfile +4 -0
  9. data/README.md +117 -0
  10. data/Rakefile +6 -0
  11. data/c_nifti.gemspec +31 -0
  12. data/ext/nifticlib/extconf.rb +30 -0
  13. data/ext/nifticlib/include/nifti_image.h +2 -0
  14. data/ext/nifticlib/include/nifti_image_converters.h +3 -0
  15. data/ext/nifticlib/include/nifti_image_dimensions.h +1 -0
  16. data/ext/nifticlib/include/nifti_image_intents.h +1 -0
  17. data/ext/nifticlib/include/nifti_image_metadata.h +1 -0
  18. data/ext/nifticlib/include/nifti_image_quaternions.h +1 -0
  19. data/ext/nifticlib/include/nifti_image_spacings.h +1 -0
  20. data/ext/nifticlib/include/nifti_image_timings.h +1 -0
  21. data/ext/nifticlib/include/nifti_image_transforms.h +1 -0
  22. data/ext/nifticlib/nifti_image.c +169 -0
  23. data/ext/nifticlib/nifti_image_converters.c +65 -0
  24. data/ext/nifticlib/nifti_image_dimensions.c +113 -0
  25. data/ext/nifticlib/nifti_image_intents.c +45 -0
  26. data/ext/nifticlib/nifti_image_metadata.c +133 -0
  27. data/ext/nifticlib/nifti_image_quaternions.c +59 -0
  28. data/ext/nifticlib/nifti_image_spacings.c +87 -0
  29. data/ext/nifticlib/nifti_image_timings.c +66 -0
  30. data/ext/nifticlib/nifti_image_transforms.c +38 -0
  31. data/ext/nifticlib/nifticlib-2.0.0/CMakeLists.txt +140 -0
  32. data/ext/nifticlib/nifticlib-2.0.0/CTestConfig.cmake +13 -0
  33. data/ext/nifticlib/nifticlib-2.0.0/LICENSE +9 -0
  34. data/ext/nifticlib/nifticlib-2.0.0/Makefile +265 -0
  35. data/ext/nifticlib/nifticlib-2.0.0/Makefile.cross_mingw32 +94 -0
  36. data/ext/nifticlib/nifticlib-2.0.0/README +79 -0
  37. data/ext/nifticlib/nifticlib-2.0.0/Testing/CMakeLists.txt +7 -0
  38. data/ext/nifticlib/nifticlib-2.0.0/Testing/Data/ATestReferenceImageForReadingAndWriting.nii.gz +0 -0
  39. data/ext/nifticlib/nifticlib-2.0.0/Testing/Makefile +21 -0
  40. data/ext/nifticlib/nifticlib-2.0.0/Testing/README_regress +50 -0
  41. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/@show.diffs +33 -0
  42. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/@test +80 -0
  43. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/CMakeLists.txt +47 -0
  44. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/bricks_test.sh +32 -0
  45. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/comment_test.sh +65 -0
  46. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/dci_test.sh +46 -0
  47. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/dsets_test.sh +61 -0
  48. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/dts_test.sh +75 -0
  49. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/fetch_data_test.sh +45 -0
  50. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/mod_header_test.sh +60 -0
  51. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/newfiles_test.sh +36 -0
  52. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c01.versions +10 -0
  53. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c02.nt.help +5 -0
  54. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c03.hist +5 -0
  55. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c04.disp.anat0.info +7 -0
  56. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c05.mod.hdr +9 -0
  57. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c06.add.ext +22 -0
  58. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c07.cbl.4bricks +8 -0
  59. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c08.dts.19.36.11 +4 -0
  60. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c09.dts4.compare +9 -0
  61. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c10.dci.ts4 +15 -0
  62. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c10a.dci.run.210 +16 -0
  63. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c11.add.comment +8 -0
  64. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c12.check.comments +7 -0
  65. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c13.check.hdrs +5 -0
  66. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c14.make.dsets +21 -0
  67. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c15.new.files +21 -0
  68. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c16.rand.swap +35 -0
  69. data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c17.file.case +34 -0
  70. data/ext/nifticlib/nifticlib-2.0.0/Testing/niftilib/CMakeLists.txt +15 -0
  71. data/ext/nifticlib/nifticlib-2.0.0/Testing/niftilib/nifti_test.c +690 -0
  72. data/ext/nifticlib/nifticlib-2.0.0/Testing/niftilib/nifti_test2.c +32 -0
  73. data/ext/nifticlib/nifticlib-2.0.0/Updates.txt +110 -0
  74. data/ext/nifticlib/nifticlib-2.0.0/bin/.gitkeep +0 -0
  75. data/ext/nifticlib/nifticlib-2.0.0/docs/Doxy_nifti.txt +123 -0
  76. data/ext/nifticlib/nifticlib-2.0.0/docs/Doxyfile.ORIG +746 -0
  77. data/ext/nifticlib/nifticlib-2.0.0/examples/CMakeLists.txt +15 -0
  78. data/ext/nifticlib/nifticlib-2.0.0/examples/Makefile +48 -0
  79. data/ext/nifticlib/nifticlib-2.0.0/examples/clib_01_read_write.c +94 -0
  80. data/ext/nifticlib/nifticlib-2.0.0/examples/fsl_api_driver.c +142 -0
  81. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/CMakeLists.txt +32 -0
  82. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/Makefile +29 -0
  83. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/fslio.c +2426 -0
  84. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/fslio.tcl +83 -0
  85. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imcp +65 -0
  86. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imglob +59 -0
  87. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imln +37 -0
  88. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/immv +64 -0
  89. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imrm +29 -0
  90. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imtest +53 -0
  91. data/ext/nifticlib/nifticlib-2.0.0/fsliolib/remove_ext +33 -0
  92. data/ext/nifticlib/nifticlib-2.0.0/include/.gitkeep +0 -0
  93. data/ext/nifticlib/nifticlib-2.0.0/nifticdf/CMakeLists.txt +28 -0
  94. data/ext/nifticlib/nifticlib-2.0.0/nifticdf/Makefile +28 -0
  95. data/ext/nifticlib/nifticlib-2.0.0/nifticdf/nifticdf.c +11107 -0
  96. data/ext/nifticlib/nifticlib-2.0.0/niftilib/CMakeLists.txt +33 -0
  97. data/ext/nifticlib/nifticlib-2.0.0/niftilib/Makefile +31 -0
  98. data/ext/nifticlib/nifticlib-2.0.0/niftilib/nifti1_io.c +7509 -0
  99. data/ext/nifticlib/nifticlib-2.0.0/packaging/DevPackage.template +18 -0
  100. data/ext/nifticlib/nifticlib-2.0.0/packaging/nifticlib.spec +62 -0
  101. data/ext/nifticlib/nifticlib-2.0.0/real_easy/nifti1_read_write.c +361 -0
  102. data/ext/nifticlib/nifticlib-2.0.0/utils/CMakeLists.txt +73 -0
  103. data/ext/nifticlib/nifticlib-2.0.0/utils/Makefile +55 -0
  104. data/ext/nifticlib/nifticlib-2.0.0/utils/nifti1_test.c +95 -0
  105. data/ext/nifticlib/nifticlib-2.0.0/utils/nifti_stats.c +95 -0
  106. data/ext/nifticlib/nifticlib-2.0.0/utils/nifti_tool.c +4193 -0
  107. data/ext/nifticlib/nifticlib-2.0.0/utils/nifti_tool.h +163 -0
  108. data/ext/nifticlib/nifticlib-2.0.0/znzlib/CMakeLists.txt +31 -0
  109. data/ext/nifticlib/nifticlib-2.0.0/znzlib/Makefile +33 -0
  110. data/ext/nifticlib/nifticlib-2.0.0/znzlib/znzlib.c +322 -0
  111. data/ext/nifticlib/nifticlib.c +107 -0
  112. data/ext/nifticlib/patches/nifticlib_fpic.patch +13 -0
  113. data/features/read_modify_write.feature +11 -0
  114. data/features/step_definitions/nifti_image_steps.rb +16 -0
  115. data/features/support/env.rb +14 -0
  116. data/features/support/fixtures/sample.nii.gz +0 -0
  117. data/lib/c_nifti.rb +9 -0
  118. data/lib/c_nifti/data.rb +70 -0
  119. data/lib/c_nifti/header.rb +16 -0
  120. data/lib/c_nifti/header_element.rb +13 -0
  121. data/lib/c_nifti/header_element/datatype.rb +49 -0
  122. data/lib/c_nifti/header_element/datatype/base.rb +9 -0
  123. data/lib/c_nifti/header_element/datatype/binary.rb +11 -0
  124. data/lib/c_nifti/header_element/datatype/double.rb +11 -0
  125. data/lib/c_nifti/header_element/datatype/float.rb +11 -0
  126. data/lib/c_nifti/header_element/datatype/long_double.rb +11 -0
  127. data/lib/c_nifti/header_element/datatype/long_long.rb +11 -0
  128. data/lib/c_nifti/header_element/datatype/signed_char.rb +11 -0
  129. data/lib/c_nifti/header_element/datatype/signed_int.rb +11 -0
  130. data/lib/c_nifti/header_element/datatype/signed_short.rb +11 -0
  131. data/lib/c_nifti/header_element/datatype/unsigned_char.rb +11 -0
  132. data/lib/c_nifti/header_element/datatype/unsigned_int.rb +11 -0
  133. data/lib/c_nifti/header_element/datatype/unsigned_long_long.rb +11 -0
  134. data/lib/c_nifti/header_element/datatype/unsigned_short.rb +11 -0
  135. data/lib/c_nifti/header_element/dimensions.rb +53 -0
  136. data/lib/c_nifti/header_element/intents.rb +25 -0
  137. data/lib/c_nifti/header_element/metadata.rb +49 -0
  138. data/lib/c_nifti/header_element/miscellaneous.rb +25 -0
  139. data/lib/c_nifti/header_element/quaternions.rb +33 -0
  140. data/lib/c_nifti/header_element/spacings.rb +45 -0
  141. data/lib/c_nifti/header_element/timings.rb +37 -0
  142. data/lib/c_nifti/header_element/transforms.rb +21 -0
  143. data/lib/c_nifti/image.rb +31 -0
  144. data/lib/c_nifti/version.rb +3 -0
  145. data/lib/nifticlib.rb +1 -0
  146. data/spec/data_spec.rb +112 -0
  147. data/spec/factories/nifti_images.rb +9 -0
  148. data/spec/header_element/datatype/base_spec.rb +9 -0
  149. data/spec/header_element/datatype/binary_spec.rb +9 -0
  150. data/spec/header_element/datatype/double_spec.rb +9 -0
  151. data/spec/header_element/datatype/float_spec.rb +9 -0
  152. data/spec/header_element/datatype/long_double_spec.rb +9 -0
  153. data/spec/header_element/datatype/long_long_spec.rb +9 -0
  154. data/spec/header_element/datatype/signed_char_spec.rb +9 -0
  155. data/spec/header_element/datatype/signed_int_spec.rb +9 -0
  156. data/spec/header_element/datatype/signed_short_spec.rb +9 -0
  157. data/spec/header_element/datatype/unsigned_char_spec.rb +9 -0
  158. data/spec/header_element/datatype/unsigned_int_spec.rb +9 -0
  159. data/spec/header_element/datatype/unsigned_long_long.rb +9 -0
  160. data/spec/header_element/datatype/unsigned_short_spec.rb +9 -0
  161. data/spec/header_element/datatype_spec.rb +109 -0
  162. data/spec/header_element/dimensions_spec.rb +105 -0
  163. data/spec/header_element/intents_spec.rb +48 -0
  164. data/spec/header_element/metadata_spec.rb +96 -0
  165. data/spec/header_element/miscellaneous_spec.rb +48 -0
  166. data/spec/header_element/quaternions_spec.rb +64 -0
  167. data/spec/header_element/spacings_spec.rb +88 -0
  168. data/spec/header_element/timings_spec.rb +72 -0
  169. data/spec/header_element/transforms_spec.rb +64 -0
  170. data/spec/image_spec.rb +39 -0
  171. data/spec/spec_helper.rb +85 -0
  172. metadata +363 -0
@@ -0,0 +1,55 @@
1
+ CC = gcc
2
+ CFLAGS = -ansi -pedantic
3
+
4
+ FSLIO_INCS = -I../include
5
+ NIFTI_INCS = -I../include
6
+ ZNZ_INCS = -I/usr/include
7
+
8
+ FSLIO_LIBS = -L../lib -lfslio
9
+ NIFTI_LIBS = -L../lib -lniftiio
10
+ NIFTICDF_LIBS = -L../lib -lnifticdf
11
+ ZNZ_LIBS = -L/usr/lib -L../lib -lznz -lm -lz
12
+
13
+
14
+
15
+ ##############################################################
16
+ # platform specific redefines (to use, set ARCH appropriately)
17
+
18
+ ## ARCH = X86_64
19
+
20
+ ifeq ($(ARCH),SGI) ## SGI 32bit
21
+ ZNZ_INCS = -I/usr/freeware/include
22
+ ZNZ_LIBS = -L/usr/freeware/lib32 -L../lib -lznz -lm -lz
23
+ else
24
+ ifeq ($(ARCH),I386) ## 32-bit Linux
25
+ ZNZ_INCS = -I/usr/include
26
+ ZNZ_LIBS = -L/usr/lib -L../lib -lznz -lm -lz
27
+ else
28
+ ifeq ($(ARCH),X86_64) ## 64-bit Linux
29
+ ZNZ_INCS =
30
+ ZNZ_LIBS = -L../lib -lznz -lm -lz
31
+ endif
32
+ endif
33
+ endif
34
+
35
+ ####################################################
36
+
37
+
38
+ UTILS_PROGS = nifti_stats nifti_tool nifti1_test
39
+
40
+
41
+
42
+ all: $(UTILS_PROGS)
43
+
44
+ clean:
45
+ rm -f $(UTILS_PROGS)
46
+
47
+
48
+ nifti_stats: nifti_stats.c
49
+ $(CC) $(CFLAGS) -o nifti_stats nifti_stats.c $(NIFTI_INCS) $(ZNZ_INCS) $(NIFTICDF_LIBS) $(NIFTI_LIBS) $(ZNZ_LIBS)
50
+
51
+ nifti_tool: nifti_tool.c nifti_tool.h
52
+ $(CC) $(CFLAGS) -Wall -o nifti_tool nifti_tool.c $(NIFTI_INCS) $(ZNZ_INCS) $(NIFTI_LIBS) $(ZNZ_LIBS)
53
+
54
+ nifti1_test: nifti1_test.c
55
+ $(CC) $(CFLAGS) -o nifti1_test nifti1_test.c $(NIFTI_INCS) $(ZNZ_INCS) $(NIFTI_LIBS) $(ZNZ_LIBS)
@@ -0,0 +1,95 @@
1
+ #include <nifti1_io.h> /* directly include I/O library functions */
2
+
3
+ /*-----------------------------------------------*/
4
+ /* cc -o nifti1_test -O2 nifti1_test.c -lm */
5
+ /*-----------------------------------------------*/
6
+
7
+ /****************************************************************************/
8
+
9
+ int main( int argc , char *argv[] )
10
+ {
11
+ nifti_image *nim ;
12
+ int iarg=1 , outmode=1 , ll , argn=1, usegzip=0;
13
+ char *tmpstr;
14
+
15
+ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
16
+ printf("Usage: nifti1_test [-n2|-n1|-na|-a2] infile [prefix]\n"
17
+ "\n"
18
+ " If prefix is given, then the options mean:\n"
19
+ " -a2 ==> write an ANALYZE 7.5 file pair: prefix.hdr/prefix.img\n"
20
+ " -n2 ==> write a NIFTI-1 file pair: prefix.hdr/prefix.img\n"
21
+ " -n1 ==> write a NIFTI-1 single file: prefix.nii\n"
22
+ " -na ==> write a NIFTI-1 ASCII+binary file: prefix.nia\n");
23
+ printf(" -za2 => write an ANALYZE 7.5 file pair:\n"
24
+ " prefix.hdr.gz/prefix.img.gz\n"
25
+ " -zn2 => write a NIFTI-1 file pair: prefix.hdr.gz/prefix.img.gz\n"
26
+ " -zn1 => write a NIFTI-1 single file: prefix.nii.gz\n");
27
+ printf(" The default is '-n1'.\n"
28
+ "\n"
29
+ " If prefix is not given, then the header info from infile\n"
30
+ " file is printed to stdout.\n"
31
+ "\n"
32
+ " Please note that the '.nia' format is NOT part of the\n"
33
+ " NIFTI-1 specification, but is provided mostly for ease\n"
34
+ " of visualization (e.g., you can edit a .nia file and\n"
35
+ " change some header fields, then rewrite it as .nii)\n"
36
+ ) ;
37
+ printf("\nsizeof(nifti_1_header)=%u\n",
38
+ (unsigned int)sizeof(nifti_1_header)) ;
39
+ exit(0) ;
40
+ }
41
+
42
+ if( argv[1][0] == '-' ){
43
+ argn=1;
44
+ if (argv[1][1] == 'z' ) {
45
+ usegzip = 1;
46
+ argn=2;
47
+ }
48
+ if( argv[1][argn] == 'a' ){
49
+ outmode = 0 ;
50
+ } else if( argv[1][argn] == 'n' ){
51
+ switch( argv[1][argn+1] ){
52
+ case '1': outmode = 1 ; break ;
53
+ default: outmode = 2 ; break ;
54
+ case 'a': outmode = 3 ; break ;
55
+ }
56
+ }
57
+ iarg++ ;
58
+ }
59
+
60
+ if( iarg >= argc ){
61
+ fprintf(stderr,"** ERROR: no input file on command line!?\n"); exit(1);
62
+ }
63
+
64
+ nim = nifti_image_read( argv[iarg++] , 1 ) ;
65
+ if( nim == NULL ) exit(1) ;
66
+
67
+ if( iarg >= argc ){ nifti_image_infodump(nim); exit(0); }
68
+
69
+ nim->nifti_type = outmode ;
70
+ if( nim->fname != NULL ) free(nim->fname) ;
71
+ if( nim->iname != NULL ) free(nim->iname) ;
72
+
73
+ ll = strlen(argv[iarg]) ;
74
+ tmpstr = nifti_makebasename(argv[iarg]);
75
+ nim->fname = (char *)calloc(1,ll+8) ; strcpy(nim->fname,tmpstr) ;
76
+ nim->iname = (char *)calloc(1,ll+8) ; strcpy(nim->iname,tmpstr) ;
77
+ free(tmpstr);
78
+ if( nim->nifti_type == 1 ){
79
+ strcat(nim->fname,".nii") ;
80
+ strcat(nim->iname,".nii") ;
81
+ } else if ( nim->nifti_type == 3 ){
82
+ strcat(nim->fname,".nia") ;
83
+ strcat(nim->iname,".nia") ;
84
+ } else {
85
+ strcat(nim->fname,".hdr") ;
86
+ strcat(nim->iname,".img") ;
87
+ }
88
+ if (usegzip) {
89
+ strcat(nim->fname,".gz");
90
+ strcat(nim->iname,".gz");
91
+ }
92
+ nifti_image_write( nim ) ;
93
+ nifti_image_free( nim ) ;
94
+ exit(0) ;
95
+ }
@@ -0,0 +1,95 @@
1
+ #include "nifti1.h" /* for the NIFTI_INTENT_* constants */
2
+ #include "nifticdf.h"
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <math.h>
6
+ #include <string.h>
7
+
8
+ int main( int argc , char *argv[] )
9
+ {
10
+ double val , p , p1=0.0,p2=0.0,p3=0.0 ;
11
+ double vbot,vtop,vdel ;
12
+ int code , iarg=1 , doq=0 , dod=0 , doi=0 , doz=0 , doh=0 ;
13
+
14
+ /*-- print some help for the pitiful user --*/
15
+
16
+ if( argc < 3 || strstr(argv[1],"help") != NULL ){
17
+ int ii ;
18
+ printf("\n") ;
19
+ printf("Demo program for computing NIfTI statistical functions.\n") ;
20
+ printf("Usage: nifti_stats [-q|-d|-1|-z] val CODE [p1 p2 p3]\n") ;
21
+ printf(" val can be a single number or in the form bot:top:step.\n") ;
22
+ printf(" default ==> output p = Prob(statistic < val).\n") ;
23
+ printf(" -q ==> output is 1-p.\n") ;
24
+ printf(" -d ==> output is density.\n") ;
25
+ printf(" -1 ==> output is x such that Prob(statistic < x) = val.\n") ;
26
+ printf(" -z ==> output is z such that Normal cdf(z) = p(val).\n") ;
27
+ printf(" -h ==> output is z such that 1/2-Normal cdf(z) = p(val).\n");
28
+ printf(" Allowable CODEs:\n") ;
29
+ for( ii=NIFTI_FIRST_STATCODE ; ii <= NIFTI_LAST_STATCODE ; ii++ ){
30
+ printf(" %-10s",inam[ii]); if((ii-NIFTI_FIRST_STATCODE)%6==5)printf("\n");
31
+ }
32
+ printf("\n") ;
33
+ printf(" Following CODE are distributional parameters, as needed.\n");
34
+ printf("\n") ;
35
+ printf("Results are written to stdout, 1 number per output line.\n") ;
36
+ printf("Example (piping output into AFNI program 1dplot):\n") ;
37
+ printf(" nifti_stats -d 0:4:.001 INVGAUSS 1 3 | 1dplot -dx 0.001 -stdin\n");
38
+ printf("\n") ;
39
+ printf("Author - RW Cox - SSCC/NIMH/NIH/DHHS/USA/EARTH - March 2004\n") ;
40
+ printf("\n") ;
41
+ exit(0) ;
42
+ }
43
+
44
+ /*-- check first arg to see if it is an output option;
45
+ if so, set the appropriate output flag to determine what to compute --*/
46
+
47
+ if( strcmp(argv[iarg],"-q") == 0 ){ doq = 1 ; iarg++ ; }
48
+ else if( strcmp(argv[iarg],"-d") == 0 ){ dod = 1 ; iarg++ ; }
49
+ else if( strcmp(argv[iarg],"-1") == 0 ){ doi = 1 ; iarg++ ; }
50
+ else if( strcmp(argv[iarg],"-z") == 0 ){ doz = 1 ; iarg++ ; }
51
+ else if( strcmp(argv[iarg],"-h") == 0 ){ doh = 1 ; iarg++ ; }
52
+
53
+ /*-- get the value(s) to process --*/
54
+
55
+ vbot=vtop=vdel = 0.0 ;
56
+ sscanf( argv[iarg++] , "%lf:%lf:%lf" , &vbot,&vtop,&vdel ) ;
57
+ if( vbot >= vtop ) vdel = 0.0 ;
58
+ if( vdel <= 0.0 ) vtop = vbot ;
59
+
60
+ /*-- decode the CODE into the integer signifying the distribution --*/
61
+
62
+ code = nifti_intent_code(argv[iarg++]) ;
63
+ if( code < 0 ){ fprintf(stderr,"illegal code=%s\n",argv[iarg-1]); exit(1); }
64
+
65
+ /*-- get the parameters, if present (defaults are 0) --*/
66
+
67
+ if( argc > iarg ) p1 = strtod(argv[iarg++],NULL) ;
68
+ if( argc > iarg ) p2 = strtod(argv[iarg++],NULL) ;
69
+ if( argc > iarg ) p3 = strtod(argv[iarg++],NULL) ;
70
+
71
+ /*-- loop over input value(s), compute output, write to stdout --*/
72
+
73
+ for( val=vbot ; val <= vtop ; val += vdel ){
74
+ if( doq ) /* output = 1-cdf */
75
+ p = nifti_stat2rcdf( val , code,p1,p2,p3 ) ;
76
+ else if( dod ) /* output = density */
77
+ p = 1000.0*( nifti_stat2cdf(val+.001,code,p1,p2,p3)
78
+ -nifti_stat2cdf(val ,code,p1,p2,p3)) ;
79
+ else if( doi ) /* output = inverse */
80
+ p = nifti_cdf2stat( val , code,p1,p2,p3 ) ;
81
+ else if( doz ) /* output = z score */
82
+ p = nifti_stat2zscore( val , code,p1,p2,p3 ) ;
83
+ else if( doh ) /* output = halfz score */
84
+ p = nifti_stat2hzscore( val , code,p1,p2,p3 ) ;
85
+ else /* output = cdf */
86
+ p = nifti_stat2cdf( val , code,p1,p2,p3 ) ;
87
+
88
+ printf("%.9g\n",p) ;
89
+ if( vdel <= 0.0 ) break ; /* the case of just 1 value */
90
+ }
91
+
92
+ /*-- terminus est --*/
93
+
94
+ exit(0) ;
95
+ }
@@ -0,0 +1,4193 @@
1
+ /*--------------------------------------------------------------------------*/
2
+ /*! \file nifti_tool.c
3
+ * \brief a tool for nifti file perusal, manipulation and copying
4
+ * written by Rick Reynolds, SSCC, NIMH, January 2005
5
+ * <pre>
6
+ *
7
+ * usage: nifti_tool [options] -infiles files...
8
+ *
9
+ * Via this tool, one should be able to:
10
+ *
11
+ * - copy a set of volumes (sub-bricks) from one dataset to another
12
+ * - copy a dataset, restricting some dimensions to given indices
13
+ *
14
+ * - display the contents of a nifti_image (or various fields)
15
+ * - display the contents of a nifti1_header (or various fields)
16
+ * - display AFNI extensions (they are text)
17
+ * - display the time series at coordinates i,j,k
18
+ * - display the data from any collapsed image
19
+ *
20
+ * - do a diff on two nifti_image structs (or various fields)
21
+ * - do a diff on two nifti1_header structs (or various fields)
22
+ *
23
+ * - add an AFNI extension
24
+ * - remove any extension
25
+ *
26
+ * - modify any field(s) of a nifti_image
27
+ * - modify any field(s) of a nifti1_struct
28
+ *
29
+ * usage forms:
30
+ *
31
+ * nifti_tool -help
32
+ * nifti_tool -help_hdr
33
+ * nifti_tool -help_nim
34
+ * nifti_tool -help_ana
35
+ * nifti_tool -help_datatypes
36
+ * nifti_tool -hist
37
+ * nifti_tool -ver
38
+ * nifti_tool -nifti_hist
39
+ * nifti_tool -nifti_ver
40
+ * nifti_tool -with_zlib
41
+ *
42
+ * nifti_tool -check_hdr -infiles f1 ...
43
+ * nifti_tool -check_nim -infiles f1 ...
44
+
45
+ * nifti_tool -disp_exts -infiles f1 ...
46
+ * nifti_tool -disp_hdr [-field fieldname] [...] -infiles f1 ...
47
+ * nifti_tool -disp_nim [-field fieldname] [...] -infiles f1 ...
48
+ * nifti_tool -disp_ana [-field fieldname] [...] -infiles f1 ...
49
+ * nifti_tool -disp_ts I J K [-dci_lines] -infiles f1 ...
50
+ * nifti_tool -disp_ci I J K T U V W [-dci_lines] -infiles f1 ...
51
+ *
52
+ * nifti_tool -diff_hdr [-field fieldname] [...] -infiles f1 f2
53
+ * nifti_tool -diff_nim [-field fieldname] [...] -infiles f1 f2
54
+ *
55
+ * nifti_tool -add_afni_ext "extension in quotes" -infiles f1 ...
56
+ * nifti_tool -add_comment_ext "extension in quotes" -infiles f1 ...
57
+ * nifti_tool -rm_ext ext_index -infiles f1 ...
58
+ *
59
+ * nifti_tool -mod_hdr [-mod_field fieldname new_val] [...] -infiles f1 ...
60
+ * nifti_tool -mod_nim [-mod_field fieldname new_val] [...] -infiles f1 ...
61
+ *
62
+ * </pre> */
63
+ /*-------------------------------------------------------------------------*/
64
+
65
+ /*! module history */
66
+ static char * g_history[] =
67
+ {
68
+ "----------------------------------------------------------------------\n"
69
+ "nifti_tool modification history:\n"
70
+ "\n",
71
+ "0.1 30 December 2004 [rickr]\n"
72
+ " (Rick Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
73
+ " - skeleton version: options read and printed\n"
74
+ "\n",
75
+ "1.0 07 January 2005 [rickr]\n"
76
+ " - initial release version\n"
77
+ "\n",
78
+ "1.1 14 January 2005 [rickr]\n"
79
+ " - changed all non-error/non-debug output from stderr to stdout\n"
80
+ " note: creates a mis-match between normal output and debug messages\n"
81
+ " - modified act_diff_hdrs and act_diff_nims to do the processing in\n"
82
+ " lower-level functions\n",
83
+ " - added functions diff_hdrs, diff_hdrs_list, diff_nims, diff_nims_list\n"
84
+ " - added function get_field, to return a struct pointer via a fieldname\n"
85
+ " - made 'quiet' output more quiet (no description on output)\n"
86
+ " - made hdr and nim_fields arrays global, so do not pass in main()\n"
87
+ " - return (from main()) after first act_diff() difference\n"
88
+ "\n",
89
+ "1.2 9 February 2005 [rickr] - minor\n"
90
+ " - defined a local NTL_FERR macro (so it does not come from nifti1_io.h)\n"
91
+ " - added new set_byte_order parameter to nifti_set_filenames\n"
92
+ "\n",
93
+ "1.3 23 February 2005 [rickr] - sourceforge.net merge\n"
94
+ " - moved to utils directory\n"
95
+ " - added simple casts of 3 pointers for -pedantic warnings\n"
96
+ " - added a doxygen comment for the file\n"
97
+ "\n",
98
+ "1.4 02 March 2005 [rickr] - small update\n"
99
+ " - no validation in nifti_read_header calls\n"
100
+ "\n",
101
+ "1.5 05 April 2005 [rickr] - small update\n"
102
+ " - refuse mod_hdr for gzipped files (we cannot do partial overwrites)\n"
103
+ "\n",
104
+ "1.6 08 April 2005 [rickr] - added cbl, cci and dts functionality\n"
105
+ " - added -cbl: 'copy brick list' dataset copy functionality\n"
106
+ " - added -ccd: 'copy collapsed data' dataset copy functionality\n"
107
+ " - added -disp_ts: 'disp time series' data display functionality\n"
108
+ " - moved raw data display to disp_raw_data()\n"
109
+ "\n",
110
+ "1.7 14 April 2005 [rickr] - added data display functionality\n"
111
+ " - added -dci: 'display collapsed image' functionality\n"
112
+ " - modified -dts to use -dci\n"
113
+ " - modified and updated the help in use_full()\n"
114
+ " - changed copy_collapsed_dims to copy_collapsed_image, etc.\n",
115
+ " - fixed problem in disp_raw_data() for printing NT_DT_CHAR_PTR\n"
116
+ " - modified act_disp_ci():\n"
117
+ " o was act_disp_ts(), now displays arbitrary collapsed image data\n"
118
+ " o added missed debug filename act_disp_ci()\n"
119
+ " o can now save free() of data pointer for end of file loop\n",
120
+ " - modified disp_raw_data()\n"
121
+ " o takes a flag for whether to print newline\n"
122
+ " o trailing spaces and zeros are removed from printing floats\n"
123
+ " - added clear_float_zeros(), to remove trailing zeros\n"
124
+ "\n",
125
+ "1.8 19 April 2005 [rickr] - COMMENT extensions\n"
126
+ " - added int_list struct, and keep_hist,etypes,command fields to nt_opts\n"
127
+ " - added -add_comment_ext action\n"
128
+ " - allowed for removal of multiple extensions, including option of ALL\n"
129
+ " - added -keep_hist option, to store the command as a COMMENT extension\n",
130
+ " (includes fill_cmd_string() and add_int(), is done for all actions)\n"
131
+ " - added remove_ext_list(), for removing a list of extensions by indices\n"
132
+ " - added -strip action, to strip all extensions and descrip fields\n"
133
+ "\n",
134
+ "1.9 25 Aug 2005 [rickr] - const/string cleanup for warnings\n",
135
+ "1.10 18 Nov 2005 [rickr] - added check_hdr and check_nim actions\n",
136
+ "1.11 31 Jan 2006 [rickr] - check for new vox_offset in act_mod_hdrs\n",
137
+ "1.12 02 Mar 2006 [rickr]\n"
138
+ " - in act_cbl(), check for nt = 0 because of niftilib update 1.17\n",
139
+ "1.13 24 Apr 2006 [rickr] - act_disp_ci(): remove time series length check\n",
140
+ "1.14 04 Jun 2007 [rickr] - free_opts_mem(), to appease valgrind\n",
141
+ "1.15 05 Jun 2007 [rickr] - act_check_hdrs: free(nim)->nifti_image_free()\n",
142
+ "1.16 12 Jun 2007 [rickr] - allow creation of datasets via MAKE_IM\n",
143
+ " - added nt_image_read, nt_read_header and nt_read_bricks\n"
144
+ " to wrap nifti read functions, allowing creation of new datasets\n"
145
+ " - added -make_im, -new_dim, -new_datatype and -copy_im\n"
146
+ "1.17 13 Jun 2007 [rickr] - added help for -copy_im, enumerate examples\n",
147
+ "1.18 23 Jun 2007 [rickr] - main returns 0 on -help, -hist, -ver\n"
148
+ "1.19 28 Nov 2007 [rickr] - added -help_datatypes\n",
149
+ "1.20 13 Jun 2008 [rickr]\n"
150
+ " - added -with_zlib\n"
151
+ " - added ability to create extension from text file (for J. Gunter)\n",
152
+ "1.21 03 Aug 2008 [rickr] - ANALYZE 7.5 support\n"
153
+ " - added -help_ana, -disp_ana,\n"
154
+ " -swap_as_analyze, -swap_as_nifti, -swap_as_old\n"
155
+ "1.22 08 Oct 2008 [rickr] - allow cbl with indices in 0..nt*nu*nv*nw-1\n"
156
+ "1.23 06 Jul 2010 [rickr]\n",
157
+ " - in nt_read_bricks, bsize computation should allow for large integers\n"
158
+ "----------------------------------------------------------------------\n"
159
+ };
160
+ static char g_version[] = "version 1.23 (July 6, 2010)";
161
+ static int g_debug = 1;
162
+
163
+ #define _NIFTI_TOOL_C_
164
+ #include "nifti1_io.h"
165
+ #include "nifti_tool.h"
166
+
167
+ /* local prototypes */
168
+ static int free_opts_mem(nt_opts * nopt);
169
+ static int num_volumes(nifti_image * nim);
170
+ static char * read_file_text(char * filename, int * length);
171
+
172
+ #define NTL_FERR(func,msg,file) \
173
+ fprintf(stderr,"** ERROR (%s): %s '%s'\n",func,msg,file)
174
+
175
+ /* val may be a function call, so evalulate first, and return result */
176
+ #define FREE_RETURN(val) \
177
+ do{ int tval=(val); free_opts_mem(&opts); return tval; } while(0)
178
+
179
+ /* these are effectively constant, and are built only for verification */
180
+ field_s g_hdr_fields[NT_HDR_NUM_FIELDS]; /* nifti_1_header fields */
181
+ field_s g_ana_fields[NT_ANA_NUM_FIELDS]; /* nifti_analyze75 */
182
+ field_s g_nim_fields[NT_NIM_NUM_FIELDS]; /* nifti_image fields */
183
+
184
+ int main( int argc, char * argv[] )
185
+ {
186
+ nt_opts opts;
187
+ int rv;
188
+
189
+ if( (rv = process_opts(argc, argv, &opts)) != 0) /* then return */
190
+ {
191
+ if( rv < 0 ) FREE_RETURN(1); /* free opts memory, and return */
192
+ else FREE_RETURN(0); /* valid usage */
193
+ }
194
+
195
+ if( (rv = verify_opts(&opts, argv[0])) != 0 )
196
+ FREE_RETURN(rv);
197
+
198
+ /* now perform the requested action(s) */
199
+
200
+ if( (rv = fill_hdr_field_array(g_hdr_fields)) != 0 )
201
+ FREE_RETURN(rv);
202
+
203
+ if( (rv = fill_nim_field_array(g_nim_fields)) != 0 )
204
+ FREE_RETURN(rv);
205
+
206
+ if( (rv = fill_ana_field_array(g_ana_fields)) != 0 )
207
+ FREE_RETURN(rv);
208
+
209
+ /* 'check' functions, first */
210
+ if( opts.check_hdr || opts.check_nim ) /* allow for both */
211
+ FREE_RETURN( act_check_hdrs(&opts) );
212
+
213
+ /* copy or dts functions -- do not continue after these */
214
+ if( opts.cbl ) FREE_RETURN( act_cbl(&opts) );
215
+ if( opts.cci ) FREE_RETURN( act_cci(&opts) );
216
+ if( opts.dts || opts.dci ) FREE_RETURN( act_disp_ci(&opts) );
217
+
218
+ /* perform modifications early, in case we allow multiple actions */
219
+ if( opts.strip && ((rv = act_strip (&opts)) != 0) ) FREE_RETURN(rv);
220
+
221
+ if( opts.add_exts && ((rv = act_add_exts (&opts)) != 0) ) FREE_RETURN(rv);
222
+ if( opts.rm_exts && ((rv = act_rm_ext (&opts)) != 0) ) FREE_RETURN(rv);
223
+
224
+ if( opts.mod_hdr && ((rv = act_mod_hdrs (&opts)) != 0) ) FREE_RETURN(rv);
225
+ if( opts.mod_nim && ((rv = act_mod_nims (&opts)) != 0) ) FREE_RETURN(rv);
226
+
227
+ if((opts.swap_hdr || opts.swap_ana || opts.swap_old )
228
+ && ((rv = act_swap_hdrs (&opts)) != 0) ) FREE_RETURN(rv);
229
+
230
+ /* if a diff, return wither a difference exists (like the UNIX command) */
231
+ if( opts.diff_hdr && ((rv = act_diff_hdrs(&opts)) != 0) ) FREE_RETURN(rv);
232
+ if( opts.diff_nim && ((rv = act_diff_nims(&opts)) != 0) ) FREE_RETURN(rv);
233
+
234
+ /* last action type is display */
235
+ if( opts.disp_exts && ((rv = act_disp_exts(&opts)) != 0) ) FREE_RETURN(rv);
236
+ if( opts.disp_hdr && ((rv = act_disp_hdrs(&opts)) != 0) ) FREE_RETURN(rv);
237
+ if( opts.disp_nim && ((rv = act_disp_nims(&opts)) != 0) ) FREE_RETURN(rv);
238
+ if( opts.disp_ana && ((rv = act_disp_anas(&opts)) != 0) ) FREE_RETURN(rv);
239
+
240
+ FREE_RETURN(0);
241
+ }
242
+
243
+ /*----------------------------------------------------------------------
244
+ * process user options, return 0 on success
245
+ *----------------------------------------------------------------------*/
246
+ int process_opts( int argc, char * argv[], nt_opts * opts )
247
+ {
248
+ int ac;
249
+
250
+ memset(opts, 0, sizeof(*opts));
251
+
252
+ opts->prefix = NULL;
253
+ opts->debug = 1; /* init debug level to basic output */
254
+
255
+ /* init options for creating a new dataset via "MAKE_IM" */
256
+ opts->new_datatype = NIFTI_TYPE_INT16;
257
+ opts->new_dim[0] = 3;
258
+ opts->new_dim[1] = 1; opts->new_dim[2] = 1; opts->new_dim[3] = 1;
259
+
260
+ if( argc < 2 ) return usage(argv[0], USE_FULL);
261
+
262
+ /* terminal options are first, the rest are sorted */
263
+ for( ac = 1; ac < argc; ac++ )
264
+ {
265
+ if( ! strncmp(argv[ac], "-help_datatypes", 9) )
266
+ {
267
+ ac++;
268
+ if( ac >= argc )
269
+ nifti_disp_type_list(3); /* show all types */
270
+ else if( argv[ac][0] == 'd' || argv[ac][0] == 'D' )
271
+ nifti_disp_type_list(1); /* show DT_* types */
272
+ else if( argv[ac][0] == 't' || argv[ac][0] == 'T' )
273
+ nifti_test_datatype_sizes(1); /* test each nbyper and swapsize */
274
+ else
275
+ nifti_disp_type_list(2); /* show NIFTI_* types */
276
+ return 1;
277
+ }
278
+ else if( ! strncmp(argv[ac], "-help_hdr", 9) )
279
+ return usage(argv[0], USE_FIELD_HDR);
280
+ else if( ! strncmp(argv[ac], "-help_nim", 9) )
281
+ return usage(argv[0], USE_FIELD_NIM);
282
+ else if( ! strncmp(argv[ac], "-help_ana", 9) )
283
+ return usage(argv[0], USE_FIELD_ANA);
284
+ else if( ! strncmp(argv[ac], "-help", 5) )
285
+ return usage(argv[0], USE_FULL);
286
+ else if( ! strncmp(argv[ac], "-hist", 5) )
287
+ return usage(argv[0], USE_HIST);
288
+ else if( ! strncmp(argv[ac], "-ver", 2) )
289
+ return usage(argv[0], USE_VERSION);
290
+ else if( ! strncmp(argv[ac], "-nifti_hist", 11) )
291
+ {
292
+ nifti_disp_lib_hist();
293
+ return 1;
294
+ }
295
+ else if( ! strncmp(argv[ac], "-nifti_ver", 10) )
296
+ {
297
+ nifti_disp_lib_version();
298
+ return 1;
299
+ }
300
+ else if( ! strncmp(argv[ac], "-with_zlib", 5) ) {
301
+ printf("Was NIfTI library compiled with zlib? %s\n",
302
+ nifti_compiled_with_zlib() ? "YES" : "NO");
303
+ return 1;
304
+ }
305
+
306
+ /* begin normal execution options... */
307
+ else if( ! strncmp(argv[ac], "-add_afni_ext", 9) )
308
+ {
309
+ ac++;
310
+ CHECK_NEXT_OPT(ac, argc, "-add_afni_ext");
311
+ if( add_string(&opts->elist, argv[ac]) ) return -1; /* add extension */
312
+ if( add_int(&opts->etypes, NIFTI_ECODE_AFNI) ) return -1;
313
+ opts->add_exts = 1;
314
+ }
315
+ else if( ! strncmp(argv[ac], "-add_comment_ext", 9) )
316
+ {
317
+ ac++;
318
+ CHECK_NEXT_OPT(ac, argc, "-add_comment_ext");
319
+ if( add_string(&opts->elist, argv[ac]) ) return -1; /* add extension */
320
+ if( add_int(&opts->etypes, NIFTI_ECODE_COMMENT) ) return -1;
321
+ opts->add_exts = 1;
322
+ }
323
+ else if( ! strncmp(argv[ac], "-check_hdr", 10) )
324
+ opts->check_hdr = 1;
325
+ else if( ! strncmp(argv[ac], "-check_nim", 10) )
326
+ opts->check_nim = 1;
327
+ else if( ! strncmp(argv[ac], "-copy_brick_list", 11) ||
328
+ ! strncmp(argv[ac], "-copy_im", 10) ||
329
+ ! strncmp(argv[ac], "-cbl", 4) )
330
+ {
331
+ opts->cbl = 1;
332
+ }
333
+ else if( ! strncmp(argv[ac], "-copy_collapsed_image", 10) ||
334
+ ! strncmp(argv[ac], "-cci", 4) )
335
+ {
336
+ /* we need to read in the 7 dimension values */
337
+ int index;
338
+ opts->ci_dims[0] = 0;
339
+ for( index = 1; index < 8; index++ )
340
+ {
341
+ ac++;
342
+ CHECK_NEXT_OPT_MSG(ac,argc,"-cci","7 dimension values are requred");
343
+ if( ! isdigit(argv[ac][0]) && strcmp(argv[ac],"-1") ){
344
+ fprintf(stderr,"** -cci param %d (= '%s') is not a valid\n"
345
+ " consider: 'nifti_tool -help'\n",index,argv[ac]);
346
+ return -1;
347
+ }
348
+ opts->ci_dims[index] = atoi(argv[ac]);
349
+ }
350
+
351
+ opts->cci = 1;
352
+ }
353
+ else if( ! strncmp(argv[ac], "-debug", 6) )
354
+ {
355
+ ac++;
356
+ CHECK_NEXT_OPT(ac, argc, "-debug");
357
+ opts->debug = atoi(argv[ac]);
358
+ }
359
+ else if( ! strncmp(argv[ac], "-diff_hdr", 8) )
360
+ opts->diff_hdr = 1;
361
+ else if( ! strncmp(argv[ac], "-diff_nim", 8) )
362
+ opts->diff_nim = 1;
363
+ else if( ! strncmp(argv[ac], "-disp_exts", 7) )
364
+ opts->disp_exts = 1;
365
+ else if( ! strncmp(argv[ac], "-disp_hdr", 8) )
366
+ opts->disp_hdr = 1;
367
+ else if( ! strncmp(argv[ac], "-disp_nim", 8) )
368
+ opts->disp_nim = 1;
369
+ else if( ! strncmp(argv[ac], "-disp_ana", 8) )
370
+ opts->disp_ana = 1;
371
+ else if( ! strncmp(argv[ac], "-dci_lines", 6) || /* before -dts */
372
+ ! strncmp(argv[ac], "-dts_lines", 6) )
373
+ {
374
+ opts->dci_lines = 1;
375
+ }
376
+ else if( ! strncmp(argv[ac], "-disp_collapsed_image", 10) ||
377
+ ! strncmp(argv[ac], "-disp_ci", 8) )
378
+ {
379
+ /* we need to read in the 7 dimension values */
380
+ int index;
381
+ opts->ci_dims[0] = 0;
382
+ for( index = 1; index < 8; index++ )
383
+ {
384
+ ac++;
385
+ CHECK_NEXT_OPT_MSG(ac,argc,"-disp_ci",
386
+ "7 dimension values are requred");
387
+ if( ! isdigit(argv[ac][0]) && strcmp(argv[ac],"-1") ){
388
+ fprintf(stderr,"** -disp_ci param %d (= '%s') is not a valid\n"
389
+ " consider: 'nifti_tool -help'\n",index,argv[ac]);
390
+ return -1;
391
+ }
392
+ opts->ci_dims[index] = atoi(argv[ac]);
393
+ }
394
+
395
+ opts->dci = 1;
396
+ }
397
+ else if( ! strncmp(argv[ac], "-disp_ts", 10) ||
398
+ ! strncmp(argv[ac], "-dts", 4) )
399
+ {
400
+ /* we need to read in the ijk indices into the ci_dims array */
401
+ int index;
402
+ for( index = 1; index <= 3; index++ )
403
+ {
404
+ ac++;
405
+ CHECK_NEXT_OPT_MSG(ac,argc,"-dts","i,j,k indices are requied\n");
406
+ if( ! isdigit(argv[ac][0]) ){
407
+ fprintf(stderr,"** -dts param %d (= '%s') is not a number\n"
408
+ " consider: 'nifti_tool -help'\n",index,argv[ac]);
409
+ return -1;
410
+ }
411
+ opts->ci_dims[index] = atoi(argv[ac]);
412
+ }
413
+ /* and fill the rest of the array */
414
+ opts->ci_dims[0] = 0;
415
+ for( index = 4; index < 8; index++ ) opts->ci_dims[index] = -1;
416
+
417
+ opts->dts = 1;
418
+ }
419
+ else if( ! strncmp(argv[ac], "-field", 2) )
420
+ {
421
+ ac++;
422
+ CHECK_NEXT_OPT(ac, argc, "-field");
423
+ if( add_string(&opts->flist, argv[ac]) ) return -1; /* add field */
424
+ }
425
+ else if( ! strncmp(argv[ac], "-infiles", 3) )
426
+ {
427
+ int count;
428
+ /* for -infiles, get all next arguments until a '-' or done */
429
+ ac++;
430
+ for( count = 0; (ac < argc) && (argv[ac][0] != '-'); ac++, count++ )
431
+ if( add_string(&opts->infiles, argv[ac]) ) return -1;/* add field */
432
+ if( count > 0 && ac < argc ) ac--; /* more options to process */
433
+ if( g_debug > 2 ) fprintf(stderr,"+d have %d file names\n", count);
434
+ }
435
+ else if( ! strncmp(argv[ac], "-make_image", 8) )
436
+ {
437
+ opts->make_im = 1; /* will setup later, as -cbl and MAKE_IM */
438
+ }
439
+ else if( ! strncmp(argv[ac], "-mod_field", 6) )
440
+ {
441
+ ac++;
442
+ CHECK_NEXT_OPT(ac, argc, "-mod_field");
443
+ if( add_string(&opts->flist, argv[ac]) ) return -1; /* add field */
444
+ ac++;
445
+ CHECK_NEXT_OPT(ac, argc, "-mod_field (2)");
446
+ if( add_string(&opts->vlist, argv[ac]) ) return -1; /* add value */
447
+ }
448
+ else if( ! strncmp(argv[ac], "-mod_hdr", 7) )
449
+ opts->mod_hdr = 1;
450
+ else if( ! strncmp(argv[ac], "-mod_nim", 7) )
451
+ opts->mod_nim = 1;
452
+ else if( ! strncmp(argv[ac], "-keep_hist", 5) )
453
+ opts->keep_hist = 1;
454
+ else if( ! strncmp(argv[ac], "-new_dim", 8) )
455
+ {
456
+ /* we need to read in the 8 dimension values */
457
+ int index;
458
+ for( index = 0; index < 8; index++ )
459
+ {
460
+ ac++;
461
+ CHECK_NEXT_OPT_MSG(ac,argc,"-new_dim","8 dim values are requred");
462
+ if( ! isdigit(argv[ac][0]) && strcmp(argv[ac],"-1") ){
463
+ fprintf(stderr,"** -new_dim param %d (= '%s') is not a valid\n"
464
+ " consider: 'nifti_tool -help'\n",index,argv[ac]);
465
+ return -1;
466
+ }
467
+ opts->new_dim[index] = atoi(argv[ac]);
468
+ }
469
+ }
470
+ else if( ! strncmp(argv[ac], "-new_datatype", 10) )
471
+ {
472
+ ac++;
473
+ CHECK_NEXT_OPT(ac, argc, "-new_datatype");
474
+ opts->new_datatype = atoi(argv[ac]);
475
+ }
476
+ else if( ! strncmp(argv[ac], "-overwrite", 6) )
477
+ opts->overwrite = 1;
478
+ else if( ! strncmp(argv[ac], "-prefix", 4) )
479
+ {
480
+ ac++;
481
+ CHECK_NEXT_OPT(ac, argc, "-prefix");
482
+ opts->prefix = argv[ac];
483
+ }
484
+ else if( ! strncmp(argv[ac], "-quiet", 3) )
485
+ opts->debug = 0;
486
+ else if( ! strncmp(argv[ac], "-rm_ext", 7) )
487
+ {
488
+ ac++;
489
+ CHECK_NEXT_OPT(ac, argc, "-rm_ext");
490
+ if( strcmp(argv[ac],"ALL") == 0 ) /* special case, pass -1 */
491
+ {
492
+ if( add_string(&opts->elist, "-1") ) return -1;
493
+ }
494
+ else
495
+ {
496
+ int index = atoi(argv[ac]);
497
+ if( (index != -1) && ((index > 1000) || !isdigit(*argv[ac])) ){
498
+ fprintf(stderr,
499
+ "** '-rm_ext' requires an extension index (read '%s')\n",
500
+ argv[ac]);
501
+ return -1;
502
+ }
503
+ if( add_string(&opts->elist, argv[ac]) ) return -1;
504
+ }
505
+ opts->rm_exts = 1;
506
+ }
507
+ else if( ! strncmp(argv[ac], "-strip_extras", 6) )
508
+ opts->strip = 1;
509
+ else if( ! strncmp(argv[ac], "-swap_as_analyze", 12) )
510
+ opts->swap_ana = 1;
511
+ else if( ! strncmp(argv[ac], "-swap_as_nifti", 12) )
512
+ opts->swap_hdr = 1;
513
+ else if( ! strncmp(argv[ac], "-swap_as_old", 12) )
514
+ opts->swap_old = 1;
515
+ else
516
+ {
517
+ fprintf(stderr,"** unknown option: '%s'\n", argv[ac]);
518
+ return -1;
519
+ }
520
+ }
521
+
522
+ if( opts->make_im )
523
+ {
524
+ if( opts->infiles.len > 0 )
525
+ {
526
+ fprintf(stderr,"** -infiles is invalid when using -make_im\n");
527
+ return -1;
528
+ }
529
+ /* apply -make_im via -cbl and "MAKE_IM" */
530
+ opts->cbl = 1;
531
+ if( add_string(&opts->infiles, NT_MAKE_IM_NAME) ) return -1;
532
+ }
533
+
534
+ /* verify for programming purposes */
535
+ if( opts->add_exts && ( opts->elist.len != opts->etypes.len ) )
536
+ {
537
+ fprintf(stderr,"** ext list length (%d) != etype length (%d)\n",
538
+ opts->elist.len, opts->etypes.len);
539
+ return -1;
540
+ }
541
+
542
+ g_debug = opts->debug;
543
+ nifti_set_debug_level(g_debug);
544
+
545
+ fill_cmd_string(opts, argc, argv); /* copy this command */
546
+
547
+ if( g_debug > 2 ) disp_nt_opts("options read: ", opts);
548
+
549
+ return 0;
550
+ }
551
+
552
+
553
+ /*----------------------------------------------------------------------
554
+ * verify that the options make sense
555
+ *----------------------------------------------------------------------*/
556
+ int verify_opts( nt_opts * opts, char * prog )
557
+ {
558
+ int ac, errs = 0; /* number of requested action types */
559
+
560
+ /* check that only one of disp, diff, mod or add_*_ext is used */
561
+ ac = (opts->check_hdr || opts->check_nim ) ? 1 : 0;
562
+ ac += (opts->diff_hdr || opts->diff_nim ) ? 1 : 0;
563
+ ac += (opts->disp_hdr || opts->disp_nim ||
564
+ opts->disp_ana || opts->disp_exts ) ? 1 : 0;
565
+ ac += (opts->mod_hdr || opts->mod_nim ) ? 1 : 0;
566
+ ac += (opts->swap_hdr || opts->swap_ana || opts->swap_old ) ? 1 : 0;
567
+ ac += (opts->add_exts || opts->rm_exts ) ? 1 : 0;
568
+ ac += (opts->strip ) ? 1 : 0;
569
+ ac += (opts->cbl ) ? 1 : 0;
570
+ ac += (opts->cci ) ? 1 : 0;
571
+ ac += (opts->dts || opts->dci ) ? 1 : 0;
572
+
573
+ if( ac < 1 )
574
+ {
575
+ fprintf(stderr,
576
+ "** no action option, so nothing to do...\n"
577
+ " (try one of '-add...', '-diff...', '-disp...' or '-mod...')\n"
578
+ " (see '%s -help' for details)\n", prog);
579
+ return 1;
580
+ }
581
+ else if( ac > 1 )
582
+ {
583
+ fprintf(stderr,
584
+ "** only one action option is allowed, please use only one of:\n"
585
+ " '-add_...', '-check_...', '-diff_...', '-disp_...',\n"
586
+ " '-mod_...', '-strip', '-dts', '-cbl' or '-cci'\n"
587
+ " (see '%s -help' for details)\n", prog);
588
+ return 1;
589
+ }
590
+
591
+ /* can modify nifti_1_header or nifti_image, but not both */
592
+ if( opts->mod_hdr && opts->mod_nim )
593
+ {
594
+ fprintf(stderr,"** cannot use both '-mod_hdr' and '-mod_nim'\n");
595
+ return 1;
596
+ }
597
+
598
+ /* can add or remove extensions, but not both */
599
+ if( opts->add_exts && opts->rm_exts )
600
+ {
601
+ fprintf(stderr,"** cannot use both '-add_*_ext' and '-rm_ext'\n");
602
+ return 1;
603
+ }
604
+ if( (opts->add_exts || opts->rm_exts) && opts->elist.len <= 0 )
605
+ {
606
+ fprintf(stderr,"** missing extensions to add or remove\n");
607
+ return 1;
608
+ }
609
+
610
+ /* if modify, then we need fields and corresponding values */
611
+ if( opts->mod_hdr || opts->mod_nim )
612
+ {
613
+ if( opts->flist.len <= 0 )
614
+ {
615
+ fprintf(stderr,"** missing field to modify (need '-mod_field' opt)\n");
616
+ return 1;
617
+ }
618
+ if( opts->flist.len != opts->vlist.len )
619
+ {
620
+ fprintf(stderr,"** error: modifying %d fields with %d values\n",
621
+ opts->flist.len, opts->vlist.len);
622
+ return 1;
623
+ }
624
+ }
625
+
626
+ /* verify the number of files given for each of 4 action types */
627
+
628
+ /* -diff_... : require nfiles == 2 */
629
+ if( opts->diff_hdr || opts->diff_nim )
630
+ {
631
+ if( opts->infiles.len != 2 )
632
+ {
633
+ fprintf(stderr,"** '-diff_XXX' options require exactly 2 inputs files\n");
634
+ return 1;
635
+ }
636
+ }
637
+ /* if we are making changes, but not overwriting... */
638
+ else if( (opts->elist.len > 0 || opts->mod_hdr || opts->mod_nim ||
639
+ opts->swap_hdr || opts->swap_ana || opts->swap_old ) &&
640
+ !opts->overwrite )
641
+ {
642
+ if( opts->infiles.len > 1 )
643
+ {
644
+ fprintf(stderr,"** without -overwrite, only one input file may be"
645
+ " modified at a time\n");
646
+ errs++;
647
+ }
648
+ else if( ! opts->prefix )
649
+ {
650
+ fprintf(stderr,"** missing -prefix for output file\n");
651
+ errs++;
652
+ }
653
+ }
654
+
655
+ if( opts->dci_lines && ! opts->dts && ! opts->dci )
656
+ {
657
+ fprintf(stderr,"** option '-dci_lines' must only be used with '-dts'\n");
658
+ errs++;
659
+ }
660
+
661
+ if( opts->infiles.len <= 0 ) /* in any case */
662
+ {
663
+ fprintf(stderr,"** missing input files (see -infiles option)\n");
664
+ errs++;
665
+ }
666
+
667
+ if ( opts->overwrite && opts->prefix )
668
+ {
669
+ fprintf(stderr, "** please specify only one of -prefix and -overwrite\n");
670
+ errs++;
671
+ }
672
+
673
+ if( errs ) return 1;
674
+
675
+ if( g_debug > 1 ) fprintf(stderr,"+d options seem valid\n");
676
+
677
+ return 0;
678
+ }
679
+
680
+
681
+ /*----------------------------------------------------------------------
682
+ * re-assemble the command string into opts->command
683
+ *----------------------------------------------------------------------*/
684
+ int fill_cmd_string( nt_opts * opts, int argc, char * argv[])
685
+ {
686
+ char * cp;
687
+ int len, remain = NT_CMD_LEN; /* NT_CMD_LEN is max command len */
688
+ int c, ac;
689
+ int has_space; /* arguments containing space must be quoted */
690
+ int skip = 0; /* counter to skip some of the arguments */
691
+
692
+ /* get the first argument separately */
693
+ len = sprintf( opts->command, "\n command: %s", argv[0] );
694
+ cp = opts->command + len;
695
+ remain -= len;
696
+
697
+ /* get the rest, with special attention to input files */
698
+ for( ac = 1; ac < argc; ac++ )
699
+ {
700
+ if( skip ){ skip--; continue; } /* then skip these arguments */
701
+
702
+ len = strlen(argv[ac]);
703
+ if( len + 3 >= remain ) { /* extra 3 for space and possible '' */
704
+ fprintf(stderr,"FCS: no space remaining for command, continuing...\n");
705
+ return 1;
706
+ }
707
+
708
+ /* put the argument in, possibly with '' */
709
+
710
+ has_space = 0;
711
+ for( c = 0; c < len-1; c++ )
712
+ if( isspace(argv[ac][c]) ){ has_space = 1; break; }
713
+ if( has_space ) len = sprintf(cp, " '%s'", argv[ac]);
714
+ else len = sprintf(cp, " %s", argv[ac]);
715
+
716
+ remain -= len;
717
+
718
+ /* infiles is okay, but after the *next* argument, we may skip files */
719
+ /* (danger, will robinson! hack alert!) */
720
+ if( !strncmp(argv[ac-1],"-infiles",3) )
721
+ {
722
+ /* if more than 4 (just to be arbitrary) input files,
723
+ include only the first and last */
724
+ if( opts->infiles.len > 4 )
725
+ skip = opts->infiles.len - 2;
726
+ }
727
+
728
+ cp += len;
729
+ }
730
+
731
+ if( g_debug > 1 ){
732
+ fprintf(stderr,"+d filled command string, %d args, %d bytes\n",
733
+ argc, (int)(cp - opts->command));
734
+ if( g_debug > 2 ) fprintf(stderr,"%s\n", opts->command);
735
+ }
736
+
737
+ return 0;
738
+ }
739
+
740
+
741
+ /*----------------------------------------------------------------------
742
+ * - only bother to alloc one pointer at a time (don't need efficiency here)
743
+ * - return 0 on success
744
+ *----------------------------------------------------------------------*/
745
+ int add_int(int_list * ilist, int val)
746
+ {
747
+ if( ilist->len == 0 ) ilist->list = NULL; /* just to be safe */
748
+ ilist->len++;
749
+ ilist->list = (int *)realloc(ilist->list,ilist->len*sizeof(int));
750
+ if( ! ilist->list ){
751
+ fprintf(stderr,"** failed to alloc %d (int *) elements\n",ilist->len);
752
+ return -1;
753
+ }
754
+
755
+ ilist->list[ilist->len-1] = val;
756
+
757
+ return 0;
758
+ }
759
+
760
+
761
+ /*----------------------------------------------------------------------
762
+ * - do not duplicate the string
763
+ * - only bother to alloc one pointer at a time (don't need efficiency here)
764
+ * - return 0 on success
765
+ *----------------------------------------------------------------------*/
766
+ int add_string(str_list * slist, char * str)
767
+ {
768
+ if( slist->len == 0 ) slist->list = NULL; /* just to be safe */
769
+ slist->len++;
770
+ slist->list = (char **)realloc(slist->list,slist->len*sizeof(char *));
771
+ if( ! slist->list ){
772
+ fprintf(stderr,"** failed to alloc %d (char *) elements\n",slist->len);
773
+ return -1;
774
+ }
775
+
776
+ slist->list[slist->len-1] = str;
777
+
778
+ return 0;
779
+ }
780
+
781
+
782
+ /*----------------------------------------------------------------------
783
+ * display information on using the program
784
+ *----------------------------------------------------------------------*/
785
+ int usage(char * prog, int level)
786
+ {
787
+ int c, len;
788
+ if( level == USE_SHORT )
789
+ {
790
+ fprintf(stdout,"usage %s [options] -infiles files...\n", prog);
791
+ fprintf(stdout,"usage %s -help\n", prog);
792
+ return -1;
793
+ }
794
+ else if( level == USE_FULL )
795
+ use_full("nifti_tool"); /* let's not allow paths in here */
796
+ else if( level == USE_HIST )
797
+ {
798
+ len = sizeof(g_history)/sizeof(char *);
799
+ for( c = 0; c < len; c++)
800
+ fputs(g_history[c], stdout);
801
+ }
802
+ else if( level == USE_FIELD_HDR )
803
+ {
804
+ field_s nhdr_fields[NT_HDR_NUM_FIELDS]; /* just do it all here */
805
+
806
+ fill_hdr_field_array(nhdr_fields);
807
+ disp_field_s_list("nifti_1_header: ", nhdr_fields, NT_HDR_NUM_FIELDS);
808
+ }
809
+ else if( level == USE_FIELD_ANA )
810
+ {
811
+ field_s nhdr_fields[NT_ANA_NUM_FIELDS]; /* just do it all here */
812
+
813
+ fill_ana_field_array(nhdr_fields);
814
+ disp_field_s_list("nifti_analyze75: ",nhdr_fields,NT_ANA_NUM_FIELDS);
815
+ }
816
+ else if( level == USE_FIELD_NIM )
817
+ {
818
+ field_s nim_fields[NT_NIM_NUM_FIELDS];
819
+
820
+ fill_nim_field_array(nim_fields);
821
+ disp_field_s_list("nifti_image: ", nim_fields, NT_NIM_NUM_FIELDS);
822
+ }
823
+ else if( level == USE_VERSION )
824
+ fprintf(stdout, "%s, %s\n", prog, g_version);
825
+ else {
826
+ fprintf(stdout,"** illegal level for usage(): %d\n", level);
827
+ return -1;
828
+ }
829
+
830
+ return 1;
831
+ }
832
+
833
+
834
+ /*----------------------------------------------------------------------
835
+ * full usage
836
+ *----------------------------------------------------------------------*/
837
+ int use_full(char * prog)
838
+ {
839
+ printf(
840
+ "nifti_tool\n"
841
+ "\n"
842
+ " - display, modify or compare nifti structures in datasets\n"
843
+ " - copy a dataset by selecting a list of volumes from the original\n"
844
+ " - copy a dataset, collapsing any dimensions, each to a single index\n"
845
+ " - display a time series for a voxel, or more generally, the data\n"
846
+ " from any collapsed image, in ASCII text\n");
847
+ printf(
848
+ "\n"
849
+ " This program can be used to display information from nifti datasets,\n"
850
+ " to modify information in nifti datasets, to look for differences\n"
851
+ " between two nifti datasets (like the UNIX 'diff' command), and to copy\n"
852
+ " a dataset to a new one, either by restricting any dimensions, or by\n"
853
+ " copying a list of volumes (the time dimension) from a dataset.\n"
854
+ "\n");
855
+ printf(
856
+ " Only one action type is allowed, e.g. one cannot modify a dataset\n"
857
+ " and then take a 'diff'.\n"
858
+ "\n");
859
+ printf(
860
+ " one can display - any or all fields in the nifti_1_header structure\n"
861
+ " - any or all fields in the nifti_image structure\n"
862
+ " - any or all fields in the nifti_analyze75 structure\n"
863
+ " - the extensions in the nifti_image structure\n"
864
+ " - the time series from a 4-D dataset, given i,j,k\n"
865
+ " - the data from any collapsed image, given dims. list\n"
866
+ "\n");
867
+ printf(
868
+ " one can check - perform internal check on the nifti_1_header struct\n"
869
+ " (by nifti_hdr_looks_good())\n"
870
+ " - perform internal check on the nifti_image struct\n"
871
+ " (by nifti_nim_is_valid())\n"
872
+ "\n");
873
+ printf(
874
+ " one can modify - any or all fields in the nifti_1_header structure\n"
875
+ " - any or all fields in the nifti_image structure\n"
876
+ " - swap all fields in NIFTI or ANALYZE header structure\n"
877
+ " add/rm - any or all extensions in the nifti_image structure\n"
878
+ " remove - all extensions and descriptions from the datasets\n"
879
+ "\n");
880
+ printf(
881
+ " one can compare - any or all field pairs of nifti_1_header structures\n"
882
+ " - any or all field pairs of nifti_image structures\n"
883
+ "\n"
884
+ " one can copy - an arbitrary list of dataset volumes (time points)\n"
885
+ " - a dataset, collapsing across arbitrary dimensions\n"
886
+ " (restricting those dimensions to the given indices)\n"
887
+ "\n"
888
+ " one can create - a new dataset out of nothing\n"
889
+ "\n");
890
+ printf(
891
+ " Note: to learn about which fields exist in either of the structures,\n"
892
+ " or to learn a field's type, size of each element, or the number\n"
893
+ " of elements in the field, use either the '-help_hdr' option, or\n"
894
+ " the '-help_nim' option. No further options are required.\n"
895
+ " ------------------------------\n");
896
+ printf(
897
+ "\n"
898
+ " usage styles:\n"
899
+ "\n"
900
+ " nifti_tool -help : show this help\n"
901
+ " nifti_tool -help_hdr : show nifti_1_header field info\n"
902
+ " nifti_tool -help_nim : show nifti_image field info\n"
903
+ " nifti_tool -help_ana : show nifti_analyze75 field info\n"
904
+ " nifti_tool -help_datatypes : show datatype table\n"
905
+ "\n");
906
+ printf(
907
+ " nifti_tool -ver : show the current version\n"
908
+ " nifti_tool -hist : show the modification history\n"
909
+ " nifti_tool -nifti_ver : show the nifti library version\n"
910
+ " nifti_tool -nifti_hist : show the nifti library history\n"
911
+ " nifti_tool -with_zlib : was library compiled with zlib\n"
912
+ "\n"
913
+ "\n");
914
+ printf(
915
+ " nifti_tool -check_hdr -infiles f1 ...\n"
916
+ " nifti_tool -check_nim -infiles f1 ...\n"
917
+ "\n");
918
+ printf(
919
+ " nifti_tool -copy_brick_list -infiles f1'[indices...]'\n"
920
+ " nifti_tool -copy_collapsed_image I J K T U V W -infiles f1\n"
921
+ " nifti_tool -copy_im -infiles f1\n"
922
+ "\n");
923
+ printf(
924
+ " nifti_tool -make_im -prefix new_im.nii\n"
925
+ "\n");
926
+ printf(
927
+ " nifti_tool -disp_hdr [-field FIELDNAME] [...] -infiles f1 ...\n"
928
+ " nifti_tool -disp_nim [-field FIELDNAME] [...] -infiles f1 ...\n"
929
+ " nifti_tool -disp_ana [-field FIELDNAME] [...] -infiles f1 ...\n"
930
+ " nifti_tool -disp_exts -infiles f1 ...\n"
931
+ " nifti_tool -disp_ts I J K [-dci_lines] -infiles f1 ...\n"
932
+ " nifti_tool -disp_ci I J K T U V W [-dci_lines] -infiles f1 ...\n"
933
+ "\n");
934
+ printf(
935
+ " nifti_tool -mod_hdr [-mod_field FIELDNAME NEW_VAL] [...] -infiles f1\n"
936
+ " nifti_tool -mod_nim [-mod_field FIELDNAME NEW_VAL] [...] -infiles f1\n"
937
+ "\n"
938
+ " nifti_tool -swap_as_nifti -overwrite -infiles f1\n"
939
+ " nifti_tool -swap_as_analyze -overwrite -infiles f1\n"
940
+ " nifti_tool -swap_as_old -overwrite -infiles f1\n"
941
+ "\n");
942
+ printf(
943
+ " nifti_tool -add_afni_ext 'extension in quotes' [...] -infiles f1\n"
944
+ " nifti_tool -add_comment_ext 'extension in quotes' [...] -infiles f1\n"
945
+ " nifti_tool -add_comment_ext 'file:FILENAME' [...] -infiles f1\n"
946
+ " nifti_tool -rm_ext INDEX [...] -infiles f1 ...\n"
947
+ " nifti_tool -strip_extras -infiles f1 ...\n"
948
+ "\n");
949
+ printf(
950
+ " nifti_tool -diff_hdr [-field FIELDNAME] [...] -infiles f1 f2\n"
951
+ " nifti_tool -diff_nim [-field FIELDNAME] [...] -infiles f1 f2\n"
952
+ "\n"
953
+ " ------------------------------\n");
954
+
955
+ printf(
956
+ "\n"
957
+ " selected examples:\n"
958
+ "\n"
959
+ " A. checks header (for problems):\n"
960
+ "\n"
961
+ " 1. nifti_tool -check_hdr -infiles dset0.nii dset1.nii\n"
962
+ " 2. nifti_tool -check_hdr -infiles *.nii *.hdr\n"
963
+ " 3. nifti_tool -check_hdr -quiet -infiles *.nii *.hdr\n"
964
+ "\n");
965
+ printf(
966
+ " B. show header differences:\n"
967
+ "\n"
968
+ " 1. nifti_tool -diff_hdr -field dim -field intent_code \\\n"
969
+ " -infiles dset0.nii dset1.nii \n"
970
+ " 2. nifti_tool -diff_hdr -new_dims 3 10 20 30 0 0 0 0 \\\n"
971
+ " -infiles my_dset.nii MAKE_IM \n"
972
+ "\n"
973
+ " C. display structures or fields:\n"
974
+ "\n");
975
+ printf(
976
+ " 1. nifti_tool -disp_hdr -infiles dset0.nii dset1.nii dset2.nii\n"
977
+ " 2. nifti_tool -disp_hdr -field dim -field descrip -infiles dset.nii\n"
978
+ " 3. nifti_tool -disp_exts -infiles dset0.nii dset1.nii dset2.nii\n"
979
+ " 4. nifti_tool -disp_ts 23 0 172 -infiles dset1_time.nii\n"
980
+ " 5. nifti_tool -disp_ci 23 0 172 -1 0 0 0 -infiles dset1_time.nii\n"
981
+ "\n");
982
+ printf(
983
+ " 6. nifti_tool -disp_ana -infiles analyze.hdr\n"
984
+ " 7. nifti_tool -disp_nim -infiles nifti.nii\n"
985
+ "\n");
986
+ printf(
987
+ " D. create a new dataset from nothing:\n"
988
+ "\n"
989
+ " 1. nifti_tool -make_im -prefix new_im.nii \n"
990
+ " 2. nifti_tool -make_im -prefix float_im.nii \\\n"
991
+ " -new_dims 3 10 20 30 0 0 0 0 -new_datatype 16\n");
992
+ printf(
993
+ " 3. nifti_tool -mod_hdr -mod_field descrip 'dataset with mods' \\\n"
994
+ " -new_dims 3 10 20 30 0 0 0 0 \\\n"
995
+ " -prefix new_desc.nii -infiles MAKE_IM\n"
996
+ "\n");
997
+ printf(
998
+ " E. copy dataset, brick list or collapsed image:\n"
999
+ "\n"
1000
+ " 1. nifti_tool -copy_im -prefix new.nii -infiles dset0.nii\n"
1001
+ " 2. nifti_tool -cbl -prefix new_07.nii -infiles dset0.nii'[0,7]'\n"
1002
+ " 3. nifti_tool -cbl -prefix new_partial.nii \\\n"
1003
+ " -infiles dset0.nii'[3..$(2)]'\n"
1004
+ "\n"
1005
+ " 4. nifti_tool -cci 5 4 17 -1 -1 -1 -1 -prefix new_5_4_17.nii\n"
1006
+ " 5. nifti_tool -cci 5 0 17 -1 -1 2 -1 -keep_hist \\\n"
1007
+ " -prefix new_5_0_17_2.nii\n"
1008
+ "\n");
1009
+ printf(
1010
+ " F. modify the header (modify fields or swap entire header):\n"
1011
+ "\n"
1012
+ " 1. nifti_tool -mod_hdr -prefix dnew -infiles dset0.nii \\\n"
1013
+ " -mod_field dim '4 64 64 20 30 1 1 1 1'\n"
1014
+ " 2. nifti_tool -mod_hdr -prefix dnew -infiles dset0.nii \\\n"
1015
+ " -mod_field descrip 'beer, brats and cheese, mmmmm...'\n"
1016
+ );
1017
+ printf(
1018
+ " 3. cp old_dset.hdr nifti_swap.hdr \n"
1019
+ " nifti_tool -swap_as_nifti -overwrite -infiles nifti_swap.hdr\n"
1020
+ " 4. cp old_dset.hdr analyze_swap.hdr \n"
1021
+ " nifti_tool -swap_as_analyze -overwrite -infiles analyze_swap.hdr\n"
1022
+ " 5. nifti_tool -swap_as_old -prefix old_swap.hdr -infiles old_dset.hdr\n"
1023
+ " nifti_tool -diff_hdr -infiles nifti_swap.hdr old_swap.hdr\n"
1024
+ "\n");
1025
+ printf(
1026
+ " G. strip, add or remove extensions:\n"
1027
+ " (in example #3, the extension is copied from a text file)\n"
1028
+ "\n"
1029
+ "\n"
1030
+ " 1. nifti_tool -strip -overwrite -infiles *.nii\n"
1031
+ " 2. nifti_tool -add_comment 'converted from MY_AFNI_DSET+orig' \\\n"
1032
+ " -prefix dnew -infiles dset0.nii\n"
1033
+ );
1034
+ printf(
1035
+ " 3. nifti_tool -add_comment 'file:my.extension.txt' \\\n"
1036
+ " -prefix dnew -infiles dset0.nii\n"
1037
+ " 4. nifti_tool -rm_ext ALL -prefix dset1 -infiles dset0.nii\n"
1038
+ " 5. nifti_tool -rm_ext 2 -rm_ext 3 -rm_ext 5 -overwrite \\\n"
1039
+ " -infiles dset0.nii\n"
1040
+ "\n"
1041
+ " ------------------------------\n");
1042
+ printf(
1043
+ "\n"
1044
+ " options for check actions:\n"
1045
+ "\n");
1046
+ printf(
1047
+ " -check_hdr : check for a valid nifti_1_header struct\n"
1048
+ "\n"
1049
+ " This action is used to check the nifti_1_header structure for\n"
1050
+ " problems. The nifti_hdr_looks_good() function is used for the\n"
1051
+ " test, and currently checks:\n"
1052
+ " \n"
1053
+ " dim[], sizeof_hdr, magic, datatype\n"
1054
+ " \n"
1055
+ " More tests can be requested of the author.\n"
1056
+ "\n");
1057
+ printf(
1058
+ " e.g. perform checks on the headers of some datasets\n"
1059
+ " nifti_tool -check_hdr -infiles dset0.nii dset1.nii\n"
1060
+ " nifti_tool -check_hdr -infiles *.nii *.hdr\n"
1061
+ " \n"
1062
+ " e.g. add the -quiet option, so that only erros are reported\n"
1063
+ " nifti_tool -check_hdr -quiet -infiles *.nii *.hdr\n"
1064
+ "\n");
1065
+ printf(
1066
+ " -check_nim : check for a valid nifti_image struct\n"
1067
+ "\n"
1068
+ " This action is used to check the nifti_image structure for\n"
1069
+ " problems. This is tested via both nifti_convert_nhdr2nim()\n"
1070
+ " and nifti_nim_is_valid(), though other functions are called\n"
1071
+ " below them, of course. Current checks are:\n"
1072
+ "\n");
1073
+ printf(
1074
+ " dim[], sizeof_hdr, datatype, fname, iname, nifti_type\n"
1075
+ " \n"
1076
+ " Note that creation of a nifti_image structure depends on good\n"
1077
+ " header fields. So errors are terminal, meaning this check would\n"
1078
+ " probably report at most one error, even if more exist. The\n"
1079
+ " -check_hdr action is more complete.\n"
1080
+ "\n");
1081
+ printf(
1082
+ " More tests can be requested of the author.\n"
1083
+ "\n");
1084
+ printf(
1085
+ " e.g. nifti_tool -check_nim -infiles dset0.nii dset1.nii\n"
1086
+ " e.g. nifti_tool -check_nim -infiles *.nii *.hdr\n"
1087
+ "\n");
1088
+ printf(
1089
+ " ------------------------------\n");
1090
+
1091
+ printf(
1092
+ "\n"
1093
+ " options for create action:\n"
1094
+ "\n");
1095
+ printf(
1096
+ " -make_im : create a new dataset from nothing\n"
1097
+ "\n"
1098
+ " With this the user can create a new dataset of a basic style,\n"
1099
+ " which can then be modified with other options. This will create\n"
1100
+ " zero-filled data of the appropriate size.\n"
1101
+ " \n");
1102
+ printf(
1103
+ " The default is a 1x1x1 image of shorts. These settings can be\n"
1104
+ " modified with the -new_dim option, to set the 8 dimension values,\n"
1105
+ " and the -new_datatype, to provide the integral type for the data.\n"
1106
+ "\n");
1107
+ printf(
1108
+ " See -new_dim, -new_datatype and -infiles for more information.\n"
1109
+ " \n"
1110
+ " Note that any -infiles dataset of the name MAKE_IM will also be\n"
1111
+ " created on the fly.\n"
1112
+ "\n");
1113
+ printf(
1114
+ " -new_dim D0 .. D7 : specify the dim array for the a new dataset.\n"
1115
+ "\n"
1116
+ " e.g. -new_dim 4 64 64 27 120 0 0 0\n"
1117
+ "\n"
1118
+ " This dimension list will apply to any dataset created via\n"
1119
+ " MAKE_IM or -make_im. All 8 values are required. Recall that\n"
1120
+ " D0 is the number of dimensions, and D1 through D7 are the sizes.\n"
1121
+ " \n");
1122
+ printf(
1123
+ " -new_datatype TYPE : specify the dim array for the a new dataset.\n"
1124
+ "\n"
1125
+ " e.g. -new_datatype 16\n"
1126
+ " default: -new_datatype 4 (short)\n"
1127
+ "\n"
1128
+ " This dimension list will apply to any dataset created via\n"
1129
+ " MAKE_IM or -make_im. TYPE should be one of the NIFTI_TYPE_*\n"
1130
+ " numbers, from nifti1.h.\n"
1131
+ " \n");
1132
+ printf(
1133
+ " ------------------------------\n");
1134
+ printf(
1135
+ "\n"
1136
+ " options for copy actions:\n"
1137
+ "\n"
1138
+ " -copy_brick_list : copy a list of volumes to a new dataset\n"
1139
+ " -cbl : (a shorter, alternative form)\n"
1140
+ " -copy_im : (a shorter, alternative form)\n"
1141
+ "\n");
1142
+ printf(
1143
+ " This action allows the user to copy a list of volumes (over time)\n"
1144
+ " from one dataset to another. The listed volumes can be in any\n"
1145
+ " order and contain repeats, but are of course restricted to\n"
1146
+ " the set of values {1, 2, ..., nt-1}, from dimension 4.\n"
1147
+ "\n");
1148
+ printf(
1149
+ " This option is a flag. The index list is specified with the input\n"
1150
+ " dataset, contained in square brackets. Note that square brackets\n"
1151
+ " are special to most UNIX shells, so they should be contained\n"
1152
+ " within single quotes. Syntax of an index list:\n"
1153
+ "\n"
1154
+ " notes:\n"
1155
+ "\n");
1156
+ printf(
1157
+ " - indices start at zero\n"
1158
+ " - indices end at nt-1, which has the special symbol '$'\n"
1159
+ " - single indices should be separated with commas, ','\n"
1160
+ " e.g. -infiles dset0.nii'[0,3,8,5,2,2,2]'\n"
1161
+ " - ranges may be specified using '..' or '-' \n");
1162
+ printf(
1163
+ " e.g. -infiles dset0.nii'[2..95]'\n"
1164
+ " e.g. -infiles dset0.nii'[2..$]'\n"
1165
+ " - ranges may have step values, specified in ()\n"
1166
+ " example: 2 through 95 with a step of 3, i.e. {2,5,8,11,...,95}\n"
1167
+ " e.g. -infiles dset0.nii'[2..95(3)]'\n"
1168
+ "\n");
1169
+ printf(
1170
+ " This functionality applies only to 3 or 4-dimensional datasets.\n"
1171
+ "\n"
1172
+ " e.g. to copy a dataset:\n"
1173
+ " nifti_tool -copy_im -prefix new.nii -infiles dset0.nii\n"
1174
+ "\n");
1175
+ printf(
1176
+ " e.g. to copy sub-bricks 0 and 7:\n"
1177
+ " nifti_tool -cbl -prefix new_07.nii -infiles dset0.nii'[0,7]'\n"
1178
+ "\n"
1179
+ " e.g. to copy an entire dataset:\n"
1180
+ " nifti_tool -cbl -prefix new_all.nii -infiles dset0.nii'[0..$]'\n"
1181
+ "\n");
1182
+ printf(
1183
+ " e.g. to copy every other time point, skipping the first three:\n"
1184
+ " nifti_tool -cbl -prefix new_partial.nii \\\n"
1185
+ " -infiles dset0.nii'[3..$(2)]'\n"
1186
+ "\n"
1187
+ "\n"
1188
+ " -copy_collapsed_image ... : copy a list of volumes to a new dataset\n"
1189
+ " -cci I J K T U V W : (a shorter, alternative form)\n"
1190
+ "\n");
1191
+ printf(
1192
+ " This action allows the user to copy a collapsed dataset, where\n"
1193
+ " some dimensions are collapsed to a given index. For instance, the\n"
1194
+ " X dimension could be collapsed to i=42, and the time dimensions\n"
1195
+ " could be collapsed to t=17. To collapse a dimension, set Di to\n"
1196
+ " the desired index, where i is in {0..ni-1}. Any dimension that\n"
1197
+ " should not be collapsed must be listed as -1.\n"
1198
+ "\n");
1199
+ printf(
1200
+ " Any number (of valid) dimensions can be collapsed, even down to a\n"
1201
+ " a single value, by specifying enough valid indices. The resulting\n"
1202
+ " dataset will then have a reduced number of non-trivial dimensions.\n"
1203
+ "\n"
1204
+ " Assume dset0.nii has nim->dim[8] = { 4, 64, 64, 21, 80, 1, 1, 1 }.\n"
1205
+ " Note that this is a 4-dimensional dataset.\n"
1206
+ "\n");
1207
+ printf(
1208
+ " e.g. copy the time series for voxel i,j,k = 5,4,17\n"
1209
+ " nifti_tool -cci 5 4 17 -1 -1 -1 -1 -prefix new_5_4_17.nii\n"
1210
+ "\n"
1211
+ " e.g. read the single volume at time point 26\n"
1212
+ " nifti_tool -cci -1 -1 -1 26 -1 -1 -1 -prefix new_t26.nii\n"
1213
+ "\n");
1214
+ printf(
1215
+ " Assume dset1.nii has nim->dim[8] = { 6, 64, 64, 21, 80, 4, 3, 1 }.\n"
1216
+ " Note that this is a 6-dimensional dataset.\n"
1217
+ "\n"
1218
+ " e.g. copy all time series for voxel i,j,k = 5,0,17, with v=2\n"
1219
+ " (and add the command to the history)\n"
1220
+ " nifti_tool -cci 5 0 17 -1 -1 2 -1 -keep_hist \\\n"
1221
+ " -prefix new_5_0_17_2.nii\n"
1222
+ "\n");
1223
+ printf(
1224
+ " e.g. copy all data where i=3, j=19 and v=2\n"
1225
+ " (I do not claim to know a good reason to do this)\n"
1226
+ " nifti_tool -cci 3 19 -1 -1 -1 2 -1 -prefix new_mess.nii\n"
1227
+ "\n"
1228
+ " See '-disp_ci' for more information (which displays/prints the\n"
1229
+ " data, instead of copying it to a new dataset).\n"
1230
+ "\n"
1231
+ " ------------------------------\n");
1232
+
1233
+ printf(
1234
+ "\n"
1235
+ " options for display actions:\n"
1236
+ "\n"
1237
+ " -disp_hdr : display nifti_1_header fields for datasets\n"
1238
+ "\n"
1239
+ " This flag means the user wishes to see some of the nifti_1_header\n"
1240
+ " fields in one or more nifti datasets. The user may want to specify\n"
1241
+ " mutliple '-field' options along with this. This option requires\n"
1242
+ " one or more files input, via '-infiles'.\n"
1243
+ "\n");
1244
+ printf(
1245
+ " If no '-field' option is present, all fields will be displayed.\n"
1246
+ "\n"
1247
+ " e.g. to display the contents of all fields:\n"
1248
+ " nifti_tool -disp_hdr -infiles dset0.nii\n"
1249
+ " nifti_tool -disp_hdr -infiles dset0.nii dset1.nii dset2.nii\n"
1250
+ "\n"
1251
+ " e.g. to display the contents of select fields:\n"
1252
+ " nifti_tool -disp_hdr -field dim -infiles dset0.nii\n"
1253
+ " nifti_tool -disp_hdr -field dim -field descrip -infiles dset0.nii\n"
1254
+ "\n");
1255
+ printf(
1256
+ " -disp_nim : display nifti_image fields for datasets\n"
1257
+ "\n"
1258
+ " This flag option works the same way as the '-disp_hdr' option,\n"
1259
+ " except that the fields in question are from the nifti_image\n"
1260
+ " structure.\n"
1261
+ "\n");
1262
+ printf(
1263
+ " -disp_ana : display nifti_analyze75 fields for datasets\n"
1264
+ "\n"
1265
+ " This flag option works the same way as the '-disp_hdr' option,\n"
1266
+ " except that the fields in question are from the nifti_analyze75\n"
1267
+ " structure.\n"
1268
+ "\n");
1269
+ printf(
1270
+ " -disp_exts : display all AFNI-type extensions\n"
1271
+ "\n"
1272
+ " This flag option is used to display all nifti_1_extension data,\n"
1273
+ " for only those extensions of type AFNI (code = 4). The only\n"
1274
+ " other option used will be '-infiles'.\n"
1275
+ "\n");
1276
+ printf(
1277
+ " e.g. to display the extensions in datasets:\n"
1278
+ " nifti_tool -disp_exts -infiles dset0.nii\n"
1279
+ " nifti_tool -disp_exts -infiles dset0.nii dset1.nii dset2.nii\n"
1280
+ "\n");
1281
+ printf(
1282
+ " -disp_ts I J K : display ASCII time series at i,j,k = I,J,K\n"
1283
+ "\n"
1284
+ " This option is used to display the time series data for the voxel\n"
1285
+ " at i,j,k indices I,J,K. The data is displayed in text, either all\n"
1286
+ " on one line (the default), or as one number per line (via the\n"
1287
+ " '-dci_lines' option).\n"
1288
+ "\n");
1289
+ printf(
1290
+ " Notes:\n"
1291
+ "\n"
1292
+ " o This function applies only to 4-dimensional datasets.\n"
1293
+ " o The '-quiet' option can be used to suppress the text header,\n"
1294
+ " leaving only the data.\n"
1295
+ " o This option is short for using '-disp_ci' (display collapsed\n"
1296
+ " image), restricted to 4-dimensional datasets. i.e. :\n"
1297
+ " -disp_ci I J K -1 -1 -1 -1\n"
1298
+ "\n");
1299
+ printf(
1300
+ " e.g. to display the time series at voxel 23, 0, 172:\n"
1301
+ " nifti_tool -disp_ts 23 0 172 -infiles dset1_time.nii\n"
1302
+ " nifti_tool -disp_ts 23 0 172 -dci_lines -infiles dset1_time.nii\n"
1303
+ " nifti_tool -disp_ts 23 0 172 -quiet -infiles dset1_time.nii\n"
1304
+ "\n");
1305
+ printf(
1306
+ " -disp_collapsed_image : display ASCII values for collapsed dataset\n"
1307
+ " -disp_ci I J K T U V W : (a shorter, alternative form)\n"
1308
+ "\n"
1309
+ " This option is used to display all of the data from a collapsed\n"
1310
+ " image, given the dimension list. The data is displayed in text,\n"
1311
+ " either all on one line (the default), or as one number per line\n"
1312
+ " (by using the '-dci_lines' flag).\n"
1313
+ "\n");
1314
+ printf(
1315
+ " The '-quiet' option can be used to suppress the text header.\n"
1316
+ "\n"
1317
+ " e.g. to display the time series at voxel 23, 0, 172:\n"
1318
+ " nifti_tool -disp_ci 23 0 172 -1 0 0 0 -infiles dset1_time.nii\n"
1319
+ "\n"
1320
+ " e.g. to display z-slice 14, at time t=68:\n"
1321
+ " nifti_tool -disp_ci -1 -1 14 68 0 0 0 -infiles dset1_time.nii\n"
1322
+ "\n"
1323
+ " See '-ccd' for more information, which copies such data to a new\n"
1324
+ " dataset, instead of printing it to the terminal window.\n"
1325
+ "\n"
1326
+ " ------------------------------\n");
1327
+ printf(
1328
+ "\n"
1329
+ " options for modification actions:\n"
1330
+ "\n"
1331
+ " -mod_hdr : modify nifti_1_header fields for datasets\n"
1332
+ "\n"
1333
+ " This action is used to modify some of the nifti_1_header fields in\n"
1334
+ " one or more datasets. The user must specify a list of fields to\n"
1335
+ " modify via one or more '-mod_field' options, which include field\n"
1336
+ " names, along with the new (set of) values.\n"
1337
+ "\n");
1338
+ printf(
1339
+ " The user can modify a dataset in place, or use '-prefix' to\n"
1340
+ " produce a new dataset, to which the changes have been applied.\n"
1341
+ " It is recommended to normally use the '-prefix' option, so as not\n"
1342
+ " to ruin a dataset.\n"
1343
+ "\n");
1344
+ printf(
1345
+ " Note that some fields have a length greater than 1, meaning that\n"
1346
+ " the field is an array of numbers, or a string of characters. In\n"
1347
+ " order to modify an array of numbers, the user must provide the\n"
1348
+ " correct number of values, and contain those values in quotes, so\n"
1349
+ " that they are seen as a single option.\n"
1350
+ "\n");
1351
+ printf(
1352
+ " To modify a string field, put the string in quotes.\n"
1353
+ "\n"
1354
+ " The '-mod_field' option takes a field_name and a list of values.\n"
1355
+ "\n"
1356
+ " e.g. to modify the contents of various fields:\n"
1357
+ "\n");
1358
+ printf(
1359
+ " nifti_tool -mod_hdr -prefix dnew -infiles dset0.nii \\\n"
1360
+ " -mod_field qoffset_x -17.325\n"
1361
+ " nifti_tool -mod_hdr -prefix dnew -infiles dset0.nii \\\n"
1362
+ " -mod_field dim '4 64 64 20 30 1 1 1 1'\n"
1363
+ " nifti_tool -mod_hdr -prefix dnew -infiles dset0.nii \\\n"
1364
+ " -mod_field descrip 'beer, brats and cheese, mmmmm...'\n"
1365
+ "\n");
1366
+ printf(
1367
+ " e.g. to modify the contents of multiple fields:\n"
1368
+ " nifti_tool -mod_hdr -prefix dnew -infiles dset0.nii \\\n"
1369
+ " -mod_field qoffset_x -17.325 -mod_field slice_start 1\n"
1370
+ "\n"
1371
+ " e.g. to modify the contents of multiple files (must overwrite):\n"
1372
+ " nifti_tool -mod_hdr -overwrite -mod_field qoffset_x -17.325 \\\n"
1373
+ " -infiles dset0.nii dset1.nii\n"
1374
+ "\n");
1375
+ printf(
1376
+ " -mod_nim : modify nifti_image fields for datasets\n"
1377
+ "\n"
1378
+ " This action option is used the same way that '-mod_hdr' is used,\n"
1379
+ " except that the fields in question are from the nifti_image\n"
1380
+ " structure.\n"
1381
+ "\n");
1382
+ printf(
1383
+ " -strip_extras : remove extensions and descriptions from datasets\n"
1384
+ "\n"
1385
+ " This action is used to attempt to 'clean' a dataset of general\n"
1386
+ " text, in order to make it more anonymous. Extensions and the\n"
1387
+ " nifti_image descrip field are cleared by this action.\n"
1388
+ "\n");
1389
+ printf(
1390
+ " e.g. to strip all *.nii datasets in this directory:\n"
1391
+ " nifti_tool -strip -overwrite -infiles *.nii\n"
1392
+ "\n");
1393
+ printf(
1394
+ " -swap_as_nifti : swap the header according to nifti_1_header\n"
1395
+ "\n"
1396
+ " Perhaps a NIfTI header is mal-formed, and the user explicitly\n"
1397
+ " wants to swap it before performing other operations. This action\n"
1398
+ " will swap the field bytes under the assumption that the header is\n"
1399
+ " in the NIfTI format.\n"
1400
+ "\n");
1401
+ printf(
1402
+ " ** The recommended course of action is to make a copy of the\n"
1403
+ " dataset and overwrite the header via -overwrite. If the header\n"
1404
+ " needs such an operation, it is likely that the data would not\n"
1405
+ " otherwise be read in correctly.\n"
1406
+ "\n");
1407
+ printf(
1408
+ " -swap_as_analyze : swap the header according to nifti_analyze75\n"
1409
+ "\n"
1410
+ " Perhaps an ANALYZE header is mal-formed, and the user explicitly\n"
1411
+ " wants to swap it before performing other operations. This action\n"
1412
+ " will swap the field bytes under the assumption that the header is\n"
1413
+ " in the ANALYZE 7.5 format.\n"
1414
+ "\n");
1415
+ printf(
1416
+ " ** The recommended course of action is to make a copy of the\n"
1417
+ " dataset and overwrite the header via -overwrite. If the header\n"
1418
+ " needs such an operation, it is likely that the data would not\n"
1419
+ " otherwise be read in correctly.\n"
1420
+ "\n");
1421
+ printf(
1422
+ " -swap_as_old : swap the header using the old method\n"
1423
+ "\n"
1424
+ " As of library version 1.35 (3 Aug, 2008), nifticlib now swaps all\n"
1425
+ " fields of a NIfTI dataset (including UNUSED ones), and it swaps\n"
1426
+ " ANALYZE datasets according to the nifti_analyze75 structure.\n"
1427
+ " This is a significant different in the case of ANALYZE datasets.\n"
1428
+ "\n");
1429
+ printf(
1430
+ " The -swap_as_old option was added to compare the results of the\n"
1431
+ " swapping methods, or to undo one swapping method and replace it\n"
1432
+ " with another (such as to undo the old method and apply the new).\n"
1433
+ "\n");
1434
+ printf(" ------------------------------\n");
1435
+ printf(
1436
+ "\n"
1437
+ " options for adding/removing extensions:\n"
1438
+ "\n"
1439
+ " -add_afni_ext EXT : add an AFNI extension to the dataset\n"
1440
+ "\n"
1441
+ " This option is used to add AFNI-type extensions to one or more\n"
1442
+ " datasets. This option may be used more than once to add more than\n"
1443
+ " one extension.\n"
1444
+ "\n"
1445
+ " If EXT is of the form 'file:FILENAME', then the extension will\n"
1446
+ " be read from the file, FILENAME.\n"
1447
+ "\n");
1448
+ printf(
1449
+ " The '-prefix' option is recommended, to create a new dataset.\n"
1450
+ " In such a case, only a single file may be taken as input. Using\n"
1451
+ " '-overwrite' allows the user to overwrite the current file, or\n"
1452
+ " to add the extension(s) to multiple files, overwriting them.\n"
1453
+ "\n");
1454
+ printf(
1455
+ " e.g. to add a generic AFNI extension:\n"
1456
+ " nifti_tool -add_afni_ext 'wow, my first extension' -prefix dnew \\\n"
1457
+ " -infiles dset0.nii\n"
1458
+ "\n"
1459
+ " e.g. to add multiple AFNI extensions:\n"
1460
+ " nifti_tool -add_afni_ext 'wow, my first extension :)' \\\n"
1461
+ " -add_afni_ext 'look, my second...' \\\n"
1462
+ " -prefix dnew -infiles dset0.nii\n"
1463
+ "\n");
1464
+ printf(
1465
+ " e.g. to add an extension, and overwrite the dataset:\n"
1466
+ " nifti_tool -add_afni_ext 'some AFNI extension' -overwrite \\\n"
1467
+ " -infiles dset0.nii dset1.nii \n"
1468
+ "\n");
1469
+ printf(
1470
+ " -add_comment_ext EXT : add a COMMENT extension to the dataset\n"
1471
+ "\n"
1472
+ " This option is used to add COMMENT-type extensions to one or more\n"
1473
+ " datasets. This option may be used more than once to add more than\n"
1474
+ " one extension. This option may also be used with '-add_afni_ext'.\n"
1475
+ "\n"
1476
+ " If EXT is of the form 'file:FILENAME', then the extension will\n"
1477
+ " be read from the file, FILENAME.\n"
1478
+ "\n");
1479
+ printf(
1480
+ " The '-prefix' option is recommended, to create a new dataset.\n"
1481
+ " In such a case, only a single file may be taken as input. Using\n"
1482
+ " '-overwrite' allows the user to overwrite the current file, or\n"
1483
+ " to add the extension(s) to multiple files, overwriting them.\n"
1484
+ "\n");
1485
+ printf(
1486
+ " e.g. to add a comment about the dataset:\n"
1487
+ " nifti_tool -add_comment 'converted from MY_AFNI_DSET+orig' \\\n"
1488
+ " -prefix dnew \\\n"
1489
+ " -infiles dset0.nii\n"
1490
+ "\n");
1491
+ printf(
1492
+ " e.g. to add multiple extensions:\n"
1493
+ " nifti_tool -add_comment 'add a comment extension' \\\n"
1494
+ " -add_afni_ext 'and an AFNI XML style extension' \\\n"
1495
+ " -add_comment 'dataset copied from dset0.nii' \\\n"
1496
+ " -prefix dnew -infiles dset0.nii\n"
1497
+ "\n");
1498
+ printf(
1499
+ " -rm_ext INDEX : remove the extension given by INDEX\n"
1500
+ "\n"
1501
+ " This option is used to remove any single extension from the\n"
1502
+ " dataset. Multiple extensions require multiple options.\n"
1503
+ "\n"
1504
+ " notes - extension indices begin with 0 (zero)\n"
1505
+ " - to view the current extensions, see '-disp_exts'\n"
1506
+ " - all exensions can be removed using ALL or -1 for INDEX\n"
1507
+ "\n");
1508
+ printf(
1509
+ " e.g. to remove the extension #0:\n"
1510
+ " nifti_tool -rm_ext 0 -overwrite -infiles dset0.nii\n"
1511
+ "\n"
1512
+ " e.g. to remove ALL extensions:\n"
1513
+ " nifti_tool -rm_ext ALL -prefix dset1 -infiles dset0.nii\n"
1514
+ " nifti_tool -rm_ext -1 -prefix dset1 -infiles dset0.nii\n"
1515
+ "\n");
1516
+ printf(
1517
+ " e.g. to remove the extensions #2, #3 and #5:\n"
1518
+ " nifti_tool -rm_ext 2 -rm_ext 3 -rm_ext 5 -overwrite \\\n"
1519
+ " -infiles dset0.nii\n"
1520
+ "\n"
1521
+ " ------------------------------\n");
1522
+
1523
+ printf(
1524
+ "\n"
1525
+ " options for showing differences:\n"
1526
+ "\n"
1527
+ " -diff_hdr : display header field diffs between two datasets\n"
1528
+ "\n"
1529
+ " This option is used to find differences between two datasets.\n"
1530
+ " If any fields are different, the contents of those fields is\n"
1531
+ " displayed (unless the '-quiet' option is used).\n"
1532
+ "\n");
1533
+ printf(
1534
+ " A list of fields can be specified by using multiple '-field'\n"
1535
+ " options. If no '-field' option is given, all fields will be\n"
1536
+ " checked.\n"
1537
+ "\n"
1538
+ " Exactly two dataset names must be provided via '-infiles'.\n"
1539
+ "\n"
1540
+ " e.g. to display all nifti_1_header field differences:\n"
1541
+ " nifti_tool -diff_hdr -infiles dset0.nii dset1.nii\n"
1542
+ "\n");
1543
+ printf(
1544
+ " e.g. to display selected nifti_1_header field differences:\n"
1545
+ " nifti_tool -diff_hdr -field dim -field intent_code \\\n"
1546
+ " -infiles dset0.nii dset1.nii \n"
1547
+ "\n"
1548
+ " -diff_nim : display nifti_image field diffs between datasets\n"
1549
+ "\n"
1550
+ " This option works the same as '-diff_hdr', except that the fields\n"
1551
+ " in question are from the nifti_image structure.\n"
1552
+ "\n"
1553
+ " ------------------------------\n");
1554
+
1555
+ printf(
1556
+ "\n"
1557
+ " miscellaneous options:\n"
1558
+ "\n"
1559
+ " -debug LEVEL : set the debugging level\n"
1560
+ "\n"
1561
+ " Level 0 will attempt to operate with no screen output, but errors.\n"
1562
+ " Level 1 is the default.\n"
1563
+ " Levels 2 and 3 give progressively more infomation.\n"
1564
+ "\n"
1565
+ " e.g. -debug 2\n"
1566
+ "\n");
1567
+ printf(
1568
+ " -field FIELDNAME : provide a field to work with\n"
1569
+ "\n"
1570
+ " This option is used to provide a field to display, modify or\n"
1571
+ " compare. This option can be used along with one of the action\n"
1572
+ " options presented above.\n"
1573
+ "\n"
1574
+ " See '-disp_hdr', above, for complete examples.\n"
1575
+ "\n"
1576
+ " e.g. nifti_tool -field descrip\n"
1577
+ " e.g. nifti_tool -field descrip -field dim\n"
1578
+ "\n");
1579
+ printf(
1580
+ " -infiles file0... : provide a list of files to work with\n"
1581
+ "\n"
1582
+ " This parameter is required for any of the actions, in order to\n"
1583
+ " provide a list of files to process. If input filenames do not\n"
1584
+ " have an extension, the directory we be searched for any\n"
1585
+ " appropriate files (such as .nii or .hdr).\n"
1586
+ "\n");
1587
+ printf(
1588
+ " Note: if the filename has the form MAKE_IM, then a new dataset\n"
1589
+ " will be created, without the need for file input.\n"
1590
+ "\n");
1591
+ printf(
1592
+ " See '-mod_hdr', above, for complete examples.\n"
1593
+ "\n"
1594
+ " e.g. nifti_tool -infiles file0.nii\n"
1595
+ " e.g. nifti_tool -infiles file1.nii file2 file3.hdr\n"
1596
+ "\n");
1597
+ printf(
1598
+ " -mod_field NAME 'VALUE_LIST' : provide new values for a field\n"
1599
+ "\n"
1600
+ " This parameter is required for any the modification actions.\n"
1601
+ " If the user wants to modify any fields of a dataset, this is\n"
1602
+ " where the fields and values are specified.\n"
1603
+ "\n");
1604
+ printf(
1605
+ " NAME is a field name (in either the nifti_1_header structure or\n"
1606
+ " the nifti_image structure). If the action option is '-mod_hdr',\n"
1607
+ " then NAME must be the name of a nifti_1_header field. If the\n"
1608
+ " action is '-mod_nim', NAME must be from a nifti_image structure.\n"
1609
+ "\n");
1610
+ printf(
1611
+ " VALUE_LIST must be one or more values, as many as are required\n"
1612
+ " for the field, contained in quotes if more than one is provided.\n"
1613
+ "\n"
1614
+ " Use 'nifti_tool -help_hdr' to get a list of nifti_1_header fields\n"
1615
+ " Use 'nifti_tool -help_nim' to get a list of nifti_image fields\n"
1616
+ "\n"
1617
+ " See '-mod_hdr', above, for complete examples.\n"
1618
+ "\n");
1619
+ printf(
1620
+ " e.g. modifying nifti_1_header fields:\n"
1621
+ " -mod_field descrip 'toga, toga, toga'\n"
1622
+ " -mod_field qoffset_x 19.4 -mod_field qoffset_z -11\n"
1623
+ " -mod_field pixdim '1 0.9375 0.9375 1.2 1 1 1 1'\n"
1624
+ "\n");
1625
+ printf(
1626
+ " -keep_hist : add the command as COMMENT (to the 'history')\n"
1627
+ "\n"
1628
+ " When this option is used, the current command will be added\n"
1629
+ " as a NIFTI_ECODE_COMMENT type extension. This provides the\n"
1630
+ " ability to keep a history of commands affecting a dataset.\n"
1631
+ "\n"
1632
+ " e.g. -keep_hist\n"
1633
+ "\n");
1634
+ printf(
1635
+ " -overwrite : any modifications will be made to input files\n"
1636
+ "\n"
1637
+ " This option is used so that all field modifications, including\n"
1638
+ " extension additions or deletions, will be made to the files that\n"
1639
+ " are input.\n"
1640
+ "\n");
1641
+ printf(
1642
+ " In general, the user is recommended to use the '-prefix' option\n"
1643
+ " to create new files. But if overwriting the contents of the\n"
1644
+ " input files is prefered, this is how to do it.\n"
1645
+ "\n"
1646
+ " See '-mod_hdr' or '-add_afni_ext', above, for complete examples.\n"
1647
+ "\n"
1648
+ " e.g. -overwrite\n"
1649
+ "\n");
1650
+ printf(
1651
+ " -prefix : specify an output file to write change into\n"
1652
+ "\n"
1653
+ " This option is used to specify an output file to write, after\n"
1654
+ " modifications have been made. If modifications are being made,\n"
1655
+ " then either '-prefix' or '-overwrite' is required.\n"
1656
+ "\n"
1657
+ " If no extension is given, the output extension will be '.nii'.\n"
1658
+ "\n");
1659
+ printf(
1660
+ " e.g. -prefix new_dset\n"
1661
+ " e.g. -prefix new_dset.nii\n"
1662
+ " e.g. -prefix new_dset.hdr\n"
1663
+ "\n"
1664
+ " -quiet : report only errors or requested information\n"
1665
+ "\n"
1666
+ " This option is equivalent to '-debug 0'.\n"
1667
+ "\n"
1668
+ " ------------------------------\n");
1669
+
1670
+ printf(
1671
+ "\n"
1672
+ " basic help options:\n"
1673
+ "\n"
1674
+ " -help : show this help\n"
1675
+ "\n"
1676
+ " e.g. nifti_tool -help\n"
1677
+ "\n"
1678
+ " -help_hdr : show nifti_1_header field info\n"
1679
+ "\n"
1680
+ " e.g. nifti_tool -help_hdr\n"
1681
+ "\n"
1682
+ " -help_nim : show nifti_image field info\n"
1683
+ "\n"
1684
+ " e.g. nifti_tool -help_nim\n"
1685
+ "\n"
1686
+ " -help_ana : show nifti_analyze75 field info\n"
1687
+ "\n"
1688
+ " e.g. nifti_tool -help_ana\n"
1689
+ );
1690
+
1691
+ printf(
1692
+ "\n"
1693
+ " -help_datatypes [TYPE] : display datatype table\n"
1694
+ "\n"
1695
+ " e.g. nifti_tool -help_datatypes\n"
1696
+ " e.g. nifti_tool -help_datatypes N\n"
1697
+ "\n"
1698
+ " This displays the contents of the nifti_type_list table.\n"
1699
+ " An additional 'D' or 'N' parameter will restrict the type\n"
1700
+ " name to 'DT_' or 'NIFTI_TYPE_' names, 'T' will test.\n");
1701
+
1702
+ printf(
1703
+ "\n"
1704
+ " -ver : show the program version number\n"
1705
+ "\n"
1706
+ " e.g. nifti_tool -ver\n"
1707
+ "\n"
1708
+ " -hist : show the program modification history\n"
1709
+ "\n"
1710
+ " e.g. nifti_tool -hist\n"
1711
+ "\n");
1712
+ printf(
1713
+ " -nifti_ver : show the nifti library version number\n"
1714
+ "\n"
1715
+ " e.g. nifti_tool -nifti_ver\n"
1716
+ "\n"
1717
+ " -nifti_hist : show the nifti library modification history\n"
1718
+ "\n"
1719
+ " e.g. nifti_tool -nifti_hist\n"
1720
+ "\n"
1721
+ " -with_zlib : print whether library was compiled with zlib\n"
1722
+ "\n"
1723
+ " e.g. nifti_tool -with_zlib\n"
1724
+ "\n"
1725
+ " ------------------------------\n"
1726
+ "\n"
1727
+ " R. Reynolds\n"
1728
+ " compiled: %s\n"
1729
+ " %s\n\n",
1730
+ __DATE__, g_version );
1731
+
1732
+ return 1;
1733
+ }
1734
+
1735
+
1736
+ /*----------------------------------------------------------------------
1737
+ * display the contents of the struct and all lists
1738
+ *----------------------------------------------------------------------*/
1739
+ int disp_nt_opts(char * mesg, nt_opts * opts)
1740
+ {
1741
+ int c;
1742
+
1743
+ if( mesg ) fputs(mesg, stderr);
1744
+ if( ! opts )
1745
+ {
1746
+ fprintf(stderr,"** disp_nt_opts: missing opts\n");
1747
+ return -1;
1748
+ }
1749
+
1750
+ fprintf(stderr,"nt_opts @ %p\n"
1751
+ " check_hdr, check_nim = %d, %d\n"
1752
+ " diff_hdr, diff_nim = %d, %d\n"
1753
+ " disp_hdr, disp_nim = %d, %d\n"
1754
+ " disp_ana, disp_exts = %d, %d\n"
1755
+ " add_exts, rm_exts = %d, %d\n"
1756
+ " mod_hdr, mod_nim = %d, %d\n"
1757
+ " swap_hdr, swap_ana = %d, %d\n"
1758
+ " swap_old = %d\n"
1759
+ " cbl, cci = %d, %d\n"
1760
+ " dts, dci_lines = %d, %d\n"
1761
+ " make_im = %d\n",
1762
+ (void *)opts,
1763
+ opts->check_hdr, opts->check_nim,
1764
+ opts->diff_hdr, opts->diff_nim, opts->disp_hdr, opts->disp_nim,
1765
+ opts->disp_ana, opts->disp_exts, opts->add_exts, opts->rm_exts,
1766
+ opts->mod_hdr, opts->mod_nim,
1767
+ opts->swap_hdr, opts->swap_ana, opts->swap_old,
1768
+ opts->cbl, opts->cci,
1769
+ opts->dts, opts->dci_lines, opts->make_im );
1770
+
1771
+ fprintf(stderr," ci_dims[8] = ");
1772
+ disp_raw_data(opts->ci_dims, DT_INT32, 8, ' ', 1);
1773
+ fprintf(stderr," new_dim[8] = ");
1774
+ disp_raw_data(opts->new_dim, DT_INT32, 8, ' ', 1);
1775
+
1776
+ fprintf(stderr,"\n"
1777
+ " new_datatype = %d\n"
1778
+ " debug, keep_hist = %d, %d\n"
1779
+ " overwrite = %d\n"
1780
+ " prefix = '%s'\n",
1781
+ opts->new_datatype, opts->debug, opts->keep_hist, opts->overwrite,
1782
+ opts->prefix ? opts->prefix : "(NULL)" );
1783
+
1784
+ fprintf(stderr," elist (length %d) :\n", opts->elist.len);
1785
+ for( c = 0; c < opts->elist.len; c++ )
1786
+ fprintf(stderr," %d : %s\n", c, opts->elist.list[c]);
1787
+
1788
+ fprintf(stderr," etypes (length %d) : ", opts->etypes.len);
1789
+ disp_raw_data(opts->etypes.list, DT_INT32, opts->etypes.len, ' ', 0);
1790
+ fputc('\n',stderr);
1791
+
1792
+ fprintf(stderr," flist (length %d) :\n", opts->flist.len);
1793
+ for( c = 0; c < opts->flist.len; c++ )
1794
+ fprintf(stderr," %d : %s\n", c, opts->flist.list[c]);
1795
+
1796
+ fprintf(stderr," vlist (length %d) :\n", opts->vlist.len);
1797
+ for( c = 0; c < opts->vlist.len; c++ )
1798
+ fprintf(stderr," %d : %s\n", c, opts->vlist.list[c]);
1799
+
1800
+ fprintf(stderr," infiles (length %d) :\n", opts->infiles.len);
1801
+ for( c = 0; c < opts->infiles.len; c++ )
1802
+ fprintf(stderr," %d : %s\n", c, opts->infiles.list[c]);
1803
+
1804
+ fprintf(stderr," command len : %d\n",(int)strlen(opts->command));
1805
+
1806
+ return 0;
1807
+ }
1808
+
1809
+
1810
+ /*----------------------------------------------------------------------
1811
+ * For each file, add all extensions with type NIFTI_ECODE_AFNI.
1812
+ * Though it should not matter, copy the trailing null characters.
1813
+ *----------------------------------------------------------------------*/
1814
+ int act_add_exts( nt_opts * opts )
1815
+ {
1816
+ nifti_image * nim;
1817
+ char * ext, * edata = NULL;
1818
+ int fc, ec, elen;
1819
+
1820
+ if( g_debug > 2 ){
1821
+ fprintf(stderr,"+d adding %d extensions to %d files...\n"
1822
+ " extension types are: ",
1823
+ opts->elist.len, opts->infiles.len);
1824
+ disp_raw_data(opts->etypes.list, DT_INT32, opts->etypes.len, ' ', 1);
1825
+ }
1826
+
1827
+ if( opts->prefix && opts->infiles.len != 1 ){
1828
+ fprintf(stderr,"** error: we have a prefix but %d files\n",
1829
+ opts->infiles.len);
1830
+ return 1;
1831
+ }
1832
+
1833
+ if( opts->elist.len <= 0 ) return 0;
1834
+
1835
+ for( fc = 0; fc < opts->infiles.len; fc++ )
1836
+ {
1837
+ nim = nt_image_read( opts, opts->infiles.list[fc], 1 );
1838
+ if( !nim ) return 1; /* errors come from the library */
1839
+
1840
+ for( ec = 0; ec < opts->elist.len; ec++ ){
1841
+ ext = opts->elist.list[ec];
1842
+ elen = strlen(ext);
1843
+ if( !strncmp(ext,"file:",5) ){
1844
+ edata = read_file_text(ext+5, &elen);
1845
+ if( !edata || elen <= 0 ) {
1846
+ fprintf(stderr,"** failed to read extension data from '%s'\n",
1847
+ ext+5);
1848
+ continue;
1849
+ }
1850
+ ext = edata;
1851
+ }
1852
+
1853
+ if( nifti_add_extension(nim, ext, elen, opts->etypes.list[ec]) ){
1854
+ nifti_image_free(nim);
1855
+ return 1;
1856
+ }
1857
+
1858
+ /* if extension came from file, free the data */
1859
+ if( edata ){ free(edata); edata = NULL; }
1860
+ }
1861
+
1862
+ if( opts->keep_hist && nifti_add_extension(nim, opts->command,
1863
+ strlen(opts->command), NIFTI_ECODE_COMMENT) )
1864
+ fprintf(stderr,"** failed to add command to image as extension\n");
1865
+
1866
+ if( opts->prefix &&
1867
+ nifti_set_filenames(nim, opts->prefix, !opts->overwrite, 1) )
1868
+ {
1869
+ nifti_image_free(nim);
1870
+ return 1;
1871
+ }
1872
+
1873
+ if( g_debug > 1 )
1874
+ fprintf(stderr,"+d writing %s with %d new extension(s)\n",
1875
+ opts->infiles.list[fc], opts->elist.len);
1876
+
1877
+ nifti_image_write(nim);
1878
+ nifti_image_free(nim);
1879
+ }
1880
+
1881
+ if( g_debug > 0 )
1882
+ fprintf(stderr,"+d added %d extension(s) to %d files\n",
1883
+ opts->elist.len, opts->infiles.len);
1884
+
1885
+ return 0;
1886
+ }
1887
+
1888
+ /*----------------------------------------------------------------------
1889
+ * Return the allocated file contents.
1890
+ *----------------------------------------------------------------------*/
1891
+ static char * read_file_text(char * filename, int * length)
1892
+ {
1893
+ FILE * fp;
1894
+ char * text;
1895
+ int len, bytes;
1896
+
1897
+ if( !filename || !length ) {
1898
+ fprintf(stderr,"** bad params to read_file_text\n");
1899
+ return NULL;
1900
+ }
1901
+
1902
+ len = nifti_get_filesize(filename);
1903
+ if( len <= 0 ) {
1904
+ fprintf(stderr,"** RFT: file '%s' appears empty\n", filename);
1905
+ return NULL;
1906
+ }
1907
+
1908
+ fp = fopen(filename, "r");
1909
+ if( !fp ) {
1910
+ fprintf(stderr,"** RFT: failed to open '%s' for reading\n", filename);
1911
+ return NULL;
1912
+ }
1913
+
1914
+ /* allocate the bytes, and fill them with the file contents */
1915
+
1916
+ text = (char *)malloc(len * sizeof(char));
1917
+ if( !text ) {
1918
+ fprintf(stderr,"** RFT: failed to allocate %d bytes\n", len);
1919
+ fclose(fp);
1920
+ return NULL;
1921
+ }
1922
+
1923
+ bytes = fread(text, sizeof(char), len, fp);
1924
+ fclose(fp); /* in any case */
1925
+
1926
+ if( bytes != len ) {
1927
+ fprintf(stderr,"** RFT: read only %d of %d bytes from %s\n",
1928
+ bytes, len, filename);
1929
+ free(text);
1930
+ return NULL;
1931
+ }
1932
+
1933
+ /* success */
1934
+
1935
+ if( g_debug > 1 ) {
1936
+ fprintf(stderr,"++ found extension of length %d in file %s\n",
1937
+ len, filename);
1938
+ if( g_debug > 2 )
1939
+ fprintf(stderr,"++ text is:\n%s\n", text);
1940
+ }
1941
+
1942
+ *length = len;
1943
+
1944
+ return text;
1945
+ }
1946
+
1947
+ /*----------------------------------------------------------------------
1948
+ * For each file, strip the extra fields.
1949
+ *
1950
+ * Clear extensions and descrip field. No other generic strings will get
1951
+ * passed to nifti_1_header struct.
1952
+ *
1953
+ * - this may make the datasets more anonymous
1954
+ * - no history is appended here
1955
+ *----------------------------------------------------------------------*/
1956
+ int act_strip( nt_opts * opts )
1957
+ {
1958
+ nifti_image * nim;
1959
+ int fc;
1960
+
1961
+ if( g_debug > 2 )
1962
+ fprintf(stderr,"+d stripping extras from %d files\n", opts->infiles.len);
1963
+
1964
+ if( opts->prefix && opts->infiles.len != 1 ){
1965
+ fprintf(stderr,"** error: we have a prefix but %d files\n",
1966
+ opts->infiles.len);
1967
+ return 1;
1968
+ }
1969
+
1970
+ for( fc = 0; fc < opts->infiles.len; fc++ )
1971
+ {
1972
+ nim = nt_image_read( opts, opts->infiles.list[fc], 1 );
1973
+ if( !nim ) return 1; /* errors come from the library */
1974
+
1975
+ /* now remove the extensions */
1976
+ nifti_free_extensions(nim);
1977
+ memset(nim->descrip, 0, 80);
1978
+
1979
+ if( opts->prefix &&
1980
+ nifti_set_filenames(nim, opts->prefix, !opts->overwrite, 1) ){
1981
+ nifti_image_free(nim);
1982
+ return 1;
1983
+ }
1984
+
1985
+ if( g_debug > 1 )
1986
+ fprintf(stderr,"+d writing %s without extensions or 'descrip'\n",
1987
+ nim->fname);
1988
+
1989
+ nifti_image_write(nim);
1990
+
1991
+ if( g_debug > 3 ) nifti_image_infodump(nim);
1992
+ nifti_image_free(nim);
1993
+ }
1994
+
1995
+ if( g_debug > 0 )
1996
+ fprintf(stderr,"+d stripped extras from %d files\n", opts->infiles.len);
1997
+
1998
+ return 0;
1999
+ }
2000
+
2001
+
2002
+ /*----------------------------------------------------------------------
2003
+ * For each file, remove the given extension for the given indices.
2004
+ *
2005
+ * Note that index = -1 means to remove them all.
2006
+ *----------------------------------------------------------------------*/
2007
+ int act_rm_ext( nt_opts * opts )
2008
+ {
2009
+ nifti_image * nim;
2010
+ int fc, ext_ind, num_ext;
2011
+
2012
+ if( g_debug > 2 )
2013
+ fprintf(stderr,"+d removing %d extensions from %d files...\n",
2014
+ opts->elist.len, opts->infiles.len);
2015
+
2016
+ if( opts->elist.len <= 0 ) return 0;
2017
+
2018
+ if( opts->prefix && opts->infiles.len != 1 ){
2019
+ fprintf(stderr,"** error: we have a prefix but %d files\n",
2020
+ opts->infiles.len);
2021
+ return 1;
2022
+ }
2023
+ else if( opts->overwrite && opts->infiles.len != 1 &&
2024
+ strcmp(opts->elist.list[0], "-1") ) {
2025
+ fprintf(stderr,"** error: for multiple files, can only delete ALL\n");
2026
+ return 1;
2027
+ }
2028
+
2029
+ ext_ind = atoi(opts->elist.list[0]);
2030
+ if( ext_ind < -1 ){
2031
+ fprintf(stderr,"** bad extension index to remove: %d\n", ext_ind);
2032
+ return 1;
2033
+ }
2034
+
2035
+ if( g_debug > 1 ) fprintf(stderr,"+d removing extension index %d\n",ext_ind);
2036
+
2037
+ for( fc = 0; fc < opts->infiles.len; fc++ )
2038
+ {
2039
+ nim = nt_image_read( opts, opts->infiles.list[fc], 1 );
2040
+ if( !nim ) return 1; /* errors come from the library */
2041
+
2042
+ /* note the number of extensions for later */
2043
+ num_ext = nim->num_ext;
2044
+
2045
+ /* now remove the extensions */
2046
+ if( remove_ext_list(nim, opts->elist.list, opts->elist.len) )
2047
+ return 1;
2048
+
2049
+ if( opts->keep_hist && nifti_add_extension(nim, opts->command,
2050
+ strlen(opts->command), NIFTI_ECODE_COMMENT) )
2051
+ fprintf(stderr,"** failed to add command to image as extension\n");
2052
+
2053
+ if( opts->prefix &&
2054
+ nifti_set_filenames(nim, opts->prefix, !opts->overwrite, 1) ){
2055
+ nifti_image_free(nim);
2056
+ return 1;
2057
+ }
2058
+
2059
+ if( g_debug > 1 )
2060
+ fprintf(stderr,"+d writing %s with %d fewer extension(s)\n",
2061
+ nim->fname, ext_ind == -1 ? num_ext : opts->elist.len);
2062
+
2063
+ nifti_image_write(nim);
2064
+ nifti_image_free(nim);
2065
+ }
2066
+
2067
+ if( g_debug > 0 )
2068
+ fprintf(stderr,"+d removed %s extension(s) from %d files\n",
2069
+ ext_ind == -1 ? "ALL" : "1", opts->infiles.len);
2070
+
2071
+ return 0;
2072
+ }
2073
+
2074
+
2075
+ /*----------------------------------------------------------------------
2076
+ * remove extensions by index
2077
+ *
2078
+ * return: 0 on success, -1 on failure
2079
+ *----------------------------------------------------------------------*/
2080
+ int remove_ext_list( nifti_image * nim, char ** elist, int len )
2081
+ {
2082
+ int * marks;
2083
+ int c, ec, extval;
2084
+
2085
+ if( len > nim->num_ext ){
2086
+ fprintf(stderr, "** cannot remove %d exts from image '%s' with only %d\n",
2087
+ len, nim->fname, nim->num_ext);
2088
+ return -1;
2089
+ }
2090
+
2091
+ if( len <= 0 ){
2092
+ fprintf(stderr,"** REL: (%d) no extensions to remove?\n",len);
2093
+ return -1;
2094
+ }
2095
+
2096
+ extval = atoi(elist[0]); /* check the first value */
2097
+
2098
+ /* first special case, elist[0] == -1 */
2099
+ if( extval == -1 )
2100
+ {
2101
+ if( g_debug > 1 )
2102
+ fprintf(stderr,"+d removing ALL (%d) extensions from '%s'\n",
2103
+ nim->num_ext, nim->fname );
2104
+ nifti_free_extensions(nim);
2105
+ return 0;
2106
+ }
2107
+
2108
+ if( g_debug > 2 )
2109
+ fprintf(stderr,"+d removing %d exts from '%s'\n", len, nim->fname );
2110
+
2111
+ if( ! (marks = (int *)calloc(nim->num_ext, sizeof(int))) ) {
2112
+ fprintf(stderr,"** failed to alloc %d marks\n",nim->num_ext);
2113
+ return -1;
2114
+ }
2115
+
2116
+ /* mark all extensions for removal */
2117
+ for( ec = 0; ec < len; ec++ )
2118
+ {
2119
+ extval = atoi(elist[ec]);
2120
+
2121
+ if( extval < 0 || extval >= nim->num_ext ){
2122
+ fprintf(stderr,"** ext #%d (= %d) is out of range [0,%d] for %s\n",
2123
+ ec, extval, nim->num_ext-1, nim->fname);
2124
+ free(marks); return -1;
2125
+ }
2126
+
2127
+ if( marks[extval] ){
2128
+ fprintf(stderr,"** ext #%d (= %d) is a duplicate", ec, extval);
2129
+ free(marks); return -1;
2130
+ }
2131
+
2132
+ marks[extval]++;
2133
+ }
2134
+
2135
+ /* now remove them - count from top down to do lazy programming */
2136
+ for( ec = nim->num_ext-1; ec >= 0; ec-- )
2137
+ {
2138
+ if( !marks[ec] ) continue; /* do not delete this one */
2139
+
2140
+ if( g_debug > 2 )
2141
+ disp_nifti1_extension("+d removing ext: ",nim->ext_list+ec,-1);
2142
+
2143
+ /* delete this data, and shift the list down (yeah, inefficient) */
2144
+ if( nim->ext_list[ec].edata ) free( nim->ext_list[ec].edata );
2145
+
2146
+ /* move anything above down one */
2147
+ for( c = ec+1; c < nim->num_ext; c++ )
2148
+ nim->ext_list[c-1] = nim->ext_list[c];
2149
+
2150
+ nim->num_ext--;
2151
+ }
2152
+
2153
+ if( g_debug > 3 ) fprintf(stderr,"-d done removing extensions\n");
2154
+
2155
+ if( nim->num_ext == 0 ){ /* did we trash the only extension? */
2156
+ if( g_debug > 1 )
2157
+ fprintf(stderr,"-d removed ALL extensions from %s\n",nim->fname);
2158
+ free(nim->ext_list);
2159
+ nim->ext_list = NULL;
2160
+ }
2161
+
2162
+ return 0;
2163
+ }
2164
+
2165
+
2166
+ /*----------------------------------------------------------------------
2167
+ * check for diffs between all fields in opts->flist, or in the
2168
+ * entire nifti_1_header
2169
+ *
2170
+ * if quiet mode (debug == 0) return on first diff
2171
+ *
2172
+ * return: 1 if diffs exist, 0 otherwise
2173
+ *----------------------------------------------------------------------*/
2174
+ int act_diff_hdrs( nt_opts * opts )
2175
+ {
2176
+ nifti_1_header * nhdr0, * nhdr1;
2177
+ int diffs = 0;
2178
+
2179
+ if( opts->infiles.len != 2 ){
2180
+ fprintf(stderr,"** -diff_hdr requires 2 -infiles, have %d\n",
2181
+ opts->infiles.len);
2182
+ return 1;
2183
+ }
2184
+
2185
+ if( g_debug > 2 )
2186
+ fprintf(stderr,"-d nifti_1_header diff between %s and %s...\n",
2187
+ opts->infiles.list[0], opts->infiles.list[1]);
2188
+
2189
+ /* get the nifiti headers (but do not validate them) */
2190
+
2191
+ nhdr0 = nt_read_header(opts, opts->infiles.list[0], NULL, 0);
2192
+ if( ! nhdr0 ) return 1; /* errors have been printed */
2193
+
2194
+ nhdr1 = nt_read_header(opts, opts->infiles.list[1], NULL, 0);
2195
+ if( ! nhdr1 ){ free(nhdr0); return 1; }
2196
+
2197
+ if( g_debug > 1 )
2198
+ fprintf(stderr,"\n-d nifti_1_header diffs between '%s' and '%s'...\n",
2199
+ opts->infiles.list[0], opts->infiles.list[1]);
2200
+
2201
+ if( opts->flist.len <= 0 )
2202
+ diffs = diff_hdrs(nhdr0, nhdr1, g_debug > 0);
2203
+ else
2204
+ diffs = diff_hdrs_list(nhdr0, nhdr1, &opts->flist, g_debug > 0);
2205
+
2206
+ if( diffs == 0 && g_debug > 1 )
2207
+ fprintf(stderr,"+d no differences found\n");
2208
+ else if ( g_debug > 2 )
2209
+ fprintf(stderr,"+d %d differences found\n", diffs);
2210
+
2211
+ free(nhdr0);
2212
+ free(nhdr1);
2213
+
2214
+ return (diffs > 0);
2215
+ }
2216
+
2217
+
2218
+ /*----------------------------------------------------------------------
2219
+ * check for diffs between all fields in opts->flist, or in the
2220
+ * entire nifti_image
2221
+ *
2222
+ * if quiet mode (debug == 0) return on first diff
2223
+ *
2224
+ * return: 1 if diffs exist, 0 otherwise
2225
+ *----------------------------------------------------------------------*/
2226
+ int act_diff_nims( nt_opts * opts )
2227
+ {
2228
+ nifti_image * nim0, * nim1;
2229
+ int diffs = 0;
2230
+
2231
+ if( opts->infiles.len != 2 ){
2232
+ fprintf(stderr,"** -diff_nim requires 2 -infiles, have %d\n",
2233
+ opts->infiles.len);
2234
+ return 1;
2235
+ }
2236
+
2237
+ if( g_debug > 2 )
2238
+ fprintf(stderr,"-d nifti_image diff between %s and %s...\n",
2239
+ opts->infiles.list[0], opts->infiles.list[1]);
2240
+
2241
+ /* get the nifiti images */
2242
+
2243
+ nim0 = nt_image_read(opts, opts->infiles.list[0], 0);
2244
+ if( ! nim0 ) return 1; /* errors have been printed */
2245
+
2246
+ nim1 = nt_image_read(opts, opts->infiles.list[1], 0);
2247
+ if( ! nim1 ){ free(nim0); return 1; }
2248
+
2249
+ if( g_debug > 1 )
2250
+ fprintf(stderr,"\n-d nifti_image diffs between '%s' and '%s'...\n",
2251
+ opts->infiles.list[0], opts->infiles.list[1]);
2252
+
2253
+ if( opts->flist.len <= 0 )
2254
+ diffs = diff_nims(nim0, nim1, g_debug > 0);
2255
+ else
2256
+ diffs = diff_nims_list(nim0, nim1, &opts->flist, g_debug > 0);
2257
+
2258
+ if( diffs == 0 && g_debug > 1 )
2259
+ fprintf(stderr,"+d no differences found\n");
2260
+ else if ( g_debug > 2 )
2261
+ fprintf(stderr,"+d %d differences found\n", diffs);
2262
+
2263
+ nifti_image_free(nim0);
2264
+ nifti_image_free(nim1);
2265
+
2266
+ return (diffs > 0);
2267
+ }
2268
+
2269
+
2270
+ /*----------------------------------------------------------------------
2271
+ * for each file, read nifti1_header
2272
+ * if checking header, check it
2273
+ * if checking nifti_image, convert and check it
2274
+ *----------------------------------------------------------------------*/
2275
+ int act_check_hdrs( nt_opts * opts )
2276
+ {
2277
+ nifti_1_header * nhdr;
2278
+ nifti_image * nim;
2279
+ int filenum, rv;
2280
+
2281
+ if( g_debug > 2 )
2282
+ fprintf(stderr,"-d checking hdrs/nims for %d nifti datasets...\n",
2283
+ opts->infiles.len);
2284
+
2285
+ for( filenum = 0; filenum < opts->infiles.len; filenum++ )
2286
+ {
2287
+ /* do not validate the header structure */
2288
+ nhdr = nt_read_header(opts, opts->infiles.list[filenum], NULL, 0);
2289
+ if( !nhdr ) continue; /* errors are printed from library */
2290
+
2291
+ if( opts->check_hdr )
2292
+ {
2293
+ if( g_debug > 1 )
2294
+ fprintf(stdout,"\nchecking nifti_1_header for file '%s'\n",
2295
+ opts->infiles.list[filenum]);
2296
+
2297
+ rv = nifti_hdr_looks_good(nhdr);
2298
+
2299
+ if( rv && g_debug > 0 ) /* if quiet, no GOOD response */
2300
+ printf("header IS GOOD for file %s\n",opts->infiles.list[filenum]);
2301
+ else if( ! rv )
2302
+ printf("header FAILURE for file %s\n",opts->infiles.list[filenum]);
2303
+ }
2304
+
2305
+ if( opts->check_nim )
2306
+ {
2307
+ nim = nifti_convert_nhdr2nim(*nhdr, opts->infiles.list[filenum]);
2308
+ if( !nim ) continue; /* errors are printed from library */
2309
+
2310
+ if( g_debug > 1 )
2311
+ fprintf(stdout,"\nchecking nifti_image for file '%s'\n",
2312
+ opts->infiles.list[filenum]);
2313
+
2314
+ rv = nifti_nim_is_valid(nim, 1); /* complain about errors */
2315
+
2316
+ if( rv && g_debug > 0 ) /* if quiet, no GOOD response */
2317
+ printf("nifti_image IS GOOD for file %s\n",
2318
+ opts->infiles.list[filenum]);
2319
+ else if( ! rv )
2320
+ printf("nifti_image FAILURE for file %s\n",
2321
+ opts->infiles.list[filenum]);
2322
+
2323
+ nifti_image_free(nim);
2324
+ }
2325
+
2326
+ free(nhdr);
2327
+ }
2328
+
2329
+ return 0;
2330
+ }
2331
+
2332
+
2333
+ /*----------------------------------------------------------------------
2334
+ * display all extensions for each dataset
2335
+ *----------------------------------------------------------------------*/
2336
+ int act_disp_exts( nt_opts * opts )
2337
+ {
2338
+ nifti_image * nim;
2339
+ char mesg[32];
2340
+ int ec, fc;
2341
+
2342
+ if( g_debug > 2 )
2343
+ fprintf(stderr,"-d displaying all extensions for %d files...\n",
2344
+ opts->infiles.len);
2345
+
2346
+ for( fc = 0; fc < opts->infiles.len; fc++ )
2347
+ {
2348
+ nim = nt_image_read(opts, opts->infiles.list[fc], 0);
2349
+ if( !nim ) return 1; /* errors are printed from library */
2350
+
2351
+ if( g_debug > 0 )
2352
+ fprintf(stdout,"header file '%s', num_ext = %d\n",
2353
+ nim->fname, nim->num_ext);
2354
+ for( ec = 0; ec < nim->num_ext; ec++ )
2355
+ {
2356
+ sprintf(mesg, " ext #%d : ", ec);
2357
+ disp_nifti1_extension(mesg, nim->ext_list + ec, -1);
2358
+ }
2359
+
2360
+ nifti_image_free(nim);
2361
+ }
2362
+
2363
+ return 0;
2364
+ }
2365
+
2366
+
2367
+ /*----------------------------------------------------------------------
2368
+ * for each file, read nifti1_header and display all fields
2369
+ *----------------------------------------------------------------------*/
2370
+ int act_disp_hdrs( nt_opts * opts )
2371
+ {
2372
+ nifti_1_header * nhdr;
2373
+ field_s * fnhdr;
2374
+ char ** sptr;
2375
+ int nfields, filenum, fc;
2376
+
2377
+ /* set the number of fields to display */
2378
+ nfields = opts->flist.len > 0 ? opts->flist.len : NT_HDR_NUM_FIELDS;
2379
+
2380
+ if( g_debug > 2 )
2381
+ fprintf(stderr,"-d displaying %d fields for %d nifti datasets...\n",
2382
+ nfields, opts->infiles.len);
2383
+
2384
+ for( filenum = 0; filenum < opts->infiles.len; filenum++ )
2385
+ {
2386
+ /* do not validate the header structure */
2387
+ nhdr = nt_read_header(opts, opts->infiles.list[filenum], NULL, 0);
2388
+ if( !nhdr ) return 1; /* errors are printed from library */
2389
+
2390
+ if( g_debug > 0 )
2391
+ fprintf(stdout,"\nheader file '%s', num_fields = %d\n",
2392
+ opts->infiles.list[filenum], nfields);
2393
+ if( g_debug > 1 )
2394
+ fprintf(stderr,"-d header is: %s\n",
2395
+ nifti_hdr_looks_good(nhdr) ? "valid" : "invalid");
2396
+
2397
+ if( opts->flist.len <= 0 ) /* then display all fields */
2398
+ disp_field("\nall fields:\n", g_hdr_fields, nhdr, nfields, g_debug>0);
2399
+ else /* print only the requested fields... */
2400
+ {
2401
+ /* must locate each field before printing it */
2402
+ sptr = opts->flist.list;
2403
+ for( fc = 0; fc < opts->flist.len; fc++ )
2404
+ {
2405
+ fnhdr = get_hdr_field(*sptr, filenum == 0);
2406
+ if( fnhdr ) disp_field(NULL, fnhdr, nhdr, 1, g_debug>0 && fc == 0);
2407
+ sptr++;
2408
+ }
2409
+ }
2410
+
2411
+ free(nhdr);
2412
+ }
2413
+
2414
+ return 0;
2415
+ }
2416
+
2417
+
2418
+ /*----------------------------------------------------------------------
2419
+ * for each file, read nifti_analyze75 and display all fields
2420
+ *----------------------------------------------------------------------*/
2421
+ int act_disp_anas( nt_opts * opts )
2422
+ {
2423
+ nifti_analyze75 * nhdr;
2424
+ field_s * fnhdr;
2425
+ char ** sptr;
2426
+ int nfields, filenum, fc;
2427
+
2428
+ /* set the number of fields to display */
2429
+ nfields = opts->flist.len > 0 ? opts->flist.len : NT_ANA_NUM_FIELDS;
2430
+
2431
+ if( g_debug > 2 )
2432
+ fprintf(stderr,"-d displaying %d fields for %d ANALYZE datasets...\n",
2433
+ nfields, opts->infiles.len);
2434
+
2435
+ for( filenum = 0; filenum < opts->infiles.len; filenum++ )
2436
+ {
2437
+ /* do not validate the header structure */
2438
+ nhdr = (nifti_analyze75 *)nt_read_header(opts,
2439
+ opts->infiles.list[filenum], NULL, 0);
2440
+ if( !nhdr ) return 1; /* errors are printed from library */
2441
+
2442
+ if( g_debug > 0 )
2443
+ fprintf(stdout,"\nanalyze header file '%s', num_fields = %d\n",
2444
+ opts->infiles.list[filenum], nfields);
2445
+ if( g_debug > 1 )
2446
+ fprintf(stderr,"-d analyze header is: %s\n",
2447
+ nifti_hdr_looks_good((nifti_1_header *)nhdr) ?
2448
+ "valid" : "invalid");
2449
+
2450
+ if( opts->flist.len <= 0 ) /* then display all fields */
2451
+ disp_field("\nall fields:\n", g_ana_fields, nhdr, nfields, g_debug>0);
2452
+ else /* print only the requested fields... */
2453
+ {
2454
+ /* must locate each field before printing it */
2455
+ sptr = opts->flist.list;
2456
+ for( fc = 0; fc < opts->flist.len; fc++ )
2457
+ {
2458
+ fnhdr = get_hdr_field(*sptr, filenum == 0);
2459
+ if( fnhdr ) disp_field(NULL, fnhdr, nhdr, 1, g_debug>0 && fc == 0);
2460
+ sptr++;
2461
+ }
2462
+ }
2463
+
2464
+ free(nhdr);
2465
+ }
2466
+
2467
+ return 0;
2468
+ }
2469
+
2470
+
2471
+ /*----------------------------------------------------------------------
2472
+ * for each file, get nifti_image and display all fields
2473
+ *----------------------------------------------------------------------*/
2474
+ int act_disp_nims( nt_opts * opts )
2475
+ {
2476
+ nifti_image * nim;
2477
+ field_s * fnim;
2478
+ char ** sptr;
2479
+ int nfields, filenum, fc;
2480
+
2481
+ /* set the number of fields to display */
2482
+ nfields = opts->flist.len > 0 ? opts->flist.len : NT_NIM_NUM_FIELDS;
2483
+
2484
+ if( g_debug > 2 )
2485
+ fprintf(stderr,"-d displaying %d fields for %d nifti datasets...\n",
2486
+ nfields, opts->infiles.len);
2487
+
2488
+ for( filenum = 0; filenum < opts->infiles.len; filenum++ )
2489
+ {
2490
+ nim = nt_image_read(opts, opts->infiles.list[filenum], 0);
2491
+ if( !nim ) return 1; /* errors are printed from library */
2492
+
2493
+ if( g_debug > 0 )
2494
+ fprintf(stdout,"\nheader file '%s', num_fields = %d, fields:\n\n",
2495
+ nim->fname, nfields);
2496
+
2497
+ if( opts->flist.len <= 0 ) /* then display all fields */
2498
+ disp_field("all fields:\n", g_nim_fields, nim, nfields, g_debug > 0);
2499
+ else /* print only the requested fields... */
2500
+ {
2501
+ /* must locate each field before printing it */
2502
+ sptr = opts->flist.list;
2503
+ for( fc = 0; fc < opts->flist.len; fc++ )
2504
+ {
2505
+ fnim = get_nim_field(*sptr, filenum == 0);
2506
+ if( fnim ) disp_field(NULL, fnim, nim, 1, g_debug > 0 && fc == 0);
2507
+ sptr++;
2508
+ }
2509
+ }
2510
+
2511
+ nifti_image_free(nim);
2512
+ }
2513
+
2514
+ return 0;
2515
+ }
2516
+
2517
+
2518
+ /*----------------------------------------------------------------------
2519
+ * - read header
2520
+ * - modify header
2521
+ * - if -prefix duplicate file
2522
+ * - else if swapped, swap back
2523
+ * - overwrite file header (allows (danger-of) no evaluation of data)
2524
+ *----------------------------------------------------------------------*/
2525
+ int act_mod_hdrs( nt_opts * opts )
2526
+ {
2527
+ nifti_1_header * nhdr;
2528
+ nifti_image * nim; /* for reading/writing entire datasets */
2529
+ int filec, swap;
2530
+ char * fname, * dupname;
2531
+ char func[] = { "act_mod_hdrs" };
2532
+
2533
+ if( g_debug > 2 )
2534
+ fprintf(stderr,"-d modifying %d fields for %d nifti headers...\n",
2535
+ opts->flist.len, opts->infiles.len);
2536
+ if( opts->flist.len <= 0 || opts->infiles.len <= 0 ) return 0;
2537
+
2538
+ for( filec = 0; filec < opts->infiles.len; filec++ )
2539
+ {
2540
+ fname = opts->infiles.list[filec]; /* for convenience and mod file */
2541
+
2542
+ if( nifti_is_gzfile(fname) ){
2543
+ fprintf(stderr,"** sorry, cannot modify a gzipped file: %s\n", fname);
2544
+ continue;
2545
+ }
2546
+
2547
+ /* do not validate the header structure */
2548
+ nhdr = nt_read_header(opts, fname, &swap, 0);
2549
+ if( !nhdr ) return 1;
2550
+
2551
+ if( g_debug > 1 )
2552
+ {
2553
+ fprintf(stderr,"-d modifying %d fields of '%s' header\n",
2554
+ opts->flist.len, fname);
2555
+ fprintf(stderr,"-d header is: %s\n",
2556
+ nifti_hdr_looks_good(nhdr) ? "valid" : "invalid");
2557
+ }
2558
+
2559
+ /* okay, let's actually trash the data fields */
2560
+ if( modify_all_fields(nhdr, opts, g_hdr_fields, NT_HDR_NUM_FIELDS) )
2561
+ {
2562
+ free(nhdr);
2563
+ return 1;
2564
+ }
2565
+
2566
+ dupname = NULL; /* unless we duplicate file */
2567
+
2568
+ /* possibly duplicate the current dataset before writing new header */
2569
+ if( opts->prefix )
2570
+ {
2571
+ nim = nt_image_read(opts, fname, 1); /* get data */
2572
+ if( !nim ) {
2573
+ fprintf(stderr,"** failed to dup file '%s' before modifying\n",
2574
+ fname);
2575
+ return 1;
2576
+ }
2577
+ if( opts->keep_hist && nifti_add_extension(nim, opts->command,
2578
+ strlen(opts->command), NIFTI_ECODE_COMMENT) )
2579
+ fprintf(stderr,"** failed to add command to image as exten\n");
2580
+ if( nifti_set_filenames(nim, opts->prefix, 1, 1) )
2581
+ {
2582
+ NTL_FERR(func,"failed to set prefix for new file: ",opts->prefix);
2583
+ nifti_image_free(nim);
2584
+ return 1;
2585
+ }
2586
+ dupname = nifti_strdup(nim->fname); /* so we know to free it */
2587
+ fname = dupname;
2588
+ nifti_image_write(nim); /* create the duplicate file */
2589
+ /* if we added a history note, get the new offset into the header */
2590
+ /* mod: if the new offset is valid, use it 31 Jan 2006 [rickr] */
2591
+ if( nim->iname_offset >= 348 ) nhdr->vox_offset = nim->iname_offset;
2592
+ nifti_image_free(nim);
2593
+ }
2594
+ else if ( swap )
2595
+ swap_nifti_header(nhdr, NIFTI_VERSION(*nhdr));
2596
+
2597
+ /* if all is well, overwrite header in fname dataset */
2598
+ (void)write_hdr_to_file(nhdr, fname); /* errors printed in function */
2599
+
2600
+ if( dupname ) free(dupname);
2601
+ free(nhdr);
2602
+ }
2603
+
2604
+ return 0;
2605
+ }
2606
+
2607
+
2608
+ /*----------------------------------------------------------------------
2609
+ * - read header
2610
+ * - swap header
2611
+ * - if -prefix duplicate file
2612
+ * - overwrite file header (allows (danger-of) no evaluation of data)
2613
+ *----------------------------------------------------------------------*/
2614
+ int act_swap_hdrs( nt_opts * opts )
2615
+ {
2616
+ nifti_1_header * nhdr;
2617
+ nifti_image * nim; /* for reading/writing entire datasets */
2618
+ int filec, swap;
2619
+ char * fname, * dupname;
2620
+ char func[] = { "act_mod_hdrs" };
2621
+
2622
+ /* count requested operations: "there can be only one", and not Sean */
2623
+ swap = opts->swap_hdr + opts->swap_ana + opts->swap_old;
2624
+ if( swap > 1 ) {
2625
+ fprintf(stderr,"** can perform only one swap method\n");
2626
+ return 1;
2627
+ } else if( ! swap )
2628
+ return 0; /* probably shouldn't be here */
2629
+
2630
+ if( g_debug > 2 )
2631
+ fprintf(stderr,"-d swapping headers of %d files...\n",opts->infiles.len);
2632
+
2633
+ for( filec = 0; filec < opts->infiles.len; filec++ )
2634
+ {
2635
+ fname = opts->infiles.list[filec]; /* for convenience and mod file */
2636
+
2637
+ if( nifti_is_gzfile(fname) ){
2638
+ fprintf(stderr,"** sorry, cannot swap a gzipped header: %s\n", fname);
2639
+ continue;
2640
+ }
2641
+
2642
+ /* do not validate the header structure */
2643
+ nhdr = nt_read_header(opts, fname, &swap, 0);
2644
+ if( !nhdr ) return 1;
2645
+
2646
+ if( g_debug > 1 ) {
2647
+ char * str = "NIfTI";
2648
+ if( opts->swap_ana || (opts->swap_old && !NIFTI_VERSION(*nhdr)) )
2649
+ str = "ANALYZE";
2650
+ fprintf(stderr,"-d %sswapping %s header of file %s\n",
2651
+ opts->swap_old ? "OLD " : "", str, fname);
2652
+ }
2653
+
2654
+ if( ! swap ) { /* if not yet swapped, do as the user requested */
2655
+
2656
+ if( opts->swap_old ) old_swap_nifti_header(nhdr, NIFTI_VERSION(*nhdr));
2657
+ else swap_nifti_header(nhdr, opts->swap_ana ? 0 : 1);
2658
+
2659
+ } else { /* swapped already: if not correct, need to undo */
2660
+
2661
+ /* if swapped the wrong way, undo and swap as the user requested */
2662
+ if ( opts->swap_ana && NIFTI_VERSION(*nhdr) ) {
2663
+ /* want swapped as ANALYZE, but was swapped as NIFTI */
2664
+ swap_nifti_header(nhdr, 1); /* undo NIFTI */
2665
+ swap_nifti_header(nhdr, 0); /* swap ANALYZE */
2666
+ } else if( opts->swap_hdr && !NIFTI_VERSION(*nhdr) ) {
2667
+ /* want swapped as NIFTI, but was swapped as ANALYZE */
2668
+ swap_nifti_header(nhdr, 0); /* undo ANALYZE */
2669
+ swap_nifti_header(nhdr, 1); /* swap NIFTI */
2670
+ } else if ( opts->swap_old ) {
2671
+ /* undo whichever was done and apply the old way */
2672
+ swap_nifti_header(nhdr, NIFTI_VERSION(*nhdr));
2673
+ old_swap_nifti_header(nhdr, NIFTI_VERSION(*nhdr));
2674
+ }
2675
+
2676
+ /* else it was swapped the right way to begin with */
2677
+
2678
+ }
2679
+
2680
+ dupname = NULL; /* unless we duplicate file */
2681
+
2682
+ /* possibly duplicate the current dataset before writing new header */
2683
+ if( opts->prefix )
2684
+ {
2685
+ nim = nt_image_read(opts, fname, 1); /* get data */
2686
+ if( !nim ) {
2687
+ fprintf(stderr,"** failed to dup file '%s' before modifying\n",
2688
+ fname);
2689
+ return 1;
2690
+ }
2691
+ if( opts->keep_hist && nifti_add_extension(nim, opts->command,
2692
+ strlen(opts->command), NIFTI_ECODE_COMMENT) )
2693
+ fprintf(stderr,"** failed to add command to image as exten\n");
2694
+ if( nifti_set_filenames(nim, opts->prefix, 1, 1) )
2695
+ {
2696
+ NTL_FERR(func,"failed to set prefix for new file: ",opts->prefix);
2697
+ nifti_image_free(nim);
2698
+ return 1;
2699
+ }
2700
+ dupname = nifti_strdup(nim->fname); /* so we know to free it */
2701
+ fname = dupname;
2702
+ nifti_image_write(nim); /* create the duplicate file */
2703
+ /* if we added a history note, get the new offset into the header */
2704
+ /* mod: if the new offset is valid, use it 31 Jan 2006 [rickr] */
2705
+ if( nim->iname_offset >= 348 ) nhdr->vox_offset = nim->iname_offset;
2706
+ nifti_image_free(nim);
2707
+ }
2708
+
2709
+ /* if all is well, overwrite header in fname dataset */
2710
+ (void)write_hdr_to_file(nhdr, fname); /* errors printed in function */
2711
+
2712
+ if( dupname ) free(dupname);
2713
+ free(nhdr);
2714
+ }
2715
+
2716
+ return 0;
2717
+ }
2718
+
2719
+
2720
+ /*----------------------------------------------------------------------
2721
+ * - read image w/data, modify and write
2722
+ *----------------------------------------------------------------------*/
2723
+ int act_mod_nims( nt_opts * opts )
2724
+ {
2725
+ nifti_image * nim; /* for reading/writing entire datasets */
2726
+ int filec;
2727
+ char func[] = { "act_mod_nims" };
2728
+
2729
+ if( g_debug > 2 )
2730
+ fprintf(stderr,"-d modifying %d fields for %d nifti images...\n",
2731
+ opts->flist.len, opts->infiles.len);
2732
+ if( opts->flist.len <= 0 || opts->infiles.len <= 0 ) return 0;
2733
+
2734
+ for( filec = 0; filec < opts->infiles.len; filec++ )
2735
+ {
2736
+ nim = nt_image_read(opts, opts->infiles.list[filec], 1); /* with data */
2737
+
2738
+ if( g_debug > 1 )
2739
+ fprintf(stderr,"-d modifying %d fields from '%s' image\n",
2740
+ opts->flist.len, opts->infiles.list[filec]);
2741
+
2742
+ /* okay, let's actually trash the data fields */
2743
+ if( modify_all_fields(nim, opts, g_nim_fields, NT_NIM_NUM_FIELDS) )
2744
+ {
2745
+ nifti_image_free(nim);
2746
+ return 1;
2747
+ }
2748
+
2749
+ /* add command as COMMENT extension */
2750
+ if( opts->keep_hist && nifti_add_extension(nim, opts->command,
2751
+ strlen(opts->command), NIFTI_ECODE_COMMENT) )
2752
+ fprintf(stderr,"** failed to add command to image as extension\n");
2753
+
2754
+ /* possibly duplicate the current dataset before writing new header */
2755
+ if( opts->prefix )
2756
+ if( nifti_set_filenames(nim, opts->prefix, 1, 1) )
2757
+ {
2758
+ NTL_FERR(func,"failed to set prefix for new file: ",opts->prefix);
2759
+ nifti_image_free(nim);
2760
+ return 1;
2761
+ }
2762
+
2763
+ nifti_image_write(nim); /* and write it out, piece of cake :) */
2764
+ nifti_image_free(nim);
2765
+ }
2766
+
2767
+ return 0;
2768
+ }
2769
+
2770
+
2771
+ /*----------------------------------------------------------------------
2772
+ * overwrite nifti_1_header in the given file
2773
+ *----------------------------------------------------------------------*/
2774
+ int write_hdr_to_file( nifti_1_header * nhdr, char * fname )
2775
+ {
2776
+ znzFile fp;
2777
+ size_t bytes;
2778
+ char func[] = { "write_hdr_to_file" };
2779
+ int rv = 0;
2780
+
2781
+ fp = znzopen(fname,"r+b",nifti_is_gzfile(fname));
2782
+ if( znz_isnull(fp) ){
2783
+ NTL_FERR(func, "failed to re-open mod file", fname);
2784
+ return 1;
2785
+ }
2786
+
2787
+ bytes = znzwrite(nhdr, 1, sizeof(nifti_1_header), fp);
2788
+ if( bytes != sizeof(nifti_1_header)){
2789
+ NTL_FERR(func, "failed to write header to file",fname);
2790
+ fprintf(stderr," - wrote %d of %d bytes\n",
2791
+ (int)bytes,(int)sizeof(nifti_1_header));
2792
+ rv = 1;
2793
+ }
2794
+
2795
+ if( g_debug > 3 )
2796
+ disp_nifti_1_header("+d writing new header to file : ", nhdr);
2797
+
2798
+ znzclose(fp);
2799
+
2800
+ return rv;
2801
+ }
2802
+
2803
+
2804
+ /*----------------------------------------------------------------------
2805
+ * modify all fields in the list
2806
+ *----------------------------------------------------------------------*/
2807
+ int modify_all_fields( void * basep, nt_opts * opts, field_s * fields, int flen)
2808
+ {
2809
+ field_s * fp;
2810
+ int fc, lc; /* field and list counters */
2811
+
2812
+ if( opts->flist.len <= 0 ) return 0;
2813
+ if( opts->flist.len != opts->vlist.len ){
2814
+ fprintf(stderr,"** have %d fields but %d new values\n",
2815
+ opts->flist.len, opts->vlist.len);
2816
+ return 1;
2817
+ }
2818
+
2819
+ for( lc = 0; lc < opts->flist.len; lc++ )
2820
+ {
2821
+ /* is it in the list? */
2822
+ fp = fields;
2823
+ for( fc = 0; fc < flen; fc++, fp++ )
2824
+ if( strcmp(opts->flist.list[lc], fp->name) == 0 ) break;
2825
+
2826
+ if( fc == flen ) /* do no modifications on failure */
2827
+ {
2828
+ fprintf(stderr,"** field '%s' not found in structure\n",
2829
+ opts->flist.list[lc]);
2830
+ return 1;
2831
+ }
2832
+
2833
+ if( modify_field( basep, fp, opts->vlist.list[lc]) )
2834
+ return 1;
2835
+ }
2836
+
2837
+ return 0;
2838
+ }
2839
+
2840
+
2841
+ /*----------------------------------------------------------------------
2842
+ * modify a single field with the given value field
2843
+ *
2844
+ * pointer fields are not allowed here
2845
+ *----------------------------------------------------------------------*/
2846
+ int modify_field(void * basep, field_s * field, char * data)
2847
+ {
2848
+ float fval;
2849
+ char * posn = data;
2850
+ int val, max, fc, nchars;
2851
+
2852
+ if( g_debug > 1 )
2853
+ fprintf(stderr,"+d modifying field '%s' with '%s'\n", field->name, data);
2854
+
2855
+ if( !data || strlen(data) == 0 )
2856
+ {
2857
+ fprintf(stderr,"** no data for '%s' field modification\n",field->name);
2858
+ return 1;
2859
+ }
2860
+
2861
+ switch( field->type )
2862
+ {
2863
+ case DT_UNKNOWN:
2864
+ case NT_DT_POINTER:
2865
+ case NT_DT_CHAR_PTR:
2866
+ case NT_DT_EXT_PTR:
2867
+ default:
2868
+ fprintf(stderr,"** refusing to modify a pointer field, '%s'\n",
2869
+ field->name);
2870
+ return 1;
2871
+
2872
+ case DT_INT8:
2873
+ {
2874
+ max = 127;
2875
+ for( fc = 0; fc < field->len; fc++ )
2876
+ {
2877
+ if( sscanf(posn, " %d%n", &val, &nchars) != 1 )
2878
+ {
2879
+ fprintf(stderr,"** found %d of %d modify values\n",
2880
+ fc,field->len);
2881
+ return 1;
2882
+ }
2883
+ if( val > max || val < -(max+1) )
2884
+ {
2885
+ fprintf(stderr,
2886
+ "** mod val #%d (= %d) outside byte range [-%d,%d]\n",
2887
+ fc, val, max+1, max);
2888
+ return 1;
2889
+ }
2890
+ /* otherwise, we're good */
2891
+ (((char *)basep + field->offset))[fc] = (char)val;
2892
+ if( g_debug > 1 )
2893
+ fprintf(stderr,"+d setting posn %d of '%s' to %d\n",
2894
+ fc, field->name, val);
2895
+ posn += nchars;
2896
+ }
2897
+ }
2898
+ break;
2899
+
2900
+ case DT_INT16:
2901
+ {
2902
+ max = 32767;
2903
+ for( fc = 0; fc < field->len; fc++ )
2904
+ {
2905
+ if( sscanf(posn, " %d%n", &val, &nchars) != 1 )
2906
+ {
2907
+ fprintf(stderr,"** found %d of %d modify values\n",
2908
+ fc,field->len);
2909
+ return 1;
2910
+ }
2911
+ if( val > max || val < -(max+1) )
2912
+ {
2913
+ fprintf(stderr,
2914
+ "** mod val #%d (= %d) outside byte range [-%d,%d]\n",
2915
+ fc, val, max+1, max);
2916
+ return 1;
2917
+ }
2918
+ /* otherwise, we're good */
2919
+ ((short *)((char *)basep + field->offset))[fc] = (short)val;
2920
+ if( g_debug > 1 )
2921
+ fprintf(stderr,"+d setting posn %d of '%s' to %d\n",
2922
+ fc, field->name, val);
2923
+ posn += nchars;
2924
+ }
2925
+ }
2926
+ break;
2927
+
2928
+ case DT_INT32:
2929
+ {
2930
+ for( fc = 0; fc < field->len; fc++ )
2931
+ {
2932
+ if( sscanf(posn, " %d%n", &val, &nchars) != 1 )
2933
+ {
2934
+ fprintf(stderr,"** found %d of %d modify values\n",
2935
+ fc,field->len);
2936
+ return 1;
2937
+ }
2938
+ ((int *)((char *)basep + field->offset))[fc] = val;
2939
+ if( g_debug > 1 )
2940
+ fprintf(stderr,"+d setting posn %d of '%s' to %d\n",
2941
+ fc, field->name, val);
2942
+ posn += nchars;
2943
+ }
2944
+ }
2945
+ break;
2946
+
2947
+ case DT_FLOAT32:
2948
+ {
2949
+ for( fc = 0; fc < field->len; fc++ )
2950
+ {
2951
+ if( sscanf(posn, " %f%n", &fval, &nchars) != 1 )
2952
+ {
2953
+ fprintf(stderr,"** found %d of %d modify values\n",
2954
+ fc,field->len);
2955
+ return 1;
2956
+ }
2957
+ /* otherwise, we're good */
2958
+ ((float *)((char *)basep + field->offset))[fc] = fval;
2959
+ if( g_debug > 1 )
2960
+ fprintf(stderr,"+d setting posn %d of '%s' to %f\n",
2961
+ fc, field->name, fval);
2962
+ posn += nchars;
2963
+ }
2964
+ }
2965
+ break;
2966
+
2967
+ case NT_DT_STRING:
2968
+ {
2969
+ char * dest = (char *)basep + field->offset;
2970
+ nchars = strlen(data);
2971
+ strncpy(dest, data, field->len);
2972
+ if( nchars < field->len ) /* clear the rest */
2973
+ memset(dest+nchars, '\0', field->len-nchars);
2974
+ }
2975
+ break;
2976
+ }
2977
+
2978
+ return 0;
2979
+ }
2980
+
2981
+
2982
+ /*----------------------------------------------------------------------
2983
+ * fill the nifti_1_header field list
2984
+ *----------------------------------------------------------------------*/
2985
+ int fill_hdr_field_array( field_s * nh_fields )
2986
+ {
2987
+ nifti_1_header nhdr;
2988
+ field_s * nhf = nh_fields;
2989
+ int rv, errs;
2990
+
2991
+ memset(nhf, 0, NT_HDR_NUM_FIELDS*sizeof(field_s));
2992
+
2993
+ /* this macro takes (TYPE, NAME, NUM) and does:
2994
+ fill_field(nhdr, TYPE, NT_OFF(nhdr,NAME), NUM, "NAME");
2995
+ nhf++;
2996
+ */
2997
+ errs = 0;
2998
+ NT_SFILL(nhdr, nhf, DT_INT32, sizeof_hdr, 1, rv); errs += rv;
2999
+ NT_SFILL(nhdr, nhf, NT_DT_STRING, data_type, 10, rv); errs += rv;
3000
+ NT_SFILL(nhdr, nhf, NT_DT_STRING, db_name, 18, rv); errs += rv;
3001
+ NT_SFILL(nhdr, nhf, DT_INT32, extents, 1, rv); errs += rv;
3002
+ NT_SFILL(nhdr, nhf, DT_INT16, session_error, 1, rv); errs += rv;
3003
+ NT_SFILL(nhdr, nhf, NT_DT_STRING, regular, 1, rv); errs += rv;
3004
+ NT_SFILL(nhdr, nhf, DT_INT8, dim_info, 1, rv); errs += rv;
3005
+
3006
+ NT_SFILL(nhdr, nhf, DT_INT16, dim, 8, rv); errs += rv;
3007
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, intent_p1, 1, rv); errs += rv;
3008
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, intent_p2, 1, rv); errs += rv;
3009
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, intent_p3, 1, rv); errs += rv;
3010
+ NT_SFILL(nhdr, nhf, DT_INT16, intent_code, 1, rv); errs += rv;
3011
+
3012
+ NT_SFILL(nhdr, nhf, DT_INT16, datatype, 1, rv); errs += rv;
3013
+ NT_SFILL(nhdr, nhf, DT_INT16, bitpix, 1, rv); errs += rv;
3014
+ NT_SFILL(nhdr, nhf, DT_INT16, slice_start, 1, rv); errs += rv;
3015
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, pixdim, 8, rv); errs += rv;
3016
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, vox_offset, 1, rv); errs += rv;
3017
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, scl_slope, 1, rv); errs += rv;
3018
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, scl_inter, 1, rv); errs += rv;
3019
+ NT_SFILL(nhdr, nhf, DT_INT16, slice_end, 1, rv); errs += rv;
3020
+
3021
+ NT_SFILL(nhdr, nhf, DT_INT8, slice_code, 1, rv); errs += rv;
3022
+ NT_SFILL(nhdr, nhf, DT_INT8, xyzt_units, 1, rv); errs += rv;
3023
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, cal_max, 1, rv); errs += rv;
3024
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, cal_min, 1, rv); errs += rv;
3025
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, slice_duration, 1, rv); errs += rv;
3026
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, toffset, 1, rv); errs += rv;
3027
+ NT_SFILL(nhdr, nhf, DT_INT32, glmax, 1, rv); errs += rv;
3028
+ NT_SFILL(nhdr, nhf, DT_INT32, glmin, 1, rv); errs += rv;
3029
+
3030
+ NT_SFILL(nhdr, nhf, NT_DT_STRING, descrip, 80, rv); errs += rv;
3031
+ NT_SFILL(nhdr, nhf, NT_DT_STRING, aux_file, 24, rv); errs += rv;
3032
+ NT_SFILL(nhdr, nhf, DT_INT16, qform_code, 1, rv); errs += rv;
3033
+ NT_SFILL(nhdr, nhf, DT_INT16, sform_code, 1, rv); errs += rv;
3034
+
3035
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, quatern_b, 1, rv); errs += rv;
3036
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, quatern_c, 1, rv); errs += rv;
3037
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, quatern_d, 1, rv); errs += rv;
3038
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, qoffset_x, 1, rv); errs += rv;
3039
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, qoffset_y, 1, rv); errs += rv;
3040
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, qoffset_z, 1, rv); errs += rv;
3041
+
3042
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, srow_x, 4, rv); errs += rv;
3043
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, srow_y, 4, rv); errs += rv;
3044
+ NT_SFILL(nhdr, nhf, DT_FLOAT32, srow_z, 4, rv); errs += rv;
3045
+ NT_SFILL(nhdr, nhf, NT_DT_STRING, intent_name, 16, rv); errs += rv;
3046
+ NT_SFILL(nhdr, nhf, NT_DT_STRING, magic, 4, rv); errs += rv;
3047
+
3048
+ if( errs > 0 ){
3049
+ fprintf(stderr, "** %d fill_fields errors!\n", errs);
3050
+ return 1;
3051
+ }
3052
+
3053
+ /* failure here is a serious problem */
3054
+ if( check_total_size("nifti_1_header test: ", nh_fields,
3055
+ NT_HDR_NUM_FIELDS, sizeof(nhdr)) )
3056
+ return 1;
3057
+
3058
+ if( g_debug > 3 )
3059
+ disp_field_s_list("nh_fields: ", nh_fields, NT_HDR_NUM_FIELDS);
3060
+
3061
+ return 0;
3062
+ }
3063
+
3064
+
3065
+ /*----------------------------------------------------------------------
3066
+ * fill the nifti_image field list
3067
+ *----------------------------------------------------------------------*/
3068
+ int fill_nim_field_array( field_s * nim_fields )
3069
+ {
3070
+ nifti_image nim;
3071
+ field_s * nif = nim_fields;
3072
+ int rv, errs;
3073
+
3074
+ memset(nif, 0, NT_NIM_NUM_FIELDS*sizeof(field_s));
3075
+
3076
+ errs = 0;
3077
+
3078
+ NT_SFILL(nim, nif, DT_INT32, ndim, 1, rv); errs += rv;
3079
+ NT_SFILL(nim, nif, DT_INT32, nx, 1, rv); errs += rv;
3080
+ NT_SFILL(nim, nif, DT_INT32, ny, 1, rv); errs += rv;
3081
+ NT_SFILL(nim, nif, DT_INT32, nz, 1, rv); errs += rv;
3082
+ NT_SFILL(nim, nif, DT_INT32, nt, 1, rv); errs += rv;
3083
+ NT_SFILL(nim, nif, DT_INT32, nu, 1, rv); errs += rv;
3084
+ NT_SFILL(nim, nif, DT_INT32, nv, 1, rv); errs += rv;
3085
+ NT_SFILL(nim, nif, DT_INT32, nw, 1, rv); errs += rv;
3086
+ NT_SFILL(nim, nif, DT_INT32, dim, 8, rv); errs += rv;
3087
+ NT_SFILL(nim, nif, DT_INT32, nvox, 1, rv); errs += rv;
3088
+ NT_SFILL(nim, nif, DT_INT32, nbyper, 1, rv); errs += rv;
3089
+ NT_SFILL(nim, nif, DT_INT32, datatype, 1, rv); errs += rv;
3090
+ NT_SFILL(nim, nif, DT_FLOAT32, dx, 1, rv); errs += rv;
3091
+ NT_SFILL(nim, nif, DT_FLOAT32, dy, 1, rv); errs += rv;
3092
+ NT_SFILL(nim, nif, DT_FLOAT32, dz, 1, rv); errs += rv;
3093
+ NT_SFILL(nim, nif, DT_FLOAT32, dt, 1, rv); errs += rv;
3094
+ NT_SFILL(nim, nif, DT_FLOAT32, du, 1, rv); errs += rv;
3095
+ NT_SFILL(nim, nif, DT_FLOAT32, dv, 1, rv); errs += rv;
3096
+ NT_SFILL(nim, nif, DT_FLOAT32, dw, 1, rv); errs += rv;
3097
+ NT_SFILL(nim, nif, DT_FLOAT32, pixdim, 8, rv); errs += rv;
3098
+ NT_SFILL(nim, nif, DT_FLOAT32, scl_slope, 1, rv); errs += rv;
3099
+ NT_SFILL(nim, nif, DT_FLOAT32, scl_inter, 1, rv); errs += rv;
3100
+ NT_SFILL(nim, nif, DT_FLOAT32, cal_min, 1, rv); errs += rv;
3101
+ NT_SFILL(nim, nif, DT_FLOAT32, cal_max, 1, rv); errs += rv;
3102
+ NT_SFILL(nim, nif, DT_INT32, qform_code, 1, rv); errs += rv;
3103
+ NT_SFILL(nim, nif, DT_INT32, sform_code, 1, rv); errs += rv;
3104
+ NT_SFILL(nim, nif, DT_INT32, freq_dim, 1, rv); errs += rv;
3105
+ NT_SFILL(nim, nif, DT_INT32, phase_dim, 1, rv); errs += rv;
3106
+ NT_SFILL(nim, nif, DT_INT32, slice_dim, 1, rv); errs += rv;
3107
+ NT_SFILL(nim, nif, DT_INT32, slice_code, 1, rv); errs += rv;
3108
+ NT_SFILL(nim, nif, DT_INT32, slice_start, 1, rv); errs += rv;
3109
+ NT_SFILL(nim, nif, DT_INT32, slice_end, 1, rv); errs += rv;
3110
+ NT_SFILL(nim, nif, DT_FLOAT32, slice_duration, 1, rv); errs += rv;
3111
+ NT_SFILL(nim, nif, DT_FLOAT32, quatern_b, 1, rv); errs += rv;
3112
+ NT_SFILL(nim, nif, DT_FLOAT32, quatern_c, 1, rv); errs += rv;
3113
+ NT_SFILL(nim, nif, DT_FLOAT32, quatern_d, 1, rv); errs += rv;
3114
+ NT_SFILL(nim, nif, DT_FLOAT32, qoffset_x, 1, rv); errs += rv;
3115
+ NT_SFILL(nim, nif, DT_FLOAT32, qoffset_y, 1, rv); errs += rv;
3116
+ NT_SFILL(nim, nif, DT_FLOAT32, qoffset_z, 1, rv); errs += rv;
3117
+ NT_SFILL(nim, nif, DT_FLOAT32, qfac, 1, rv); errs += rv;
3118
+ NT_SFILL(nim, nif, DT_FLOAT32, qto_xyz, 16, rv); errs += rv;
3119
+ NT_SFILL(nim, nif, DT_FLOAT32, qto_ijk, 16, rv); errs += rv;
3120
+ NT_SFILL(nim, nif, DT_FLOAT32, sto_xyz, 16, rv); errs += rv;
3121
+ NT_SFILL(nim, nif, DT_FLOAT32, sto_ijk, 16, rv); errs += rv;
3122
+ NT_SFILL(nim, nif, DT_FLOAT32, toffset, 1, rv); errs += rv;
3123
+ NT_SFILL(nim, nif, DT_INT32, xyz_units, 1, rv); errs += rv;
3124
+ NT_SFILL(nim, nif, DT_INT32, time_units, 1, rv); errs += rv;
3125
+ NT_SFILL(nim, nif, DT_INT32, nifti_type, 1, rv); errs += rv;
3126
+ NT_SFILL(nim, nif, DT_INT32, intent_code, 1, rv); errs += rv;
3127
+ NT_SFILL(nim, nif, DT_FLOAT32, intent_p1, 1, rv); errs += rv;
3128
+ NT_SFILL(nim, nif, DT_FLOAT32, intent_p2, 1, rv); errs += rv;
3129
+ NT_SFILL(nim, nif, DT_FLOAT32, intent_p3, 1, rv); errs += rv;
3130
+ NT_SFILL(nim, nif, NT_DT_STRING, intent_name, 16, rv); errs += rv;
3131
+ NT_SFILL(nim, nif, NT_DT_STRING, descrip, 80, rv); errs += rv;
3132
+ NT_SFILL(nim, nif, NT_DT_STRING, aux_file, 24, rv); errs += rv;
3133
+ NT_SFILL(nim, nif, NT_DT_CHAR_PTR, fname, 1, rv); errs += rv;
3134
+ NT_SFILL(nim, nif, NT_DT_CHAR_PTR, iname, 1, rv); errs += rv;
3135
+ NT_SFILL(nim, nif, DT_INT32, iname_offset, 1, rv); errs += rv;
3136
+ NT_SFILL(nim, nif, DT_INT32, swapsize, 1, rv); errs += rv;
3137
+ NT_SFILL(nim, nif, DT_INT32, byteorder, 1, rv); errs += rv;
3138
+ NT_SFILL(nim, nif, NT_DT_POINTER, data, 1, rv); errs += rv;
3139
+ NT_SFILL(nim, nif, DT_INT32, num_ext, 1, rv); errs += rv;
3140
+ NT_SFILL(nim, nif, NT_DT_EXT_PTR, ext_list, 1, rv); errs += rv;
3141
+
3142
+ if( errs > 0 ){
3143
+ fprintf(stderr, "** %d fill_fields errors "
3144
+ "(note that pointers get aligned)\n", errs);
3145
+ return 1;
3146
+ }
3147
+
3148
+ if( g_debug > 3 ) /* failure here is not an error condition */
3149
+ check_total_size("nifti_image test: ", nim_fields,
3150
+ NT_NIM_NUM_FIELDS, sizeof(nim));
3151
+
3152
+ if( g_debug > 3 )
3153
+ disp_field_s_list("nim_fields: ", nim_fields, NT_NIM_NUM_FIELDS);
3154
+
3155
+ return 0;
3156
+ }
3157
+
3158
+
3159
+ /*----------------------------------------------------------------------
3160
+ * fill the nifti_analyze75 field list
3161
+ *----------------------------------------------------------------------*/
3162
+ int fill_ana_field_array( field_s * ah_fields )
3163
+ {
3164
+ nifti_analyze75 nhdr;
3165
+ field_s * ahf = ah_fields;
3166
+ int rv, errs;
3167
+
3168
+ memset(ahf, 0, NT_ANA_NUM_FIELDS*sizeof(field_s));
3169
+
3170
+ /* this macro takes (TYPE, NAME, NUM) and does:
3171
+ fill_field(nhdr, TYPE, NT_OFF(nhdr,NAME), NUM, "NAME");
3172
+ nhf++;
3173
+ */
3174
+ errs = 0;
3175
+ NT_SFILL(nhdr, ahf, DT_INT32, sizeof_hdr, 1, rv); errs += rv;
3176
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, data_type, 10, rv); errs += rv;
3177
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, db_name, 18, rv); errs += rv;
3178
+ NT_SFILL(nhdr, ahf, DT_INT32, extents, 1, rv); errs += rv;
3179
+ NT_SFILL(nhdr, ahf, DT_INT16, session_error, 1, rv); errs += rv;
3180
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, regular, 1, rv); errs += rv;
3181
+ NT_SFILL(nhdr, ahf, DT_INT8, hkey_un0, 1, rv); errs += rv;
3182
+
3183
+ NT_SFILL(nhdr, ahf, DT_INT16, dim, 8, rv); errs += rv;
3184
+ NT_SFILL(nhdr, ahf, DT_INT16, unused8, 1, rv); errs += rv;
3185
+ NT_SFILL(nhdr, ahf, DT_INT16, unused9, 1, rv); errs += rv;
3186
+ NT_SFILL(nhdr, ahf, DT_INT16, unused10, 1, rv); errs += rv;
3187
+ NT_SFILL(nhdr, ahf, DT_INT16, unused11, 1, rv); errs += rv;
3188
+ NT_SFILL(nhdr, ahf, DT_INT16, unused12, 1, rv); errs += rv;
3189
+ NT_SFILL(nhdr, ahf, DT_INT16, unused13, 1, rv); errs += rv;
3190
+ NT_SFILL(nhdr, ahf, DT_INT16, unused14, 1, rv); errs += rv;
3191
+
3192
+ NT_SFILL(nhdr, ahf, DT_INT16, datatype, 1, rv); errs += rv;
3193
+ NT_SFILL(nhdr, ahf, DT_INT16, bitpix, 1, rv); errs += rv;
3194
+ NT_SFILL(nhdr, ahf, DT_INT16, dim_un0, 1, rv); errs += rv;
3195
+
3196
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, pixdim, 8, rv); errs += rv;
3197
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, vox_offset, 1, rv); errs += rv;
3198
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, funused1, 1, rv); errs += rv;
3199
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, funused2, 1, rv); errs += rv;
3200
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, funused3, 1, rv); errs += rv;
3201
+
3202
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, cal_max, 1, rv); errs += rv;
3203
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, cal_min, 1, rv); errs += rv;
3204
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, compressed, 1, rv); errs += rv;
3205
+ NT_SFILL(nhdr, ahf, DT_FLOAT32, verified, 1, rv); errs += rv;
3206
+ NT_SFILL(nhdr, ahf, DT_INT32, glmax, 1, rv); errs += rv;
3207
+ NT_SFILL(nhdr, ahf, DT_INT32, glmin, 1, rv); errs += rv;
3208
+
3209
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, descrip, 80, rv); errs += rv;
3210
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, aux_file, 24, rv); errs += rv;
3211
+
3212
+ NT_SFILL(nhdr, ahf, DT_INT8, orient, 1, rv); errs += rv;
3213
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, originator, 10, rv); errs += rv;
3214
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, generated, 10, rv); errs += rv;
3215
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, scannum, 10, rv); errs += rv;
3216
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, patient_id, 10, rv); errs += rv;
3217
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, exp_date, 10, rv); errs += rv;
3218
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, exp_time, 10, rv); errs += rv;
3219
+ NT_SFILL(nhdr, ahf, NT_DT_STRING, hist_un0, 3, rv); errs += rv;
3220
+
3221
+ NT_SFILL(nhdr, ahf, DT_INT32, views , 1, rv); errs += rv;
3222
+ NT_SFILL(nhdr, ahf, DT_INT32, vols_added, 1, rv); errs += rv;
3223
+ NT_SFILL(nhdr, ahf, DT_INT32, start_field, 1, rv); errs += rv;
3224
+ NT_SFILL(nhdr, ahf, DT_INT32, field_skip, 1, rv); errs += rv;
3225
+
3226
+ NT_SFILL(nhdr, ahf, DT_INT32, omax, 1, rv); errs += rv;
3227
+ NT_SFILL(nhdr, ahf, DT_INT32, omin, 1, rv); errs += rv;
3228
+ NT_SFILL(nhdr, ahf, DT_INT32, smax, 1, rv); errs += rv;
3229
+ NT_SFILL(nhdr, ahf, DT_INT32, smin, 1, rv); errs += rv;
3230
+
3231
+ if( errs > 0 ){
3232
+ fprintf(stderr, "** %d ana fill_fields errors!\n", errs);
3233
+ return 1;
3234
+ }
3235
+
3236
+ /* failure here is a serious problem */
3237
+ if( check_total_size("nifti_analyze75 test: ", ah_fields, NT_ANA_NUM_FIELDS,
3238
+ sizeof(nhdr)) )
3239
+ return 1;
3240
+
3241
+ if( g_debug > 3 )
3242
+ disp_field_s_list("ah_fields: ", ah_fields, NT_ANA_NUM_FIELDS);
3243
+
3244
+ return 0;
3245
+ }
3246
+
3247
+
3248
+ /*----------------------------------------------------------------------
3249
+ * compare sizes to offset, including total
3250
+ *----------------------------------------------------------------------*/
3251
+ int check_total_size( char * mesg, field_s * fields, int nfields, int tot_size )
3252
+ {
3253
+ field_s * fp;
3254
+ int c, total;
3255
+ int bad_offs;
3256
+
3257
+ total = 0;
3258
+ bad_offs = 0;
3259
+ for( c = 0, fp = fields; c < nfields; c++, fp++ ){
3260
+ if( fp->offset != total ){
3261
+ if( g_debug > 2 )
3262
+ fprintf(stderr,"** bad offset for field '%s'\n"
3263
+ " offset = %d, total = %d\n",
3264
+ fp->name, fp->offset, total);
3265
+ bad_offs++;
3266
+ }
3267
+
3268
+ total += fp->size * fp->len;
3269
+ }
3270
+
3271
+ if( g_debug > 1 || (g_debug > 0 && bad_offs > 0) ){
3272
+ fputs(mesg, stderr); c = 0;
3273
+ if( bad_offs > 0 ){
3274
+ fprintf(stderr,"** found %d bad offsets\n", bad_offs); c++; }
3275
+ if( total != tot_size ){
3276
+ fprintf(stderr,"** computed total %d not equal to struct size %d\n",
3277
+ total, tot_size); c++; }
3278
+ if( c == 0 ) fputs("... okay\n", stderr);
3279
+ }
3280
+
3281
+ if( bad_offs > 0 ) return 1;
3282
+
3283
+ return 0;
3284
+ }
3285
+
3286
+
3287
+ /*----------------------------------------------------------------------
3288
+ * fill the field structure with the given data
3289
+ *----------------------------------------------------------------------*/
3290
+ int fill_field( field_s * fp, int type, int offset, int num, char * name )
3291
+ {
3292
+ fp->type = type;
3293
+ fp->offset = offset;
3294
+ fp->size = 1; /* init before check */
3295
+ fp->len = num;
3296
+
3297
+ strncpy(fp->name, name, NT_FIELD_NAME_LEN-1);
3298
+
3299
+ switch( type ){
3300
+ case DT_UNKNOWN:
3301
+ case DT_INT8:
3302
+ case NT_DT_STRING:
3303
+ fp->size = 1;
3304
+ break;
3305
+
3306
+ case DT_INT16:
3307
+ fp->size = 2;
3308
+ break;
3309
+
3310
+ case DT_INT32:
3311
+ case DT_FLOAT32:
3312
+ fp->size = 4;
3313
+ break;
3314
+
3315
+ case NT_DT_POINTER:
3316
+ case NT_DT_CHAR_PTR:
3317
+ case NT_DT_EXT_PTR:
3318
+ fp->size = (int)sizeof(void *);
3319
+ break;
3320
+
3321
+ default:
3322
+ fprintf(stderr,"** fill_field: invalid type %d\n", type );
3323
+ return 1;
3324
+ }
3325
+
3326
+ return 0;
3327
+ }
3328
+
3329
+
3330
+ /*----------------------------------------------------------------------
3331
+ * display the contents of all of the field structures
3332
+ *----------------------------------------------------------------------*/
3333
+ char * field_type_str( int type )
3334
+ {
3335
+ if( type == DT_INT8 ) return "DT_INT8";
3336
+ if( type == DT_INT16 ) return "DT_INT16";
3337
+ if( type == DT_INT32 ) return "DT_INT32";
3338
+ if( type == DT_FLOAT32 ) return "DT_FLOAT32";
3339
+ if( type == NT_DT_STRING ) return "NT_DT_STRING";
3340
+ if( type == NT_DT_POINTER ) return "NT_DT_POINTER";
3341
+ if( type == NT_DT_CHAR_PTR ) return "NT_DT_CHAR_PTR"; /* longest: 14 */
3342
+ if( type == NT_DT_EXT_PTR ) return "NT_DT_EXT_PTR";
3343
+
3344
+ return "DT_UNKNOWN"; /* for DT_UNKNOWN, or as an else */
3345
+ }
3346
+
3347
+ #define NT_MAX_DT_STR_LEN 14
3348
+
3349
+ /*----------------------------------------------------------------------
3350
+ * display the contents of all of the field structures
3351
+ *----------------------------------------------------------------------*/
3352
+ int disp_field_s_list( char * mesg, field_s * fp, int nfields )
3353
+ {
3354
+ int c;
3355
+
3356
+ if( mesg ) fputs(mesg, stdout);
3357
+
3358
+ fprintf(stdout," %d fields:\n"
3359
+ " name size len offset type\n"
3360
+ " ------------------- ---- --- ------ --------------\n",
3361
+ nfields);
3362
+
3363
+ for( c = 0; c < nfields; c++, fp++ )
3364
+ fprintf(stdout," %-*s %4d %3d %4d %-14s\n",
3365
+ NT_FIELD_NAME_LEN-1, fp->name, fp->size, fp->len,
3366
+ fp->offset, field_type_str(fp->type));
3367
+
3368
+ return 0;
3369
+ }
3370
+
3371
+
3372
+ /*----------------------------------------------------------------------
3373
+ * display the contents of all of the field structures
3374
+ *----------------------------------------------------------------------*/
3375
+ int disp_field(char *mesg, field_s *fieldp, void * str, int nfields, int header)
3376
+ {
3377
+ field_s * fp;
3378
+ int c;
3379
+
3380
+ if( mesg ) fputs(mesg, stdout);
3381
+
3382
+ if( header && g_debug > 0 ){
3383
+ fprintf(stdout, " name offset nvals values\n");
3384
+ fprintf(stdout, " ------------------- ------ ----- ------\n");
3385
+ }
3386
+
3387
+ fp = fieldp;
3388
+ for( c = 0; c < nfields; c++, fp++ )
3389
+ {
3390
+ /* start by displaying the field information */
3391
+ if( g_debug > 0 )
3392
+ fprintf(stdout, " %-*.*s %4d %3d ",
3393
+ NT_FIELD_NAME_LEN-1, NT_FIELD_NAME_LEN-1, fp->name,
3394
+ fp->offset, fp->len);
3395
+
3396
+ /* now, print the value(s), depending on the type */
3397
+ switch( fp->type ){
3398
+ case DT_UNKNOWN:
3399
+ default:
3400
+ fprintf(stdout,"(unknown data type)\n");
3401
+ break;
3402
+
3403
+ case DT_INT8: case DT_UINT8:
3404
+ case DT_INT16: case DT_UINT16:
3405
+ case DT_INT32: case DT_UINT32:
3406
+ case DT_FLOAT32: case DT_FLOAT64:
3407
+ disp_raw_data((char *)str+fp->offset, fp->type, fp->len, ' ', 1);
3408
+ break;
3409
+
3410
+ case NT_DT_POINTER:
3411
+ fprintf(stdout,"(raw data of unknown type)\n");
3412
+ break;
3413
+
3414
+ case NT_DT_CHAR_PTR: /* look for string of length <= 40 */
3415
+ {
3416
+ char * sp;
3417
+ int len;
3418
+
3419
+ /* start by sucking the pointer stored here */
3420
+ sp = *(char **)((char *)str + fp->offset);
3421
+
3422
+ if( ! sp ){ fprintf(stdout,"(NULL)\n"); break; } /* anything? */
3423
+
3424
+ /* see if we have a printable string here */
3425
+ for(len = 0; len <= 40 && *sp && isprint(*sp); len++, sp++ )
3426
+ ;
3427
+ if( len > 40 )
3428
+ fprintf(stdout,"(apparent long string)\n");
3429
+ else if ( len == 0 )
3430
+ fprintf(stdout,"(empty string)\n");
3431
+ else if( *sp && !isprint(*sp) ) /* if no termination, it's bad */
3432
+ fprintf(stdout,"(non-printable string)\n");
3433
+ else /* woohoo! a good string */
3434
+ fprintf(stdout,"'%.40s'\n",*(char **)((char *)str + fp->offset));
3435
+ break;
3436
+ }
3437
+
3438
+ case NT_DT_EXT_PTR:
3439
+ {
3440
+ nifti1_extension * extp;
3441
+
3442
+ /* yank the address sitting there into extp */
3443
+ extp = *(nifti1_extension **)((char *)str + fp->offset);
3444
+
3445
+ /* the user may use -disp_exts to display all of them */
3446
+ if( extp ) disp_nifti1_extension(NULL, extp, 6);
3447
+ else fprintf(stdout,"(NULL)\n");
3448
+ break;
3449
+ }
3450
+
3451
+ case NT_DT_STRING:
3452
+ {
3453
+ char * charp = (char *)str + fp->offset;
3454
+ fprintf(stdout,"%.*s\n", fp->len, charp);
3455
+ break;
3456
+ }
3457
+ }
3458
+ }
3459
+
3460
+ return 0;
3461
+ }
3462
+
3463
+
3464
+ /*----------------------------------------------------------------------
3465
+ * no display, just return whether any fields differ
3466
+ *----------------------------------------------------------------------*/
3467
+ int diff_field(field_s *fieldp, void * str0, void * str1, int nfields)
3468
+ {
3469
+ field_s * fp;
3470
+ char * cp0, * cp1;
3471
+ int fnum, c, size;
3472
+
3473
+ fp = fieldp;
3474
+ for( fnum = 0; fnum < nfields; fnum++, fp++ )
3475
+ {
3476
+ switch( fp->type ){
3477
+ case DT_UNKNOWN: /* all basic types are easy */
3478
+ case DT_INT8:
3479
+ case DT_INT16:
3480
+ case DT_INT32:
3481
+ case DT_FLOAT32:
3482
+ case NT_DT_STRING:
3483
+ size = fp->size * fp->len; /* total field size */
3484
+ cp0 = (char *)str0 + fp->offset;
3485
+ cp1 = (char *)str1 + fp->offset;
3486
+ for( c = 0; c < size; c++, cp0++, cp1++ )
3487
+ if( *cp0 != *cp1 ) break;
3488
+
3489
+ if(c < size) return 1; /* found a diff */
3490
+
3491
+ break;
3492
+
3493
+ case NT_DT_POINTER: /* let's pass on these - no diff */
3494
+ case NT_DT_CHAR_PTR:
3495
+
3496
+ break;
3497
+
3498
+ case NT_DT_EXT_PTR:
3499
+ {
3500
+ nifti1_extension * ext0, * ext1;
3501
+
3502
+ ext0 = *(nifti1_extension **)((char *)str0 + fp->offset);
3503
+ ext1 = *(nifti1_extension **)((char *)str1 + fp->offset);
3504
+
3505
+ if( ! ext0 && ! ext1 ) break; /* continue on */
3506
+
3507
+ if( ext0 && ! ext1 ) return 1; /* pointer diff is diff */
3508
+ if( ! ext0 && ext1 ) return 1;
3509
+
3510
+ /* just check size and type for a single extension */
3511
+ if( ext0->esize != ext1->esize ) return 1;
3512
+ if( ext0->ecode != ext1->ecode ) return 1;
3513
+
3514
+ break;
3515
+ }
3516
+ }
3517
+ }
3518
+
3519
+ return 0; /* no diffs found */
3520
+ }
3521
+
3522
+
3523
+ /*----------------------------------------------------------------------
3524
+ * display a single extension
3525
+ *----------------------------------------------------------------------*/
3526
+ int disp_nifti1_extension(char *mesg, nifti1_extension * ext, int maxlen)
3527
+ {
3528
+ int len;
3529
+ if( mesg ) fputs(mesg, stdout);
3530
+
3531
+ if( !ext )
3532
+ {
3533
+ fprintf(stderr,"** no extension to display\n");
3534
+ return 1;
3535
+ }
3536
+
3537
+ fprintf(stdout,"ecode = %d, esize = %d, edata = ",
3538
+ ext->ecode, ext->esize);
3539
+
3540
+ if( !ext->edata )
3541
+ fprintf(stdout,"(NULL)\n");
3542
+ else if ( ext->ecode == NIFTI_ECODE_AFNI ||
3543
+ ext->ecode == NIFTI_ECODE_COMMENT )
3544
+ {
3545
+ len = ext->esize-8;
3546
+ if( maxlen >= 0 && len > maxlen ) len = maxlen;
3547
+ fprintf(stdout,"%.*s\n", len, (char *)ext->edata);
3548
+ }
3549
+ else
3550
+ fprintf(stdout,"(unknown data type)\n");
3551
+
3552
+ fflush(stdout);
3553
+
3554
+ return 0;
3555
+ }
3556
+
3557
+
3558
+ /*----------------------------------------------------------------------
3559
+ * return the appropritate pointer into the g_hdr_fields struct
3560
+ *----------------------------------------------------------------------*/
3561
+ field_s * get_hdr_field( char * fname, int show_fail )
3562
+ {
3563
+ field_s * fp;
3564
+ int c;
3565
+
3566
+ if( ! fname || *fname == '\0' ) return NULL;
3567
+
3568
+ fp = g_hdr_fields;
3569
+ for( c = 0; c < NT_HDR_NUM_FIELDS; c++, fp++ )
3570
+ if( strcmp(fname, fp->name) == 0 ) break;
3571
+
3572
+ if( c == NT_HDR_NUM_FIELDS )
3573
+ {
3574
+ if( show_fail > 0 )
3575
+ fprintf(stderr,"** get_hdr_field: field not found in hdr: %s\n",fname);
3576
+ return NULL;
3577
+ }
3578
+
3579
+ return fp;
3580
+ }
3581
+
3582
+
3583
+ /*----------------------------------------------------------------------
3584
+ * return the appropritate pointer into the g_hdr_fields struct
3585
+ *----------------------------------------------------------------------*/
3586
+ field_s * get_nim_field( char * fname, int show_fail )
3587
+ {
3588
+ field_s * fp;
3589
+ int c;
3590
+
3591
+ if( ! fname || *fname == '\0' ) return NULL;
3592
+
3593
+ fp = g_nim_fields;
3594
+ for( c = 0; c < NT_NIM_NUM_FIELDS; c++, fp++ )
3595
+ if( strcmp(fname, fp->name) == 0 ) break;
3596
+
3597
+ if( c == NT_NIM_NUM_FIELDS )
3598
+ {
3599
+ if( show_fail > 0 )
3600
+ fprintf(stderr,"** get_nim_field: field not found in hdr: %s\n",fname);
3601
+ return NULL;
3602
+ }
3603
+
3604
+ return fp;
3605
+ }
3606
+
3607
+
3608
+ /*----------------------------------------------------------------------
3609
+ * return the number of fields that differ
3610
+ *----------------------------------------------------------------------*/
3611
+ int diff_hdrs( nifti_1_header * s0, nifti_1_header * s1, int display )
3612
+ {
3613
+ field_s * fp = g_hdr_fields;
3614
+ int c, ndiff = 0;
3615
+
3616
+ for( c = 0; c < NT_HDR_NUM_FIELDS; c++, fp++ )
3617
+ if( diff_field(fp, s0, s1, 1) )
3618
+ {
3619
+ if( display ) disp_field(NULL, fp, s0, 1, ndiff == 0);
3620
+ if( display ) disp_field(NULL, fp, s1, 1, 0);
3621
+ ndiff++;
3622
+ }
3623
+
3624
+ return ndiff;
3625
+ }
3626
+
3627
+
3628
+ /*----------------------------------------------------------------------
3629
+ * return the number of fields that differ
3630
+ *----------------------------------------------------------------------*/
3631
+ int diff_nims( nifti_image * s0, nifti_image * s1, int display )
3632
+ {
3633
+ field_s * fp = g_nim_fields;
3634
+ int c, ndiff = 0;
3635
+
3636
+ for( c = 0; c < NT_NIM_NUM_FIELDS; c++, fp++ )
3637
+ if( diff_field(fp, s0, s1, 1) )
3638
+ {
3639
+ if( display ) disp_field(NULL, fp, s0, 1, ndiff == 0);
3640
+ if( display ) disp_field(NULL, fp, s1, 1, 0);
3641
+ ndiff++;
3642
+ }
3643
+
3644
+ return ndiff;
3645
+ }
3646
+
3647
+
3648
+ /*----------------------------------------------------------------------
3649
+ * return the number of fields that differ
3650
+ *----------------------------------------------------------------------*/
3651
+ int diff_hdrs_list( nifti_1_header * s0, nifti_1_header * s1, str_list * slist,
3652
+ int display )
3653
+ {
3654
+ field_s * fp;
3655
+ char ** sptr;
3656
+ int c, ndiff = 0;
3657
+
3658
+ sptr = slist->list;
3659
+ for( c = 0; c < slist->len; c++ )
3660
+ {
3661
+ fp = get_hdr_field(*sptr, 1); /* "not found" displayed in func */
3662
+ if( fp && diff_field(fp, s0, s1, 1) )
3663
+ {
3664
+ if( display ) disp_field(NULL, fp, s0, 1, ndiff == 0);
3665
+ if( display ) disp_field(NULL, fp, s1, 1, 0);
3666
+ ndiff++;
3667
+ }
3668
+ sptr++;
3669
+ }
3670
+
3671
+ return ndiff;
3672
+ }
3673
+
3674
+
3675
+ /*----------------------------------------------------------------------
3676
+ * return the number of fields that differ
3677
+ *----------------------------------------------------------------------*/
3678
+ int diff_nims_list( nifti_image * s0, nifti_image * s1, str_list * slist,
3679
+ int display )
3680
+ {
3681
+ field_s * fp;
3682
+ char ** sptr;
3683
+ int c, ndiff = 0;
3684
+
3685
+ sptr = slist->list;
3686
+ for( c = 0; c < slist->len; c++ )
3687
+ {
3688
+ fp = get_nim_field(*sptr, 1); /* "not found" displayed in func */
3689
+ if( fp && diff_field(fp, s0, s1, 1) )
3690
+ {
3691
+ if( display ) disp_field(NULL, fp, s0, 1, ndiff == 0);
3692
+ if( display ) disp_field(NULL, fp, s1, 1, 0);
3693
+ ndiff++;
3694
+ }
3695
+ sptr++;
3696
+ }
3697
+
3698
+ return ndiff;
3699
+ }
3700
+
3701
+
3702
+ /*----------------------------------------------------------------------
3703
+ * display data from collapsed_image
3704
+ *----------------------------------------------------------------------*/
3705
+ int act_disp_ci( nt_opts * opts )
3706
+ {
3707
+ nifti_image * nim;
3708
+ void * data = NULL;
3709
+ char space = ' '; /* use space or newline */
3710
+ int filenum, len, err;
3711
+
3712
+ if( opts->dci_lines ) space = '\n'; /* then use newlines as separators */
3713
+
3714
+ if( g_debug > 2 && opts->dts )
3715
+ {
3716
+ fprintf(stderr,"-d displaying time series at (i,j,k) = (%d,%d,%d)\n"
3717
+ " for %d nifti datasets...\n\n", opts->ci_dims[1],
3718
+ opts->ci_dims[2], opts->ci_dims[3], opts->infiles.len);
3719
+ }
3720
+ else if ( g_debug > 2 ) /* the general collapsed image form */
3721
+ {
3722
+ fprintf(stderr,"-d displaying collapsed image for %d datasets...\n\n"
3723
+ " dims = ", opts->infiles.len);
3724
+ disp_raw_data(opts->ci_dims, DT_INT32, 8, ' ', 1);
3725
+ }
3726
+
3727
+ for( filenum = 0; filenum < opts->infiles.len; filenum++ )
3728
+ {
3729
+ err = 0;
3730
+ nim = nt_image_read(opts, opts->infiles.list[filenum], 0);
3731
+ if( !nim ) continue; /* errors are printed from library */
3732
+ if( opts->dts && nim->ndim != 4 )
3733
+ {
3734
+ fprintf(stderr,"** error: dataset '%s' is not 4-dimensional\n",
3735
+ nim->fname);
3736
+ err++;
3737
+ }
3738
+
3739
+ switch( nim->datatype )
3740
+ {
3741
+ case DT_INT8: case DT_INT16: case DT_INT32:
3742
+ case DT_UINT8: case DT_UINT16: case DT_UINT32:
3743
+ case DT_FLOAT32: case DT_FLOAT64:
3744
+ if( g_debug > 1 )
3745
+ fprintf(stderr,"-d datatype %d of size %d\n",
3746
+ nim->datatype, nim->nbyper);
3747
+ break;
3748
+ default:
3749
+ fprintf(stderr,"** dataset '%s' has unknown type %d\n",
3750
+ nim->fname, nim->datatype);
3751
+ err++;
3752
+ break;
3753
+ }
3754
+
3755
+ if( err ) { nifti_image_free(nim); continue; }
3756
+
3757
+ len = nifti_read_collapsed_image(nim, opts->ci_dims, &data);
3758
+ if( len < 0 || !data )
3759
+ {
3760
+ fprintf(stderr,"** FAILURE for dataset '%s'\n", nim->fname);
3761
+ if( data ) free(data);
3762
+ err++;
3763
+ }
3764
+
3765
+ /* remove check for length of time series 24 Apr 2006 */
3766
+
3767
+ if( err ){ nifti_image_free(nim); continue; }
3768
+
3769
+ /* now just print the results */
3770
+ if( g_debug > 0 )
3771
+ {
3772
+ fprintf(stdout,"\ndataset '%s' @ (", nim->fname);
3773
+ if( opts->dts ) disp_raw_data(opts->ci_dims+1, DT_INT32, 3, ' ', 0);
3774
+ else disp_raw_data(opts->ci_dims+1, DT_INT32, 7, ' ', 0);
3775
+ fprintf(stdout,")\n");
3776
+ }
3777
+
3778
+ disp_raw_data(data, nim->datatype, len / nim->nbyper, space, 1);
3779
+
3780
+ nifti_image_free(nim);
3781
+ }
3782
+
3783
+ if( data ) free(data);
3784
+
3785
+ return 0;
3786
+ }
3787
+
3788
+
3789
+ int disp_raw_data( void * data, int type, int nvals, char space, int newline )
3790
+ {
3791
+ char * dp, fbuf[32];
3792
+ int c, size;
3793
+
3794
+ nifti_datatype_sizes( type, &size, NULL ); /* get nbyper */
3795
+
3796
+ for( c = 0, dp = (char *)data; c < nvals; c++, dp += size )
3797
+ {
3798
+ switch( type )
3799
+ {
3800
+ case DT_INT8:
3801
+ printf("%d", *(char *)dp);
3802
+ break;
3803
+ case DT_INT16:
3804
+ printf("%d", *(short *)dp);
3805
+ break;
3806
+ case DT_INT32:
3807
+ printf("%d", *(int *)dp);
3808
+ break;
3809
+ case DT_UINT8:
3810
+ printf("%u", *(unsigned char *)dp);
3811
+ break;
3812
+ case DT_UINT16:
3813
+ printf("%u", *(unsigned short *)dp);
3814
+ break;
3815
+ case DT_UINT32:
3816
+ printf("%u", *(unsigned int *)dp);
3817
+ break;
3818
+ case DT_FLOAT32:
3819
+ {
3820
+ sprintf(fbuf,"%f", *(float *)dp);
3821
+ clear_float_zeros(fbuf);
3822
+ printf("%s", fbuf);
3823
+ break;
3824
+ }
3825
+ case DT_FLOAT64:
3826
+ {
3827
+ sprintf(fbuf,"%f", *(double *)dp);
3828
+ clear_float_zeros(fbuf);
3829
+ printf("%s", fbuf);
3830
+ break;
3831
+ }
3832
+ default:
3833
+ fprintf(stderr,"** disp_raw_data: unknown type %d\n", type);
3834
+ return 1;
3835
+ }
3836
+ if( c < nvals - 1 ) fputc(space,stdout);
3837
+ }
3838
+
3839
+ if ( newline ) fputc('\n',stdout);
3840
+
3841
+ return 0;
3842
+ }
3843
+
3844
+ /*----------------------------------------------------------------------
3845
+ * remove trailing zeros from string of printed float
3846
+ * return 1 if something was cleared
3847
+ * 0 if not
3848
+ *----------------------------------------------------------------------*/
3849
+ int clear_float_zeros( char * str )
3850
+ {
3851
+ char * dp = strchr(str, '.'), * valp;
3852
+ int len;
3853
+
3854
+ if( !dp ) return 0; /* nothing to clear */
3855
+
3856
+ len = strlen(dp);
3857
+
3858
+ /* never clear what is just to the right of '.' */
3859
+ for( valp = dp+len-1; (valp > dp+1) && (*valp==' ' || *valp=='0'); valp-- )
3860
+ *valp = '\0'; /* clear, so we don't worry about break conditions */
3861
+
3862
+ if( valp < dp + len - 1 ) return 1;
3863
+ return 0;
3864
+ }
3865
+
3866
+ /* return the number of volumes in the nifti_image */
3867
+ static int num_volumes(nifti_image * nim)
3868
+ {
3869
+ int ind, nvols = 1;
3870
+
3871
+ if( nim->dim[0] < 1 ) return 0;
3872
+
3873
+ for( ind = 4; ind <= nim->dim[0]; ind++ )
3874
+ nvols *= nim->dim[ind];
3875
+
3876
+ return nvols;
3877
+ }
3878
+
3879
+
3880
+ /*----------------------------------------------------------------------
3881
+ * create a new dataset using sub-brick selection
3882
+ *----------------------------------------------------------------------*/
3883
+ int act_cbl( nt_opts * opts )
3884
+ {
3885
+ nifti_brick_list NBL;
3886
+ nifti_image * nim;
3887
+ char * fname, * selstr, * cp;
3888
+ int * blist;
3889
+ int err = 0;
3890
+
3891
+ if( g_debug > 2 )
3892
+ fprintf(stderr,"-d copying file info from '%s' to '%s'\n",
3893
+ opts->infiles.list[0], opts->prefix);
3894
+
3895
+ /* sanity checks */
3896
+ if( ! opts->prefix ) {
3897
+ fprintf(stderr,"** error: -prefix is required with -cbl function\n");
3898
+ return 1;
3899
+ } else if( opts->infiles.len > 1 ) {
3900
+ fprintf(stderr,"** sorry, at the moment -cbl allows only 1 input\n");
3901
+ return 1;
3902
+ }
3903
+
3904
+ /* remove selector from fname, and copy selector string */
3905
+ fname = nifti_strdup(opts->infiles.list[0]);
3906
+ cp = strchr(fname,'['); if( !cp ) cp = strchr(fname,'{');
3907
+
3908
+ if( !cp ) {
3909
+ if( g_debug > 1 )
3910
+ fprintf(stderr,"-d using -cbl without brick list in '%s'\n",fname);
3911
+ selstr = nifti_strdup("[0..$]");
3912
+ } else {
3913
+ selstr = nifti_strdup(cp);
3914
+ *cp = '\0'; /* remove selection string from fname */
3915
+ }
3916
+
3917
+ if( g_debug > 1 )
3918
+ fprintf(stderr,"+d -cbl: using '%s' for selection string\n", selstr);
3919
+
3920
+ nim = nt_image_read(opts, fname, 0); /* get image */
3921
+ if( !nim ) return 1;
3922
+
3923
+ /* since nt can be zero now (sigh), check for it 02 Mar 2006 [rickr] */
3924
+ blist = nifti_get_intlist(nim->nt > 0 ? num_volumes(nim) : 1, selstr);
3925
+ nifti_image_free(nim); /* throw away, will re-load */
3926
+ if( !blist ){
3927
+ fprintf(stderr,"** failed sub-brick selection using '%s'\n",selstr);
3928
+ free(fname); free(selstr); return 1;
3929
+ }
3930
+
3931
+ nim = nt_read_bricks(opts, fname, blist[0], blist+1, &NBL);
3932
+ free(blist); /* with this */
3933
+ if( !nim ){ free(fname); free(selstr); return 1; }
3934
+
3935
+ if( g_debug > 1 ) fprintf(stderr,"+d sub-bricks loaded\n");
3936
+
3937
+ /* add command as COMMENT extension */
3938
+ if( opts->keep_hist && nifti_add_extension(nim, opts->command,
3939
+ strlen(opts->command), NIFTI_ECODE_COMMENT) )
3940
+ fprintf(stderr,"** failed to add command to image as extension\n");
3941
+
3942
+ /* replace filenames using prefix */
3943
+ if( nifti_set_filenames(nim, opts->prefix, 1, 1) )
3944
+ {
3945
+ fprintf(stderr,"** failed to set names, prefix = '%s'\n",opts->prefix);
3946
+ err++;
3947
+ }
3948
+
3949
+ if(g_debug>2) disp_field("new nim:\n",g_nim_fields,nim,NT_NIM_NUM_FIELDS,1);
3950
+
3951
+ /* and finally, write out results */
3952
+ if( err == 0 && nifti_nim_is_valid(nim, g_debug) )
3953
+ nifti_image_write_bricks(nim, &NBL);
3954
+
3955
+ nifti_image_free(nim);
3956
+ nifti_free_NBL(&NBL);
3957
+ free(fname);
3958
+ free(selstr);
3959
+
3960
+ return 0;
3961
+ }
3962
+
3963
+
3964
+ /*----------------------------------------------------------------------
3965
+ * create a new dataset using read_collapsed_image
3966
+ *----------------------------------------------------------------------*/
3967
+ int act_cci( nt_opts * opts )
3968
+ {
3969
+ nifti_image * nim;
3970
+ int c;
3971
+
3972
+ if( g_debug > 2 )
3973
+ fprintf(stderr,"-d collapsing file info from '%s' to '%s'\n",
3974
+ opts->infiles.list[0], opts->prefix);
3975
+
3976
+ /* sanity checks */
3977
+ if( ! opts->prefix ) {
3978
+ fprintf(stderr,"** error: -prefix is required with -cci function\n");
3979
+ return 1;
3980
+ } else if( opts->infiles.len > 1 ) {
3981
+ fprintf(stderr,"** sorry, at the moment -cci allows only 1 input\n");
3982
+ return 1;
3983
+ }
3984
+
3985
+ nim = nt_image_read(opts, opts->infiles.list[0], 0);
3986
+ if( !nim ) return 1;
3987
+ nim->data = NULL; /* just to be sure */
3988
+
3989
+ if( nifti_read_collapsed_image(nim, opts->ci_dims, &nim->data) < 0 )
3990
+ {
3991
+ nifti_image_free(nim);
3992
+ return 1;
3993
+ }
3994
+
3995
+ /* add command as COMMENT extension */
3996
+ if( opts->keep_hist && nifti_add_extension(nim, opts->command,
3997
+ strlen(opts->command), NIFTI_ECODE_COMMENT) )
3998
+ fprintf(stderr,"** failed to add command to image as extension\n");
3999
+
4000
+ /* replace filenames using prefix */
4001
+ if( nifti_set_filenames(nim, opts->prefix, 1, 1) )
4002
+ {
4003
+ fprintf(stderr,"** failed to set names, prefix = '%s'\n",opts->prefix);
4004
+ nifti_image_free(nim);
4005
+ return 1;
4006
+ }
4007
+
4008
+ for( c = 1; c < 8; c++ ) /* nuke any collapsed dimension */
4009
+ if( opts->ci_dims[c] >= 0 ) nim->dim[c] = 1;
4010
+
4011
+ nifti_update_dims_from_array(nim);
4012
+
4013
+ if(g_debug>2) disp_field("new nim:\n",g_nim_fields,nim,NT_NIM_NUM_FIELDS,1);
4014
+
4015
+ /* and finally, write out results */
4016
+ if( nifti_nim_is_valid(nim, g_debug) ) nifti_image_write(nim);
4017
+
4018
+ nifti_image_free(nim);
4019
+
4020
+ return 0;
4021
+ }
4022
+
4023
+
4024
+ /*----------------------------------------------------------------------
4025
+ * free all of the lists in the struct
4026
+ * note: strings were not allocated
4027
+ *----------------------------------------------------------------------*/
4028
+ static int free_opts_mem( nt_opts * nopt )
4029
+ {
4030
+ if( !nopt ) return 1;
4031
+
4032
+ if( nopt->elist.list ) free(nopt->elist.list);
4033
+ if( nopt->etypes.list ) free(nopt->etypes.list);
4034
+ if( nopt->flist.list ) free(nopt->flist.list);
4035
+ if( nopt->vlist.list ) free(nopt->vlist.list);
4036
+ if( nopt->infiles.list ) free(nopt->infiles.list);
4037
+
4038
+ return 0;
4039
+ }
4040
+
4041
+
4042
+ /*----------------------------------------------------------------------
4043
+ * wrapper for nifti_image_read
4044
+ *
4045
+ * this adds the option to generage an empty image, if the
4046
+ * filename starts with "MAKE_IM"
4047
+ *----------------------------------------------------------------------*/
4048
+ nifti_image * nt_image_read( nt_opts * opts, char * fname, int doread )
4049
+ {
4050
+ if( !opts || !fname ) {
4051
+ fprintf(stderr,"** nt_image_read: bad params (%p,%p)\n",
4052
+ (void *)opts, (void *)fname);
4053
+ return NULL;
4054
+ }
4055
+
4056
+ /* if the user does not want an empty image, do normal image_read */
4057
+ if( strncmp(fname,NT_MAKE_IM_NAME,strlen(NT_MAKE_IM_NAME)) ) {
4058
+ if(g_debug > 1)
4059
+ fprintf(stderr,"-d calling nifti_image_read(%s,%d)\n",fname,doread);
4060
+ return nifti_image_read(fname, doread);
4061
+ }
4062
+
4063
+ /* so generate an emtpy image */
4064
+ if(g_debug > 1) {
4065
+ fprintf(stderr,"+d NT_IR: generating EMPTY IMAGE from %s...\n",fname);
4066
+ if(g_debug > 2) {
4067
+ printf(" new_dim[8] = ");
4068
+ disp_raw_data(opts->new_dim, DT_INT32, 8, ' ', 1);
4069
+ printf(" new_datatype = %d\n", opts->new_datatype);
4070
+ fflush(stdout);
4071
+ }
4072
+ }
4073
+
4074
+ /* create a new nifti_image, with data depending on doread */
4075
+ return nifti_make_new_nim(opts->new_dim, opts->new_datatype, doread);
4076
+ }
4077
+
4078
+
4079
+ /*----------------------------------------------------------------------
4080
+ * wrapper for nifti_read_header
4081
+ *
4082
+ * this adds the option to generage an empty image, if the
4083
+ * filename starts with "MAKE_IM"
4084
+ *----------------------------------------------------------------------*/
4085
+ nifti_1_header * nt_read_header(nt_opts * opts, char * fname, int * swapped,
4086
+ int check)
4087
+ {
4088
+ /* swapped is not necessary */
4089
+ if( !opts || !fname ) {
4090
+ fprintf(stderr,"** nt_read_header: bad params (%p,%p)\n",
4091
+ (void *)opts,(void *)fname);
4092
+ return NULL;
4093
+ }
4094
+
4095
+ /* if the user does not want an empty image, do normal image_read */
4096
+ if( strncmp(fname,NT_MAKE_IM_NAME,strlen(NT_MAKE_IM_NAME)) ) {
4097
+ if(g_debug > 1)
4098
+ fprintf(stderr,"-d calling nifti_read_header(%s,...)\n", fname);
4099
+ return nifti_read_header(fname, swapped, check);
4100
+ }
4101
+
4102
+ /* so generate an emtpy image */
4103
+ if(g_debug > 1) {
4104
+ fprintf(stderr,"+d NT_RH: generating EMPTY IMAGE from %s...\n",fname);
4105
+ if(g_debug > 2) {
4106
+ printf(" new_dim[8] = ");
4107
+ disp_raw_data(opts->new_dim, DT_INT32, 8, ' ', 1);
4108
+ printf(" new_datatype = %d\n", opts->new_datatype);
4109
+ fflush(stdout);
4110
+ }
4111
+ }
4112
+
4113
+ /* return creation of new header */
4114
+ return nifti_make_new_header(opts->new_dim, opts->new_datatype);
4115
+ }
4116
+
4117
+
4118
+
4119
+ /*----------------------------------------------------------------------
4120
+ * wrapper for nifti_read_header
4121
+ *
4122
+ * this adds the option to generage an empty image, if the
4123
+ * filename starts with "MAKE_IM"
4124
+ *----------------------------------------------------------------------*/
4125
+ nifti_image * nt_read_bricks(nt_opts * opts, char * fname, int len, int * list,
4126
+ nifti_brick_list * NBL)
4127
+ {
4128
+ nifti_image * nim;
4129
+ int c;
4130
+
4131
+ /* swapped is not necessary */
4132
+ if( !opts || !fname || !NBL ) {
4133
+ fprintf(stderr,"** nt_read_bricks: bad params (%p,%p,%p)\n",
4134
+ (void *)opts, (void *)fname, (void *)NBL);
4135
+ return NULL;
4136
+ }
4137
+
4138
+ /* if the user does not want an empty image, do normal read_bricks */
4139
+ if( strncmp(fname,NT_MAKE_IM_NAME,strlen(NT_MAKE_IM_NAME)) ) {
4140
+ if(g_debug > 1)
4141
+ fprintf(stderr,"-d calling nifti_image_read_bricks(%s,...)\n",fname);
4142
+ return nifti_image_read_bricks(fname, len, list, NBL);
4143
+ }
4144
+
4145
+ /* so generate an emtpy image */
4146
+ if(g_debug > 1) {
4147
+ fprintf(stderr,"+d NT_RB: generating EMPTY IMAGE from %s...\n",fname);
4148
+ if(g_debug > 2) {
4149
+ printf(" new_dim[8] = ");
4150
+ disp_raw_data(opts->new_dim, DT_INT32, 8, ' ', 1);
4151
+ printf(" new_datatype = %d\n", opts->new_datatype);
4152
+ if( list && len > 0 ) {
4153
+ printf(" brick_list[%d] = ", len);
4154
+ disp_raw_data(list, DT_INT32, len, ' ', 1);
4155
+ }
4156
+ fflush(stdout); /* disp_raw_data uses stdout */
4157
+ }
4158
+ }
4159
+
4160
+ /* first, get nim struct without data */
4161
+ nim = nifti_make_new_nim(opts->new_dim, opts->new_datatype, 0);
4162
+ if( !nim ) {
4163
+ fprintf(stderr,"** nt_read_bricks, nifti_make_new_nim failure\n");
4164
+ return NULL;
4165
+ }
4166
+
4167
+ /* now populate NBL (can be based only on len and nim) */
4168
+ NBL->nbricks = len;
4169
+ NBL->bsize = (size_t)nim->nbyper * nim->nx * nim->ny * nim->nz;
4170
+ NBL->bricks = (void **)calloc(NBL->nbricks, sizeof(void *));
4171
+ if( !NBL->bricks ){
4172
+ fprintf(stderr,"** NRB: failed to alloc %d pointers\n",NBL->nbricks);
4173
+ nifti_image_free(nim);
4174
+ return NULL;
4175
+ }
4176
+
4177
+ if(g_debug > 1)
4178
+ fprintf(stderr,"+d NRB, allocating %d bricks of %u bytes...\n",
4179
+ NBL->nbricks, (unsigned)NBL->bsize);
4180
+
4181
+ /* now allocate the data pointers */
4182
+ for( c = 0; c < len; c++ ) {
4183
+ NBL->bricks[c] = calloc(1, NBL->bsize);
4184
+ if( !NBL->bricks[c] ){
4185
+ fprintf(stderr,"** NRB: failed to alloc brick %d of %u bytes\n",
4186
+ c, (unsigned)NBL->bsize);
4187
+ nifti_free_NBL(NBL); nifti_image_free(nim); return NULL;
4188
+ }
4189
+ }
4190
+
4191
+ return nim;
4192
+ }
4193
+