function headerInfo = get_GE_Signa3xInfo(fileName)

% function headerInfo = get_GE_Signa3xInfo(fileName)
% 
% This function rteturns the header information from a image file acquired
% using GE.x signa scanner.
% 
% Input: fileName: for example 'I.001' 
% headerInfo: an structure describing the foloowing parameters
% 
%   offset: byte offset before start of image
%   nx: Image array size in x-coordinate dimension. 
%   ny: Image array size in y-coordinate dimension.
%   bitPerPixel: number of bits per pixel (Ex. 16)
%   dz:  pixel resolution along z axis
%   dx:  pixel resolution along x axis
%   dy:  pixel resolution along y axis
%   TLHC: 1 x 3 arary representing grid coordinates for the top left hand corner
%   TRHC: 1 x 3 arary representing grid coordinates for the top right hand corner
%   BRHC: 1 x 3 arary representing grid coordinates for the bottom right hand
%   corber
%
%   zOff: z offset from the grid origin
%   xOff: x offset from the grid origin
%   yOff: y offset from the grid origin
%   Orientation: Direction of positive x and y axis for example 'RLAP'
%   indicartes that positive x axis  alined along righ to left and positive
%   y axis is alinged along anterior to posterior.
%   TR: MR relaxation time in second, Ex: '0.5 s'
%   TE: MR echo time in ms, EX: '11.872 ms'
%   seriesNumber: Self explanatory
%   ImageNumber: Self explanatory
%   ImageDate: Self explanatory
%   ImageTime: Self explanatory
% 
% 
%  ICM, Oct, 2011




headerInfo = [];
fid = fopen(fileName,'r','b');
C = fread(fid,4,'char=>char')';

if ~strcmp(C,'IMGF')
    
    disp('It appears that the file is not proper GE image.');
    return
    
end


headerInfo.offset = fread(fid,1,'uint');
headerInfo.nx = fread(fid,1,'uint');

if (headerInfo.nx < 0 || headerInfo.nx > 8192)
    
    %wrong Byte order close and reopen file with little endian byte order
    fclose(fid);
    fid = fopen(fileName,'r','l');
    headerInfo.offset = fread(fid,1,'uint');
    headerInfo.nx = fread(fid,1,'uint');

end




headerInfo.ny = fread(fid,1,'uint');
headerInfo.bitPerPixel = fread(fid,1,'uint');
headerInfo.flag = fread(fid,1,'uint'); % 1 for uncompressed


% getting information about the image

fseek(fid, 148,-1);
offset = fread(fid,1,'int');
fseek(fid,offset + 26,-1);
headerInfo.dz = fread(fid,1,'float');

fseek(fid,offset + 50,-1);
headerInfo.dx = fread(fid,1,'float');
headerInfo.dy = fread(fid,1,'float');

% grid orientation: from 3 sets of LPI corner coordinates: 
% xyz[1..3] = top left hand corner of image     (TLHC)   
% xyz[4..6] = top right hand corner of image    (TRHC)   
% xyz[7..9] = bottom right hand corner of image (BRHC)   
% GEMS coordinate orientation here is LPI   

fseek(fid,offset + 154,-1);
xyz = fread(fid,9,'float');


%printf("  TLHC= %g %g %g\n"
%                     "  TRHC= %g %g %g\n"
%                     "  BRHC= %g %g %g\n" ,
%                     xyz[0],xyz[1],xyz[2],xyz[3],xyz[4],xyz[5],xyz[6],xyz[
%                     7],xyz[8] ) ;

headerInfo.TLHC = [xyz(1) xyz(2) xyz(3)];
headerInfo.TRHC = [xyz(4) xyz(5) xyz(6)];
headerInfo.BRHC = [xyz(7) xyz(8) xyz(9)];




% x-axis orientation 
% ii determines which spatial direction is x-axis  
% and is the direction that has the biggest change 
% between the TLHC and TRHC                        


