1 #include "mrilib.h"
2 #include "thd.h"
3 
4 /*******************************************************************/
5 /******** 03 Dec 2003: Read an MPEG file as an AFNI dataset ********/
6 /*******************************************************************/
7 
8 /*-----------------------------------------------------------------*/
9 /*! Open an MPEG file as an unpopulated AFNI dataset.
10     It will be populated in THD_load_mpeg().
11 -------------------------------------------------------------------*/
12 
THD_open_mpeg(char * hname)13 THD_3dim_dataset * THD_open_mpeg( char *hname )
14 {
15    int nim , ii , datum_type ;
16    MRI_IMARR *imar ;
17    MRI_IMAGE *im ;
18    char *eee ;
19    THD_3dim_dataset *dset=NULL ;
20    char prefix[THD_MAX_PREFIX] , *ppp ;
21    THD_ivec3 nxyz , orixyz ;
22    THD_fvec3 dxyz , orgxyz ;
23    int iview ;
24    int   nx,ny,nz,nt ;
25    float dx,dy,dz,dt ;
26 
27 
28 ENTRY("THD_open_mpeg") ;
29 
30    /*-- count slices in the file --*/
31 
32    imar = mri_read_mpeg( hname ) ;
33    if( imar == NULL ) RETURN(NULL) ;
34    nim = IMARR_COUNT(imar) ;
35 
36    /*-- get data type for each voxel --*/
37 
38    im         = IMARR_SUBIM(imar,0) ;
39    datum_type = im->kind ;
40 
41    /*-- compute dimensions of images, and number of images --*/
42 
43    nx = im->nx ;
44    ny = im->ny ;
45    DESTROY_IMARR(imar) ;
46    if( nx < 2 || ny < 2 ) RETURN(NULL) ;
47 
48    eee = getenv("AFNI_MPEG_DATASETS") ;
49    if( eee == NULL ) eee = "SPACE" ;
50    switch( toupper(*eee) ){
51      default:
52      case 'T': nz = 1   ; nt = nim ; break ;
53      case 'S': nz = nim ; nt = 1   ; break ;
54    }
55 
56    /*-- voxel sizes --*/
57 
58    dx = dy = dz = dt = 1.0 ;
59 
60    /*-- make a dataset --*/
61 
62    dset = EDIT_empty_copy(NULL) ;
63 
64    dset->idcode.str[0] = 'M' ;  /* overwrite 1st 3 bytes */
65    dset->idcode.str[1] = 'P' ;
66    dset->idcode.str[2] = 'G' ;
67 
68    MCW_hash_idcode( hname , dset ) ;  /* 06 May 2005 */
69 
70    ppp = THD_trailname(hname,0) ;                   /* strip directory */
71    MCW_strncpy( prefix , ppp , THD_MAX_PREFIX ) ;   /* to make prefix */
72 
73    nxyz.ijk[0] = nx ; dxyz.xyz[0] = dx ;  /* setup axes lengths and voxel sizes */
74    nxyz.ijk[1] = ny ; dxyz.xyz[1] = dy ;
75    nxyz.ijk[2] = nz ; dxyz.xyz[2] = dz ;
76 
77    /*-- set orientation --*/
78 
79    { char *ori = "LAI" ;
80      int oxx,oyy,ozz ;
81      if( ori == NULL || strlen(ori) < 3 ) ori = "LAI"; /* set default LPI */
82 
83      oxx = ORCODE(ori[0]); oyy = ORCODE(ori[1]); ozz = ORCODE(ori[2]);
84      if( !OR3OK(oxx,oyy,ozz) ){
85        oxx = ORI_L2R_TYPE; oyy = ORI_A2P_TYPE; ozz = ORI_I2S_TYPE; /* LAI? */
86      }
87 
88      orixyz.ijk[0] = oxx ;
89      orixyz.ijk[1] = oyy ;
90      orixyz.ijk[2] = ozz ;
91    }
92 
93    /*-- origin of coordinates --*/
94 
95    orgxyz.xyz[0] = -0.5 * (nx-1) * dx ;
96    orgxyz.xyz[1] = -0.5 * (ny-1) * dy ;
97    orgxyz.xyz[2] = -0.5 * (nz-1) * dz ;
98 
99    iview = VIEW_ORIGINAL_TYPE ;
100 
101    /* 10 Oct 2002: change voxel size signs, if axis orientation is negative */
102    /*              [above, we assumed that axes were oriented in - to + way] */
103 
104    if( ORIENT_sign[orixyz.ijk[0]] == '-' ){
105      dxyz.xyz[0]   = -dxyz.xyz[0]   ;
106      orgxyz.xyz[0] = -orgxyz.xyz[0] ;
107    }
108 
109    if( ORIENT_sign[orixyz.ijk[1]] == '-' ){
110      dxyz.xyz[1]   = -dxyz.xyz[1]   ;
111      orgxyz.xyz[1] = -orgxyz.xyz[1] ;
112    }
113 
114    if( ORIENT_sign[orixyz.ijk[2]] == '-' ){
115      dxyz.xyz[2]   = -dxyz.xyz[2]   ;
116      orgxyz.xyz[2] = -orgxyz.xyz[2] ;
117    }
118 
119    /*-- actually send the values above into the dataset header --*/
120 
121    EDIT_dset_items( dset ,
122                       ADN_prefix      , prefix ,
123                       ADN_datum_all   , datum_type ,
124                       ADN_nxyz        , nxyz ,
125                       ADN_xyzdel      , dxyz ,
126                       ADN_xyzorg      , orgxyz ,
127                       ADN_xyzorient   , orixyz ,
128                       ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
129                       ADN_nvals       , nt ,
130                       ADN_type        , HEAD_ANAT_TYPE ,
131                       ADN_view_type   , iview ,
132                       ADN_func_type   , ANAT_MRAN_TYPE ,
133                     ADN_none ) ;
134 
135    if( nt > 1 )              /** pretend it is 3D+time **/
136       EDIT_dset_items( dset ,
137                          ADN_func_type, ANAT_EPI_TYPE ,
138                          ADN_ntt      , nt ,
139                          ADN_ttorg    , 0.0 ,
140                          ADN_ttdel    , dt ,
141                          ADN_ttdur    , 0.0 ,
142                          ADN_tunits   , UNITS_SEC_TYPE ,
143                        ADN_none ) ;
144 
145    /*-- flag to read data from disk using MPEG mode --*/
146 
147    dset->dblk->diskptr->storage_mode = STORAGE_BY_MPEG ;
148    strcpy( dset->dblk->diskptr->brick_name , hname ) ;
149 
150    RETURN(dset) ;
151 }
152 
153 /*---------------------------------------------------------------------*/
154 /*! Load an MPEG dataset from disk.
155 -----------------------------------------------------------------------*/
156 
THD_load_mpeg(THD_datablock * dblk)157 void THD_load_mpeg( THD_datablock *dblk )
158 {
159    THD_diskptr *dkptr ;
160    int nx,ny,nz,nv , nxy,nxyz,nxyzv , ibr,nbad , nbar ;
161    void *ptr ;
162    MRI_IMARR *imar ;
163    MRI_IMAGE *im ;
164    byte *bim , *bar ;
165 
166 ENTRY("THD_load_mpeg") ;
167 
168    /*-- check inputs --*/
169 
170    if( !ISVALID_DATABLOCK(dblk)                       ||
171        dblk->diskptr->storage_mode != STORAGE_BY_MPEG ||
172        dblk->brick == NULL                              ) EXRETURN ;
173 
174    dkptr = dblk->diskptr ;
175 
176    imar = mri_read_mpeg( dkptr->brick_name ) ;
177    if( imar == NULL ) EXRETURN ;
178 
179    /*-- allocate space for data --*/
180 
181    nx = dkptr->dimsizes[0] ;
182    ny = dkptr->dimsizes[1] ;  nxy   = nx * ny   ;
183    nz = dkptr->dimsizes[2] ;  nxyz  = nxy * nz  ;
184    nv = dkptr->nvals       ;  nxyzv = nxyz * nv ;
185 
186    dblk->malloc_type = DATABLOCK_MEM_MALLOC ;
187 
188    /*-- malloc space for each brick separately --*/
189 
190    for( nbad=ibr=0 ; ibr < nv ; ibr++ ){
191      if( DBLK_ARRAY(dblk,ibr) == NULL ){
192        ptr = AFMALL(void, DBLK_BRICK_BYTES(dblk,ibr) ) ;
193        mri_fix_data_pointer( ptr ,  DBLK_BRICK(dblk,ibr) ) ;
194        if( ptr == NULL ) nbad++ ;
195      }
196    }
197 
198    /*-- if couldn't get them all, take our ball and go home in a snit --*/
199 
200    if( nbad > 0 ){
201      fprintf(stderr,
202              "\n** failed to malloc %d MPEG bricks out of %d\n\a",nbad,nv);
203      for( ibr=0 ; ibr < nv ; ibr++ ){
204        if( DBLK_ARRAY(dblk,ibr) != NULL ){
205          free(DBLK_ARRAY(dblk,ibr)) ;
206          mri_fix_data_pointer( NULL , DBLK_BRICK(dblk,ibr) ) ;
207        }
208      }
209      DESTROY_IMARR(imar) ; EXRETURN ;
210    }
211 
212    /*-- load data from image array into sub-brick arrays! --*/
213 
214    nbar = mri_datum_size( DBLK_BRICK_TYPE(dblk,0) ) * nx*ny ;
215    if( nv == 1 ){                   /* all data goes into 1 sub-brick */
216      bar = DBLK_ARRAY(dblk,0) ;
217      for( ibr=0 ; ibr < nz ; ibr++ ){
218        im = IMARR_SUBIM(imar,ibr) ; bim = mri_data_pointer(im) ;
219        memcpy( bar , bim , nbar ) ;
220        bar += nbar ;
221      }
222    } else {                         /* each slice is a separate sub-brick */
223      for( ibr=0 ; ibr < nv ; ibr++ ){
224        bar = DBLK_ARRAY(dblk,ibr) ;
225        im = IMARR_SUBIM(imar,ibr) ; bim = mri_data_pointer(im) ;
226        memcpy( bar , bim , nbar ) ;
227      }
228    }
229 
230    DESTROY_IMARR(imar) ;
231    EXRETURN ;
232 }
233