1 #ifndef _MRILIB_DICOM_STUFF_
2 #define _MRILIB_DICOM_STUFF_
3 
4 #include "vecmat.h"
5 
6 /*-- manufacturer codes --*/
7 
8 #undef  AFD_MAN_OFFSET
9 #define AFD_MAN_OFFSET     7532000
10 
11 #define AFD_MAN_SIEMENS    (AFD_MAN_OFFSET + 1)
12 #define AFD_MAN_GE         (AFD_MAN_OFFSET + 2)
13 #define AFD_MAN_PHILIPS    (AFD_MAN_OFFSET + 3)
14 #define AFD_MAN_TOSHIBA    (AFD_MAN_OFFSET + 4)
15 #define AFD_MAN_FONAR      (AFD_MAN_OFFSET + 5)
16 #define AFD_MAN_HITACHI    (AFD_MAN_OFFSET + 6)
17 #define AFD_MAN_MAGNASERV  (AFD_MAN_OFFSET + 7)
18 #define AFD_MAN_ODIN       (AFD_MAN_OFFSET + 8)
19 #define AFD_MAN_ONI        (AFD_MAN_OFFSET + 9)
20 #define AFD_MAN_BRUKER     (AFD_MAN_OFFSET +10)
21 #define AFD_MAN_VARIAN     (AFD_MAN_OFFSET +11)
22 
23 /*-- struct to hold header info from one file --*/
24 
25 typedef struct {
26   int   manufacturer_code ;                 /* from ID  group */
27   float tr , slice_spacing , slice_thick ;  /* from ACQ group */
28   float pos_xx , pos_yy , pos_zz ,          /* from REL group */
29         ori_ix , ori_iy , ori_iz ,
30         ori_jx , ori_jy , ori_jz ,
31         slice_loc ;
32   float di , dj ;                           /* from IMG group */
33   int   ni , nj , nk ;
34   unsigned data_offset, data_length ;       /* from PXL group */
35   int      nbits ;
36 
37   float rescale_intercept, rescale_slope,
38         window_center    , window_width  ;
39 
40   char *filename ;                          /* where 'tis */
41   void *extra_info ;                        /* whatever   */
42   char  manufacturer_string[128] ;
43 } AFD_dicom_header ;
44 
45 typedef struct {
46    THD_fvec3 xvec, yvec;            /* Image Orientation fields */
47    THD_fvec3 dfpos1;                /* image origin for first two slices*/
48    THD_fvec3 dfpos2;
49    THD_fvec3 del;                   /* voxel dimensions */
50    int mosaic;                      /* data is mosaic */
51    int mos_ix, mos_nx, mos_ny, mos_nslice; /* mosaic properties */
52    int nx, ny;                      /* overall mosaic dimensions */
53    float Tr_dicom[4][4];            /* transformation matrix */
54    float slice_xyz[2][3];           /* coordinates for 1st and last slices */
55    int mos_sliceinfo;               /* flag for existence of coordinate info */
56    int flip_slices;
57 } oblique_info;
58 
59 extern oblique_info obl_info;
60 
61 /*-- global processing structs (image fields and env vars) --*/
62 typedef struct {
63    int     study, series, image, image_index; /* DICOM image values  */
64    float   acq_time;                    /* acquisition time, if set  */
65    float   slice_loc;                   /* 0020 1041 REL Slice Loc   */
66    int     is_obl, is_mosaic;           /* oblique flag, mosaic flag */
67    int     mos_nslice, mos_nx, mos_ny;  /* mosaic dimensions         */
68 } dicom_image_globals_t;
69 extern dicom_image_globals_t g_image_info;
70 
71 /* persistent globals (not per image) to control processing */
72 typedef struct {
73    int     init;                /* have the vars been initialized?       */
74    int     read_data;           /* flag: do we read data at all?      */
75    int     verb;                /* AFNI_DICOM_VERBOSE               */
76    int     rescale;             /* AFNI_DICOM_RESCALE              */
77    int     window;              /* AFNI_DICOM_WINDOW              */
78    int     use_last_elem;       /* AFNI_DICOM_USE_LAST_ELEMENT   */
79 } dicom_globals_t;
80 extern dicom_globals_t g_dicom_ctrl;
81 
82 /*-- extra_info from Siemens --*/
83 
84 #define AFD_EIT_SIEMENS AFD_MAN_SIEMENS
85 
86 typedef struct {
87   int eitype ;          /* type code for this extra info */
88   int mosaic_num    ,   /* number of sub-images actually stored in mosaic */
89       mos_ix,mos_iy ,   /* number of sub-images along each edge of mosaic */
90       mos_nx,mos_ny ,   /* dimensions of mosaic sub-images                */
91       mos_nz         ;  /* overall size of mosaic = mos_ix * mos_iy       */
92 
93   float auto_align[16]; /* auto align matrix, if [15] == 1 */
94 
95   int    nslice       ; /* number of slices we have info about these arrays */
96   float *position_sag ;
97   float *position_cor ;
98   float *position_tra ;
99   float *normal_sag   ;
100   float *normal_cor   ;
101   float *normal_tra   ;
102   float *inplane_rot  ;
103 } AFD_siemens_info ;
104 
105 /*------ stuff for multi-frame collections of 2D images [05 May 2008] ------*/
106 
107 typedef struct {
108   int nframe ;                      /* number of frames */
109   int *time_index , *stack_index ;  /* nframe of each array */
110   float *xpos , *ypos , *zpos ;     /* might be NULL */
111 } MultiFrame_info ;
112 
113 #define INIT_MultiFrame(mf,n)                                    \
114  do{ (mf) = (MultiFrame_info *)malloc(sizeof(MultiFrame_info));  \
115      (mf)->nframe      = (n) ;                                   \
116      (mf)->time_index  = (int *)  calloc(sizeof(int)  ,(n)) ;    \
117      (mf)->stack_index = (int *)  calloc(sizeof(int)  ,(n)) ;    \
118      (mf)->xpos        = (float *)calloc(sizeof(float),(n)) ;    \
119      (mf)->ypos        = (float *)calloc(sizeof(float),(n)) ;    \
120      (mf)->zpos        = (float *)calloc(sizeof(float),(n)) ;    \
121  } while(0)
122 
123 #define KILL_MultiFrame(mf)                                      \
124  do{ if( (mf) != NULL ){                                         \
125        if( (mf)->time_index  ) free((void *)(mf)->time_index) ;  \
126        if( (mf)->stack_index ) free((void *)(mf)->stack_index) ; \
127        if( (mf)->xpos        ) free((void *)(mf)->xpos) ;        \
128        if( (mf)->ypos        ) free((void *)(mf)->ypos) ;        \
129        if( (mf)->zpos        ) free((void *)(mf)->zpos) ;        \
130        free((void *)(mf)) ; (mf) = NULL ;                        \
131      }                                                           \
132  } while(0)
133 
134 #define DELPOS_MultiFrame(mf)                                           \
135  do{ if( (mf) != NULL ){                                                \
136        if( (mf)->xpos ){ free((void *)(mf)->xpos); (mf)->xpos = NULL; } \
137        if( (mf)->ypos ){ free((void *)(mf)->ypos); (mf)->ypos = NULL; } \
138        if( (mf)->zpos ){ free((void *)(mf)->zpos); (mf)->xpos = NULL; } \
139      }                                                                  \
140  } while(0)
141 
142 /*-- prototypes --*/
143 
144 extern char *AFD_manufacturer_code_to_string( int code ) ;
145 extern void AFD_siemens_info_free( void *aei ) ;
146 extern void AFD_dicom_header_free( AFD_dicom_header *adh ) ;
147 extern int AFD_manufacturer_string_to_code( char * ) ;
148 extern AFD_dicom_header * AFD_scanfor_header( char * ) ;
149 extern char * AFD_format_header( AFD_dicom_header *adh ) ;
150 extern int disp_dicom_globals(char * mesg);
151 extern void dicom_debug(int verb_level);
152 
153 extern MultiFrame_info * AFD_scanfor_MultiFrame( char *ppp ) ;
154 
155 #endif /* _MRILIB_DICOM_STUFF_ */
156