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