00001 
00002 #define VERSION         "3.2a (March 22, 2005)"
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 static char g_history[] = 
00072  "----------------------------------------------------------------------\n"
00073  " file_tool history:\n"
00074  "\n"
00075  " 1.0  September 11, 2002\n"
00076  "   - initial release\n"
00077  "\n"
00078  " 1.1  February 26, 2003\n"
00079  "   - added -quiet option\n"
00080  "   - use dynamic allocation for data to read\n"
00081  "\n"
00082  " 1.2  May 06, 2003  (will go to 2.0 after more changes are made)\n"
00083  "   - added interface for reading GEMS 4.x formatted image files\n"
00084  "   - added corresponding options -ge4_all, -ge4_image, -ge4_series\n"
00085  "   - added options to display raw numeric data:\n"
00086  "       disp_int2, disp_int4, disp_real4\n"
00087  "   - changed local version of l_THD_filesize to THD_filesize, as\n"
00088  "     the ge4_ functions may get that from mrilib.\n"
00089  "\n"
00090  " 2.0  May 29, 2003\n"
00091  "   - added information for ge4 study header\n"
00092  "   - added option -ge4_study\n"
00093  "\n"
00094  " 2.1  June 02, 2003\n"
00095  "   - changed format of call to ge4_read_header()\n"
00096  "   - made swap_[24]() static\n"
00097  "\n"
00098  " 2.2  July 27, 2003\n"
00099  "   - wrap unknown printed strings in NULL check\n"
00100  "\n"
00101  " 3.0  March 17, 2004\n"
00102  "   - added binary editing (gee, that's why I wrote it 18 months ago...)\n"
00103  "     (see -mod_type s/uint1, s/uint2, s/uint4, float4, float8\n"
00104  "   - added '-ge_off' option, to display file offsets for some GEMS fields\n"
00105  "   - added '-hist' option, to display this history\n"
00106  "\n"
00107  " 3.1  March 17, 2004\n"
00108  "   - only check length against data_len for string mods\n"
00109  "\n"
00110  " 3.2  March 24, 2004\n"
00111  "   - only check max length when modifying data (thanks, PSFB)\n"
00112  "\n"
00113  " 3.2a March 22, 2005\n"
00114  "   - removed all tabs\n"
00115  "----------------------------------------------------------------------\n";
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 #include <stdio.h>
00126 #include <stdlib.h>
00127 #include <string.h>
00128 #include <math.h>
00129 #include <sys/types.h>
00130 #include <sys/stat.h>
00131 #include <unistd.h>
00132 
00133 #include "file_tool.h"
00134 #include "ge4_header.h"
00135 
00136 char g_rep_output_data[MAX_STR_LEN];    
00137 
00138 static int swap_2 ( void * ptr );
00139 static int swap_4 ( void * ptr );
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 int main ( int argc, char * argv[] )
00148 {
00149     param_t P;
00150     int     rv;
00151 
00152     if ( (rv = set_params( &P, argc, argv ) ) < 0 )
00153         return rv;
00154     else if ( rv > 0 )
00155         return 0;
00156 
00157     if ( (rv = attack_files( &P ) ) != 0 )
00158         return rv;
00159 
00160     return 0;
00161 }
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 int
00170 attack_files( param_t * p )
00171 {
00172     int fc, rv;
00173 
00174     for ( fc = 0; fc < p->num_files; fc++ )
00175     {
00176         if ( p->ge_disp )
00177         {
00178             if ( (rv = process_ge( p->flist[fc], p )) != 0 )
00179                 return rv;
00180         }
00181         else if ( p->ge4_disp )
00182         {
00183             if ( (rv = process_ge4( p->flist[fc], p )) != 0 )
00184                 return rv;
00185         }
00186         else if ( ( rv = process_file( p->flist[fc], p) ) != 0 )
00187             return rv;
00188     }
00189 
00190     return 0;
00191 }
00192 
00193 
00194 
00195 
00196 
00197 
00198 int
00199 process_ge4( char * filename, param_t * p )
00200 {
00201     ge4_header H;
00202     int        rv;
00203 
00204     rv = ge4_read_header( &H, filename, 0 );
00205 
00206     if ( rv != 0 )
00207     {
00208         if ( p->ge4_disp )      
00209         {
00210             printf( "%s : GEMS 4.x header failure : %d\n", filename, rv );
00211             return 0;
00212         }
00213         else                    
00214             return -1;
00215     }
00216 
00217     if ( (p->debug > 1) || (p->ge4_disp & GE4_DISP_STUDY) )
00218         idisp_ge4_study_header( filename, &H.std_h );
00219 
00220     if ( (p->debug > 1) || (p->ge4_disp & GE4_DISP_SERIES) )
00221         idisp_ge4_series_header( filename, &H.ser_h );
00222 
00223     if ( (p->debug > 1) || (p->ge4_disp & GE4_DISP_IMAGE) )
00224         idisp_ge4_image_header( filename, &H.im_h );
00225 
00226     return 0;
00227 }
00228 
00229 
00230 
00231 
00232 
00233 
00234 int
00235 process_ge( char * filename, param_t * p )
00236 {
00237     ge_header_info H;
00238     ge_extras      E;
00239     ge_off         off;
00240     int            rv;
00241 
00242     rv = read_ge_header( filename, &H, &E, &off );
00243 
00244     if ( rv != 0 )
00245     {
00246         if ( p->ge_disp )  
00247         {
00248             printf( "%s : GE header failure : %d\n", filename, rv );
00249             return 0;  
00250         }
00251         else
00252             return -1;     
00253     }
00254 
00255     if ( (p->debug > 1) || (p->ge_disp & GE_HEADER) )
00256         r_idisp_ge_header_info( filename, &H );
00257 
00258     if ( (p->debug > 1) || (p->ge_disp & GE_EXTRAS ) )
00259         r_idisp_ge_extras( filename, &E );
00260 
00261     if ( p->ge_disp & GE_OFF )
00262         disp_ge_offsets( filename, &off );
00263 
00264     if ( p->ge_disp & GE_UV17 )
00265         printf( "%s : run # %d\n", filename, H.uv17 );
00266 
00267     return 0;
00268 }
00269 
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 int
00283 process_file( char * filename, param_t * p )
00284 {
00285     FILE        * fp;
00286     static char * fdata = NULL;
00287     int           nbytes;
00288 
00289     if ( (fp = fopen( filename, "r+" )) == NULL )
00290     {
00291         fprintf( stderr, "failure: cannot open <%s> for 'rw'\n", filename );
00292         return -1;
00293     }
00294 
00295     if ( fdata == NULL )
00296     {
00297         fdata = (char*) calloc( p->length, sizeof(char) );
00298         if ( fdata == NULL )
00299         {
00300             fprintf( stderr, "failure: cannot allocate %d bytes for data\n",
00301                      p->length );
00302             return -1;
00303         }
00304     }
00305 
00306     if ( fseek( fp, p->offset, SEEK_SET ) )
00307     {
00308         fprintf( stderr, "failure: cannot seek to <%ld> in file '%s'\n",
00309                  p->offset, filename );
00310         fclose( fp );
00311         return -1;
00312     }
00313 
00314     if ( (nbytes = fread( fdata, 1, p->length, fp )) != p->length )
00315     {
00316         fprintf( stderr, "failure: read only %d of %d bytes from file '%s'\n",
00317                  nbytes, p->length, filename );
00318         fclose( fp );
00319         return -1;
00320     }
00321 
00322     
00323     if ( !p->modify || p->debug )
00324     {
00325         if ( ! p->quiet && ! p->ndisp )
00326             printf( "<%s> : '", filename );
00327 
00328         
00329         if ( p->ndisp )
00330         {
00331             if ( disp_numeric_data( fdata, p, stdout ) )
00332             {
00333                 fclose( fp );
00334                 return -1;
00335             }
00336         }
00337         else if ( (nbytes = fwrite(fdata, 1, p->length, stdout)) != p->length )
00338         {
00339             fprintf( stderr, "\nfailure: wrote only %d of %d bytes to '%s'\n",
00340                      nbytes, p->length, "stdout" );
00341             fclose( fp );
00342             return -1;
00343         }
00344         if ( ! p->quiet && ! p->ndisp )
00345             puts( "'" );        
00346     }
00347 
00348     if ( p->modify )  
00349     {
00350         if ( fseek( fp, p->offset, SEEK_SET ) )
00351         {
00352             fprintf( stderr, "failure: cannot re-seek to <%ld> in file '%s'\n",
00353                      p->offset, filename );
00354             fclose( fp );
00355             return -1;
00356         }
00357 
00358         if ( (nbytes = write_data_to_file( fp, filename, p ) ) < 0 )
00359         {
00360             fclose( fp );
00361             return -1;
00362         }
00363 
00364         if ( p->debug > 0 )
00365         {
00366             printf( "wrote '%s' (%d bytes) to file '%s', position %ld\n",
00367                     p->mod_data, p->length, filename, p->offset );
00368         }
00369     }
00370 
00371     fclose( fp );
00372 
00373     return 0;
00374 }
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 int write_data_to_file( FILE * fp, char * filename, param_t * p )
00385 {
00386     double   dval;
00387     char   * outp, * inp, * endp;
00388     int      dsize, c, nbytes;
00389 
00390     if ( (dsize = mtype_size( p->mod_type )) < 1 )
00391     {
00392         fprintf(stderr,"** bad size %d for mod_type %d\n", dsize, p->mod_type);
00393         return -1;
00394     }
00395 
00396     if ( p->debug > 1 )
00397         fprintf(stderr,"-- dsize = %d\n", dsize);
00398 
00399     
00400     if ( p->mod_type == MOD_STR || p->mod_type == MOD_CHAR )
00401     {
00402         int remaining = p->length - p->data_len; 
00403 
00404         if ( (nbytes=fwrite(p->mod_data, 1, p->data_len, fp)) != p->data_len )
00405         {
00406             fprintf( stderr, "\nfailure: wrote only %d of %d bytes to '%s'\n",
00407                      nbytes, p->data_len, filename );
00408             fclose( fp );
00409             return -1;
00410         }
00411 
00412         
00413         for ( c = 0; c < remaining; c++ )
00414             fputc( '\0', fp );
00415 
00416         return p->length;
00417     }
00418 
00419     if ( p->debug > 1 ) fprintf(stderr,"++ values: ");
00420 
00421     
00422     outp = g_rep_output_data;
00423     inp  = p->mod_data;
00424     memset(outp, 0, p->length);
00425     for ( c = 0; (c+dsize) <= p->length; c += dsize, outp += dsize )
00426     {
00427         dval = strtod( inp, &endp );
00428 
00429         if ( endp && inp != endp )   
00430         {
00431             switch (p->mod_type)
00432             {
00433                 default:
00434                     fprintf(stderr,"** wdtf: bad type %d\n", p->mod_type);
00435                     return -1;
00436                 case MOD_U1:
00437                     *(unsigned char *)outp = (unsigned char)dval;
00438                     break;
00439                 case MOD_S1:
00440                     *(char *)outp = (char)dval;
00441                     break;
00442                 case MOD_U2:
00443                     *(unsigned short *)outp = (unsigned short)dval;
00444                     break;
00445                 case MOD_S2:
00446                     *(short *)outp = (short)dval;
00447                     break;
00448                 case MOD_U4:
00449                     *(unsigned long *)outp = (unsigned long)dval;
00450                     break;
00451                 case MOD_S4:
00452                     *(long *)outp = (long)dval;
00453                     break;
00454                 case MOD_F4:
00455                     *(float *)outp = (float)dval;
00456                     break;
00457                 case MOD_F8:
00458                     *(double *)outp = dval;
00459                     break;
00460             }
00461 
00462             if ( p->swap )
00463             {
00464                 if ( dsize == 2 )
00465                     swap_2( (void *)outp );
00466                 else if ( dsize == 4 )
00467                     swap_4( (void *)outp );
00468             }
00469 
00470             if ( p->debug > 1 ) fprintf(stderr," %f", dval);
00471         }
00472         else
00473             break;      
00474 
00475         inp = endp;     
00476     }
00477 
00478     if ( p->debug > 1 ) fputc('\n', stderr);
00479 
00480     
00481     nbytes = fwrite(g_rep_output_data, 1, p->length, fp);
00482     if ( nbytes != p->length )
00483     {
00484         fprintf(stderr,"** wrote only %d of %d bytes of binary data\n",
00485                 nbytes, p->length);
00486         return nbytes;
00487     }
00488 
00489     return p->length;
00490 }
00491 
00492 int mtype_size( int type )
00493 {
00494     if ( type == MOD_STR  ) return 1;
00495     if ( type == MOD_CHAR ) return 1;
00496     if ( type == MOD_U1   ) return 1;
00497     if ( type == MOD_S1   ) return 1;
00498 
00499     if ( type == MOD_U2   ) return 2;
00500     if ( type == MOD_S2   ) return 2;
00501 
00502     if ( type == MOD_U4   ) return 4;
00503     if ( type == MOD_S4   ) return 4;
00504 
00505     if ( type == MOD_F4   ) return 4;
00506     if ( type == MOD_F8   ) return 8;
00507 
00508     return -1;
00509 }
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 int
00518 set_params( param_t * p, int argc, char * argv[] )
00519 {
00520     int ac;
00521 
00522     if ( argc < 2 )
00523     {
00524         usage( argv[0], USE_SHORT );
00525         return -1;
00526     }
00527 
00528     if ( !p || !argv )
00529     {
00530         fprintf( stderr, "failure: bad params to set_params: "
00531                  "p = <%p>, ac = <%d>, av = <%p>\n",
00532                  p, argc, argv );
00533         return -1;
00534     }
00535 
00536     
00537     memset( p, 0, sizeof(*p) );
00538 
00539     for ( ac = 1; ac < argc; ac++ )
00540     {
00541         
00542         if ( ! strncmp(argv[ac], "-help_ge", 8 ) )
00543         {
00544             usage( argv[0], USE_GE );
00545             return -1;
00546         }
00547         else if ( ! strncmp(argv[ac], "-help", 3 ) )
00548         {
00549             usage( argv[0], USE_LONG );
00550             return -1;
00551         }
00552         else if ( ! strncmp(argv[ac], "-hist", 3 ) )
00553         {
00554             usage( argv[0], USE_HISTORY );
00555             return -1;
00556         }
00557         else if ( ! strncmp(argv[ac], "-debug", 6 ) )
00558         {
00559             if ( (ac+1) >= argc )
00560             {
00561                 fputs( "missing option parameter: LEVEL\n"
00562                        "option usage: -debug LEVEL\n"
00563                        "    where LEVEL is the debug level (0,1 or 2)\n",
00564                        stderr );
00565                 return -1; 
00566             }
00567 
00568             p->debug = atoi(argv[++ac]);
00569             if ( (p->debug < 0) || (p->debug > 2) )
00570             {
00571                 fprintf( stderr, "invalid debug level <%d>\n", p->debug );
00572                 return -1;
00573             }
00574         }
00575         else if ( ! strncmp(argv[ac], "-disp_int2", 10 ) )
00576         {
00577             p->ndisp |= NDISP_INT2;
00578         }
00579         else if ( ! strncmp(argv[ac], "-disp_int4", 10 ) )
00580         {
00581             p->ndisp |= NDISP_INT4;
00582         }
00583         else if ( ! strncmp(argv[ac], "-disp_real4", 11 ) )
00584         {
00585             p->ndisp |= NDISP_REAL4;
00586         }
00587         else if ( ! strncmp(argv[ac], "-mod_data", 6 ) )
00588         {
00589             if ( (ac+1) >= argc )
00590             {
00591                 fputs( "missing option parameter: DATA\n"
00592                        "option usage: -mod_data DATA\n"
00593                        "    where DATA is the replacement string or numbers\n",
00594                        stderr );
00595                 return -1; 
00596             }
00597 
00598             ac++;
00599             p->mod_data = argv[ac];
00600         }
00601         else if ( ! strncmp(argv[ac], "-mod_type", 6 ) )
00602         {
00603             if ( (ac+1) >= argc )
00604             {
00605                 fputs( "missing option parameter: TYPE\n"
00606                        "option usage: -mod_type TYPE\n"
00607                        "    where TYPE is 'val' or 'str'\n",
00608                        stderr );
00609                 return -1;
00610             }
00611 
00612             ac++;
00613             if ( (p->mod_type = check_mod_type(argv[ac])) == MOD_INVALID )
00614             {
00615                 fputs( "option usage: -mod_type TYPE\n", stderr );
00616                 fputs( "              where TYPE is 'str' or 'val'\n", stderr );
00617                 return -1;
00618             }
00619         }
00620         else if ( ! strncmp(argv[ac], "-offset", 4 ) )
00621         {
00622             if ( (ac+1) >= argc )
00623             {
00624                 fputs( "missing option parameter: OFFSET\n"
00625                        "option usage: -offset OFFSET\n"
00626                        "    where OFFSET is the file offset\n",
00627                        stderr );
00628                 return -1;
00629             }
00630 
00631             p->offset = atoi(argv[++ac]);
00632             if ( p->offset < 0 )
00633             {
00634                 fprintf( stderr, "bad file OFFSET <%ld>\n", p->offset );
00635                 return -1;
00636             }
00637         }
00638         else if ( ! strncmp(argv[ac], "-length", 4 ) )
00639         {
00640             if ( (ac+1) >= argc )
00641             {
00642                 fputs( "missing option parameter: LENGTH\n"
00643                        "option usage: -length LENGTH\n"
00644                        "    where LENGTH is the length to display or modify\n",
00645                        stderr );
00646                 return -1;
00647             }
00648 
00649             p->length = atoi(argv[++ac]);
00650             if ( p->length < 0 )
00651             {
00652                 fprintf( stderr, "bad LENGTH <%d>\n", p->length );
00653                 return -1;
00654             }
00655         }
00656         else if ( ! strncmp(argv[ac], "-quiet", 2 ) )
00657         {
00658             p->quiet = 1;
00659         }
00660         else if ( ! strncmp(argv[ac], "-swap_bytes", 3 ) )
00661         {
00662             p->swap = 1;
00663         }
00664         else if ( ! strncmp(argv[ac], "-ver", 2 ) )
00665         {
00666             usage( argv[0], USE_VERSION );
00667             return 1;
00668         }
00669         else if ( ! strncmp(argv[ac], "-infiles", 4 ) )
00670         {
00671             if ( (ac+1) >= argc )
00672             {
00673                 fputs( "missing input files...\n"
00674                        "option usage: -infiles file1 file2 ...\n",
00675                        stderr );
00676                 return -1;
00677             }
00678 
00679             ac++;
00680             p->num_files = argc - ac;
00681             p->flist     = argv + ac;
00682 
00683             break;      
00684         }
00685         
00686         else if ( ! strncmp(argv[ac], "-ge_all", 7 ) )
00687         {
00688             p->ge_disp |= GE_ALL;
00689         }
00690         else if ( ! strncmp(argv[ac], "-ge_header", 7 ) )
00691         {
00692             p->ge_disp |= GE_HEADER;
00693         }
00694         else if ( ! strncmp(argv[ac], "-ge_extras", 7 ) )
00695         {
00696             p->ge_disp |= GE_EXTRAS;
00697         }
00698         else if ( ! strncmp(argv[ac], "-ge_off", 7 ) )
00699         {
00700             p->ge_disp |= GE_OFF;
00701         }
00702         
00703         else if ( ! strncmp(argv[ac], "-ge_uv17", 7 ) ||
00704                   ! strncmp(argv[ac], "-ge_run", 7  )    )
00705         {
00706             p->ge_disp |= GE_UV17;
00707         }
00708         
00709         else if ( ! strncmp(argv[ac], "-ge4_all", 7 ) )
00710         {
00711             p->ge4_disp |= GE4_DISP_ALL;
00712         }
00713         else if ( ! strncmp(argv[ac], "-ge4_image", 7 ) )
00714         {
00715             p->ge4_disp |= GE4_DISP_IMAGE;
00716         }
00717         else if ( ! strncmp(argv[ac], "-ge4_series", 8 ) )
00718         {
00719             p->ge4_disp |= GE4_DISP_SERIES;
00720         }
00721         else if ( ! strncmp(argv[ac], "-ge4_study", 8 ) )
00722         {
00723             p->ge4_disp |= GE4_DISP_STUDY;
00724         }
00725         
00726         else
00727         {
00728             fprintf( stderr, "error: unknown option, <%s>\n", argv[ac] );
00729             return -1;
00730         }
00731     }
00732 
00733     if ( p->debug > 1 )
00734         disp_param_data( p );
00735 
00736     if ( p->num_files <= 0 )
00737     {
00738         fputs( "error: missing '-infiles' option\n", stderr );
00739         return -1;
00740     }
00741 
00742     
00743     if ( p->ge_disp || p->ge4_disp )
00744         return 0;
00745 
00746     
00747 
00748     if ( p->mod_data )
00749     {
00750         p->modify = 1;           
00751         p->data_len = strlen(p->mod_data);    
00752     }
00753     else
00754         p->modify = 0;                             
00755 
00756     if ( p->length <= 0 )
00757     {
00758         fputs( "error: missing '-length' option\n", stderr );
00759         return -1;
00760     }
00761 
00762     if ( p->modify )
00763     {
00764         if ( p->length > MAX_STR_LEN )
00765         {
00766             fprintf( stderr, "failure: length <%d> exceeds maximum %d\n",
00767                  p->length, MAX_STR_LEN );
00768             return -1;
00769         }
00770 
00771         if ( p->mod_type == MOD_CHAR )
00772         {
00773             
00774             memset( g_rep_output_data, *p->mod_data, p->length );
00775             p->mod_data = g_rep_output_data;
00776             p->data_len = p->length;
00777         }
00778         else if ( p->mod_type == MOD_STR && p->length < p->data_len )
00779         {
00780             fprintf( stderr, "failure: data length <%d> exceeds length <%d>\n",
00781                      p->data_len, p->length );
00782             return -1;
00783         }
00784     }
00785 
00786     return 0;
00787 }
00788 
00789 
00790 
00791 
00792 
00793 
00794 int check_mod_type( char * name )
00795 {
00796     
00797     if ( ! strncmp(name, "str", 3) )
00798         return MOD_STR; 
00799     if ( ! strncmp(name, "val",  3) || ! strncmp(name, "char", 4) )
00800         return MOD_CHAR;
00801 
00802     
00803     if ( ! strncmp(name, "uint1", 5) )
00804         return MOD_U1;
00805     if ( ! strncmp(name, "sint1", 5) )
00806         return MOD_S1;
00807     if ( ! strncmp(name, "uint2", 5) )
00808         return MOD_U2;
00809     if ( ! strncmp(name, "sint2", 5) )
00810         return MOD_S2;
00811     if ( ! strncmp(name, "uint4", 5) )
00812         return MOD_U4;
00813     if ( ! strncmp(name, "sint4", 5) )
00814         return MOD_S4;
00815 
00816     
00817     if ( ! strncmp(name, "float4", 6) )
00818         return MOD_F4;
00819     if ( ! strncmp(name, "float8", 6) )
00820         return MOD_F8;
00821 
00822     return MOD_INVALID;
00823 }
00824 
00825 
00826 
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 int usage( char * prog, int level )
00836 {
00837     if ( level == USE_SHORT )
00838     {
00839         printf( "usage: %s -help\n"
00840                 "usage: %s [options] file1 file2 ...\n",
00841                 prog, prog);
00842         return 0;
00843     }
00844     else if ( level == USE_VERSION )
00845     {
00846         printf( "%s, version %s, compiled: %s\n",
00847                 prog, VERSION, __DATE__ );
00848         return 0;
00849     }
00850     else if ( level == USE_HISTORY )
00851     {
00852         fputs( g_history, stdout );
00853         return 0;
00854     }
00855     else if ( level == USE_GE )
00856     {
00857         help_ge_structs( prog );
00858         return 0;
00859     }
00860     else if ( level != USE_LONG )
00861     {
00862         fprintf( stderr, "failure: bad usage level <%d>\n", level );
00863         return -1;
00864     }
00865 
00866     
00867     help_full( prog );
00868 
00869     return 0;
00870 }
00871 
00872 
00873 
00874 
00875 
00876 int
00877 help_ge_structs( char * prog )
00878 {
00879     printf( "------------------------------------------------------------\n"
00880             "These are descriptions of the elements in the GE\n"
00881             "data structures used by '%s'.  Most elements\n"
00882             "correspond to a field in the image file header.\n"
00883             "\n"
00884             "These fields are shown when running '%s'\n"
00885             "with any of the options:\n"
00886             "   '-ge_header', '-ge_extras', or '-ge_all'.\n"
00887             
00888             "----------------------------------------\n"
00889             "ge_header_info struct:\n"
00890             "\n"
00891             "    good     : is this a valid GE image file\n"
00892             "    nx,ny    : dimensions of image in voxels\n"
00893             "    uv17     : run number (user variable 17)\n"
00894             "    dx,dy,dz : directional deltas - distances between voxels\n"
00895             "    zoff     : location of image in z direction\n"
00896             "    tr,te    : TR and TE timings\n"
00897             "    orients  : orientation string for image\n"
00898             "----------------------------------------\n"
00899             
00900             "ge_extras struct:\n"
00901             "\n"
00902             "    bpp      : bytes per pixel (file_size = nx * ny * bpp)\n"
00903             "    cflag    : compression flag (here, 1 means NOT compressed)\n"
00904             "    hdroff   : offset of image header (from beginning of file)\n"
00905             "    skip     : offset of image data   (from beginning of file)\n"
00906             "    swap     : is byte swapping performed?\n"
00907             "    xyzX     : coordinate box containing image\n"
00908             "------------------------------------------------------------\n"
00909             "\n", prog, prog
00910           );
00911 
00912     return 0;
00913 }
00914 
00915 
00916 
00917 
00918 
00919 int
00920 help_full( char * prog )
00921 {
00922     printf(
00923         "\n"
00924         "%s - display or modify sections of a file\n"
00925         "\n"
00926         "    This program can be used to display or edit data in arbitrary\n"
00927         "    files.  If no '-mod_data' option is provided (with DATA), it\n"
00928         "    is assumed the user wishes only to display the specified data\n"
00929         "    (using both '-offset' and '-length', or using '-ge_XXX').\n"
00930         "\n"
00931         "  usage: %s [options] -infiles file1 file2 ...\n"
00932         "\n"
00933         "  examples:\n"
00934         "\n"
00935         "   ----- help examples -----\n"
00936         "\n"
00937         "   1. get detailed help:\n"
00938         "\n"
00939         "      %s -help\n"
00940         "\n"
00941         "   2. get descriptions of GE struct elements:\n"
00942         "\n"
00943         "      %s -help_ge\n"
00944         "\n"
00945         "   ----- GEMS 4.x and 5.x display examples -----\n"
00946         "\n"
00947         "   3. display GE header and extras info for file I.100:\n"
00948         "\n"
00949         "      %s -ge_all -infiles I.100\n"
00950         "\n"
00951         "   4. display GEMS 4.x series and image headers for file I.100:\n"
00952         "\n"
00953         "      %s -ge4_all -infiles I.100\n"
00954         "\n"
00955         "   5. display run numbers for every 100th I-file in this directory\n"
00956         "\n"
00957         "      %s -ge_uv17 -infiles I.?42\n"
00958         "      %s -ge_run  -infiles I.?42\n"
00959         "\n"
00960         "   ----- general value display examples -----\n"
00961         "\n"
00962         "   6. display the 32 characters located 100 bytes into each file:\n"
00963         "\n"
00964         "      %s -offset 100 -length 32 -infiles file1 file2\n"
00965         "\n"
00966         "   7. display the 8 4-byte reals located 100 bytes into each file:\n"
00967         "\n"
00968         "      %s -disp_real4 -offset 100 -length 32 -infiles file1 file2\n"
00969         "\n"
00970         "   ----- character modification examples -----\n"
00971         "\n"
00972         "   8. in each file, change the 8 characters at 2515 to 'hi there':\n"
00973         "\n"
00974         "      %s -mod_data \"hi there\" -offset 2515 -length 8 -infiles I.*\n"
00975         "\n"
00976         "   9. in each file, change the 21 characters at 2515 to all 'x's\n"
00977         "      (and print out extra debug info)\n"
00978         "\n"
00979         "      %s -debug 1 -mod_data x -mod_type val -offset 2515 \\\n"
00980         "                -length 21 -infiles I.*\n"
00981         "\n"
00982         "   ----- raw number modification examples -----\n"
00983         "\n"
00984         "  10. in each file, change the 3 short integers starting at position\n"
00985         "      2508 to '2 -419 17'\n"
00986         "\n"
00987         "      %s -mod_data '2 -419 17' -mod_type sint2 -offset 2508 \\\n"
00988         "                -length 6 -infiles I.*\n"
00989         "\n"
00990         "  11. in each file, change the 3 binary floats starting at position\n"
00991         "      2508 to '-83.4 2 17' (and set the next 8 bytes to zero by\n"
00992         "      setting the length to 20, instead of just 12).\n"
00993         "\n"
00994         "      %s -mod_data '-83.4 2 17' -mod_type float4 -offset 2508 \\\n"
00995         "                -length 20 -infiles I.*\n"
00996         "\n"
00997         "  12. in each file, change the 3 binary floats starting at position\n"
00998         "      2508 to '-83.4 2 17', and apply byte swapping\n"
00999         "\n"
01000         "      %s -mod_data '-83.4 2 17' -mod_type float4 -offset 2508 \\\n"
01001         "                -length 12 -swap_bytes -infiles I.*\n"
01002         "\n"
01003         "  notes:\n"
01004         "\n"
01005         "    o  Use of '-infiles' is required.\n"
01006         "    o  Use of '-length' or a GE information option is required.\n"
01007         "    o  As of this version, only modification with text is supported.\n"
01008         "       Editing binary data is coming soon to a workstation near you.\n"
01009         "\n"
01010         "  special options:\n"
01011         "\n"
01012         "    -help              : show this help information\n"
01013         "                       : e.g. -help\n"
01014         "\n"
01015         "    -version           : show version information\n"
01016         "                       : e.g. -version\n"
01017         "\n"
01018         "    -hist              : show the program's modification history\n"
01019         "\n"
01020         "    -debug LEVEL       : print extra info along the way\n"
01021         "                       : e.g. -debug 1\n"
01022         "                       : default is 0, max is 2\n"
01023         "\n"
01024         "  required 'options':\n"
01025         "\n"
01026         "    -infiles f1 f2 ... : specify input files to print from or modify\n"
01027         "                       : e.g. -infiles file1\n"
01028         "                       : e.g. -infiles I.*\n"
01029         "\n"
01030         "          Note that '-infiles' should be the final option.  This is\n"
01031         "          to allow the user an arbitrary number of input files.\n"
01032         "\n"
01033         "  GE info options:\n"
01034         "\n"
01035         "      -ge_all          : display GE header and extras info\n"
01036         "      -ge_header       : display GE header info\n"
01037         "      -ge_extras       : display extra GE image info\n"
01038         "      -ge_uv17         : display the value of uv17 (the run #)\n"
01039         "      -ge_run          : (same as -ge_uv17)\n"
01040         "      -ge_off          : display file offsets for various fields\n"
01041         "\n"
01042         "  GEMS 4.x info options:\n"
01043         "\n"
01044         "      -ge4_all         : display GEMS 4.x series and image headers\n"
01045         "      -ge4_image       : display GEMS 4.x image header\n"
01046         "      -ge4_series      : display GEMS 4.x series header\n"
01047         "      -ge4_study       : display GEMS 4.x study header\n"
01048         "\n"
01049         "  raw ascii options:\n"
01050         "\n"
01051         "    -length LENGTH     : specify the number of bytes to print/modify\n"
01052         "                       : e.g. -length 17\n"
01053         "\n"
01054         "          This includes numbers after the conversion to binary.  So\n"
01055         "          if -mod_data is '2 -63 186', and -mod_type is 'sint2' (or\n"
01056         "          signed shorts), then 6 bytes will be written (2 bytes for\n"
01057         "          each of 3 short integers).\n"
01058         "\n"
01059         "       ** Note that if the -length argument is MORE than what is\n"
01060         "          needed to write the numbers out, the remaind of the length\n"
01061         "          bytes will be written with zeros.  If '17' is given for\n"
01062         "          the length, and 3 short integers are given as data, there \n"
01063         "          will be 11 bytes of 0 written after the 6 bytes of data.\n"
01064         "\n"
01065         "    -mod_data DATA     : specify a string to change the data to\n"
01066         "                       : e.g. -mod_data hello\n"
01067         "                       : e.g. -mod_data '2 -17.4 649'\n"
01068         "                       : e.g. -mod_data \"change to this string\"\n"
01069         "\n"
01070         "          This is the data that will be writting into the modified\n"
01071         "          file.  If the -mod_type is 'str' or 'char', then the\n"
01072         "          output data will be those characters.  If the -mod_type\n"
01073         "          is any other (i.e. a binary numerical format), then the\n"
01074         "          output will be the -mod_data, converted from numerical\n"
01075         "          text to binary.\n"
01076         "\n"
01077         "       ** Note that a list of numbers must be contained in quotes,\n"
01078         "          so that it will be processed as a single parameter.\n"
01079         "\n"
01080         "    -mod_type TYPE     : specify the data type to write to the file\n"
01081         "                       : e.g. -mod_type string\n"
01082         "                       : e.g. -mod_type sint2\n"
01083         "                       : e.g. -mod_type float4\n"
01084         "                       : default is 'str'\n"
01085         "\n"
01086         "        TYPE can be one of:\n"
01087         "\n"
01088         "          str       : perform a string substitution\n"
01089         "          char, val : perform a (repeated?) character substitution\n"
01090         "          uint1     : single byte unsigned int   (binary write)\n"
01091         "          sint1     : single byte   signed int   (binary write)\n"
01092         "          uint2     : two    byte unsigned int   (binary write)\n"
01093         "          sint2     : two    byte   signed int   (binary write)\n"
01094         "          uint4     : four   byte unsigned int   (binary write)\n"
01095         "          sint4     : four   byte   signed int   (binary write)\n"
01096         "          float4    : four   byte floating point (binary write)\n"
01097         "          float8    : eight  byte floating point (binary write)\n"
01098         "\n"
01099         "          If 'str' is used, which is the default action, the data is\n"
01100         "          replaced by the contents of the string DATA (from the\n"
01101         "          '-mod_data' option).\n"
01102         "\n"
01103         "          If 'char' is used, then LENGTH bytes are replaced by the\n"
01104         "          first character of DATA, repeated LENGTH times.\n"
01105         "\n"
01106         "          For any of the others, the list of numbers found in the\n"
01107         "          -mod_data option will be written in the supplied binary\n"
01108         "          format.  LENGTH must be large enough to accomodate this\n"
01109         "          list.  And if LENGTH is higher, the output will be padded\n"
01110         "          with zeros, to fill to the requesed length.\n"
01111         "\n"
01112         "    -offset OFFSET     : use this offset into each file\n"
01113         "                       : e.g. -offset 100\n"
01114         "                       : default is 0\n"
01115         "\n"
01116         "          This is the offset into each file for the data to be\n"
01117         "          read or modified.\n"
01118         "\n"
01119         "    -quiet             : do not output header information\n"
01120         "\n"
01121         "  numeric options:\n"
01122         "\n"
01123         "    -disp_int2         : display 2-byte integers\n"
01124         "                       : e.g. -disp_int2\n"
01125         "\n"
01126         "    -disp_int4         : display 4-byte integers\n"
01127         "                       : e.g. -disp_int4\n"
01128         "\n"
01129         "    -disp_real4        : display 4-byte real numbers\n"
01130         "                       : e.g. -disp_real4\n"
01131         "\n"
01132         "    -swap_bytes        : use byte-swapping on numbers\n"
01133         "                       : e.g. -swap_bytes\n"
01134         "\n"
01135         "          If this option is used, then byte swapping is done on any\n"
01136         "          multi-byte numbers read from or written to the file.\n"
01137         "\n"
01138         "  - R Reynolds, version: %s, compiled: %s\n"
01139         "\n",
01140         prog, prog,
01141         prog, prog, prog, prog, prog, prog, prog, prog, prog,
01142         prog, prog, prog, prog,
01143         VERSION, __DATE__
01144         );
01145 
01146     return 0;
01147 }
01148 
01149 
01150 
01151 
01152 
01153 static int
01154 swap_4( void * ptr )            
01155 {
01156    unsigned char * addr = ptr;
01157 
01158    addr[0] ^= addr[3]; addr[3] ^= addr[0]; addr[0] ^= addr[3];
01159    addr[1] ^= addr[2]; addr[2] ^= addr[1]; addr[1] ^= addr[2];
01160 
01161    return 0;
01162 }
01163 
01164 
01165 
01166 
01167 
01168 static int
01169 swap_2( void * ptr )            
01170 {
01171    unsigned char * addr = ptr;
01172 
01173    addr[0] ^= addr[1]; addr[1] ^= addr[0]; addr[0] ^= addr[1];
01174 
01175    return 0;
01176 }
01177 
01178 
01179 
01180 
01181 
01182 
01183 int
01184 read_ge_header( char *pathname , ge_header_info *hi, ge_extras *E, ge_off *off )
01185 {
01186    FILE *imfile ;
01187    int  length , skip , swap=0 ;
01188    char orients[8] , str[8] ;
01189    int nx , ny , bpp , cflag , hdroff ;
01190         float uv17 = -1.0;
01191         
01192    if( hi == NULL ) return -1;            
01193    hi->good = 0 ;                       
01194    if( pathname    == NULL ||
01195        pathname[0] == '\0'   ) return -1; 
01196 
01197    length = THD_filesize( pathname ) ;
01198    if( length < 1024 ) return -1;         
01199 
01200    imfile = fopen( pathname , "r" ) ;
01201    if( imfile == NULL ) return -1;        
01202 
01203    strcpy(str,"JUNK") ;     
01204    fread(str,1,4,imfile) ;  
01205 
01206    if( str[0]!='I' || str[1]!='M' || str[2]!='G' || str[3]!='F' ){ 
01207       fclose(imfile) ; return -2;
01208    }
01209 
01210    
01211 
01212    fread( &skip , 4,1, imfile ) ; 
01213    fread( &nx   , 4,1, imfile ) ; 
01214    fread( &ny   , 4,1, imfile ) ; 
01215    fread( &bpp  , 4,1, imfile ) ; 
01216    fread( &cflag, 4,1, imfile ) ; 
01217 
01218         
01219 
01220    if( nx < 0 || nx > 8192 ){      
01221      swap = 1 ;                    
01222      swap_4(&skip); swap_4(&nx); swap_4(&ny); swap_4(&bpp); swap_4(&cflag);
01223    } else {
01224      swap = 0 ;  
01225    }
01226    if( nx < 0 || nx > 8192 || ny < 0 || ny > 8192 ){  
01227       fclose(imfile) ; return -1;
01228    }
01229 
01230    hi->nx = nx ;
01231    hi->ny = ny ;
01232 
01233    off->nx =  8;
01234    off->ny = 12;
01235 
01236    if( skip+2*nx*ny >  length ||               
01237        skip         <= 0      ||               
01238        cflag        != 1      ||               
01239        bpp          != 16        ){
01240       fclose(imfile); return -1;    
01241    }
01242 
01243    
01244 
01245    fseek( imfile , 148L , SEEK_SET ) ; 
01246    fread( &hdroff , 4,1 , imfile ) ;   
01247    if( swap ) swap_4(&hdroff) ;
01248 
01249    if( hdroff > 0 && hdroff+256 < length ){   
01250        float dx,dy,dz, xyz[9], zz ; int itr, ii,jj,kk ;
01251 
01252        
01253 
01254        fseek( imfile , hdroff+26 , SEEK_SET ) ;    
01255        fread( &dz , 4,1 , imfile ) ;
01256 
01257        fseek( imfile , hdroff+50 , SEEK_SET ) ;    
01258        fread( &dx , 4,1 , imfile ) ;
01259        fread( &dy , 4,1 , imfile ) ;
01260 
01261        off->dx = hdroff+50;
01262        off->dy = hdroff+54;
01263        off->dz = hdroff+26;
01264 
01265        if( swap ){ swap_4(&dx); swap_4(&dy); swap_4(&dz); }
01266 
01267        hi->dx = dx ; hi->dy = dy ; hi->dz = dz ;
01268 
01269        
01270        
01271        
01272        
01273        
01274 
01275        off->xyz = hdroff+154;
01276        fseek( imfile , hdroff+154 , SEEK_SET ) ;  
01277        fread( xyz , 4,9 , imfile ) ;
01278        if( swap ){
01279           swap_4(xyz+0); swap_4(xyz+1); swap_4(xyz+2);
01280           swap_4(xyz+3); swap_4(xyz+4); swap_4(xyz+5);
01281           swap_4(xyz+6); swap_4(xyz+7); swap_4(xyz+8);
01282        }
01283 
01284        
01285        
01286        
01287        
01288 
01289        dx = fabs(xyz[3]-xyz[0]) ; ii = 1 ;
01290        dy = fabs(xyz[4]-xyz[1]) ; if( dy > dx ){ ii=2; dx=dy; }
01291        dz = fabs(xyz[5]-xyz[2]) ; if( dz > dx ){ ii=3;        }
01292        dx = xyz[ii+2]-xyz[ii-1] ; if( dx < 0. ){ ii = -ii;    }
01293        switch( ii ){
01294         case  1: orients[0]= 'L'; orients[1]= 'R'; break;
01295         case -1: orients[0]= 'R'; orients[1]= 'L'; break;
01296         case  2: orients[0]= 'P'; orients[1]= 'A'; break;
01297         case -2: orients[0]= 'A'; orients[1]= 'P'; break;
01298         case  3: orients[0]= 'I'; orients[1]= 'S'; break;
01299         case -3: orients[0]= 'S'; orients[1]= 'I'; break;
01300         default: orients[0]='\0'; orients[1]='\0'; break;
01301        }
01302 
01303        
01304        
01305        
01306        
01307 
01308        dx = fabs(xyz[6]-xyz[3]) ; jj = 1 ;
01309        dy = fabs(xyz[7]-xyz[4]) ; if( dy > dx ){ jj=2; dx=dy; }
01310        dz = fabs(xyz[8]-xyz[5]) ; if( dz > dx ){ jj=3;        }
01311        dx = xyz[jj+5]-xyz[jj+2] ; if( dx < 0. ){ jj = -jj;    }
01312        switch( jj ){
01313          case  1: orients[2] = 'L'; orients[3] = 'R'; break;
01314          case -1: orients[2] = 'R'; orients[3] = 'L'; break;
01315          case  2: orients[2] = 'P'; orients[3] = 'A'; break;
01316          case -2: orients[2] = 'A'; orients[3] = 'P'; break;
01317          case  3: orients[2] = 'I'; orients[3] = 'S'; break;
01318          case -3: orients[2] = 'S'; orients[3] = 'I'; break;
01319          default: orients[2] ='\0'; orients[3] ='\0'; break;
01320        }
01321 
01322        orients[4] = '\0' ;   
01323 
01324        kk = 6 - abs(ii)-abs(jj) ;   
01325                                     
01326                                     
01327 
01328        zz = xyz[kk-1] ;             
01329 
01330        hi->zoff = zz ;
01331        strcpy(hi->orients,orients) ;
01332 
01333        
01334 
01335        off->tr = hdroff+194;
01336        fseek( imfile , hdroff+194 , SEEK_SET ) ;
01337        fread( &itr , 4,1 , imfile ) ; 
01338        if( swap ) swap_4(&itr) ;
01339        hi->tr = 1.0e-6 * itr ;        
01340 
01341        
01342 
01343        off->te = hdroff+202;
01344        fseek( imfile , hdroff+202 , SEEK_SET ) ;
01345        fread( &itr , 4,1 , imfile ) ; 
01346        if( swap ) swap_4(&itr) ;
01347        hi->te = 1.0e-6 * itr ;
01348 
01349        
01350 
01351 
01352 
01353 
01354         off->uv17 = hdroff+272+202;
01355         
01356         fseek ( imfile , hdroff+272+202, SEEK_SET ) ;
01357         fread( &uv17 , 4, 1 , imfile ) ;
01358         if( swap ) swap_4(&uv17) ;
01359         
01360         hi->uv17 = (int)uv17; 
01361         
01362         
01363         hi->good = 1 ;                  
01364 
01365         E->bpp    = bpp;                
01366         E->cflag  = cflag;
01367         E->hdroff = hdroff;
01368         E->skip   = skip;
01369         E->swap   = swap;
01370 
01371         memcpy( E->xyz, xyz, sizeof(xyz) );
01372     } 
01373 
01374     fclose(imfile);
01375     return 0;
01376 }
01377 
01378 
01379 
01380 
01381 
01382 unsigned long
01383 THD_filesize ( char * pathname )
01384 {
01385     struct stat buf;
01386 
01387     if ( pathname == NULL || *pathname == '\0' )
01388         return -1;
01389 
01390     if ( stat( pathname, &buf ) != 0 )
01391         return -1;
01392 
01393     return (unsigned long)buf.st_size;
01394 }
01395 
01396 
01397 
01398 
01399 
01400 
01401 int
01402 disp_numeric_data( char * data, param_t * p, FILE * fp )
01403 {
01404     int c;
01405 
01406     if ( data == NULL || fp == NULL )
01407     {
01408         fprintf( stderr, "** error: bad params to DND '%p,%p'\n", data, fp );
01409         return -1;
01410     }
01411 
01412     if ( p->length <= 0 || p->ndisp == 0 )
01413         return 0;
01414 
01415     
01416     if ( p->ndisp & NDISP_INT2 )
01417     {
01418         short * sp = (short *)data;
01419 
01420         fprintf( fp, "0x%4x : ", (unsigned int)p->offset );
01421         for ( c = 0; c < p->length/2; c++, sp++ )
01422         {
01423             if ( p->swap )
01424                 swap_2( sp );
01425             fprintf( fp, "%d ", *sp );
01426         }
01427         fputc( '\n', fp );
01428     }
01429 
01430     
01431     if ( p->ndisp & NDISP_INT4 )
01432     {
01433         int * ip = (int *)data;
01434 
01435         fprintf( fp, "0x%4x : ", (unsigned int)p->offset );
01436         for ( c = 0; c < p->length/4; c++, ip++ )
01437         {
01438             if ( p->swap )
01439                 swap_4( ip );
01440             fprintf( fp, "%d ", *ip );
01441         }
01442         fputc( '\n', fp );
01443     }
01444 
01445     
01446     if ( p->ndisp & NDISP_REAL4 )
01447     {
01448         float * rp = (float *)data;
01449 
01450         fprintf( fp, "0x%4x : ", (unsigned int)p->offset );
01451         for ( c = 0; c < p->length/4; c++, rp++ )
01452         {
01453             if ( p->swap )
01454                 swap_4( rp );
01455             fprintf( fp, "%f ", *rp );
01456         }
01457         fputc( '\n', fp );
01458     }
01459 
01460     return 0;
01461 }
01462 
01463 
01464 
01465 
01466 
01467 
01468 int
01469 disp_param_data( param_t * p )
01470 {
01471     if ( ! p )
01472         return -1;
01473 
01474     printf( "num_files, flist         : %d, %p\n"
01475             "debug, data_len          : %d, %d\n"
01476             "ge_disp, ge4_disp, ndisp : 0x%x, 0x%x, 0x%x\n"
01477             "\n"
01478             "swap, modify, mod_type   : %d, %d, %d\n"
01479             "offset, length, quiet    : %ld, %d, %d\n"
01480             "mod_data                 : %s\n"
01481             "\n",
01482             p->num_files, p->flist, p->debug, p->data_len,
01483             p->ge_disp, p->ge4_disp, p->ndisp, p->swap, p->modify,
01484             p->mod_type, p->offset, p->length, p->quiet,
01485             CHECK_NULL_STR(p->mod_data)
01486           );
01487 
01488     if ( p->debug > 1 )
01489     {
01490         int c;
01491 
01492         printf( "file list: " );
01493         for ( c = 0; c < p->num_files; c ++ )
01494             printf( "'%s' ", p->flist[c] );
01495         printf( "\n" );
01496     }
01497 
01498     return 0;
01499 }
01500 
01501 
01502 
01503 
01504 
01505 
01506 int
01507 r_idisp_ge_extras( char * info, ge_extras * E )
01508 {
01509     if ( info )
01510         fputs( info, stdout );
01511 
01512     if ( E == NULL )
01513     {
01514         printf( "r_idisp_ge_extras: E == NULL" );
01515         return -1;
01516     }
01517 
01518     printf( " ge_extras at %p :\n"
01519             "    bpp              = %d\n"
01520             "    cflag            = %d\n"
01521             "    hdroff           = %d\n"
01522             "    skip             = %d\n"
01523             "    swap             = %d\n"
01524             "    (xyz0,xyz1,xyz2) = (%f,%f,%f)\n"
01525             "    (xyz3,xyz4,xyz5) = (%f,%f,%f)\n"
01526             "    (xyz6,xyz7,xyz8) = (%f,%f,%f)\n",
01527             E, E->bpp, E->cflag, E->hdroff, E->skip, E->swap,
01528             E->xyz[0], E->xyz[1], E->xyz[2],
01529             E->xyz[3], E->xyz[4], E->xyz[5],
01530             E->xyz[6], E->xyz[7], E->xyz[8]
01531           );
01532     return 0;
01533 }
01534 
01535 
01536 
01537 
01538 
01539 int
01540 r_idisp_ge_header_info( char * info, ge_header_info * I )
01541 {
01542     if ( info )
01543         fputs( info, stdout );
01544 
01545     if ( I == NULL )
01546     {
01547         printf( "r_idisp_ge_header_info: I == NULL" );
01548         return -1;
01549     }
01550 
01551     printf( " ge_header_info at %p :\n"
01552             "    good        = %d\n"
01553             "    (nx,ny)     = (%d,%d)\n"
01554             "    uv17        = %d\n"
01555             "    (dx,dy,dz)  = (%f,%f,%f)\n"
01556             "    zoff        = %f\n"
01557             "    (tr,te)     = (%f,%f)\n"
01558             "    orients     = %8s\n",
01559             I, I->good, I->nx, I->ny, I->uv17,
01560             I->dx, I->dy, I->dz, I->zoff, I->tr, I->te,
01561             CHECK_NULL_STR(I->orients)
01562           );
01563 
01564     return 0;
01565 }
01566 
01567 
01568 
01569 
01570 
01571 
01572 int
01573 disp_ge_offsets( char * info, ge_off * D )
01574 {
01575     if ( info )
01576         fputs( info, stdout );
01577 
01578     if ( D == NULL )
01579     {
01580         printf( "disp_ge_offsets: D == NULL" );
01581         return -1;
01582     }
01583 
01584     printf( " ge_off at %p :\n"
01585             "    nx, ny, uv17 = %d, %d, %d\n"
01586             "    dx, dy, dz   = %d, %d, %d\n"
01587             "    tr, te, xyz  = %d, %d, %d\n",
01588             D, D->nx, D->ny, D->uv17,
01589             D->dx, D->dy, D->dz,
01590             D->tr, D->te, D->xyz
01591           );
01592 
01593     return 0;
01594 }
01595