dx = abs(xyz(4)-xyz(1)) ; 
ii = 1 ;
dy = abs(xyz(5)-xyz(2)) ; 
if( dy > dx )
    ii=2; 
    dx=dy; 
end

dz = abs(xyz(6)-xyz(3));
if( dz > dx )
    ii=3;        
end
        
dx = xyz(ii+3)-xyz(ii) ; 

if( dx < 0 )
    ii = -ii;    
    
end
    
    
  
    
    
    
           switch ii
            case  {1}
                orients(1)= 'L'; 
                orients(2)= 'R'; % Left      to Right     */
            case {-1} 
                orients(1)= 'R'; 
                orients(2)= 'L'; % Right     to Left      */
            case  {2} 
                orients(1)= 'P'; 
                orients(2)= 'A'; % Posterior to Anterior  */
            case {-2} 
                orients(1)= 'A'; 
                orients(2)= 'P'; % Anterior  to Posterior */
            case  {3} 
                orients(1)= 'I'; 
                orients(2)= 'S'; % Inferior  to Superior  */
            case {-3} 
                orients(1)= 'S'; 
                orients(2)= 'I'; % Superior  to Inferior  */
               otherwise
                   orients(1)='\0'; 
                   orients(2)='\0'; % should never happen    */
           end
 
                   
                   
               
                   
                   

%            /* y-axis orientation */
%            /* jj determines which spatial direction is y-axis  */
%            /* and is the direction that has the biggest change */
%            /* between the BRHC and TRHC                        */
% 

dx = abs(xyz(7)-xyz(4)) ; 
jj = 1 ;
dy = abs(xyz(8)-xyz(5)) ; 
if( dy > dx )
    jj=2; 
    dx=dy; 
end

dz = abs(xyz(9)-xyz(6));
if( dz > dx )
    jj=3;        
end
        
dx = xyz(jj+6)-xyz(jj+3) ; 

if( dx < 0 )
    jj = -jj;    
    
end
    
    
 
    
    
    
           switch jj
            case  {1}
                orients(3)= 'L'; 
                orients(4)= 'R'; % Left      to Right     */
            case {-1} 
                orients(3)= 'R'; 
                orients(4)= 'L'; % Right     to Left      */
            case  {2} 
                orients(3)= 'P'; 
                orients(4)= 'A'; % Posterior to Anterior  */
            case {-2} 
                orients(3)= 'A'; 
                orients(4)= 'P'; % Anterior  to Posterior */
            case  {3} 
                orients(3)= 'I'; 
                orients(4)= 'S'; % Inferior  to Superior  */
            case {-3} 
                orients(3)= 'S'; 
                orients(4)= 'I'; % Superior  to Inferior  */
               otherwise
                   orients(3)='\0'; 
                   orients(4)='\0'; % should never happen    */
           end


 kk = 6 - abs(ii)-abs(jj) ;   
% which spatial direction is z-axis   */
% where 1=LR, 2=PA, 3=IS               */
% (can't tell orientation from 1 slice) */
% 
zz = xyz(kk) ;             % z-coordinate of this slice
xx = xyz(abs(ii)) ;
yy = xyz(abs(jj)) ;
% 

headerInfo.zOff = zz;
headerInfo.xOff = xx;
headerInfo.yOff = yy;
headerInfo.Orientation = orients;


           
 fseek(fid,offset + 194,-1);
 headerInfo.TR = [num2str(fread(fid,1,'uint')*1.0e-6) ' s'];
 
 fseek(fid,offset + 202,-1);
 headerInfo.TE = [num2str(fread(fid,1,'uint')*1.0e-3) ' ms'];
 
 
 fseek( fid,offset + 10 ,-1) ;
 
 headerInfo.seriesNumber = fread(fid,1,'uint16') ;
 headerInfo.ImageNumber = fread(fid,1,'uint16' ) ;
 headerInfo.ImageDate = fread(fid,1,'uint' ) ;
 headerInfo.ImageTime = fread(fid,1,'uint' ) ;
             

 fclose(fid);   


