c_nifti 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/COPYING +621 -0
- data/COPYING.lesser +166 -0
- data/Gemfile +4 -0
- data/README.md +117 -0
- data/Rakefile +6 -0
- data/c_nifti.gemspec +31 -0
- data/ext/nifticlib/extconf.rb +30 -0
- data/ext/nifticlib/include/nifti_image.h +2 -0
- data/ext/nifticlib/include/nifti_image_converters.h +3 -0
- data/ext/nifticlib/include/nifti_image_dimensions.h +1 -0
- data/ext/nifticlib/include/nifti_image_intents.h +1 -0
- data/ext/nifticlib/include/nifti_image_metadata.h +1 -0
- data/ext/nifticlib/include/nifti_image_quaternions.h +1 -0
- data/ext/nifticlib/include/nifti_image_spacings.h +1 -0
- data/ext/nifticlib/include/nifti_image_timings.h +1 -0
- data/ext/nifticlib/include/nifti_image_transforms.h +1 -0
- data/ext/nifticlib/nifti_image.c +169 -0
- data/ext/nifticlib/nifti_image_converters.c +65 -0
- data/ext/nifticlib/nifti_image_dimensions.c +113 -0
- data/ext/nifticlib/nifti_image_intents.c +45 -0
- data/ext/nifticlib/nifti_image_metadata.c +133 -0
- data/ext/nifticlib/nifti_image_quaternions.c +59 -0
- data/ext/nifticlib/nifti_image_spacings.c +87 -0
- data/ext/nifticlib/nifti_image_timings.c +66 -0
- data/ext/nifticlib/nifti_image_transforms.c +38 -0
- data/ext/nifticlib/nifticlib-2.0.0/CMakeLists.txt +140 -0
- data/ext/nifticlib/nifticlib-2.0.0/CTestConfig.cmake +13 -0
- data/ext/nifticlib/nifticlib-2.0.0/LICENSE +9 -0
- data/ext/nifticlib/nifticlib-2.0.0/Makefile +265 -0
- data/ext/nifticlib/nifticlib-2.0.0/Makefile.cross_mingw32 +94 -0
- data/ext/nifticlib/nifticlib-2.0.0/README +79 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/CMakeLists.txt +7 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/Data/ATestReferenceImageForReadingAndWriting.nii.gz +0 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/Makefile +21 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/README_regress +50 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/@show.diffs +33 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/@test +80 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/CMakeLists.txt +47 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/bricks_test.sh +32 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/comment_test.sh +65 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/dci_test.sh +46 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/dsets_test.sh +61 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/dts_test.sh +75 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/fetch_data_test.sh +45 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/mod_header_test.sh +60 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/cmake_testscripts/newfiles_test.sh +36 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c01.versions +10 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c02.nt.help +5 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c03.hist +5 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c04.disp.anat0.info +7 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c05.mod.hdr +9 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c06.add.ext +22 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c07.cbl.4bricks +8 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c08.dts.19.36.11 +4 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c09.dts4.compare +9 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c10.dci.ts4 +15 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c10a.dci.run.210 +16 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c11.add.comment +8 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c12.check.comments +7 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c13.check.hdrs +5 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c14.make.dsets +21 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c15.new.files +21 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c16.rand.swap +35 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/nifti_regress_test/commands/c17.file.case +34 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/niftilib/CMakeLists.txt +15 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/niftilib/nifti_test.c +690 -0
- data/ext/nifticlib/nifticlib-2.0.0/Testing/niftilib/nifti_test2.c +32 -0
- data/ext/nifticlib/nifticlib-2.0.0/Updates.txt +110 -0
- data/ext/nifticlib/nifticlib-2.0.0/bin/.gitkeep +0 -0
- data/ext/nifticlib/nifticlib-2.0.0/docs/Doxy_nifti.txt +123 -0
- data/ext/nifticlib/nifticlib-2.0.0/docs/Doxyfile.ORIG +746 -0
- data/ext/nifticlib/nifticlib-2.0.0/examples/CMakeLists.txt +15 -0
- data/ext/nifticlib/nifticlib-2.0.0/examples/Makefile +48 -0
- data/ext/nifticlib/nifticlib-2.0.0/examples/clib_01_read_write.c +94 -0
- data/ext/nifticlib/nifticlib-2.0.0/examples/fsl_api_driver.c +142 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/CMakeLists.txt +32 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/Makefile +29 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/fslio.c +2426 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/fslio.tcl +83 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imcp +65 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imglob +59 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imln +37 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/immv +64 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imrm +29 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/imtest +53 -0
- data/ext/nifticlib/nifticlib-2.0.0/fsliolib/remove_ext +33 -0
- data/ext/nifticlib/nifticlib-2.0.0/include/.gitkeep +0 -0
- data/ext/nifticlib/nifticlib-2.0.0/nifticdf/CMakeLists.txt +28 -0
- data/ext/nifticlib/nifticlib-2.0.0/nifticdf/Makefile +28 -0
- data/ext/nifticlib/nifticlib-2.0.0/nifticdf/nifticdf.c +11107 -0
- data/ext/nifticlib/nifticlib-2.0.0/niftilib/CMakeLists.txt +33 -0
- data/ext/nifticlib/nifticlib-2.0.0/niftilib/Makefile +31 -0
- data/ext/nifticlib/nifticlib-2.0.0/niftilib/nifti1_io.c +7509 -0
- data/ext/nifticlib/nifticlib-2.0.0/packaging/DevPackage.template +18 -0
- data/ext/nifticlib/nifticlib-2.0.0/packaging/nifticlib.spec +62 -0
- data/ext/nifticlib/nifticlib-2.0.0/real_easy/nifti1_read_write.c +361 -0
- data/ext/nifticlib/nifticlib-2.0.0/utils/CMakeLists.txt +73 -0
- data/ext/nifticlib/nifticlib-2.0.0/utils/Makefile +55 -0
- data/ext/nifticlib/nifticlib-2.0.0/utils/nifti1_test.c +95 -0
- data/ext/nifticlib/nifticlib-2.0.0/utils/nifti_stats.c +95 -0
- data/ext/nifticlib/nifticlib-2.0.0/utils/nifti_tool.c +4193 -0
- data/ext/nifticlib/nifticlib-2.0.0/utils/nifti_tool.h +163 -0
- data/ext/nifticlib/nifticlib-2.0.0/znzlib/CMakeLists.txt +31 -0
- data/ext/nifticlib/nifticlib-2.0.0/znzlib/Makefile +33 -0
- data/ext/nifticlib/nifticlib-2.0.0/znzlib/znzlib.c +322 -0
- data/ext/nifticlib/nifticlib.c +107 -0
- data/ext/nifticlib/patches/nifticlib_fpic.patch +13 -0
- data/features/read_modify_write.feature +11 -0
- data/features/step_definitions/nifti_image_steps.rb +16 -0
- data/features/support/env.rb +14 -0
- data/features/support/fixtures/sample.nii.gz +0 -0
- data/lib/c_nifti.rb +9 -0
- data/lib/c_nifti/data.rb +70 -0
- data/lib/c_nifti/header.rb +16 -0
- data/lib/c_nifti/header_element.rb +13 -0
- data/lib/c_nifti/header_element/datatype.rb +49 -0
- data/lib/c_nifti/header_element/datatype/base.rb +9 -0
- data/lib/c_nifti/header_element/datatype/binary.rb +11 -0
- data/lib/c_nifti/header_element/datatype/double.rb +11 -0
- data/lib/c_nifti/header_element/datatype/float.rb +11 -0
- data/lib/c_nifti/header_element/datatype/long_double.rb +11 -0
- data/lib/c_nifti/header_element/datatype/long_long.rb +11 -0
- data/lib/c_nifti/header_element/datatype/signed_char.rb +11 -0
- data/lib/c_nifti/header_element/datatype/signed_int.rb +11 -0
- data/lib/c_nifti/header_element/datatype/signed_short.rb +11 -0
- data/lib/c_nifti/header_element/datatype/unsigned_char.rb +11 -0
- data/lib/c_nifti/header_element/datatype/unsigned_int.rb +11 -0
- data/lib/c_nifti/header_element/datatype/unsigned_long_long.rb +11 -0
- data/lib/c_nifti/header_element/datatype/unsigned_short.rb +11 -0
- data/lib/c_nifti/header_element/dimensions.rb +53 -0
- data/lib/c_nifti/header_element/intents.rb +25 -0
- data/lib/c_nifti/header_element/metadata.rb +49 -0
- data/lib/c_nifti/header_element/miscellaneous.rb +25 -0
- data/lib/c_nifti/header_element/quaternions.rb +33 -0
- data/lib/c_nifti/header_element/spacings.rb +45 -0
- data/lib/c_nifti/header_element/timings.rb +37 -0
- data/lib/c_nifti/header_element/transforms.rb +21 -0
- data/lib/c_nifti/image.rb +31 -0
- data/lib/c_nifti/version.rb +3 -0
- data/lib/nifticlib.rb +1 -0
- data/spec/data_spec.rb +112 -0
- data/spec/factories/nifti_images.rb +9 -0
- data/spec/header_element/datatype/base_spec.rb +9 -0
- data/spec/header_element/datatype/binary_spec.rb +9 -0
- data/spec/header_element/datatype/double_spec.rb +9 -0
- data/spec/header_element/datatype/float_spec.rb +9 -0
- data/spec/header_element/datatype/long_double_spec.rb +9 -0
- data/spec/header_element/datatype/long_long_spec.rb +9 -0
- data/spec/header_element/datatype/signed_char_spec.rb +9 -0
- data/spec/header_element/datatype/signed_int_spec.rb +9 -0
- data/spec/header_element/datatype/signed_short_spec.rb +9 -0
- data/spec/header_element/datatype/unsigned_char_spec.rb +9 -0
- data/spec/header_element/datatype/unsigned_int_spec.rb +9 -0
- data/spec/header_element/datatype/unsigned_long_long.rb +9 -0
- data/spec/header_element/datatype/unsigned_short_spec.rb +9 -0
- data/spec/header_element/datatype_spec.rb +109 -0
- data/spec/header_element/dimensions_spec.rb +105 -0
- data/spec/header_element/intents_spec.rb +48 -0
- data/spec/header_element/metadata_spec.rb +96 -0
- data/spec/header_element/miscellaneous_spec.rb +48 -0
- data/spec/header_element/quaternions_spec.rb +64 -0
- data/spec/header_element/spacings_spec.rb +88 -0
- data/spec/header_element/timings_spec.rb +72 -0
- data/spec/header_element/transforms_spec.rb +64 -0
- data/spec/image_spec.rb +39 -0
- data/spec/spec_helper.rb +85 -0
- 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
|
+
|