1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/stat.h>
4 #include <stdlib.h>
5 #include <math.h>
6 #include "siemens_vision.h"
7 #include "mrilib.h"
8 
byteswap8(double * x)9 static void byteswap8 (double *x) {
10   char *p1,*p2; double d; int i;
11   p1=(char *)x; p2=(char *)&d;
12   for(i=0;i<8;i++) p2[7-i]=p1[i];
13   (*x)=d;
14 }
15 
byteswap4(u_int * x)16 static void byteswap4( u_int * x ) {
17   char *p1,*p2 ; u_int d ; int i ;
18   p1=(char *)x; p2=(char *)&d;
19   for(i=0;i<4;i++) p2[3-i]=p1[i];
20   (*x)=d;
21 }
22 
23 /*----------------------------------------------------------------------------
24  12 Mar 2001: Program siemens_vision.c, to print info from Siemens .ima header
25               Adapted from program thor.cpp by CELS (?)
26               Compile this with
27                  cc -o siemens_vision siemens_vision.c -I. -lm
28               or
29                  make siemens_vision
30               (if you are getting this as part of the AFNI package) -- RWCox
31 ------------------------------------------------------------------------------*/
32 
main(int argc,char * argv[])33 int main( int argc , char * argv[] )
34 {
35    struct Siemens_vision_header head ;
36    FILE * fp ;
37    char orients[7] ;
38    int i,j,xx,yy , matrix , swap , slices=0 ;
39    double dd=0.0 , qq=0.0 ;
40    struct stat file_stat ;
41    int imagesize=64 ;
42    short *imar=NULL ;
43    char *prefix=NULL ; int iarg=1 , nfiles=0 ;
44 
45    if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
46       printf("Usage: siemens_vision [options] filename ...\n"
47              "Prints out information from the Siemens .ima file header(s).\n"
48              "\n"
49              "The only option is to rename the file according to the\n"
50              "TextImageNumber field stored in the header.  The option is:\n"
51              "\n"
52              "  -rename ppp\n"
53              "\n"
54              "which will rename each file to the form 'ppp.nnnn.ima',\n"
55              "where 'nnnn' is the image number expressed with 4 digits.\n"
56              "\n"
57              "When '-rename' is used, the header info from the input files\n"
58              "will not be printed.\n"
59             ) ;
60       exit(0) ;
61    }
62 
63    if( strcmp(argv[iarg],"-rename") == 0 ){
64      if( iarg+2 >= argc ){
65        fprintf(stderr,"** ERROR: not enough arguments after '-rename'\n") ;
66        exit(1) ;
67      }
68      prefix = strdup(argv[++iarg]) ;
69      if( !THD_filename_ok(prefix) ){
70        fprintf(stderr,"** ERROR: prefix after '-rename' is illegal\n") ;
71        exit(1) ;
72      }
73      iarg++ ;
74    }
75 
76    /*--- check file size ---*/
77 
78    for( ; iarg < argc ; iarg++ ){  /* loop over input filenames */
79 
80      nfiles++ ;
81 
82      i = stat( argv[iarg] , &file_stat ) ;
83      if( i < 0 ){
84        fprintf(stderr,"** Can't access file %s\n",argv[iarg]) ; exit(1) ;
85      }
86 
87      /*--- read header data ---*/
88 
89      fp = fopen( argv[iarg] , "r" ) ;
90      if( fp == NULL ) exit(1) ;
91      fread( &head , sizeof(struct Siemens_vision_header) , 1 , fp ) ;
92 
93      /*-- check some integer in header to determine if we need to byteswap --*/
94 
95      swap = ( head.SiemensStudyDateMM < 0 || head.SiemensStudyDateMM > 12 ) ;
96      if( swap ){
97         byteswap4( &(head.SiemensStudyDateMM) ) ;
98         if( head.SiemensStudyDateMM < 0 || head.SiemensStudyDateMM > 12 ){
99            printf("** Can't determine byte swap status of file %s\n",argv[iarg]) ;
100            byteswap4( &(head.SiemensStudyDateMM) ) ;
101            swap = 0 ;
102         }
103      }
104 
105      /*-- renaming? --*/
106 
107      if( prefix != NULL ){
108        char *cpt , fname[2048] ;
109        int   num = (int)strtol( head.TextImageNumber , &cpt , 10 ) ;
110        if( *cpt != '\0' && num == 0 ){
111          printf("** Can't get TextImageNumber from file %s\n",argv[iarg]) ;
112          num = iarg ;
113        }
114        sprintf(fname,"%s.%04d.ima",prefix,num) ;
115        if( THD_is_ondisk(fname) ){
116          printf("** Can't rename %s to pre-existing filename %s\n",
117                 argv[iarg],fname ) ;
118        } else {
119          printf("++ Renaming %s to %s\n",argv[iarg],fname) ;
120          rename(argv[iarg],fname) ;
121        }
122        fclose(fp) ; continue ;   /* skip to next iarg */
123      }
124 
125      /*** Below here: print out header info from file ***/
126 
127      /*-- find image size from header --*/
128 
129      if( swap ) byteswap4( &(head.DisplayMatrixSize) ) ;
130      imagesize = head.DisplayMatrixSize ;
131 
132      /*-- determine number of sub-images in file --*/
133 
134      if( file_stat.st_size==(imagesize * imagesize * 64 * 2 + SIEMENS_HEADERSIZE) ){
135        matrix = 8 ;
136      } else if( file_stat.st_size==(imagesize * imagesize * 16 * 2 + SIEMENS_HEADERSIZE) ){
137        matrix = 4;
138      } else {
139        matrix = 0 ;
140        printf("Don't recognize file size. Is this a Siemens Magnetom Vision .ima file?\n") ;
141      }
142 
143      /*-- read image data from file (but don't byteswap it) --*/
144 
145      if( matrix > 0 ){
146         imar = (short *) calloc(sizeof(short),matrix*matrix*imagesize*imagesize) ;
147         fseek( fp , SIEMENS_HEADERSIZE , SEEK_SET ) ;
148         fread( imar , sizeof(short) , matrix*matrix*imagesize*imagesize , fp ) ;
149      }
150 
151      fclose(fp) ;
152 
153      /*--- swap random info ---*/
154 
155      if (swap) {
156 #if 0
157         byteswap4(&(head.SiemensStudyDateYYYY)) ;   /* these are unsigned ints */
158         byteswap4(&(head.SiemensStudyDateMM)) ;
159         byteswap4(&(head.SiemensStudyDateDD)) ;
160         byteswap4(&(head.AcquisitionDateYYYY)) ;
161         byteswap4(&(head.AcquisitionDateMM)) ;
162         byteswap4(&(head.AcquisitionDateDD)) ;
163         byteswap4(&(head.ImageDateYYYY)) ;
164         byteswap4(&(head.ImageDateMM)) ;
165         byteswap4(&(head.ImageDateDD)) ;
166         byteswap4(&(head.SiemensStudyTimeHH)) ;
167         byteswap4(&(head.SiemensStudyTimeMM)) ;
168         byteswap4(&(head.SiemensStudyTimeSS)) ;
169         byteswap4(&(head.AcquisitionTimeHH)) ;
170         byteswap4(&(head.AcquisitionTimeMM)) ;
171         byteswap4(&(head.AcquisitionTimeSS)) ;
172         byteswap4(&(head.ImageTimeHH)) ;
173         byteswap4(&(head.ImageTimeMM)) ;
174         byteswap4(&(head.ImageTimeSS)) ;
175 #endif
176 
177         byteswap8(&(head.FOVRow));
178         byteswap8(&(head.FOVColumn));
179         byteswap8(&(head.SliceThickness));
180         byteswap8(&(head.RepetitionTime)) ;
181         byteswap8(&(head.FrequencyMHz)) ;
182         byteswap8(&(head.EchoTime)) ;
183         byteswap8(&(head.CenterPointX)) ;
184         byteswap8(&(head.CenterPointY)) ;
185         byteswap8(&(head.CenterPointZ)) ;
186         byteswap8(&(head.NormalVectorX));
187         byteswap8(&(head.NormalVectorY));
188         byteswap8(&(head.NormalVectorZ));
189         byteswap8(&(head.PixelSizeRow)) ;
190         byteswap8(&(head.PixelSizeColumn)) ;
191         byteswap8(&(head.RowVectorX)) ;
192         byteswap8(&(head.RowVectorY)) ;
193         byteswap8(&(head.RowVectorZ)) ;
194         byteswap8(&(head.ColumnVectorX)) ;
195         byteswap8(&(head.ColumnVectorY)) ;
196         byteswap8(&(head.ColumnVectorZ)) ;
197         byteswap8(&(head.DistanceFromIsocenter)) ;
198      }
199 
200      /*--- print random info ---*/
201 
202      printf("Manufact = %s\n",head.Manufacturer) ;
203      printf("Institut = %s\n",head.InstitutionName) ;
204 
205      printf("Date     = %s\n"
206             "Time     = %s\n"
207             "Sequence = %s\n"
208             "Patient  = %s\n"
209             "ImageNum = %s\n" ,
210             head.TextDate     , head.TextTime    ,
211             head.SequenceType , head.PatientName , head.TextImageNumber ) ;
212      printf("SubjectID= %s\n",head.PatientID) ;
213      printf("RF Coil  = %s\n",head.ReceivingCoil) ;
214 
215      orients[0]= head.OrientationSet1Left[0]; orients[1]=head.OrientationSet2Right[0];
216      orients[2]= head.OrientationSet1Top[0] ; orients[3]=head.OrientationSet2Down[0] ;
217      orients[4]= head.OrientationSet1Back[0]; orients[5]=head.OrientationSet2Front[0];
218      for (i=0; i<6; i++) {
219         if (orients[i]=='H') orients[i]='S';
220         if (orients[i]=='F') orients[i]='I';
221      }
222      orients[6] = '\0' ;
223      printf("Orient   = %s\n",orients) ;
224 
225      printf("FOV Row  = %g\n"
226             "FOV Col  = %g\n"
227             "SliceThk = %g\n" , head.FOVRow , head.FOVColumn , head.SliceThickness ) ;
228 
229      printf("TR       = %g\n",head.RepetitionTime) ;
230      printf("TE       = %g\n",head.EchoTime) ;
231      printf("Cen X    = %g\n",head.CenterPointX) ;
232      printf("Cen Y    = %g\n",head.CenterPointY) ;
233      printf("Cen Z    = %g\n",head.CenterPointZ) ;
234      printf("Delta X  = %g\n",head.PixelSizeRow) ;
235      printf("Delta Y  = %g\n",head.PixelSizeColumn) ;
236      printf("RowVec X = %g\n",head.RowVectorX) ;
237      printf("RowVec Y = %g\n",head.RowVectorY) ;
238      printf("RowVec Z = %g\n",head.RowVectorZ) ;
239      printf("ColVec X = %g\n",head.ColumnVectorX) ;
240      printf("ColVec Y = %g\n",head.ColumnVectorY) ;
241      printf("ColVec Z = %g\n",head.ColumnVectorZ) ;
242      printf("Normal X = %g\n",head.NormalVectorX);
243      printf("Normal Y = %g\n",head.NormalVectorY);
244      printf("Normal Z = %g\n",head.NormalVectorZ);
245 
246 #if 0
247      dd = head.RowVectorX * head.ColumnVectorX    /* vector dot products */
248          +head.RowVectorY * head.ColumnVectorY
249          +head.RowVectorZ * head.ColumnVectorZ ;
250      printf("Row*Col  = %g\n",dd) ;
251 
252      dd = head.RowVectorX * head.NormalVectorX
253          +head.RowVectorY * head.NormalVectorY
254          +head.RowVectorZ * head.NormalVectorZ ;
255      printf("Row*Nor  = %g\n",dd) ;
256 
257      dd = head.ColumnVectorX * head.NormalVectorX
258          +head.ColumnVectorY * head.NormalVectorY
259          +head.ColumnVectorZ * head.NormalVectorZ ;
260      printf("Col*Nor  = %g\n",dd) ;
261 #endif
262 
263      printf("D-IsoCen = %g\n",head.DistanceFromIsocenter) ;
264      printf("SlicePos = %s\n",head.TextSlicePosition) ;
265 
266      /*-- scan images for being all zero (blank) [doesn't depend on byteswap] --*/
267 
268      slices = matrix*matrix ;
269 
270      if( imar != NULL ){
271         int nxx = matrix*imagesize , blank ;
272         printf("Recognized %dx%d mosaic of %dx%d images:\n",matrix,matrix,imagesize,imagesize) ;
273         for( yy=0 ; yy < matrix ; yy++ ){
274            printf("  ") ;
275            for( xx=0 ; xx < matrix ; xx++ ){
276               blank = 1 ;
277               for( j=0 ; j < imagesize ; j++ ){
278                  for( i=0 ; i < imagesize ; i++ ){
279                     if( imar[i+xx*imagesize+(j+yy*imagesize)*nxx] ) blank = 0 ;
280                  }
281               }
282               printf(" %s" , (blank) ? "blank" : "full ") ;
283               if( !blank ) slices = 1 + xx + yy*matrix ;
284            }
285            printf("\n") ;
286         }
287      }
288 
289      dd = fabs(strtod(head.TextSlicePosition,NULL)) ;
290      qq = dd - (slices-1)*head.SliceThickness ;
291      if( qq > 0.0 ){
292         orients[5] = orients[4] ;
293      } else {
294          qq = -qq ;
295      }
296 
297    } /* end of loop over files */
298 
299    if( prefix == NULL ){
300      printf("\nto3d -epan"
301             " -time:zt %d %d %0.3fs alt+z"
302             " -xFOV %0.2f%c-%c"
303             " -yFOV %0.2f%c-%c"
304             " -zSLAB %0.2f%c-%0.2f%c \n" ,
305 
306          slices , nfiles , 0.001*head.RepetitionTime ,
307          0.5*head.FOVRow    , orients[0] , orients[1] ,
308          0.5*head.FOVColumn , orients[2] , orients[3] ,
309          dd , orients[4] , qq , orients[5] ) ;
310    }
311 
312    exit(0) ;
313 }
314