nifti_tool.c
来自「DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.」· C语言 代码 · 共 1,625 行 · 第 1/5 页
C
1,625 行
/*--------------------------------------------------------------------------*/
/*! \file nifti_tool.c
* \brief a tool for nifti file perusal, manipulation and copying
* written by Rick Reynolds, SSCC, NIMH, January 2005
* <pre>
*
* usage: nifti_tool [options] -infiles files...
*
* Via this tool, one should be able to:
*
* - copy a set of volumes (sub-bricks) from one dataset to another
* - copy a dataset, restricting some dimensions to given indices
*
* - display the contents of a nifti_image (or various fields)
* - display the contents of a nifti1_header (or various fields)
* - display AFNI extensions (they are text)
* - display the time series at coordinates i,j,k
* - display the data from any collapsed image
*
* - do a diff on two nifti_image structs (or various fields)
* - do a diff on two nifti1_header structs (or various fields)
*
* - add an AFNI extension
* - remove any extension
*
* - modify any field(s) of a nifti_image
* - modify any field(s) of a nifti1_struct
*
* usage forms:
*
* nifti_tool -help
* nifti_tool -help_hdr
* nifti_tool -help_nim
* nifti_tool -help_datatypes
* nifti_tool -hist
* nifti_tool -ver
* nifti_tool -nifti_hist
* nifti_tool -nifti_ver
*
* nifti_tool -check_hdr -infiles f1 ...
* nifti_tool -check_nim -infiles f1 ...
* nifti_tool -disp_exts -infiles f1 ...
* nifti_tool -disp_hdr [-field fieldname] [...] -infiles f1 ...
* nifti_tool -disp_nim [-field fieldname] [...] -infiles f1 ...
* nifti_tool -disp_ts I J K [-dci_lines] -infiles f1 ...
* nifti_tool -disp_ci I J K T U V W [-dci_lines] -infiles f1 ...
*
* nifti_tool -diff_hdr [-field fieldname] [...] -infiles f1 f2
* nifti_tool -diff_nim [-field fieldname] [...] -infiles f1 f2
*
* nifti_tool -add_afni_ext "extension in quotes" -infiles f1 ...
* nifti_tool -add_comment_ext "extension in quotes" -infiles f1 ...
* nifti_tool -rm_ext ext_index -infiles f1 ...
*
* nifti_tool -mod_hdr [-mod_field fieldname new_val] [...] -infiles f1 ...
* nifti_tool -mod_nim [-mod_field fieldname new_val] [...] -infiles f1 ...
*
* </pre> */
/*-------------------------------------------------------------------------*/
/*! module history */
static char * g_history[] =
{
"----------------------------------------------------------------------\n"
"nifti_tool modification history:\n"
"\n",
"0.1 30 December 2004 [rickr]\n"
" (Rick Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
" - skeleton version: options read and printed\n"
"\n",
"1.0 07 January 2005 [rickr]\n"
" - initial release version\n"
"\n",
"1.1 14 January 2005 [rickr]\n"
" - changed all non-error/non-debug output from stderr to stdout\n"
" note: creates a mis-match between normal output and debug messages\n"
" - modified act_diff_hdrs and act_diff_nims to do the processing in\n"
" lower-level functions\n",
" - added functions diff_hdrs, diff_hdrs_list, diff_nims, diff_nims_list\n"
" - added function get_field, to return a struct pointer via a fieldname\n"
" - made 'quiet' output more quiet (no description on output)\n"
" - made hdr and nim_fields arrays global, so do not pass in main()\n"
" - return (from main()) after first act_diff() difference\n"
"\n",
"1.2 9 February 2005 [rickr] - minor\n"
" - defined a local NTL_FERR macro (so it does not come from nifti1_io.h)\n"
" - added new set_byte_order parameter to nifti_set_filenames\n"
"\n",
"1.3 23 February 2005 [rickr] - sourceforge.net merge\n"
" - moved to utils directory\n"
" - added simple casts of 3 pointers for -pedantic warnings\n"
" - added a doxygen comment for the file\n"
"\n",
"1.4 02 March 2005 [rickr] - small update\n"
" - no validation in nifti_read_header calls\n"
"\n",
"1.5 05 April 2005 [rickr] - small update\n"
" - refuse mod_hdr for gzipped files (we cannot do partial overwrites)\n"
"\n",
"1.6 08 April 2005 [rickr] - added cbl, cci and dts functionality\n"
" - added -cbl: 'copy brick list' dataset copy functionality\n"
" - added -ccd: 'copy collapsed data' dataset copy functionality\n"
" - added -disp_ts: 'disp time series' data display functionality\n"
" - moved raw data display to disp_raw_data()\n"
"\n",
"1.7 14 April 2005 [rickr] - added data display functionality\n"
" - added -dci: 'display collapsed image' functionality\n"
" - modified -dts to use -dci\n"
" - modified and updated the help in use_full()\n"
" - changed copy_collapsed_dims to copy_collapsed_image, etc.\n",
" - fixed problem in disp_raw_data() for printing NT_DT_CHAR_PTR\n"
" - modified act_disp_ci():\n"
" o was act_disp_ts(), now displays arbitrary collapsed image data\n"
" o added missed debug filename act_disp_ci()\n"
" o can now save free() of data pointer for end of file loop\n",
" - modified disp_raw_data()\n"
" o takes a flag for whether to print newline\n"
" o trailing spaces and zeros are removed from printing floats\n"
" - added clear_float_zeros(), to remove trailing zeros\n"
"\n",
"1.8 19 April 2005 [rickr] - COMMENT extensions\n"
" - added int_list struct, and keep_hist,etypes,command fields to nt_opts\n"
" - added -add_comment_ext action\n"
" - allowed for removal of multiple extensions, including option of ALL\n"
" - added -keep_hist option, to store the command as a COMMENT extension\n",
" (includes fill_cmd_string() and add_int(), is done for all actions)\n"
" - added remove_ext_list(), for removing a list of extensions by indices\n"
" - added -strip action, to strip all extensions and descrip fields\n"
"\n",
"1.9 25 Aug 2005 [rickr] - const/string cleanup for warnings\n",
"1.10 18 Nov 2005 [rickr] - added check_hdr and check_nim actions\n",
"1.11 31 Jan 2006 [rickr] - check for new vox_offset in act_mod_hdrs\n",
"1.12 02 Mar 2006 [rickr]\n"
" - in act_cbl(), check for nt = 0 because of niftilib update 1.17\n",
"1.13 24 Apr 2006 [rickr] - act_disp_ci(): remove time series length check\n",
"1.14 04 Jun 2007 [rickr] - free_opts_mem(), to appease valgrind\n",
"1.15 05 Jun 2007 [rickr] - act_check_hdrs: free(nim)->nifti_image_free()\n",
"1.16 12 Jun 2007 [rickr] - allow creation of datasets via MAKE_IM\n",
" - added nt_image_read, nt_read_header and nt_read_bricks\n"
" to wrap nifti read functions, allowing creation of new datasets\n"
" - added -make_im, -new_dim, -new_datatype and -copy_im\n"
"1.17 13 Jun 2007 [rickr] - added help for -copy_im, enumerate examples\n",
"1.18 23 Jun 2007 [rickr] - main returns 0 on -help, -hist, -ver\n"
"1.19 28 Nov 2007 [rickr] - added -help_datatypes\n",
"----------------------------------------------------------------------\n"
};
static char g_version[] = "version 1.19 (Nov 28, 2007)";
static int g_debug = 1;
#define _NIFTI_TOOL_C_
#include "nifti1_io.h"
#include "nifti_tool.h"
/* local prototypes */
static int free_opts_mem( nt_opts * nopt );
#define NTL_FERR(func,msg,file) \
fprintf(stderr,"** ERROR (%s): %s '%s'\n",func,msg,file)
/* val may be a function call, so evalulate first, and return result */
#define FREE_RETURN(val) \
do{ int tval=(val); free_opts_mem(&opts); return tval; } while(0)
/* these are effectively constant, and are built only for verification */
field_s g_hdr_fields[NT_HDR_NUM_FIELDS]; /* nifti_1_header fields */
field_s g_nim_fields[NT_NIM_NUM_FIELDS]; /* nifti_image fields */
int main( int argc, char * argv[] )
{
nt_opts opts;
int rv;
if( (rv = process_opts(argc, argv, &opts)) != 0) /* then return */
{
if( rv < 0 ) FREE_RETURN(1); /* free opts memory, and return */
else FREE_RETURN(0); /* valid usage */
}
if( (rv = verify_opts(&opts, argv[0])) != 0 )
FREE_RETURN(rv);
/* now perform the requested action(s) */
if( (rv = fill_hdr_field_array(g_hdr_fields)) != 0 )
FREE_RETURN(rv);
if( (rv = fill_nim_field_array(g_nim_fields)) != 0 )
FREE_RETURN(rv);
/* 'check' functions, first */
if( opts.check_hdr || opts.check_nim ) /* allow for both */
FREE_RETURN( act_check_hdrs(&opts) );
/* copy or dts functions -- do not continue after these */
if( opts.cbl ) FREE_RETURN( act_cbl(&opts) );
if( opts.cci ) FREE_RETURN( act_cci(&opts) );
if( opts.dts || opts.dci ) FREE_RETURN( act_disp_ci(&opts) );
/* perform modifications early, in case we allow multiple actions */
if( opts.strip && ((rv = act_strip (&opts)) != 0) ) FREE_RETURN(rv);
if( opts.add_exts && ((rv = act_add_exts (&opts)) != 0) ) FREE_RETURN(rv);
if( opts.rm_exts && ((rv = act_rm_ext (&opts)) != 0) ) FREE_RETURN(rv);
if( opts.mod_hdr && ((rv = act_mod_hdrs (&opts)) != 0) ) FREE_RETURN(rv);
if( opts.mod_nim && ((rv = act_mod_nims (&opts)) != 0) ) FREE_RETURN(rv);
/* if a diff, return wither a difference exists (like the UNIX command) */
if( opts.diff_hdr && ((rv = act_diff_hdrs(&opts)) != 0) ) FREE_RETURN(rv);
if( opts.diff_nim && ((rv = act_diff_nims(&opts)) != 0) ) FREE_RETURN(rv);
/* last action type is display */
if( opts.disp_exts && ((rv = act_disp_exts(&opts)) != 0) ) FREE_RETURN(rv);
if( opts.disp_hdr && ((rv = act_disp_hdrs(&opts)) != 0) ) FREE_RETURN(rv);
if( opts.disp_nim && ((rv = act_disp_nims(&opts)) != 0) ) FREE_RETURN(rv);
FREE_RETURN(0);
}
/*----------------------------------------------------------------------
* process user options, return 0 on success
*----------------------------------------------------------------------*/
int process_opts( int argc, char * argv[], nt_opts * opts )
{
int ac;
memset(opts, 0, sizeof(*opts));
opts->prefix = NULL;
opts->debug = 1; /* init debug level to basic output */
/* init options for creating a new dataset via "MAKE_IM" */
opts->new_datatype = NIFTI_TYPE_INT16;
opts->new_dim[0] = 3;
opts->new_dim[1] = 1; opts->new_dim[2] = 1; opts->new_dim[3] = 1;
if( argc < 2 ) return usage(argv[0], USE_SHORT);
/* terminal options are first, the rest are sorted */
for( ac = 1; ac < argc; ac++ )
{
if( ! strncmp(argv[ac], "-help_datatypes", 9) )
{
ac++;
if( ac >= argc )
nifti_disp_type_list(3); /* show all types */
else if( argv[ac][0] == 'd' || argv[ac][0] == 'D' )
nifti_disp_type_list(1); /* show DT_* types */
else if( argv[ac][0] == 't' || argv[ac][0] == 'T' )
nifti_test_datatype_sizes(1); /* test each nbyper and swapsize */
else
nifti_disp_type_list(2); /* show NIFTI_* types */
return 1;
}
else if( ! strncmp(argv[ac], "-help_hdr", 9) )
return usage(argv[0], USE_FIELD_HDR);
else if( ! strncmp(argv[ac], "-help_nim", 9) )
return usage(argv[0], USE_FIELD_NIM);
else if( ! strncmp(argv[ac], "-help", 5) )
return usage(argv[0], USE_FULL);
else if( ! strncmp(argv[ac], "-hist", 5) )
return usage(argv[0], USE_HIST);
else if( ! strncmp(argv[ac], "-ver", 2) )
return usage(argv[0], USE_VERSION);
else if( ! strncmp(argv[ac], "-nifti_hist", 11) )
{
nifti_disp_lib_hist();
return 1;
}
else if( ! strncmp(argv[ac], "-nifti_ver", 10) )
{
nifti_disp_lib_version();
return 1;
}
/* begin normal execution options... */
else if( ! strncmp(argv[ac], "-add_afni_ext", 9) )
{
ac++;
CHECK_NEXT_OPT(ac, argc, "-add_afni_ext");
if( add_string(&opts->elist, argv[ac]) ) return -1; /* add extension */
if( add_int(&opts->etypes, NIFTI_ECODE_AFNI) ) return -1;
opts->add_exts = 1;
}
else if( ! strncmp(argv[ac], "-add_comment_ext", 9) )
{
ac++;
CHECK_NEXT_OPT(ac, argc, "-add_comment_ext");
if( add_string(&opts->elist, argv[ac]) ) return -1; /* add extension */
if( add_int(&opts->etypes, NIFTI_ECODE_COMMENT) ) return -1;
opts->add_exts = 1;
}
else if( ! strncmp(argv[ac], "-check_hdr", 10) )
opts->check_hdr = 1;
else if( ! strncmp(argv[ac], "-check_nim", 10) )
opts->check_nim = 1;
else if( ! strncmp(argv[ac], "-copy_brick_list", 11) ||
! strncmp(argv[ac], "-copy_im", 10) ||
! strncmp(argv[ac], "-cbl", 4) )
{
opts->cbl = 1;
}
else if( ! strncmp(argv[ac], "-copy_collapsed_image", 10) ||
! strncmp(argv[ac], "-cci", 4) )
{
/* we need to read in the 7 dimension values */
int index;
opts->ci_dims[0] = 0;
for( index = 1; index < 8; index++ )
{
ac++;
CHECK_NEXT_OPT_MSG(ac,argc,"-cci","7 dimension values are requred");
if( ! isdigit(argv[ac][0]) && strcmp(argv[ac],"-1") ){
fprintf(stderr,"** -cci param %d (= '%s') is not a valid\n"
" consider: 'nifti_tool -help'\n",index,argv[ac]);
return -1;
}
opts->ci_dims[index] = atoi(argv[ac]);
}
opts->cci = 1;
}
else if( ! strncmp(argv[ac], "-debug", 6) )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?