1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #include "mrilib.h"
8 
9 /*****************  New routines for AFNI-96  ***************************/
10 
11 #define DUMMY_NAME "zyxt"  /* 07 Mar 2000: changed from Elvis */
12 
13 /*--------------------------------------------------------------------
14   Routine to make a dataset that is an empty copy of an input dataset.
15   Will usually be followed by EDIT_dset_items to alter some internals.
16   Note that old_dset can be NULL, in which case EDIT_dset_items
17   will definitely need to be called before the new dataset is of use.
18 ----------------------------------------------------------------------*/
19 
EDIT_empty_copy(THD_3dim_dataset * old_dset)20 THD_3dim_dataset * EDIT_empty_copy( THD_3dim_dataset *old_dset )
21 {
22    THD_3dim_dataset *new_dset ;
23    THD_datablock    *new_dblk ;
24    THD_dataxes      *new_daxes ;
25    THD_timeaxis     *new_taxis ;
26    THD_diskptr      *new_dkptr ;
27    int               new_nvals , old_good ;
28 
29 ENTRY("EDIT_empty_copy") ; /* 29 Aug 2001 */
30 
31    old_good = ISVALID_3DIM_DATASET(old_dset) ;
32 
33    /** make some new places to store stuff **/
34 
35    new_dset                      = myRwcNew( THD_3dim_dataset ) ;
36    new_dblk  = new_dset->dblk    = myRwcNew( THD_datablock ) ;
37    new_daxes = new_dset->daxes   = myRwcNew( THD_dataxes ) ;
38    new_dkptr = new_dblk->diskptr = myRwcNew( THD_diskptr ) ;
39    new_dset->Label_Dtable = NULL;                  /* ZSS Feb 26 2010 */
40 
41    INIT_KILL(new_dset->kl) ; INIT_KILL(new_dblk->kl) ;
42    ADDTO_KILL(new_dset->kl,new_dblk)  ;
43    ADDTO_KILL(new_dset->kl,new_daxes) ;
44    ADDTO_KILL(new_dset->kl,new_dkptr) ;
45 
46    new_dset->wod_daxes         = myRwcNew(THD_dataxes) ;
47    new_dset->wod_daxes->parent = (RwcPointer) new_dset ;
48    new_dset->wod_flag          = False ;
49 
50    ADDTO_KILL(new_dset->kl,new_dset->wod_daxes) ;
51 
52    new_dset->idcode = MCW_new_idcode() ;
53    ZERO_IDCODE(new_dset->anat_parent_idcode) ;
54    ZERO_IDCODE(new_dset->warp_parent_idcode) ;
55 
56    if( old_good ){
57       new_dset->type      = old_dset->type ;      /* data types */
58       new_dset->func_type = old_dset->func_type ;
59       new_dset->view_type = old_dset->view_type ;
60       /* use template space of parent to mark as TLRC/MNI/... */
61       MCW_strncpy( new_dset->atlas_space ,
62          old_dset->atlas_space , THD_MAX_NAME ) ;
63 
64       new_nvals           = old_dset->dblk->nvals ;
65    } else {
66       new_dset->type      = HEAD_ANAT_TYPE ;
67       new_dset->func_type = ANAT_SPGR_TYPE ;
68       new_dset->view_type = VIEW_ORIGINAL_TYPE ;
69       new_nvals           = 1 ;
70    }
71 
72    new_dset->warp        = NULL ;
73    new_dset->anat_parent = NULL ;
74    new_dset->markers     = NULL ;
75    new_dset->warp_parent = NULL ;
76 
77    /*-- 14 Dec 1999: copy the anat_parent, too --*/
78 
79    if( old_good ){
80      new_dset->anat_parent = old_dset->anat_parent  ; /* actual link, for use now */
81      EDIT_COPY_ANATOMY_PARENT_ID(new_dset,old_dset) ; /* idcode, for HEAD file later */
82    }
83 
84    /*-- end of anat_parent copy --*/
85 
86    new_dset->vox_warp       = myRwcNew( THD_warp ) ;  /* create a voxel warp */
87    new_dset->vox_warp->type = ILLEGAL_TYPE ;         /* but don't put anything in it */
88    ADDTO_KILL(new_dset->kl, new_dset->vox_warp) ;    /* 3 Mar 2009 [rickr] */
89    new_dset->self_warp      = NULL ;                 /* 26 Aug 2002 */
90 
91    new_dset->warp_parent_name[0] = '\0' ;
92    new_dset->anat_parent_name[0] = '\0' ;
93 
94    MCW_strncpy( new_dset->self_name , DUMMY_NAME , THD_MAX_NAME  ) ;
95    MCW_strncpy( new_dset->label1    , DUMMY_NAME , THD_MAX_LABEL ) ;
96    MCW_strncpy( new_dset->label2    , DUMMY_NAME , THD_MAX_LABEL ) ;
97 
98    new_dset->death_mark  = 0 ;
99    new_dset->tcat_list   = NULL ;
100    new_dset->tcat_num    = 0 ;
101    new_dset->tcat_len    = NULL ;
102 #ifdef ALLOW_DATASET_VLIST
103    new_dset->pts         = NULL ;
104 #endif
105    new_dset->tagset      = NULL ;  /* Oct 1998 */
106 
107    new_dkptr->type         = DISKPTR_TYPE ;
108    new_dkptr->rank         = 3 ;
109    new_dkptr->nvals        = new_nvals ;
110    new_dkptr->byte_order   = THD_get_write_order() ;  /* 25 April 1998 */
111    if( old_good ){
112       new_dkptr->dimsizes[0]  = old_dset->daxes->nxx ;
113       new_dkptr->dimsizes[1]  = old_dset->daxes->nyy ;
114       new_dkptr->dimsizes[2]  = old_dset->daxes->nzz ;
115       /* pass on only writable storage modes    5 Mar 2012 [rickr] */
116       if( is_writable_storage_mode(DSET_STORAGE_MODE(old_dset)) ) {
117          /* ZSS Feb 5 2012 */
118          new_dkptr->storage_mode = old_dset->dblk->diskptr->storage_mode;
119       } else {
120          new_dkptr->storage_mode = STORAGE_BY_BRICK ;
121       }
122    } else {
123       new_dkptr->dimsizes[0]  = 2 ;
124       new_dkptr->dimsizes[1]  = 2 ;
125       new_dkptr->dimsizes[2]  = 2 ;
126       new_dkptr->storage_mode = STORAGE_BY_BRICK ;
127    }
128    new_dkptr->allow_directwrite = 0 ;  /* 08 May 2009 */
129 
130    if( old_good ) {
131       /* ZSS: old_dset->dblk->diskptr->directory_name
132       was used instead of "./" before  July 10 2012.
133       See afni_history -author ziad | grep -A10 '10 Jul 2012' */
134       THD_init_diskptr_names( new_dkptr ,
135                               "./", /* ZSS 07/10/2012*/
136                               NULL , DUMMY_NAME ,
137                               new_dset->view_type , True ) ;
138    } else {
139       THD_init_diskptr_names( new_dkptr ,
140                               "./" , NULL , DUMMY_NAME ,
141                               new_dset->view_type , True ) ;
142    }
143    new_dblk->type        = DATABLOCK_TYPE ;
144    new_dblk->nvals       = new_nvals ;
145    new_dblk->malloc_type = DATABLOCK_MEM_MALLOC ;
146    new_dblk->natr        = new_dblk->natr_alloc = 0 ;
147    new_dblk->atr         = NULL ;
148    new_dblk->parent      = (RwcPointer) new_dset ;
149 
150    new_dblk->vedim = NULL ; /* 05 Sep 2006 */
151 
152    new_dblk->brick_fdrcurve = NULL ; /* 23 Jan 2008 */
153    new_dblk->brick_mdfcurve = NULL ; /* 22 Oct 2008 */
154 
155    DBLK_unlock(new_dblk) ;  /* Feb 1998 */
156 
157    new_dblk->brick_fac   = NULL ;
158    new_dblk->brick_bytes = NULL ;
159    new_dblk->brick       = NULL ;
160    if( old_good )
161       THD_init_datablock_brick( new_dblk , -1 , old_dset->dblk ) ;
162    else
163       THD_init_datablock_brick( new_dblk , MRI_short , NULL ) ;
164 
165    if( old_good && old_dset->keywords != NULL )
166       THD_store_dataset_keywords( new_dset , old_dset->keywords ) ;
167    else
168       new_dset->keywords = NULL ;
169 
170    THD_null_datablock_auxdata( new_dblk ) ;
171    if( old_good ) THD_copy_datablock_auxdata( old_dset->dblk , new_dblk ) ;
172 
173    new_dblk->master_nvals = 0 ;     /* 11 Jan 1999 */
174    new_dblk->master_ival  = NULL ;  /* Copy does not inherit mastery */
175    new_dblk->master_bytes = NULL ;
176 
177    if( old_good ){
178      *new_daxes  = *(old_dset->daxes) ;    /* copy all contents */
179      if( !ISVALID_MAT44(new_daxes->ijk_to_dicom) )  /* 15 Dec 2005 */
180        THD_daxes_to_mat44(new_daxes) ;
181    } else {
182      new_daxes->type = DATAXES_TYPE ;      /* make up contents */
183 
184      new_daxes->nxx = new_dkptr->dimsizes[0] ;
185      new_daxes->nyy = new_dkptr->dimsizes[1] ;
186      new_daxes->nzz = new_dkptr->dimsizes[2] ;
187 
188      new_daxes->xxorg = new_daxes->yyorg = new_daxes->zzorg = -0.5 ;
189      new_daxes->xxdel = new_daxes->yydel = new_daxes->zzdel =  1.0 ;
190 
191      new_daxes->xxorient = ORI_R2L_TYPE ;
192      new_daxes->yyorient = ORI_A2P_TYPE ;
193      new_daxes->zzorient = ORI_I2S_TYPE ;
194      LOAD_DIAG_MAT(new_daxes->to_dicomm,1,1,1) ;
195 
196      new_daxes->xxmin = new_daxes->yymin = new_daxes->zzmin = -0.5 ;
197      new_daxes->xxmax = new_daxes->yymax = new_daxes->zzmax =  0.5 ;
198      THD_daxes_to_mat44(new_daxes) ;
199    }
200    new_daxes->parent = (RwcPointer) new_dset ;
201 
202    new_dset->stats   = NULL ;
203    new_dset->parent  = NULL ;
204 
205    if( old_good )
206      INIT_STAT_AUX( new_dset , MAX_STAT_AUX , old_dset->stat_aux ) ;
207    else
208      ZERO_STAT_AUX( new_dset ) ;
209 
210    if( old_good && ISVALID_TIMEAXIS(old_dset->taxis) ){
211      new_taxis = new_dset->taxis = myRwcNew( THD_timeaxis ) ;
212 
213      *new_taxis = *old_dset->taxis ;  /* copy contents */
214 
215      if( new_taxis->nsl > 0 ){        /* copy toff_sl array, if present */
216        int isl ;
217        new_taxis->toff_sl = (float *) RwcMalloc( sizeof(float) * new_taxis->nsl ) ;
218        for( isl = 0 ; isl < new_taxis->nsl ; isl++ )
219          new_taxis->toff_sl[isl] = old_dset->taxis->toff_sl[isl] ;
220      } else {
221        new_taxis->toff_sl = NULL ;
222      }
223    } else {
224      new_dset->taxis = NULL ;
225    }
226 
227    RETURN( new_dset );
228 }
229 
230 /*-----------------------------------------------------------------------*/
231 /*! Create a simple empty datablock, to be filled in later. */
232 
EDIT_empty_datablock(void)233 THD_datablock * EDIT_empty_datablock(void)
234 {
235    THD_datablock *new_dblk ;
236    THD_diskptr   *new_dkptr ;
237 
238 ENTRY("EDIT_empty_datablock") ;
239 
240    /** make some new places to store stuff **/
241 
242    new_dblk                 = myRwcNew( THD_datablock ) ;
243    new_dblk->type           = DATABLOCK_TYPE ;
244    new_dblk->brick          = NULL ;
245    new_dblk->brick_bytes    = NULL ;
246    new_dblk->brick_fac      = NULL ;
247    new_dblk->total_bytes    = 0    ;
248    new_dblk->malloc_type    = DATABLOCK_MEM_UNDEFINED ;
249    new_dblk->parent         = NULL ;
250    new_dblk->brick_lab      = NULL ;
251    new_dblk->brick_keywords = NULL ;
252    new_dblk->brick_statcode = NULL ;
253    new_dblk->brick_stataux  = NULL ;
254    new_dblk->master_nvals   = 0    ;
255    new_dblk->master_ival    = NULL ;
256    new_dblk->master_bytes   = NULL ;
257    new_dblk->master_bot     = 1.0  ;
258    new_dblk->master_top     = 0.0  ;
259    new_dblk->master_ncsv    = 0    ;
260    new_dblk->master_csv     = NULL ;
261    new_dblk->shm_idcode[0]  = '\0' ;
262    new_dblk->nvals          = 1 ;
263    new_dblk->natr           = new_dblk->natr_alloc = 0 ;
264    new_dblk->atr            = NULL ;
265    new_dblk->nnodes         = 0 ;       /* 12 July 2006 [rickr] */
266    new_dblk->node_list      = NULL ;
267 
268    new_dblk->vedim = NULL ; /* 05 Sep 2006 */
269 
270    new_dblk->brick_fdrcurve = NULL ; /* 23 Jan 2008 */
271    new_dblk->brick_mdfcurve = NULL ; /* 22 Oct 2008 */
272 
273    new_dkptr = new_dblk->diskptr = myRwcNew( THD_diskptr ) ;
274 
275    new_dkptr->type         = DISKPTR_TYPE ;
276    new_dkptr->rank         = 3 ;
277    new_dkptr->nvals        = 1 ;
278    new_dkptr->storage_mode = STORAGE_UNDEFINED ;
279    new_dkptr->byte_order   = THD_get_write_order() ;
280    new_dkptr->dimsizes[0]  = 2 ;
281    new_dkptr->dimsizes[1]  = 2 ;
282    new_dkptr->dimsizes[2]  = 2 ;
283 
284    THD_init_diskptr_names( new_dkptr ,
285                            "./" , NULL , DUMMY_NAME ,
286                            VIEW_ORIGINAL_TYPE , True ) ;
287 
288 STATUS("addto_kill(new_dkptr)") ;
289    INIT_KILL(new_dblk->kl) ;
290    ADDTO_KILL(new_dblk->kl,new_dkptr) ;
291 
292 STATUS("unlocking") ;
293    DBLK_unlock(new_dblk) ;
294 STATUS("nulling auxdata") ;
295    THD_null_datablock_auxdata( new_dblk ) ;
296 STATUS("done") ;
297 
298    RETURN( new_dblk ) ;
299 }
300 
301 /*-----------------------------------------------------------------------*/
302 /*! Create an empty marker set.                      13 Sep 2005 [rickr] */
303 /*  (copied from 3drefit.c)                                              */
304 
create_empty_marker_set(void)305 THD_marker_set * create_empty_marker_set(void)
306 {
307    THD_marker_set * markers = myRwcNew( THD_marker_set ) ;
308    int              ii, jj ;
309 
310    if( !markers ) return NULL;
311 
312    markers->numdef = 0 ;
313 
314    for( ii=0 ; ii < MARKS_MAXNUM ; ii++ ){       /* null all data out */
315       markers->valid[ii] = 0 ;
316       for( jj=0 ; jj < MARKS_MAXLAB  ; jj++ )
317          markers->label[ii][jj] = '\0';
318       for( jj=0 ; jj < MARKS_MAXHELP ; jj++ )
319          markers->help[ii][jj]  = '\0';
320    }
321 
322    for( ii=0 ; ii < NMARK_ALIGN ; ii++ ){       /* copy strings in */
323       MCW_strncpy( &(markers->label[ii][0]) ,
324                    THD_align_label[ii] , MARKS_MAXLAB ) ;
325       MCW_strncpy( &(markers->help[ii][0]) ,
326                    THD_align_help[ii] , MARKS_MAXHELP ) ;
327    }
328 
329    for( ii=0 ; ii < MARKS_MAXFLAG ; ii++ )     /* copy flags in */
330       markers->aflags[ii] = THD_align_aflags[ii] ;
331 
332    return markers ;
333 }
334 
335 /*------------------------------------------------------------------*/
336 
okay_to_add_markers(THD_3dim_dataset * dset)337 int okay_to_add_markers(THD_3dim_dataset * dset)
338 {
339    if( !dset )         return 0 ;
340 
341 /*    if( dset->markers ) return 0 ;  allow deletion   9 Aug 2006 [rickr] */
342 
343    /* test comes from 3drefit.c */
344    if( dset->type           == HEAD_ANAT_TYPE     &&
345        dset->view_type      == VIEW_ORIGINAL_TYPE &&
346        DSET_NUM_TIMES(dset) == 1                  &&
347        DSET_NVALS(dset)     == 1 )
348      return 1 ;
349 
350    return 0 ;
351 }
352