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 + -
显示快捷键?