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 "afni.h"
8
9 #ifndef ALLOW_PLUGINS
10 # error "Plugins not properly set up -- see machdep.h"
11 #endif
12
13 /***********************************************************************
14 Simple plugin to copy a dataset and make a new one.
15 ************************************************************************/
16
17 static char * COPY_main( PLUGIN_interface * ) ;
18
19 static char helpstring[] =
20 " Purpose: Creating a copy of a dataset.\n"
21 " Inputs:\n"
22 " Dataset = A dataset in the current session that exists in memory\n"
23 " (not warp-on-demand).\n"
24 " Prefix = Filename prefix to be used for the output dataset.\n"
25 " Fill = How to fill voxel data in new dataset:\n"
26 " Data [All] = copy all sub-bricks from input\n"
27 " Zero [All] = fill all sub-bricks with zero\n"
28 " Zero [One] = make new dataset have only 1 sub-brick,\n"
29 " and fill with zero -- this is useful for\n"
30 " creating mask datasets using the\n"
31 " 'Draw Dataset' plugin.\n"
32 " Type = Lets you change the 'type' of the output dataset, for\n"
33 " example from anat to func.\n"
34 " Datum = Lets you set the data type of the new brick. This will\n"
35 " only work when using \"Zero [All]\" or \"Zero [One]\"\n"
36 " Fill modes.\n"
37 "Author -- RWCox"
38 ;
39
40 #define NFILL 3
41 static char * fill_options[NFILL] = { "Data [All]" , "Zero [All]" , "Zero [One]" } ;
42
43 #define NDTYPE 4
44 static char * dtype_options[NDTYPE] = {
45 "byte" , "short" , "float" , "complex" } ;
46 static int dtype_kinds[NDTYPE] = {
47 MRI_byte , MRI_short , MRI_float , MRI_complex } ;
48
49 /***********************************************************************
50 Set up the interface to the user
51 ************************************************************************/
52
53
54 DEFINE_PLUGIN_PROTOTYPE
55
PLUGIN_init(int ncall)56 PLUGIN_interface * PLUGIN_init( int ncall )
57 {
58 PLUGIN_interface * plint ;
59
60 if( ncall > 0 ) return NULL ; /* only one interface */
61 CHECK_IF_ALLOWED("DATASETCOPY","Dataset Copy") ; /* 30 Sep 2016 */
62
63 /*-- set titles and call point --*/
64
65 plint = PLUTO_new_interface( "Dataset Copy" , "Make a Copy of a Dataset" , helpstring ,
66 PLUGIN_CALL_VIA_MENU , COPY_main ) ;
67
68 PLUTO_add_hint( plint , "Make a Copy of a Dataset" ) ;
69
70 PLUTO_set_sequence( plint , "A:newdset:copy" ) ;
71
72 PLUTO_set_runlabels( plint , "Copy+Keep" , "Copy+Close" ) ; /* 04 Nov 2003 */
73
74 /*-- first line of input: Dataset --*/
75
76 PLUTO_add_option( plint , "Input" , "Input" , TRUE ) ;
77 PLUTO_add_dataset(plint , "Dataset" ,
78 ANAT_ALL_MASK , FUNC_ALL_MASK ,
79 DIMEN_ALL_MASK | BRICK_ALLTYPE_MASK ) ;
80
81 /*-- second line of input: Prefix for output dataset --*/
82
83 PLUTO_add_option( plint , "Output" , "Output" , TRUE ) ;
84 PLUTO_add_string( plint , "Prefix" , 0,NULL , 19 ) ;
85
86 /*-- third line of input: Fill option --*/
87
88 PLUTO_add_option( plint , "Data Fill" , "Data Fill" , FALSE ) ;
89 PLUTO_add_string( plint , "Method" , NFILL,fill_options , 0 ) ;
90
91 /*-- fourth line of input: Type option --*/
92
93 PLUTO_add_option( plint , "Dataset" , "Dataset" , FALSE ) ;
94 PLUTO_add_string( plint , "Type" , NUM_DSET_TYPES,DSET_prefixstr , 0 ) ;
95
96 /*-- fifth line of input: Datum option --*/
97
98 PLUTO_add_option( plint , "Datum" , "Datum" , FALSE ) ;
99 PLUTO_add_string( plint , "Datum" , NDTYPE,dtype_options, 2 ) ;
100
101 return plint ;
102 }
103
104 /***************************************************************************
105 Main routine for this plugin (will be called from AFNI).
106 ****************************************************************************/
107
COPY_main(PLUGIN_interface * plint)108 static char * COPY_main( PLUGIN_interface * plint )
109 {
110 char * tag , * new_prefix , * cpt ;
111 MCW_idcode * idc ;
112 THD_3dim_dataset * dset , * new_dset ;
113 int ival , zfill=0 , ftyp=-1 , dtyp=-1, type_index=-1, data_type=-1 ;
114
115 /*--------------------------------------------------------------------*/
116 /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/
117
118 if( plint == NULL )
119 return "**********************\n"
120 "COPY_main: NULL input\n"
121 "**********************" ;
122
123 PLUTO_next_option(plint) ;
124 idc = PLUTO_get_idcode(plint) ;
125 dset = PLUTO_find_dset(idc) ;
126 if( dset == NULL )
127 return "*****************************\n"
128 "COPY_main: bad input dataset\n"
129 "*****************************" ;
130
131 dtyp = dset->type ;
132
133 PLUTO_next_option(plint) ;
134 new_prefix = PLUTO_get_string(plint) ;
135 if( ! PLUTO_prefix_ok(new_prefix) )
136 return "**********************\n"
137 "COPY_main: bad prefix\n"
138 "**********************" ;
139
140 tag = PLUTO_get_optiontag(plint) ;
141 while( tag != NULL ){
142
143 if( strcmp(tag,"Data Fill") == 0 ){
144 cpt = PLUTO_get_string(plint) ;
145 if( cpt != NULL )
146 zfill = PLUTO_string_index( cpt , NFILL , fill_options ) ;
147 }
148
149 else if( strcmp(tag,"Dataset") == 0 ){
150 cpt = PLUTO_get_string(plint) ;
151 ftyp = PLUTO_string_index( cpt , NUM_DSET_TYPES,DSET_prefixstr ) ;
152 if( ftyp >= 0 ){
153 if( ftyp <= LAST_FUNC_TYPE ){
154 dtyp = HEAD_FUNC_TYPE ;
155 } else {
156 ftyp -= (LAST_FUNC_TYPE+1) ; /* 14 Jul 1998 */
157 dtyp = HEAD_ANAT_TYPE ;
158 }
159 }
160 }
161
162 else if( strcmp(tag, "Datum") == 0 ){
163 cpt = PLUTO_get_string(plint) ;
164 type_index = PLUTO_string_index( cpt, NDTYPE, dtype_options ) ;
165 if ( (type_index >= 0) && (type_index < NDTYPE) )
166 data_type = dtype_kinds[type_index] ;
167 }
168
169 tag = PLUTO_get_optiontag(plint) ;
170 }
171
172 /*------------------------------------------------------*/
173 /*---------- At this point, the inputs are OK ----------*/
174
175 /*-- make a new dataset --*/
176
177 if( zfill == 0 ){
178 new_dset = PLUTO_copy_dset( dset , new_prefix ) ;
179 } else {
180 new_dset = EDIT_empty_copy( dset ) ;
181
182 if( ISFUNCTYPE(dtyp) && ( zfill == 2 ) )
183 ftyp = FUNC_FIM_TYPE ; /* 14 Jul 1998 */
184 }
185
186 if( new_dset == NULL )
187 return "****************************************\n"
188 "COPY_main: failed to copy input dataset\n"
189 "****************************************" ;
190
191 DSET_unload( dset ) ; /* unload old one from memory */
192
193 /*--- modify dataset, if desired ---*/
194
195 if( ftyp >= 0 ) EDIT_dset_items( new_dset ,
196 ADN_type , dtyp ,
197 ADN_func_type , ftyp ,
198 ADN_none ) ;
199
200 /*--- change type of data stored ---*/
201
202 if ( (data_type >= 0) )
203 {
204 if ( zfill )
205 EDIT_dset_items( new_dset ,
206 ADN_datum_all, data_type,
207 ADN_none ) ;
208 else{
209 DSET_delete(new_dset) ;
210
211 return "****************************************************\n"
212 "COPY_main: Cannot change type of non-zeroed dataset\n"
213 "****************************************************" ;
214 }
215 }
216
217 /* if 'Zero [All]' or 'Zero [One]' */
218
219 if( zfill ) {
220 int ityp , nbytes , nvals , ival ;
221 void * new_brick , * bp ;
222
223 EDIT_dset_items( new_dset ,
224 ADN_prefix , new_prefix ,
225 ADN_label1 , new_prefix ,
226 ADN_none ) ;
227
228 if ( zfill == 2 ) { /* for 'Zero [One]' case - just make one brick */
229 EDIT_dset_items( new_dset ,
230 ADN_nvals , 1 ,
231 ADN_ntt , 0 ,
232 ADN_none ) ;
233 }
234
235 nvals = DSET_NVALS(new_dset) ;
236
237 for ( ival = 0 ; ival < nvals ; ival++) /* get memory for bricks */
238 { /* and zero fill */
239 ityp = DSET_BRICK_TYPE(new_dset,ival) ;
240 nbytes = DSET_BRICK_BYTES(new_dset,ival) ; /* how much data */
241 new_brick = malloc( nbytes ) ;
242 EDIT_substitute_brick( new_dset , ival , ityp , new_brick ) ;
243
244 bp = DSET_BRICK_ARRAY(new_dset,ival) ; /* brick pointer */
245 EDIT_BRICK_FACTOR(new_dset,ival,0.0) ; /* brick factor */
246 memset( bp , 0 , nbytes ) ;
247 }
248 }
249
250 { char *his ;
251 tross_Copy_History( dset , new_dset ) ;
252 his = PLUTO_commandstring( plint ) ;
253 tross_Append_History( new_dset , his ) ; free(his) ;
254 }
255
256 ival = PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ;
257
258 if( ival ){
259 THD_delete_3dim_dataset( new_dset , False ) ;
260 return "**********************************************\n"
261 "COPY_main: failure to add new dataset to AFNI\n"
262 "**********************************************" ;
263 }
264
265 /*-- done successfully!!! --*/
266
267 return NULL ;
268 }
269