Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
imcalc.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include "parser.h"
00008 #include "mrilib.h"
00009
00010
00011
00012 static int CALC_datum = -1 ;
00013 static int CALC_nvox = -1 ;
00014 static PARSER_code * CALC_code = NULL ;
00015
00016 static int CALC_nx=-1 , CALC_ny=-1 ;
00017
00018 static MRI_IMAGE * CALC_im[26] ;
00019 static int CALC_type[26] ;
00020 static byte * CALC_byte[26] ;
00021 static short * CALC_short[26] ;
00022 static float * CALC_float[26] ;
00023
00024 static char CALC_output_name[256] = "imcalc.out" ;
00025
00026
00027 void CALC_read_opts( int , char ** ) ;
00028 void CALC_Syntax(void) ;
00029
00030
00031
00032
00033
00034 void CALC_read_opts( int argc , char * argv[] )
00035 {
00036 int nopt = 1 ;
00037 int ids ;
00038
00039 for( ids=0 ; ids < 26 ; ids++ ){
00040 CALC_type[ids] = -1 ;
00041 }
00042
00043 while( nopt < argc && argv[nopt][0] == '-' ){
00044
00045
00046
00047 if( strncmp(argv[nopt],"-nxy",4) == 0 ){
00048 if( ++nopt >= argc-1 ){
00049 fprintf(stderr,"need 2 arguments after -nxy!\n"); exit(1);
00050 }
00051 CALC_nx = strtol(argv[nopt++],NULL,10) ;
00052 CALC_ny = strtol(argv[nopt++],NULL,10) ;
00053 continue ;
00054 }
00055
00056
00057
00058 if( strncmp(argv[nopt],"-datum",6) == 0 ){
00059 if( ++nopt >= argc ){
00060 fprintf(stderr,"need an argument after -datum!\n") ; exit(1) ;
00061 }
00062 if( strcmp(argv[nopt],"short") == 0 ){
00063 CALC_datum = MRI_short ;
00064 } else if( strcmp(argv[nopt],"float") == 0 ){
00065 CALC_datum = MRI_float ;
00066 } else if( strcmp(argv[nopt],"byte") == 0 ){
00067 CALC_datum = MRI_byte ;
00068 } else {
00069 fprintf(stderr,"-datum of type '%s' is not supported in 3dmerge!\n",
00070 argv[nopt] ) ;
00071 exit(1) ;
00072 }
00073 nopt++ ; continue ;
00074 }
00075
00076
00077
00078 if( strncmp(argv[nopt],"-output",6) == 0 ){
00079 nopt++ ;
00080 if( nopt >= argc ){
00081 fprintf(stderr,"need argument after -output!\n") ; exit(1) ;
00082 }
00083 strncpy( CALC_output_name , argv[nopt++] , 255 ) ; CALC_output_name[255] = '\0' ;
00084 continue ;
00085 }
00086
00087
00088
00089 if( strncmp(argv[nopt],"-expr",4) == 0 ){
00090 if( CALC_code != NULL ){
00091 fprintf(stderr,"cannot have 2 -expr options!\n") ; exit(1) ;
00092 }
00093 nopt++ ;
00094 if( nopt >= argc ){
00095 fprintf(stderr,"need argument after -expr!\n") ; exit(1) ;
00096 }
00097 CALC_code = PARSER_generate_code( argv[nopt++] ) ;
00098 if( CALC_code == NULL ){
00099 fprintf(stderr,"illegal expression!\n") ; exit(1) ;
00100 }
00101 continue ;
00102 }
00103
00104
00105
00106 ids = strlen(argv[nopt]) ;
00107
00108 if( (argv[nopt][1] >= 'a' && argv[nopt][1] <= 'z') && (ids == 2) ){
00109
00110 int ival , nxyz ;
00111 MRI_IMAGE * im ;
00112
00113 ival = argv[nopt][1] - 'a' ;
00114 if( CALC_im[ival] != NULL ){
00115 fprintf(stderr,"can't open duplicate %s images!\n",argv[nopt]) ;
00116 exit(1) ;
00117 }
00118
00119 nopt++ ;
00120 if( nopt >= argc ){
00121 fprintf(stderr,"need argument after %s!\n",argv[nopt-1]) ; exit(1) ;
00122 }
00123
00124 im = mri_read_just_one( argv[nopt++] ) ;
00125 if( im == NULL ){
00126 fprintf(stderr,"can't open image %s\n",argv[nopt-1]) ; exit(1) ;
00127 }
00128
00129 nxyz = im->nvox ;
00130 if( CALC_nvox < 0 ){
00131 CALC_nvox = nxyz ;
00132 } else if( nxyz != CALC_nvox ){
00133 fprintf(stderr,"image %s differs in size from others\n",argv[nopt-1]);
00134 exit(1) ;
00135 }
00136
00137 CALC_type[ival] = im->kind ;
00138 CALC_im[ival] = im ;
00139
00140 switch( CALC_type[ival] ){
00141 default: fprintf(stderr,"illegal datum in image %s\n",argv[nopt-1]);
00142 exit(1) ;
00143
00144 case MRI_short: CALC_short[ival] = MRI_SHORT_PTR(im) ; break ;
00145 case MRI_float: CALC_float[ival] = MRI_FLOAT_PTR(im) ; break ;
00146 case MRI_byte : CALC_byte [ival] = MRI_BYTE_PTR(im) ; break ;
00147 }
00148
00149 if( CALC_datum < 0 ) CALC_datum = CALC_type[ival] ;
00150 continue ;
00151 }
00152
00153 fprintf(stderr,"Unknown option: %s\n",argv[nopt]) ; exit(1) ;
00154
00155 }
00156
00157
00158
00159 if( nopt < argc ){
00160 fprintf(stderr,"Extra command line arguments puzzle me! %s ...\n",argv[nopt]) ;
00161 exit(1) ;
00162 }
00163
00164 for( ids=0 ; ids < 26 ; ids++ ) if( CALC_im[ids] != NULL ) break ;
00165
00166 if( ids == 26 && (CALC_nx < 2 || CALC_ny < 2) ){
00167 fprintf(stderr,"No input images given!\n") ; exit(1) ;
00168 }
00169
00170 if( CALC_code == NULL ){
00171 fprintf(stderr,"No expression given!\n") ; exit(1) ;
00172 }
00173
00174 return ;
00175 }
00176
00177
00178
00179 void CALC_Syntax(void)
00180 {
00181 printf(
00182 "Do arithmetic on 2D images, pixel-by-pixel.\n"
00183 "Usage: imcalc options\n"
00184 "where the options are:\n"
00185 ) ;
00186
00187 printf(
00188 " -datum type = Coerce the output data to be stored as the given type,\n"
00189 " which may be byte, short, or float.\n"
00190 " [default = datum of first input image]\n"
00191 " -a dname = Read image 'dname' and call the voxel values 'a'\n"
00192 " in the expression. 'a' may be any letter from 'a' to 'z'.\n"
00193 " ** If some letter name is used in the expression, but not\n"
00194 " present in one of the image options here, then that\n"
00195 " variable is set to 0.\n"
00196 " -expr \"expression\"\n"
00197 " Apply the expression within quotes to the input images,\n"
00198 " one voxel at a time, to produce the output image.\n"
00199 " (\"sqrt(a*b)\" to compute the geometric mean, for example)\n"
00200 " -output name = Use 'name' for the output image filename.\n"
00201 " [default='imcalc.out']\n"
00202 "\n"
00203 "See the output of '3dcalc -help' for details on what kinds of expressions\n"
00204 "are possible. Note that complex-valued images cannot be processed (byte,\n"
00205 "short, and float are OK).\n"
00206 ) ;
00207 exit(0) ;
00208 }
00209
00210
00211
00212 int main( int argc , char * argv[] )
00213 {
00214 double atoz[26] ;
00215 int ii , ids ;
00216 MRI_IMAGE * new_im ;
00217 float * fnew ;
00218
00219
00220
00221 if( argc < 2 || strncmp(argv[1],"-help",4) == 0 ) CALC_Syntax() ;
00222
00223 machdep() ;
00224
00225 CALC_read_opts( argc , argv ) ;
00226
00227
00228
00229 if( mri_filesize(CALC_output_name) > 0 ){
00230 fprintf(stderr,
00231 "*** Output file %s already exists -- cannot continue!\n",
00232 CALC_output_name ) ;
00233 exit(1) ;
00234 }
00235
00236 for( ids=0 ; ids < 26 ; ids++ ) if( CALC_im[ids] != NULL ) break ;
00237 if( ids < 26 ){
00238 new_im = mri_new_conforming( CALC_im[ids] , MRI_float ) ;
00239 } else if( CALC_nx > 1 && CALC_ny > 1 ){
00240 new_im = mri_new( CALC_nx , CALC_ny , MRI_float ) ;
00241 CALC_nvox = new_im->nvox ;
00242 }
00243 fnew = MRI_FLOAT_PTR(new_im) ;
00244
00245 for( ids=0 ; ids < 26 ; ids++ ) atoz[ids] = 0.0 ;
00246
00247
00248
00249 for( ii=0 ; ii < CALC_nvox ; ii++ ){
00250
00251 for( ids=0 ; ids < 26 ; ids++ ){
00252 switch( CALC_type[ids] ){
00253 case MRI_short: atoz[ids] = CALC_short[ids][ii] ; break;
00254 case MRI_float: atoz[ids] = CALC_float[ids][ii] ; break;
00255 case MRI_byte : atoz[ids] = CALC_byte [ids][ii] ; break;
00256 }
00257 }
00258
00259 fnew[ii] = PARSER_evaluate_one( CALC_code , atoz ) ;
00260 }
00261
00262
00263
00264 for( ids=0 ; ids < 26 ; ids++ )
00265 if( CALC_im[ids] != NULL ) mri_free( CALC_im[ids] ) ;
00266
00267
00268
00269 switch( CALC_datum ){
00270
00271 case MRI_short:{
00272 float top ;
00273 MRI_IMAGE * shim ;
00274
00275 top = mri_maxabs( new_im ) ;
00276 if( top < 32767.0 ) shim = mri_to_short( 1.0 , new_im ) ;
00277 else shim = mri_to_short_scl( 0.0 , 10000.0 , new_im ) ;
00278
00279 mri_free(new_im) ; new_im = shim ;
00280 }
00281 break ;
00282
00283 case MRI_byte:{
00284 float top ;
00285 MRI_IMAGE * bim ;
00286
00287 top = mri_maxabs( new_im ) ;
00288 if( top < 255.0 ) bim = mri_to_byte_scl( 1.0 , 0.0 , new_im ) ;
00289 else bim = mri_to_byte_scl( 0.0 , 255.0 , new_im ) ;
00290
00291 mri_free(new_im) ; new_im = bim ;
00292 }
00293 break ;
00294 }
00295
00296
00297
00298 mri_write( CALC_output_name , new_im ) ;
00299 exit(0) ;
00300 }