00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <unistd.h>
00013 #include <stdlib.h>
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include <errno.h>
00017 #include <ctype.h>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 #include <time.h>
00021 #include <math.h>
00022
00023
00024
00025 time_t THD_file_mtime( char * pathname ) ;
00026 int THD_is_file( char * pathname ) ;
00027 int THD_is_symlink( char * pathname ) ;
00028 long THD_filesize( char * pathname ) ;
00029 int THD_is_directory( char * pathname ) ;
00030 int THD_is_executable( char * pathname ) ;
00031
00032 void MCW_file_expand( int nin , char ** fin , int * nout , char *** fout ) ;
00033 void MCW_free_expand( int gnum , char ** gout ) ;
00034 void MCW_warn_expand( int www ) ;
00035 void NIH_glob( char *fn , int *nout , char ***fout ) ;
00036 void NIH_glob_free( int gnum , char **gout ) ;
00037
00038
00039
00040 typedef struct {
00041 int good ;
00042 int nx,ny ;
00043 int uv17;
00044 float dx,dy,dz , zoff , tr,te ;
00045 char orients[8] ;
00046 } ge_header_info ;
00047
00048 void ge_header( char *pathname , ge_header_info *hi ) ;
00049 void Ifile_help ();
00050
00051
00052
00053
00054 int main( int argc , char *argv[] )
00055 {
00056 int num_I , ii,jj , ngood , nrun , i, UseUv17 = 0;
00057 char **nam_I ;
00058 char **gnam_I , *PatOpt=NULL, *OutDir = NULL;
00059 int *time_I , *uv17, lmax=0 , ll , thresh , ibot,itop ;
00060 float *zoff_I , tr , zth1,zth2 , zd ;
00061 ge_header_info geh ;
00062 int Ni, CurVolInd, *New_Vol_Loc, *VolSize, N_Vols, *TroubVolume, iTroub,
00063 MultiSliceVol, *DupSlice, iDup, BadRun, AllGood = 1, GoodRun, kar = -1,
00064 brk = 0, StrtFiles = 0;
00065 float *Dzv, fact;
00066 char fmt[128] ;
00067 FILE * fout_dbg, *fout_panga;
00068
00069 if (argc == 1) { Ifile_help(); exit(1); }
00070 kar = 1;
00071 brk = 0;
00072 StrtFiles = 0;
00073 UseUv17 = 0;
00074 while (kar < argc && !StrtFiles) {
00075 if (strcmp (argv[kar],"-h") == 0 || strcmp (argv[kar],"-help") == 0) { Ifile_help(); exit(1); }
00076
00077 if (!brk && (strcmp(argv[kar], "-nt") == 0)) {
00078 UseUv17 = 1;
00079 brk = 1;
00080 ++kar;
00081 }
00082
00083 if (!brk && (strcmp(argv[kar], "-od") == 0)) {
00084 kar ++;
00085 if (kar >= argc) {
00086 fprintf (stderr, "Error: Need argument after -od.\n");
00087 exit (1);
00088 }
00089 OutDir = (char *)malloc((strlen(argv[kar])+1)*sizeof(char));
00090
00091 sprintf(OutDir,"%s",argv[kar]);
00092 brk = 1;
00093 ++kar;
00094 }
00095
00096 if (!brk && (strcmp(argv[kar], "-sp") == 0)) {
00097 kar ++;
00098 if (kar >= argc) {
00099 fprintf (stderr, "Error: Need argument after -sp.\n");
00100 exit (1);
00101 }
00102 PatOpt = (char *)malloc((strlen(argv[kar])+1)*sizeof(char));
00103
00104 sprintf(PatOpt,"%s",argv[kar]);
00105 brk = 1;
00106 ++kar;
00107 }
00108
00109
00110 if (!brk) {
00111
00112 StrtFiles = kar;
00113 } else {
00114 brk = 0;
00115 }
00116 }
00117
00118 if (UseUv17) {
00119 fprintf(stderr,"++ using User Variable 17.\n"); }
00120 else {
00121 fprintf(stderr,"++ using time stamp.\n");}
00122
00123 if (!PatOpt) {
00124 PatOpt = (char *)malloc(sizeof(char)*10);
00125 sprintf(PatOpt,"alt+z");
00126 }
00127
00128 if (!OutDir) {
00129 OutDir = (char *)malloc(sizeof(char)*10);
00130 sprintf(OutDir,"afni");
00131 }
00132
00133 fprintf(stderr,"++ using slice pattern %s\n", PatOpt);
00134 fprintf(stderr,"++ using output directory %s\n", OutDir);
00135
00136
00137
00138
00139
00140 fout_panga = fopen("GERT_Reco","w");
00141 if (fout_panga == NULL) {
00142 fprintf(stderr,"Could not open AutoPanga for writing. Check write permissions.\n");
00143 exit(1);
00144 }
00145 fprintf(fout_panga, "#!/bin/csh -f\n");
00146 fprintf(fout_panga, "#This script was automatically generated by Ifile.\n");
00147 fprintf(fout_panga, "#Change the following options to your liking (see @RenamePanga -help for more info):\n\n");
00148 fprintf(fout_panga, "set OutlierCheck = '-oc' #set to '-oc' to check for outliers, '' to skip checking.\n");
00149 fprintf(fout_panga, "set OutPrefix = 'OutBrick' #Output brick prefix.\n\n");
00150
00151
00152 fprintf(stderr,"++ Expanding file list ...\n") ;
00153 MCW_file_expand( argc - StrtFiles, argv + StrtFiles , &num_I , &nam_I );
00154
00155 fprintf(stderr,"++ found %d '*/I.*' files\n",num_I) ;
00156
00157 if( num_I <= 0 ) exit(1) ;
00158
00159
00160
00161 time_I = (int *) calloc( sizeof(int) , num_I ) ;
00162 zoff_I = (float *) calloc( sizeof(float) , num_I ) ;
00163 gnam_I = (char **) calloc( sizeof(char *) , num_I ) ;
00164 uv17 = (int *) calloc( sizeof(int) , num_I ) ;
00165 ngood = 0 ;
00166
00167 fprintf(stderr,"++ Scanning GE headers") ;
00168 #ifdef DBG_FILE
00169 fout_dbg = fopen("DBG_IfileOut.txt","w");
00170 #endif
00171
00172 for( ii=0 ; ii < num_I ; ii++ ){
00173 ge_header( nam_I[ii] , &geh ) ;
00174
00175 if( ii%1000==999 ) fprintf(stderr,".") ;
00176
00177 if( geh.good ){
00178 zoff_I[ngood] = geh.zoff ;
00179 time_I[ngood] = (int) THD_file_mtime( nam_I[ii] ) ;
00180 gnam_I[ngood] = strdup( nam_I[ii] ) ;
00181 uv17[ngood] = geh.uv17;
00182
00183 ngood++ ;
00184
00185 ll = strlen(nam_I[ii]) ; if( ll > lmax ) lmax = ll ;
00186
00187 tr += geh.tr ;
00188 }
00189 else {
00190 fprintf(stderr,"\tFile %s: !geh.good.\t", nam_I[ii] ) ;
00191 }
00192 #ifdef DBG_FILE
00193 fprintf(fout_dbg,"%s %d\n", nam_I[ii], time_I[ii]);
00194 #endif
00195 }
00196
00197
00198 fprintf(stderr,"\n++ %d files are good images\n",ngood) ;
00199
00200 MCW_free_expand( num_I, nam_I ) ;
00201
00202
00203 if( ngood < 3 ) exit(1) ;
00204
00205
00206
00207 for( ii=ngood-1 ; ii > 0 ; ii-- ) {
00208 time_I[ii] -= time_I[ii-1] ;
00209
00210 }
00211 time_I[0] = 0 ;
00212
00213
00214
00215 tr /= ngood ;
00216 thresh = (int)( 3.0*tr+10.5 ) ;
00217
00218 if (UseUv17 == 0) {
00219
00220 fprintf(stderr,"++ File time threshold = %d s\n",thresh) ;
00221 }
00222
00223
00224
00225
00226 GoodRun = 0;
00227 nrun = 0 ;
00228 ibot = 0 ;
00229 while( ibot < ngood ){
00230
00231
00232
00233 if (UseUv17) {
00234 for( itop=ibot+1; itop<ngood && uv17[itop]==uv17[ibot]; itop++ ) {};
00235 } else {
00236 for( itop=ibot+1; itop<ngood && time_I[itop]<thresh; itop++ ) ;
00237 }
00238
00239
00240
00241
00242
00243 if( ibot == itop-1 ){
00244
00245 printf("skip: %s\n",gnam_I[ibot]) ;
00246
00247 } else {
00248
00249 nrun++ ;
00250 BadRun = 0;
00251 printf("\nRUN %02d:\t %s .. %s\t",nrun,gnam_I[ibot],gnam_I[itop-1]) ;
00252
00253
00254 if (0)
00255 {
00256
00257
00258
00259
00260 zth1 = fabs( zoff_I[ibot+1] - zoff_I[ibot] ) * 1.01 + 0.01 ;
00261 zth2 = 3.01*zth1 ;
00262
00263 for( jj=ibot ; jj < itop-1 ; jj++ ){
00264 zd = fabs( zoff_I[jj+1] - zoff_I[jj] ) ;
00265 if( zd > zth1 && zd < zth2 )
00266 printf(" image %s seems out of place\n",gnam_I[jj+1]) ;
00267 }
00268 }
00269 else
00270 {
00271
00272 Ni = itop - ibot;
00273 Dzv = (float *) calloc( sizeof(float) , Ni) ;
00274 New_Vol_Loc = (int *) calloc(sizeof(int), Ni);
00275 VolSize = (int *) calloc(sizeof(int), Ni);
00276 TroubVolume = (int *) calloc(sizeof(int), Ni);
00277 DupSlice = (int *) calloc(sizeof(int), Ni);
00278
00279 Dzv[0] = 0;
00280 Dzv[1] = zoff_I[ibot+1] - zoff_I[ibot];
00281 if (Dzv[1] < 0)
00282 {
00283 fact = -1;
00284 Dzv[1] *= fact;
00285 }
00286 else fact = 1;
00287 if (Dzv[1] != 0)
00288 MultiSliceVol = 1;
00289 else
00290 MultiSliceVol = 0;
00291
00292
00293
00294 iDup = 0;
00295 iTroub = 0;
00296 CurVolInd = 0;
00297 New_Vol_Loc[CurVolInd] = ibot;
00298 for (jj = ibot+2 ; jj < itop ; jj++ ){
00299 Dzv[jj-ibot] = fact * (zoff_I[jj] - zoff_I[jj - 1]);
00300 #ifdef DBG_FILE
00301 fprintf(fout_dbg,"Dzv %f \n", Dzv[jj-ibot]);
00302 #endif
00303 if (MultiSliceVol && !Dzv[jj-ibot]) {
00304 DupSlice[iDup] = jj;
00305 ++iDup;
00306 }
00307
00308 if (Dzv[jj-ibot] < 0) {
00309 ++CurVolInd;
00310 New_Vol_Loc[CurVolInd] = jj;
00311 VolSize[CurVolInd-1] = New_Vol_Loc[CurVolInd] - New_Vol_Loc[CurVolInd-1];
00312 if (CurVolInd > 1) {
00313 if (VolSize[CurVolInd-1] != VolSize[0]) {
00314 TroubVolume[iTroub] = CurVolInd - 1;
00315 ++iTroub;
00316 }
00317 }
00318 }
00319 }
00320 VolSize[CurVolInd] = itop - New_Vol_Loc[CurVolInd];
00321 if (VolSize[CurVolInd] != VolSize[0]) {
00322 TroubVolume[iTroub] = CurVolInd;
00323 ++iTroub;
00324 }
00325 N_Vols = CurVolInd+1;
00326 printf("%d images %d Volume(s) \n", Ni, N_Vols);
00327
00328 if (N_Vols > 1) {
00329
00330
00331
00332
00333
00334
00335 }
00336 else {
00337
00338 }
00339 if (iTroub > 0) {
00340 BadRun = 1;
00341 fprintf(stderr, "\t\33[1m***************** PANGA! Trouble volumes found. *****************\33[0m\n");
00342 fprintf(stderr, "\tVol %d %s--%s (%d slices) has a different size from the first volume (%d slices) in the series.\n", \
00343 TroubVolume[0], gnam_I[New_Vol_Loc[TroubVolume[0]]], gnam_I[New_Vol_Loc[TroubVolume[0]]+VolSize[TroubVolume[0]]-1], VolSize[TroubVolume[0]], VolSize[0]);
00344 if (iTroub > 1)
00345 fprintf(stderr, "\t%d other volumes suffer of similar ailments! Think of the children!\n", iTroub - 1);
00346
00347
00348
00349
00350
00351 }
00352 if (iDup > 0) {
00353 BadRun = 1;
00354 fprintf(stderr, "\t\33[1m***************** PANGA! Dupilcated slices found. *****************\33[0m\n");
00355 for (i=0; i < iDup; i++) {
00356 fprintf(stderr, "\tSlice %s appears to be a duplicate of slice %s.\n", gnam_I[DupSlice[i]], gnam_I[DupSlice[i]-1]);
00357 }
00358 }
00359 }
00360
00361 if (!BadRun) {
00362 ++ GoodRun;
00363 fprintf(fout_panga,"@RenamePanga %s ", strtok(gnam_I[ibot],"/"));
00364 if (MultiSliceVol)
00365 fprintf(fout_panga,"%s %d %d $OutPrefix -sp %s $OutlierCheck -od %s\n",
00366 strtok(NULL,"/I."), (int)Ni/N_Vols, N_Vols, PatOpt, OutDir);
00367 else
00368 fprintf(fout_panga,"%s %d %d $OutPrefix -sp %s $OutlierCheck -od %s\n",
00369 strtok(NULL,"/I."), N_Vols, (int)Ni/N_Vols, PatOpt, OutDir);
00370 }
00371 else
00372 {
00373 AllGood = 0;
00374 }
00375 free(Dzv);
00376 free(New_Vol_Loc);
00377 free(VolSize);
00378 free(TroubVolume);
00379 free(DupSlice);
00380 }
00381
00382 ibot = itop ;
00383 }
00384
00385 free(PatOpt);
00386 free(OutDir);
00387
00388 #ifdef DBG_FILE
00389 fclose (fout_dbg);
00390 #endif
00391 fprintf(fout_panga, "\n");
00392 fclose (fout_panga);
00393 system ("chmod u+x GERT_Reco");
00394 #if 0
00395
00396 sprintf(fmt,"%%-%d.%ds: dt=%%d zoff=%%g\n",lmax,lmax) ;
00397 for( ii=0 ; ii < ngood ; ii++ )
00398 printf(fmt,gnam_I[ii],time_I[ii],zoff_I[ii]) ;
00399 #endif
00400
00401 if (!GoodRun)
00402 system ("rm -f GERT_Reco");
00403 else
00404 fprintf(stdout,"\nFound %d complete scans.\nRun\33[1m GERT_Reco \33[0mto create AFNI bricks.\n\n", GoodRun);
00405
00406 if (AllGood)
00407 exit(0) ;
00408 else
00409 exit(1);
00410 }
00411
00412
00413 void Ifile_help ()
00414 {
00415 fprintf(stdout,"\nUsage: Ifile [Options] <File List> \n");
00416
00417 fprintf(stdout,"\n\t[-nt]: Do not use time stamp to identify complete scans.\n");
00418 fprintf(stdout,"\t Complete scans are identified from 'User Variable 17'\n"
00419 "\t in the image header.\n");
00420 fprintf(stdout,"\t[-sp Pattern]: Slice acquisition pattern.\n"
00421 "\t Sets the slice acquisition pattern.\n"
00422 "\t The default option is alt+z.\n"
00423 "\t See to3d -help for acceptable options.\n");
00424 fprintf(stdout,"\t[-od Output_Directory]: Set the output directory in @RenamePanga.\n"
00425 "\t The default is afni .\n");
00426 fprintf(stdout,"\n\t<File List>: Strings of wildcards defining series of\n");
00427 fprintf(stdout,"\t GE-Real Time (GERT) images to be assembled\n");
00428 fprintf(stdout,"\t as an afni brick. Example:\n");
00429 fprintf(stdout,"\t Ifile '*/I.*'\n");
00430 fprintf(stdout,"\t or Ifile '083/I.*' '103/I.*' '123/I.*' '143/I.*'\n\n");
00431 fprintf(stdout,"\tThe program attempts to identify complete scans from the list\n");
00432 fprintf(stdout,"\tof images supplied on command line and generates the commands\n");
00433 fprintf(stdout,"\tnecessary to turn them into AFNI bricks using the script @RenamePanga.\n");
00434 fprintf(stdout,"\tIf at least one complete scan is identified, a script file named GERT_Reco\n");
00435 fprintf(stdout,"\tis created and executing it creates the afni bricks placed in the afni directory.\n");
00436 fprintf(stdout,"\nHow does it work?\n");
00437 fprintf(stdout,"\tWith the -nt option: Ifile uses the variable 'User Variable 17' in the \n");
00438 fprintf(stdout,"\tI file's header. This option appears to be augmented each time a new\n");
00439 fprintf(stdout,"\tscan is started. (Thanks to S. Marrett for discovering the elusive variable.)\n");
00440 fprintf(stdout,"\tWithout -nt option: Ifile first examines the modification time for each image and \n");
00441 fprintf(stdout,"\tinfers from that which images form a single scan. Consecutive images that are less \n");
00442 fprintf(stdout,"\tthan T seconds apart belong to the same scan. T is set based on the mean\n");
00443 fprintf(stdout,"\ttime delay difference between successive images. The threshold currently\n");
00444 fprintf(stdout,"\tused works for the test data that we have. If it fails for your data, let us\n");
00445 fprintf(stdout,"\tknow and supply us with the data. Once a set of images is grouped into a \n");
00446 fprintf(stdout,"\tscan the sequence of slice location is analysed and duplicate, missing slices,\n");
00447 fprintf(stdout,"\tand incomplete volumes are detected. Sets of images that do not pass these tests\n");
00448 fprintf(stdout,"\tare ignored.\n");
00449 fprintf(stdout,"\nPreserving Time Info: (not necessary with -nt option but does not hurt to preserve anyway)\n");
00450 fprintf(stdout,"\tIt is important to preserve the file modification time info as you copy or untar\n");
00451 fprintf(stdout,"\tthe data. If you neglect to do so and fail to write down where each scan ends\n");
00452 fprintf(stdout,"\tand/or begins, you might have a hell of a time reconstructing your data.\n");
00453 fprintf(stdout,"\tWhen copying image directories, use \33[1m cp -rp ???/* \33[0m and when untaring \n");
00454 fprintf(stdout,"\tthe archive, use \33[1m tar --atime-preserve -xf Archive.tar \33[0m on linux.\n");
00455 fprintf(stdout,"\tOn Sun and SGI, tar -xf Archive.tar preserves the time info.\n");
00456 fprintf(stdout,"\nFuture Improvements:\n");
00457 fprintf(stdout,"\tOut of justifiable laziness, and for other less convincing reasons, I have left \n");
00458 fprintf(stdout,"\tIfile and @RenamePanga separate. They can be combined into one program but it's usage\n");
00459 fprintf(stdout,"\twould become more complicated. At any rate, the user should not notice any difference\n");
00460 fprintf(stdout,"\tsince all they have to do is run the script GERT_reco that is created by Ifile.\n\n");
00461 fprintf(stdout,"\t Dec. 12/01 (Last modified July 24/02) SSCC/NIMH \n\tRobert W. Cox(rwcox@nih.gov) and Ziad S. Saad (ziad@nih.gov)\n\n");
00462
00463 }
00464
00465
00466
00467 time_t THD_file_mtime( char * pathname )
00468 {
00469 static struct stat buf ; int ii ;
00470
00471 if( pathname == NULL ) return 0 ;
00472 ii = stat( pathname , &buf ) ; if( ii != 0 ) return 0 ;
00473 return buf.st_mtime ;
00474 }
00475
00476
00477
00478 int THD_is_file( char * pathname )
00479 {
00480 static struct stat buf ; int ii ;
00481
00482 if( pathname == NULL ) return 0 ;
00483 ii = stat( pathname , &buf ) ; if( ii != 0 ) return 0 ;
00484 ii = (buf.st_mode & S_IFREG) != 0 ; return ii ;
00485 }
00486
00487
00488
00489 int THD_is_symlink( char * pathname )
00490 {
00491 char buf[32] ; int ii ;
00492
00493 ii = readlink( pathname , buf , 32 ) ;
00494 return (ii > 0) ;
00495 }
00496
00497
00498
00499 long THD_filesize( char * pathname )
00500 {
00501 static struct stat buf ; int ii ;
00502
00503 if( pathname == NULL ) return -1 ;
00504 ii = stat( pathname , &buf ) ; if( ii != 0 ) return -1 ;
00505 return buf.st_size ;
00506 }
00507
00508
00509
00510 int THD_is_directory( char * pathname )
00511 {
00512 static struct stat buf ; int ii ;
00513
00514 if( pathname == NULL ) return 0 ;
00515 ii = stat( pathname , &buf ) ; if( ii != 0 ) return 0 ;
00516 ii = (buf.st_mode & S_IFDIR) != 0 ; return ii ;
00517 }
00518
00519
00520
00521 int THD_is_executable( char * pathname )
00522 {
00523 static struct stat buf ; int ii ;
00524
00525 if( pathname == NULL ) return 0 ;
00526 ii = stat( pathname , &buf ) ; if( ii != 0 ) return 0 ;
00527 ii = (buf.st_mode & S_IXOTH) != 0 ; return ii ;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 typedef struct {
00571 int gl_pathc;
00572 int gl_matchc;
00573 int gl_offs;
00574 int gl_flags;
00575 int (*gl_errfunc)();
00576 char **gl_pathv;
00577 } glob_t;
00578
00579 #define GLOB_APPEND 0x001
00580 #define GLOB_DOOFFS 0x002
00581 #define GLOB_ERR 0x004
00582 #define GLOB_MAGCHAR 0x008
00583 #define GLOB_MARK 0x010
00584 #define GLOB_NOCHECK 0x020
00585 #define GLOB_NOSORT 0x040
00586 #define GLOB_QUOTE 0x080
00587 #define GLOB_NOMAGIC 0x100
00588
00589 #define GLOB_ALTNOT 0x200
00590
00591 #define GLOB_NOSPACE (-1)
00592 #define GLOB_ABEND (-2)
00593
00594 int glob (const char *, int, int (*)(char *, int), glob_t *);
00595 void globfree (glob_t *);
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 #undef __P
00621 #define __P(a) a
00622
00623 #define xfree free
00624 #define xmalloc malloc
00625 #define xrealloc realloc
00626
00627 #ifdef SPARKY
00628 #undef _POSIX_SOURCE
00629 #endif
00630
00631 #include <sys/types.h>
00632 #include <sys/param.h>
00633 #include <sys/stat.h>
00634 #include <dirent.h>
00635 #include <ctype.h>
00636 typedef void * ptr_t;
00637
00638
00639
00640 #if 0
00641 # define Char __Char
00642 # include "sh.h"
00643 # undef Char
00644 # undef QUOTE
00645 # undef TILDE
00646 # undef META
00647 # undef CHAR
00648 # undef ismeta
00649 # undef Strchr
00650 #endif
00651
00652 #ifndef S_ISDIR
00653 #define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
00654 #endif
00655
00656 #if !defined(S_ISLNK) && defined(S_IFLNK)
00657 #define S_ISLNK(a) (((a) & S_IFMT) == S_IFLNK)
00658 #endif
00659
00660 #if !defined(S_ISLNK) && !defined(lstat)
00661 #define lstat stat
00662 #endif
00663
00664 typedef unsigned short Char;
00665
00666 static int glob1 __P((Char *, glob_t *, int));
00667 static int glob2 __P((Char *, Char *, Char *, glob_t *, int));
00668 static int glob3 __P((Char *, Char *, Char *, Char *,
00669 glob_t *, int));
00670 static int globextend __P((Char *, glob_t *));
00671 static int match __P((Char *, Char *, Char *, int));
00672 #ifndef __clipper__
00673 static int compare __P((const ptr_t, const ptr_t));
00674 #endif
00675 static DIR *Opendir __P((Char *));
00676 #ifdef S_IFLNK
00677 static int Lstat __P((Char *, struct stat *));
00678 #endif
00679 static Char *Strchr __P((Char *, int));
00680 #ifdef DEBUG
00681 static void qprintf __P((Char *));
00682 #endif
00683
00684 #define DOLLAR '$'
00685 #define DOT '.'
00686 #define EOS '\0'
00687 #define LBRACKET '['
00688 #define NOT '!'
00689 #define ALTNOT '^'
00690 #define QUESTION '?'
00691 #define QUOTE '\\'
00692 #define RANGE '-'
00693 #define RBRACKET ']'
00694 #define SEP '/'
00695 #define STAR '*'
00696 #define TILDE '~'
00697 #define UNDERSCORE '_'
00698
00699 #define M_META 0x8000
00700 #define M_PROTECT 0x4000
00701 #define M_MASK 0xffff
00702 #define M_ASCII 0x00ff
00703
00704 #define CHAR(c) ((c)&M_ASCII)
00705 #define META(c) ((c)|M_META)
00706 #define M_ALL META('*')
00707 #define M_END META(']')
00708 #define M_NOT META('!')
00709 #define M_ALTNOT META('^')
00710 #define M_ONE META('?')
00711 #define M_RNG META('-')
00712 #define M_SET META('[')
00713 #define ismeta(c) (((c)&M_META) != 0)
00714
00715 #include "machdep.h"
00716
00717 #if defined(SOLARIS_DIRENT_ZERO) && !defined(SOLARIS_DIRENT_PATCH)
00718 # define SOLARIS_DIRENT_PATCH
00719 #endif
00720
00721 #ifdef SOLARIS_DIRENT_PATCH
00722 struct dirent {
00723 ino_t d_ino;
00724 off_t d_off;
00725 unsigned short d_reclen;
00726 char d_name[1];
00727 };
00728 #endif
00729
00730
00731
00732
00733
00734
00735
00736
00737 static DIR *
00738 Opendir(str)
00739 register Char *str;
00740 {
00741 char buf[MAXPATHLEN];
00742 register char *dc = buf;
00743
00744 if (!*str)
00745 return (opendir("."));
00746 while ((*dc++ = *str++) != '\0')
00747 continue;
00748 return (opendir(buf));
00749 }
00750
00751 #ifdef S_IFLNK
00752 static int
00753 Lstat(fn, sb)
00754 register Char *fn;
00755 struct stat *sb;
00756 {
00757 char buf[MAXPATHLEN];
00758 register char *dc = buf;
00759
00760 while ((*dc++ = *fn++) != '\0')
00761 continue;
00762 # ifdef NAMEI_BUG
00763 {
00764 int st;
00765
00766 st = lstat(buf, sb);
00767 if (*buf)
00768 dc--;
00769 return (*--dc == '/' && !S_ISDIR(sb->st_mode) ? -1 : st);
00770 }
00771 # else
00772 return (lstat(buf, sb));
00773 # endif
00774 }
00775 #else
00776 #define Lstat Stat
00777 #endif
00778
00779 static int
00780 Stat(fn, sb)
00781 register Char *fn;
00782 struct stat *sb;
00783 {
00784 char buf[MAXPATHLEN];
00785 register char *dc = buf;
00786
00787 while ((*dc++ = *fn++) != '\0')
00788 continue;
00789 #ifdef NAMEI_BUG
00790 {
00791 int st;
00792
00793 st = stat(buf, sb);
00794 if (*buf)
00795 dc--;
00796 return (*--dc == '/' && !S_ISDIR(sb->st_mode) ? -1 : st);
00797 }
00798 #else
00799 return (stat(buf, sb));
00800 #endif
00801 }
00802
00803 static Char *
00804 Strchr(str, ch)
00805 Char *str;
00806 int ch;
00807 {
00808 do
00809 if (*str == ch)
00810 return (str);
00811 while (*str++);
00812 return (NULL);
00813 }
00814
00815 #ifdef DEBUG
00816 static void
00817 qprintf(s)
00818 Char *s;
00819 {
00820 Char *p;
00821
00822 for (p = s; *p; p++)
00823 printf("%c", *p & 0xff);
00824 printf("\n");
00825 for (p = s; *p; p++)
00826 printf("%c", *p & M_PROTECT ? '"' : ' ');
00827 printf("\n");
00828 for (p = s; *p; p++)
00829 printf("%c", *p & M_META ? '_' : ' ');
00830 printf("\n");
00831 }
00832 #endif
00833
00834 static int
00835 compare(p, q)
00836 const ptr_t p, q;
00837 {
00838 #if defined(NLS) && !defined(NOSTRCOLL)
00839 errno = 0;
00840
00841 return (strcoll(*(char **) p, *(char **) q));
00842 #else
00843 return (strcmp(*(char **) p, *(char **) q));
00844 #endif
00845 }
00846
00847
00848
00849
00850
00851
00852
00853
00854 int
00855 glob(pattern, flags, errfunc, pglob)
00856 const char *pattern;
00857 int flags;
00858 int (*errfunc) __P((char *, int));
00859 glob_t *pglob;
00860 {
00861 int err, oldpathc;
00862 Char *bufnext, *bufend, *compilebuf, m_not;
00863 const unsigned char *compilepat, *patnext;
00864 int c, not;
00865 Char patbuf[MAXPATHLEN + 1], *qpatnext;
00866 int no_match;
00867
00868 patnext = (unsigned char *) pattern;
00869 if (!(flags & GLOB_APPEND)) {
00870 pglob->gl_pathc = 0;
00871 pglob->gl_pathv = NULL;
00872 if (!(flags & GLOB_DOOFFS))
00873 pglob->gl_offs = 0;
00874 }
00875 pglob->gl_flags = flags & ~GLOB_MAGCHAR;
00876 pglob->gl_errfunc = errfunc;
00877 oldpathc = pglob->gl_pathc;
00878 pglob->gl_matchc = 0;
00879
00880 if (pglob->gl_flags & GLOB_ALTNOT) {
00881 not = ALTNOT;
00882 m_not = M_ALTNOT;
00883 }
00884 else {
00885 not = NOT;
00886 m_not = M_NOT;
00887 }
00888
00889 bufnext = patbuf;
00890 bufend = bufnext + MAXPATHLEN;
00891 compilebuf = bufnext;
00892 compilepat = patnext;
00893
00894 no_match = *patnext == not;
00895 if (no_match)
00896 patnext++;
00897
00898 if (flags & GLOB_QUOTE) {
00899
00900 while (bufnext < bufend && (c = *patnext++) != EOS)
00901 if (c == QUOTE) {
00902 if ((c = *patnext++) == EOS) {
00903 c = QUOTE;
00904 --patnext;
00905 }
00906 *bufnext++ = (Char) (c | M_PROTECT);
00907 }
00908 else
00909 *bufnext++ = (Char) c;
00910 }
00911 else
00912 while (bufnext < bufend && (c = *patnext++) != EOS)
00913 *bufnext++ = (Char) c;
00914 *bufnext = EOS;
00915
00916 bufnext = patbuf;
00917 qpatnext = patbuf;
00918
00919 while ((c = *qpatnext++) != EOS) {
00920 switch (c) {
00921 case LBRACKET:
00922 c = *qpatnext;
00923 if (c == not)
00924 ++qpatnext;
00925 if (*qpatnext == EOS ||
00926 Strchr(qpatnext + 1, RBRACKET) == NULL) {
00927 *bufnext++ = LBRACKET;
00928 if (c == not)
00929 --qpatnext;
00930 break;
00931 }
00932 pglob->gl_flags |= GLOB_MAGCHAR;
00933 *bufnext++ = M_SET;
00934 if (c == not)
00935 *bufnext++ = m_not;
00936 c = *qpatnext++;
00937 do {
00938 *bufnext++ = CHAR(c);
00939 if (*qpatnext == RANGE &&
00940 (c = qpatnext[1]) != RBRACKET) {
00941 *bufnext++ = M_RNG;
00942 *bufnext++ = CHAR(c);
00943 qpatnext += 2;
00944 }
00945 } while ((c = *qpatnext++) != RBRACKET);
00946 *bufnext++ = M_END;
00947 break;
00948 case QUESTION:
00949 pglob->gl_flags |= GLOB_MAGCHAR;
00950 *bufnext++ = M_ONE;
00951 break;
00952 case STAR:
00953 pglob->gl_flags |= GLOB_MAGCHAR;
00954
00955
00956
00957 if (bufnext == patbuf || bufnext[-1] != M_ALL)
00958 *bufnext++ = M_ALL;
00959 break;
00960 default:
00961 *bufnext++ = CHAR(c);
00962 break;
00963 }
00964 }
00965 *bufnext = EOS;
00966 #ifdef DEBUG
00967 qprintf(patbuf);
00968 #endif
00969
00970 if ((err = glob1(patbuf, pglob, no_match)) != 0)
00971 return (err);
00972
00973
00974
00975
00976
00977
00978
00979 if (pglob->gl_pathc == oldpathc &&
00980 ((flags & GLOB_NOCHECK) ||
00981 ((flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) {
00982 if (!(flags & GLOB_QUOTE)) {
00983 Char *dp = compilebuf;
00984 const unsigned char *sp = compilepat;
00985
00986 while ((*dp++ = *sp++) != '\0')
00987 continue;
00988 }
00989 else {
00990
00991
00992
00993
00994 while (*compilepat != EOS) {
00995 if (*compilepat == QUOTE) {
00996 if (*++compilepat == EOS)
00997 --compilepat;
00998 }
00999 *compilebuf++ = (unsigned char) *compilepat++;
01000 }
01001 *compilebuf = EOS;
01002 }
01003 return (globextend(patbuf, pglob));
01004 }
01005 else if (!(flags & GLOB_NOSORT))
01006 qsort((char *) (pglob->gl_pathv + pglob->gl_offs + oldpathc),
01007 pglob->gl_pathc - oldpathc, sizeof(char *),
01008 (int (*) __P((const void *, const void *))) compare);
01009 return (0);
01010 }
01011
01012 static int
01013 glob1(pattern, pglob, no_match)
01014 Char *pattern;
01015 glob_t *pglob;
01016 int no_match;
01017 {
01018 Char pathbuf[MAXPATHLEN + 1];
01019
01020
01021
01022
01023 if (*pattern == EOS)
01024 return (0);
01025 return (glob2(pathbuf, pathbuf, pattern, pglob, no_match));
01026 }
01027
01028
01029
01030
01031
01032
01033 static int
01034 glob2(pathbuf, pathend, pattern, pglob, no_match)
01035 Char *pathbuf, *pathend, *pattern;
01036 glob_t *pglob;
01037 int no_match;
01038 {
01039 struct stat sbuf;
01040 int anymeta;
01041 Char *p, *q;
01042
01043
01044
01045
01046
01047 anymeta = 0;
01048 for (;;) {
01049 if (*pattern == EOS) {
01050 *pathend = EOS;
01051
01052 if (Lstat(pathbuf, &sbuf))
01053 return (0);
01054
01055 if (((pglob->gl_flags & GLOB_MARK) &&
01056 pathend[-1] != SEP) &&
01057 (S_ISDIR(sbuf.st_mode)
01058 #ifdef S_IFLNK
01059 || (S_ISLNK(sbuf.st_mode) &&
01060 (Stat(pathbuf, &sbuf) == 0) &&
01061 S_ISDIR(sbuf.st_mode))
01062 #endif
01063 )) {
01064 *pathend++ = SEP;
01065 *pathend = EOS;
01066 }
01067 ++pglob->gl_matchc;
01068 return (globextend(pathbuf, pglob));
01069 }
01070
01071
01072 q = pathend;
01073 p = pattern;
01074 while (*p != EOS && *p != SEP) {
01075 if (ismeta(*p))
01076 anymeta = 1;
01077 *q++ = *p++;
01078 }
01079
01080 if (!anymeta) {
01081 pathend = q;
01082 pattern = p;
01083 while (*pattern == SEP)
01084 *pathend++ = *pattern++;
01085 }
01086 else
01087 return (glob3(pathbuf, pathend, pattern, p, pglob, no_match));
01088 }
01089
01090 }
01091
01092
01093 static int
01094 glob3(pathbuf, pathend, pattern, restpattern, pglob, no_match)
01095 Char *pathbuf, *pathend, *pattern, *restpattern;
01096 glob_t *pglob;
01097 int no_match;
01098 {
01099 extern int errno;
01100 DIR *dirp;
01101 struct dirent *dp;
01102 int err;
01103 Char m_not = (pglob->gl_flags & GLOB_ALTNOT) ? M_ALTNOT : M_NOT;
01104 char cpathbuf[MAXPATHLEN], *ptr;
01105 #ifdef SOLARIS_DIRENT_PATCH
01106
01107 char dname[255];
01108 int ii;
01109 #endif
01110
01111 *pathend = EOS;
01112 errno = 0;
01113
01114 if (!(dirp = Opendir(pathbuf))) {
01115
01116 for (ptr = cpathbuf; (*ptr++ = (char) *pathbuf++) != EOS;)
01117 continue;
01118 if ((pglob->gl_errfunc && (*pglob->gl_errfunc) (cpathbuf, errno)) ||
01119 (pglob->gl_flags & GLOB_ERR))
01120 return (GLOB_ABEND);
01121 else
01122 return (0);
01123 }
01124
01125 err = 0;
01126
01127
01128 while ((dp = readdir(dirp)) != NULL) {
01129 register unsigned char *sc;
01130 register Char *dc;
01131
01132 #ifdef SOLARIS_DIRENT_PATCH
01133
01134
01135
01136
01137 #ifndef SOLARIS_DIRENT_ZERO
01138 for (ii = -2 ; dp->d_name[ii] != '\0' ; ++ii) {
01139 dname[ii+2] = dp->d_name[ii];
01140 }
01141 dname[ii+2] = '\0';
01142 #else
01143 strcpy(dname, dp->d_name);
01144 #endif
01145
01146
01147
01148
01149
01150
01151 if (dname[0] == DOT && *pattern != DOT)
01152 continue;
01153 for (sc = (unsigned char *) dname, dc = pathend;
01154 #else
01155 if (dp->d_name[0] == DOT && *pattern != DOT)
01156 continue;
01157 for (sc = (unsigned char *) dp->d_name, dc = pathend;
01158 #endif
01159 (*dc++ = *sc++) != '\0';)
01160 continue;
01161 if (match(pathend, pattern, restpattern, (int) m_not) == no_match) {
01162 *pathend = EOS;
01163 continue;
01164 }
01165 err = glob2(pathbuf, --dc, restpattern, pglob, no_match);
01166 if (err)
01167 break;
01168 }
01169
01170 (void) closedir(dirp);
01171 return (err);
01172 }
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 static int
01190 globextend(path, pglob)
01191 Char *path;
01192 glob_t *pglob;
01193 {
01194 register char **pathv;
01195 register int i;
01196 unsigned int newsize;
01197 char *copy;
01198 Char *p;
01199
01200 newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
01201 pathv = (char **) (pglob->gl_pathv ?
01202 xrealloc((ptr_t) pglob->gl_pathv, (size_t) newsize) :
01203 xmalloc((size_t) newsize));
01204 if (pathv == NULL)
01205 return (GLOB_NOSPACE);
01206
01207 if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
01208
01209 pathv += pglob->gl_offs;
01210 for (i = pglob->gl_offs; --i >= 0;)
01211 *--pathv = NULL;
01212 }
01213 pglob->gl_pathv = pathv;
01214
01215 for (p = path; *p++;)
01216 continue;
01217 if ((copy = (char *) xmalloc((size_t) (p - path))) != NULL) {
01218 register char *dc = copy;
01219 register Char *sc = path;
01220
01221 while ((*dc++ = *sc++) != '\0')
01222 continue;
01223 pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
01224 }
01225 pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
01226 return ((copy == NULL) ? GLOB_NOSPACE : 0);
01227 }
01228
01229
01230
01231
01232
01233
01234 static int
01235 match(name, pat, patend, m_not)
01236 register Char *name, *pat, *patend;
01237 int m_not;
01238 {
01239 int ok, negate_range;
01240 Char c, k;
01241
01242 while (pat < patend) {
01243 c = *pat++;
01244 switch (c & M_MASK) {
01245 case M_ALL:
01246 if (pat == patend)
01247 return (1);
01248 do
01249 if (match(name, pat, patend, m_not))
01250 return (1);
01251 while (*name++ != EOS);
01252 return (0);
01253 case M_ONE:
01254 if (*name++ == EOS)
01255 return (0);
01256 break;
01257 case M_SET:
01258 ok = 0;
01259 if ((k = *name++) == EOS)
01260 return (0);
01261 if ((negate_range = ((*pat & M_MASK) == m_not)) != 0)
01262 ++pat;
01263 while (((c = *pat++) & M_MASK) != M_END) {
01264 if ((*pat & M_MASK) == M_RNG) {
01265 if (c <= k && k <= pat[1])
01266 ok = 1;
01267 pat += 2;
01268 }
01269 else if (c == k)
01270 ok = 1;
01271 }
01272 if (ok == negate_range)
01273 return (0);
01274 break;
01275 default:
01276 k = *name++;
01277 if (k != c)
01278 return (0);
01279 break;
01280 }
01281 }
01282 return (*name == EOS);
01283 }
01284
01285
01286 void
01287 globfree(pglob)
01288 glob_t *pglob;
01289 {
01290 register int i;
01291 register char **pp;
01292
01293 if (pglob->gl_pathv != NULL) {
01294 pp = pglob->gl_pathv + pglob->gl_offs;
01295 for (i = pglob->gl_pathc; i--; ++pp)
01296 if (*pp)
01297 xfree((ptr_t) *pp), *pp = NULL;
01298 xfree((ptr_t) pglob->gl_pathv), pglob->gl_pathv = NULL;
01299 }
01300 }
01301
01302 static int warn = 0 ;
01303 void MCW_warn_expand( int www ){ warn = www; return; }
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314 void NIH_glob( char *fn , int *nout , char ***fout )
01315 {
01316 MCW_file_expand( 1 , &fn , nout , fout ) ;
01317 }
01318
01319 void NIH_glob_free( int gnum , char **gout )
01320 {
01321 MCW_free_expand( gnum , gout ) ;
01322 }
01323
01324
01325
01326 void MCW_file_expand( int nin , char ** fin , int * nout , char *** fout )
01327 {
01328 glob_t gl ;
01329 int ii , gnum, gold , ilen ;
01330 char ** gout ;
01331 char * fn ;
01332 char prefix[4] , fpre[128] , fname[256] ;
01333 int b1,b2,b3,b4,b5 , ib,ig , lpre ;
01334
01335 if( nin <= 0 ){ *nout = 0 ; return ; }
01336
01337 gnum = 0 ;
01338 gout = NULL ;
01339
01340 for( ii=0 ; ii < nin ; ii++ ){
01341 fn = fin[ii] ;
01342
01343 ig = 0 ;
01344
01345
01346
01347 if( strlen(fn) > 9 && fn[0] == '3' && fn[1] == 'D' ){
01348 ib = 0 ;
01349 prefix[ib++] = '3' ;
01350 prefix[ib++] = 'D' ;
01351 if( fn[2] == ':' ){ prefix[ib++] = '\0' ; }
01352 else { prefix[ib++] = fn[2] ; prefix[ib++] = '\0' ; }
01353
01354 ig = sscanf( fn+ib , "%d:%d:%d:%d:%d:%s" ,
01355 &b1,&b2,&b3,&b4,&b5 , fname ) ;
01356
01357
01358
01359 if( ig == 6 ){
01360 sprintf(fpre , "%s:%d:%d:%d:%d:%d:" , prefix,b1,b2,b3,b4,b5) ;
01361 lpre = strlen(fpre) ;
01362 } else {
01363 ig = 0 ;
01364 }
01365 }
01366
01367 if( strlen(fn) > 9 && fn[0] == '3' && fn[1] == 'A' && fn[3] == ':' ){
01368 ib = 0 ;
01369 prefix[ib++] = '3' ;
01370 prefix[ib++] = 'A' ;
01371 prefix[ib++] = fn[2] ;
01372 prefix[ib++] = '\0' ;
01373
01374 ig = sscanf( fn+ib , "%d:%d:%d:%s" ,
01375 &b1,&b2,&b3, fname ) ;
01376
01377
01378
01379 if( ig == 4 ){
01380 sprintf(fpre , "%s:%d:%d:%d:" , prefix,b1,b2,b3) ;
01381 lpre = strlen(fpre) ;
01382 } else {
01383 ig = 0 ;
01384 }
01385 }
01386
01387 if( ig > 0 ) (void) glob( fname , 0 , NULL , &gl ) ;
01388 else (void) glob( fn , 0 , NULL , &gl ) ;
01389
01390
01391
01392 if( gl.gl_pathc > 0 ){
01393
01394
01395 gold = gnum ;
01396 gnum += gl.gl_pathc ;
01397 if( gout == NULL ) gout = (char **) malloc ( sizeof(char *)*gnum);
01398 else gout = (char **) realloc(gout, sizeof(char *)*gnum);
01399
01400 for( ib=0 ; ib < gl.gl_pathc ; ib++ ){
01401 ilen = strlen( gl.gl_pathv[ib] ) + 1 ;
01402 if( ig > 0 ) ilen += lpre ;
01403
01404 gout[ib+gold] = (char *) malloc( sizeof(char) * ilen ) ;
01405
01406 if( ig > 0 ){
01407 strcpy( gout[ib+gold] , fpre ) ;
01408 strcat( gout[ib+gold] , gl.gl_pathv[ib] ) ;
01409 }
01410 else {
01411 strcpy( gout[ib+gold] , gl.gl_pathv[ib] ) ;
01412 }
01413 }
01414
01415 } else if( ig == 6 && strcmp(fname,"ALLZERO") == 0 ){
01416
01417 gold = gnum ; gnum++ ;
01418 if( gout == NULL ) gout = (char **) malloc ( sizeof(char *)*gnum);
01419 else gout = (char **) realloc(gout, sizeof(char *)*gnum);
01420
01421 ilen = lpre + strlen(fname) + 1 ;
01422 gout[gold] = (char *) malloc( sizeof(char) * ilen ) ;
01423 strcpy( gout[gold] , fpre ) ;
01424 strcat( gout[gold] , fname ) ;
01425
01426 } else {
01427
01428 if( warn )
01429 fprintf(stderr,"** Can't find file %s\n", (ig>0) ? fname : fn ) ;
01430 }
01431
01432 globfree( &gl ) ;
01433 }
01434
01435 *nout = gnum ; *fout = gout ; return ;
01436 }
01437
01438 void MCW_free_expand( int gnum , char ** gout )
01439 {
01440 int ii ;
01441
01442 if( gout == NULL ) return ;
01443
01444 for( ii=0 ; ii < gnum ; ii++ ) free( gout[ii] ) ;
01445 free( gout ) ;
01446 return ;
01447 }
01448
01449
01450
01451
01452
01453
01454 static void swap_4(void *ppp)
01455 {
01456 unsigned char *pntr = (unsigned char *) ppp ;
01457 unsigned char b0, b1, b2, b3;
01458
01459 b0 = *pntr; b1 = *(pntr+1); b2 = *(pntr+2); b3 = *(pntr+3);
01460 *pntr = b3; *(pntr+1) = b2; *(pntr+2) = b1; *(pntr+3) = b0;
01461 }
01462
01463
01464
01465 static void swap_8(void *ppp)
01466 {
01467 unsigned char *pntr = (unsigned char *) ppp ;
01468 unsigned char b0, b1, b2, b3;
01469 unsigned char b4, b5, b6, b7;
01470
01471 b0 = *pntr ; b1 = *(pntr+1); b2 = *(pntr+2); b3 = *(pntr+3);
01472 b4 = *(pntr+4); b5 = *(pntr+5); b6 = *(pntr+6); b7 = *(pntr+7);
01473
01474 *pntr = b7; *(pntr+1) = b6; *(pntr+2) = b5; *(pntr+3) = b4;
01475 *(pntr+4) = b3; *(pntr+5) = b2; *(pntr+6) = b1; *(pntr+7) = b0;
01476 }
01477
01478
01479
01480 static void swap_2(void *ppp)
01481 {
01482 unsigned char *pntr = (unsigned char *) ppp ;
01483 unsigned char b0, b1;
01484
01485 b0 = *pntr; b1 = *(pntr+1);
01486 *pntr = b1; *(pntr+1) = b0;
01487 }
01488
01489
01490
01491
01492 void ge_header( char *pathname , ge_header_info *hi )
01493 {
01494 FILE *imfile ;
01495 int length , skip , swap=0 , gg ;
01496 char orients[8] , str[8] ;
01497 int nx , ny , bpp , cflag , hdroff , stamp=0 , iarg=1 ;
01498 float uv17 = -1.0;
01499
01500 if( hi == NULL ) return ;
01501 hi->good = 0 ;
01502 if( pathname == NULL ||
01503 pathname[0] == '\0' ) return ;
01504
01505 length = THD_filesize( pathname ) ;
01506 if( length < 1024 ) return ;
01507
01508 imfile = fopen( pathname , "r" ) ;
01509 if( imfile == NULL ) return ;
01510
01511 strcpy(str,"JUNK") ;
01512 fread(str,1,4,imfile) ;
01513
01514 if( str[0]!='I' || str[1]!='M' || str[2]!='G' || str[3]!='F' ){
01515 fclose(imfile) ; return ;
01516 }
01517
01518
01519
01520 fread( &skip , 4,1, imfile ) ;
01521 fread( &nx , 4,1, imfile ) ;
01522 fread( &ny , 4,1, imfile ) ;
01523 fread( &bpp , 4,1, imfile ) ;
01524 fread( &cflag, 4,1, imfile ) ;
01525
01526
01527
01528 if( nx < 0 || nx > 8192 ){
01529 swap = 1 ;
01530 swap_4(&skip); swap_4(&nx); swap_4(&ny); swap_4(&bpp); swap_4(&cflag);
01531 } else {
01532 swap = 0 ;
01533 }
01534 if( nx < 0 || nx > 8192 || ny < 0 || ny > 8192 ){
01535 fclose(imfile) ; return ;
01536 }
01537
01538 hi->nx = nx ;
01539 hi->ny = ny ;
01540
01541 if( skip+2*nx*ny > length ||
01542 skip <= 0 ||
01543 cflag != 1 ||
01544 bpp != 16 ) return ;
01545
01546
01547
01548 fseek( imfile , 148L , SEEK_SET ) ;
01549 fread( &hdroff , 4,1 , imfile ) ;
01550 if( swap ) swap_4(&hdroff) ;
01551
01552 if( hdroff > 0 && hdroff+256 < length ){
01553 float dx,dy,dz, xyz[9], zz, tr ; int itr, ii,jj,kk ;
01554
01555
01556
01557 fseek( imfile , hdroff+26 , SEEK_SET ) ;
01558 fread( &dz , 4,1 , imfile ) ;
01559
01560 fseek( imfile , hdroff+50 , SEEK_SET ) ;
01561 fread( &dx , 4,1 , imfile ) ;
01562 fread( &dy , 4,1 , imfile ) ;
01563
01564 if( swap ){ swap_4(&dx); swap_4(&dy); swap_4(&dz); }
01565
01566 hi->dx = dx ; hi->dy = dy ; hi->dz = dz ;
01567
01568
01569
01570
01571
01572
01573
01574 fseek( imfile , hdroff+154 , SEEK_SET ) ;
01575 fread( xyz , 4,9 , imfile ) ;
01576 if( swap ){
01577 swap_4(xyz+0); swap_4(xyz+1); swap_4(xyz+2);
01578 swap_4(xyz+3); swap_4(xyz+4); swap_4(xyz+5);
01579 swap_4(xyz+6); swap_4(xyz+7); swap_4(xyz+8);
01580 }
01581
01582
01583
01584
01585
01586
01587 dx = fabs(xyz[3]-xyz[0]) ; ii = 1 ;
01588 dy = fabs(xyz[4]-xyz[1]) ; if( dy > dx ){ ii=2; dx=dy; }
01589 dz = fabs(xyz[5]-xyz[2]) ; if( dz > dx ){ ii=3; }
01590 dx = xyz[ii+2]-xyz[ii-1] ; if( dx < 0. ){ ii = -ii; }
01591 switch( ii ){
01592 case 1: orients[0]= 'L'; orients[1]= 'R'; break;
01593 case -1: orients[0]= 'R'; orients[1]= 'L'; break;
01594 case 2: orients[0]= 'P'; orients[1]= 'A'; break;
01595 case -2: orients[0]= 'A'; orients[1]= 'P'; break;
01596 case 3: orients[0]= 'I'; orients[1]= 'S'; break;
01597 case -3: orients[0]= 'S'; orients[1]= 'I'; break;
01598 default: orients[0]='\0'; orients[1]='\0'; break;
01599 }
01600
01601
01602
01603
01604
01605
01606 dx = fabs(xyz[6]-xyz[3]) ; jj = 1 ;
01607 dy = fabs(xyz[7]-xyz[4]) ; if( dy > dx ){ jj=2; dx=dy; }
01608 dz = fabs(xyz[8]-xyz[5]) ; if( dz > dx ){ jj=3; }
01609 dx = xyz[jj+5]-xyz[jj+2] ; if( dx < 0. ){ jj = -jj; }
01610 switch( jj ){
01611 case 1: orients[2] = 'L'; orients[3] = 'R'; break;
01612 case -1: orients[2] = 'R'; orients[3] = 'L'; break;
01613 case 2: orients[2] = 'P'; orients[3] = 'A'; break;
01614 case -2: orients[2] = 'A'; orients[3] = 'P'; break;
01615 case 3: orients[2] = 'I'; orients[3] = 'S'; break;
01616 case -3: orients[2] = 'S'; orients[3] = 'I'; break;
01617 default: orients[2] ='\0'; orients[3] ='\0'; break;
01618 }
01619
01620 orients[4] = '\0' ;
01621
01622 kk = 6 - abs(ii)-abs(jj) ;
01623
01624
01625
01626 zz = xyz[kk-1] ;
01627
01628 hi->zoff = zz ;
01629 strcpy(hi->orients,orients) ;
01630
01631
01632
01633 fseek( imfile , hdroff+194 , SEEK_SET ) ;
01634 fread( &itr , 4,1 , imfile ) ;
01635 if( swap ) swap_4(&itr) ;
01636 hi->tr = 1.0e-6 * itr ;
01637
01638
01639
01640 fseek( imfile , hdroff+202 , SEEK_SET ) ;
01641 fread( &itr , 4,1 , imfile ) ;
01642 if( swap ) swap_4(&itr) ;
01643 hi->te = 1.0e-6 * itr ;
01644
01645
01646
01647
01648 fseek ( imfile , hdroff+272+202, SEEK_SET ) ;
01649 fread( &uv17 , 4, 1 , imfile ) ;
01650 if( swap ) swap_4(&uv17) ;
01651
01652 hi->uv17 = (int)uv17;
01653
01654
01655 hi->good = 1 ;
01656
01657 }
01658
01659 fclose(imfile) ; return ;
01660 }