Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
float_scan.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include <math.h>
00008 #include <stdio.h>
00009 #include <unistd.h>
00010 #include <stdlib.h>
00011
00012 #if defined(SUN) || defined(SOLARIS) || defined(SGI)
00013 # include <ieeefp.h>
00014 # define USE_ISNANF
00015 #endif
00016
00017 #if defined(OSF1)
00018 # define USE_ISNANF
00019 #endif
00020
00021 #if defined(HP)
00022 # define USE_ISNANF
00023 # define USE_FINITEF
00024 #endif
00025
00026 #ifdef USE_ISNANF
00027 # define IS_NAN(x) isnanf(x)
00028 #else
00029 # define IS_NAN(x) isnan(x)
00030 #endif
00031
00032 #ifdef USE_FINITEF
00033 # define IS_FINITE(x) finitef(x)
00034 #else
00035 # define IS_FINITE(x) finite(x)
00036 #endif
00037
00038 #define FSET(nf) do{ fseek(fp,sizeof(float)*(nf),SEEK_SET); fpos=(nf); } while(0)
00039
00040 #define NBUF 1024
00041
00042 #define READ_BUF do{ nbuf = fread(fbuf,sizeof(float),NBUF,fp); } while(0)
00043 #define WRITE_BUF \
00044 do{ fwrite(fbuf,sizeof(float),nbuf,stdout); fflush(stdout); } while(0)
00045
00046 int main( int argc , char * argv[] )
00047 {
00048 int iarg=1 , ii , typ ;
00049 int fix=0 , verb=0 , skip=0 ;
00050 int num_inf=0 , num_nan=0 , num_this ;
00051
00052 int fsize , fpos ; FILE * fp ;
00053
00054 int nbuf ; float fbuf[NBUF] ;
00055
00056
00057
00058 if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
00059 printf( "Usage: float_scan [options] input_filename\n"
00060 "Scans the input file of IEEE floating point numbers for\n"
00061 "illegal values: infinities and not-a-number (NaN) values.\n"
00062 "\n"
00063 "Options:\n"
00064 " -fix = Writes a copy of the input file to stdout (which\n"
00065 " should be redirected using '>'), replacing\n"
00066 " illegal values with 0. If this option is not\n"
00067 " used, the program just prints out a report.\n"
00068 " -v = Verbose mode: print out index of each illegal value.\n"
00069 " -skip n = Skip the first n floating point locations\n"
00070 " (i.e., the first %d*n bytes) in the file\n"
00071 "\n"
00072 "N.B.: This program does NOT work on compressed files, nor does it\n"
00073 " work on byte-swapped files (e.g., files transferred between\n"
00074 " Sun/SGI/HP and Intel platforms), nor does it work on images\n"
00075 " stored in the 'flim' format!\n"
00076 "\n"
00077 "The program 'exit status' is 1 if any illegal values were\n"
00078 "found in the input file. If no errors were found, then\n"
00079 "the exit status is 0. You can check the exit status by\n"
00080 "using the shell variable $status. A C-shell example:\n"
00081 " float_scan fff\n"
00082 " if ( $status == 1 ) then\n"
00083 " float_scan -fix fff > Elvis.Aaron.Presley\n"
00084 " rm -f fff\n"
00085 " mv Elvis.Aaron.Presley fff\n"
00086 " endif\n"
00087 ,
00088 (int)sizeof(float)
00089 ) ;
00090 exit(0) ;
00091 }
00092
00093
00094
00095 while( argv[iarg][0] == '-' ){
00096
00097 if( strcmp(argv[iarg],"-fix") == 0 ){
00098 fix = 1 ;
00099 iarg++ ; continue ;
00100 }
00101
00102 if( strcmp(argv[iarg],"-v") == 0 ){
00103 verb = 1 ;
00104 iarg++ ; continue ;
00105 }
00106
00107 if( strcmp(argv[iarg],"-skip") == 0 ){
00108 if( ++iarg >= argc ){
00109 fprintf(stderr,"*** no value after -skip?!\n") ; exit(0) ;
00110 }
00111 skip = strtol( argv[iarg] , NULL , 10 ) ;
00112 if( skip < 0 ){
00113 fprintf(stderr,"*** -skip value of %d is illegal!\n",skip) ; exit(0) ;
00114 } else if ( skip == 0 ){
00115 fprintf(stderr,"+++ -skip value of 0 is legal, but not required.\n") ;
00116 }
00117 iarg++ ; continue ;
00118 }
00119
00120 fprintf(stderr,"*** Unknown option: %s\n",argv[iarg] ) ; exit(0) ;
00121 }
00122
00123 if( iarg >= argc ){
00124 fprintf(stderr,"*** No input filename given!?\n") ; exit(0) ;
00125 }
00126
00127
00128
00129 fp = fopen( argv[iarg] , "r" ) ;
00130 if( fp == NULL ){
00131 fprintf(stderr,"*** Can't open input file: %s\n",argv[iarg]) ; exit(0) ;
00132 }
00133
00134 fsize = THD_filesize( argv[iarg] ) ;
00135 if( fsize % sizeof(float) != 0 ){
00136 fprintf(stderr,"*** File %s is %d bytes long: not a multiple of %d!\n",
00137 argv[iarg] , fsize , (int)sizeof(float) ) ;
00138 exit(0) ;
00139 }
00140
00141 FSET(skip) ;
00142
00143
00144
00145 while(1){
00146
00147 READ_BUF ; if( nbuf == 0 ) break ;
00148
00149 for( num_this=ii=0 ; ii < nbuf ; ii++ ){
00150
00151 if( ! IS_FINITE(fbuf[ii]) ){
00152
00153 typ = IS_NAN(fbuf[ii]) ;
00154 if( typ ) num_nan++ ; else num_inf++ ;
00155
00156 if( verb )
00157 fprintf(stderr," [%d] is %s\n",
00158 fpos+ii , (typ) ? "NaN" : "Infinite") ;
00159
00160 fbuf[ii] = 0.0 ; num_this++ ;
00161 }
00162 }
00163
00164 if( fix ) WRITE_BUF ;
00165
00166 FSET(fpos+nbuf) ;
00167
00168 }
00169
00170
00171
00172 fclose(fp) ;
00173
00174 if( num_nan )
00175 fprintf(stderr,"+++ Found %d NaN values in %s\n" ,num_nan,argv[iarg]) ;
00176 if( num_inf )
00177 fprintf(stderr,"+++ Found %d Infinite values in %s\n",num_inf,argv[iarg]) ;
00178 if( num_nan+num_inf == 0 )
00179 fprintf(stderr,"+++ No float errors found in %s\n",argv[iarg]) ;
00180
00181 exit( (num_nan+num_inf) > 0 ) ;
00182 }