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 #include "thd.h"
9
10 /***********************************************************************
11 The first set of routines is concerned with "attributes".
12 These are values stored in the header file of a dataset,
13 and can be conceived of being in the form
14 name = value value value ...
15 where "name" is an identifying string, and "value value value ..."
16 is an array of values. These attributes are read in, and later
17 interrogated to form the actual data structure of a THD_3dim_dataset.
18 ************************************************************************/
19
atr_print(ATR_any * atr,char * ssep,char * spsep,char quote,int do_name)20 void atr_print( ATR_any *atr, char *ssep, char *spsep, char quote, int do_name)
21 {
22 int ii ;
23 char ssep_def[]={"~"};
24 int neword = 1;
25
26 if (!ssep) ssep = ssep_def;
27
28 switch( atr->type ){
29
30 default:
31 ERROR_message("Illegal attribute type found: %d",atr->type);
32 exit(1) ;
33
34 case ATR_FLOAT_TYPE:{
35 ATR_float *aa = (ATR_float *) atr ;
36 if( do_name ) printf("%s = ",aa->name) ;
37 for( ii=0 ; ii < aa->nfl ; ii++ )
38 printf("%s ",MV_format_fval(aa->fl[ii])) ;
39 printf("\n") ;
40 }
41 return ;
42
43 case ATR_INT_TYPE:{
44 ATR_int *aa = (ATR_int *) atr ;
45 if( do_name ) printf("%s = ",aa->name) ;
46 for( ii=0 ; ii < aa->nin ; ii++ )
47 printf("%d ",aa->in[ii]) ;
48 printf("\n") ;
49 }
50 return ;
51
52 case ATR_STRING_TYPE:{
53 ATR_string *aa = (ATR_string *) atr ;
54 char *str = (char *)malloc(sizeof(char)*(aa->nch+1)) ;
55 char *eee ;
56 memcpy(str,aa->ch,aa->nch) ; str[aa->nch] = '\0' ;
57
58 #if 0
59 eee = tross_Expand_String(str) ;
60 #else
61 eee = NULL ;
62 #endif
63 if( do_name ) printf("%s = ",aa->name) ;
64 if( eee != NULL ){
65 printf("%s\n",eee) ; free(eee) ;
66 } else if( str[0] != '\0' ){
67 int isb = 0;
68 neword = 1;
69 for (ii=0; ii<aa->nch;++ii) {
70 if (str[ii] == '\0') {
71 ++isb;
72 if (quote != '\0') printf("%c", quote);
73 if (strcmp(ssep,"NUM") == 0) {
74 /* handled below*/
75 } else {
76 printf("%s",ssep);
77 }
78 neword = 1;
79 } else {
80 if (neword) {
81 if (strcmp(ssep,"NUM") == 0) {
82 printf(" %d ",isb);
83 }
84 if (quote != '\0') printf("%c", quote);
85 }
86 if (spsep && str[ii] == ' ') printf("%s", spsep);
87 else printf("%c", str[ii]);
88 neword = 0;
89 }
90 }
91 printf("\n") ;
92 } else {
93 printf("(null)\n") ;
94 }
95 free(str) ;
96 }
97 return ;
98 }
99 }
100
101 /*-----------------------------------------------------------------------*/
102 /*! Given the rudiments of a datablock, read all the attributes into it
103 -------------------------------------------------------------------------*/
104
THD_read_all_atr(char * headername,THD_datablock * blk)105 void THD_read_all_atr( char *headername , THD_datablock *blk )
106 {
107 ATR_any *next_atr ;
108 int code , ii ;
109 FILE *header_file ;
110
111 ENTRY("THD_read_all_atr") ;
112
113 if( ! ISVALID_DATABLOCK(blk) )
114 THD_FATAL_ERROR( "Illegal datablock type in THD_read_all_atr" ) ;
115
116 blk->natr = 0 ; /* initialize to no attributes */
117 blk->natr_alloc = 0 ;
118 blk->atr = NULL ;
119
120 /*--- certain types of filenames are verboten ---*/
121
122 if( STRING_HAS_SUFFIX(headername,".mnc") ) EXRETURN ;
123 if( STRING_HAS_SUFFIX(headername,".nii") ) EXRETURN ;
124 if( STRING_HAS_SUFFIX(headername,".nii.gz") ) EXRETURN ;
125 if( STRING_HAS_SUFFIX(headername,".mri") ) EXRETURN ;
126 if( STRING_HAS_SUFFIX(headername,".ctf") ) EXRETURN ;
127 if( STRING_HAS_SUFFIX(headername,".hdr") ) EXRETURN ;
128 if( STRING_HAS_SUFFIX(headername,".mpg") ) EXRETURN ;
129
130 /*--- open file; if unable to do so, exeunt ---*/
131
132 header_file = fopen( headername , "r" ) ;
133 if( header_file == NULL ) EXRETURN ;
134
135 /*--- 01 Jun 2005: check if this is a NIML-style header file ---*/
136
137 { char buf[1024] , *cpt ; int nbuf ;
138 nbuf = fread( buf , 1 , 1023 , header_file ) ; /* read first 1K */
139 if( nbuf > 0 ){ /* got something? */
140 buf[nbuf] = '\0' ;
141 cpt = strstr( buf , "<AFNI_" ) ;
142 if( cpt != NULL ){ /*** NIML Dataset!!! ***/
143 fclose( header_file ) ; /* is reopened by NIML */
144 THD_read_niml_atr( headername , blk ) ; /** read the new way! **/
145 EXRETURN ;
146 }
147 }
148 rewind( header_file ) ; /*** old style dataset ==> read it below ***/
149 }
150
151 /*----- read attributes from the header file -----*/
152
153 do{
154 char aname[THD_MAX_NAME] , atypestr[THD_MAX_NAME] ;
155 int atype , acount ;
156
157 atypestr[0] = aname[0] = '\0' ; acount = 0 ;
158
159 code = fscanf( header_file ,
160 " type = %s name = %s count = %d" ,
161 atypestr , aname , &acount ) ;
162
163 if( code == 3 && acount == 0 ) continue ; /* 24 Nov 2009 */
164
165 code = (code != 3 || acount < 1) ? FAIL : SUCCESS ;
166 if( code == FAIL ) break ; /* bad read */
167
168 for( atype=FIRST_ATR_TYPE ; atype <= LAST_ATR_TYPE ; atype++ )
169 if( strcmp(atypestr,ATR_typestr[atype]) == 0 ) break ;
170
171 if( atype > LAST_ATR_TYPE ){ /* bad read */
172 code = FAIL ;
173 break ;
174 }
175
176 if( blk->natr == blk->natr_alloc ){ /* make new space */
177 blk->natr_alloc += ATR_ALLINC ;
178 blk->atr = (ATR_any *)
179 RwcRealloc( (char *)blk->atr,
180 sizeof(ATR_any) * blk->natr_alloc );
181 }
182 next_atr = &(blk->atr[blk->natr]) ;
183 (blk->natr)++ ;
184
185 switch( atype ){
186
187 case ATR_FLOAT_TYPE:{
188 ATR_float *new_atr = (ATR_float *) next_atr ;
189 char bbb[256] ;
190
191 new_atr->type = ATR_FLOAT_TYPE ;
192 new_atr->name = RwcNewString( aname ) ;
193 new_atr->nfl = acount ;
194 new_atr->fl = (float *) RwcMalloc( sizeof(float) * acount ) ;
195
196 code = 0 ;
197 for( ii=0 ; ii < acount ; ii++ ){
198 #if 0
199 code += fscanf( header_file , "%f" , &(new_atr->fl[ii]) ) ;
200 #else
201 bbb[0] = '\0' ; fscanf( header_file , "%255s" , bbb ) ;
202 if( bbb[0] != '\0' ){
203 new_atr->fl[ii] = strtod( bbb , NULL ) ;
204 code++ ;
205 }
206 #endif
207 }
208 code = (code != acount) ? FAIL : SUCCESS ;
209
210 ADDTO_KILL( blk->kl , new_atr->name ) ;
211 ADDTO_KILL( blk->kl , new_atr->fl ) ;
212 }
213 break ;
214
215 case ATR_INT_TYPE:{
216 ATR_int *new_atr = (ATR_int *) next_atr ;
217
218 new_atr->type = ATR_INT_TYPE ;
219 new_atr->name = RwcNewString( aname ) ;
220 new_atr->nin = acount ;
221 new_atr->in = (int *) RwcMalloc( sizeof(int) * acount ) ;
222
223 code = 0 ;
224 for( ii=0 ; ii < acount ; ii++ ){
225 code += fscanf( header_file , "%d" , &(new_atr->in[ii]) ) ;
226 }
227 code = (code != acount) ? FAIL : SUCCESS ;
228
229 ADDTO_KILL( blk->kl , new_atr->name ) ;
230 ADDTO_KILL( blk->kl , new_atr->in ) ;
231 }
232 break ;
233
234 case ATR_STRING_TYPE:{
235 ATR_string *new_atr = (ATR_string *) next_atr ;
236
237 new_atr->type = ATR_STRING_TYPE ;
238 new_atr->name = RwcNewString( aname ) ;
239 new_atr->nch = acount ;
240 new_atr->ch = (char *) RwcMalloc( sizeof(char) * acount ) ;
241
242 fscanf( header_file , " '" ) ;
243
244 code = 0 ;
245 for( ii=0 ; ii < acount ; ii++ ){
246 code += fscanf( header_file , "%c" , &(new_atr->ch[ii]) ) ;
247 }
248 code = (code != acount) ? FAIL : SUCCESS ;
249
250 THD_unzblock( acount , new_atr->ch ) ;
251
252 ADDTO_KILL( blk->kl , new_atr->name ) ;
253 ADDTO_KILL( blk->kl , new_atr->ch ) ;
254 }
255 break ;
256 } /* end of switch */
257
258 if( code == FAIL ) break ; /* exit if an error! */
259 } while(1) ; /* end of for loop over all attributes */
260
261 fclose( header_file ) ; EXRETURN ;
262 }
263
264 /*-----------------------------------------------------------------------*/
265 /*! Read NIML-formatted attributes from the header file. [01 Jun 2005]
266 -------------------------------------------------------------------------*/
267
THD_read_niml_atr(char * headername,THD_datablock * blk)268 void THD_read_niml_atr( char *headername , THD_datablock *blk )
269 {
270 NI_stream ns ;
271 void *nini ;
272 NI_group *ngr ;
273 char sname[2048] ;
274 long fsize ;
275
276 ENTRY("THD_read_niml_atr") ;
277
278 /** open NIML stream to read from the file **/
279
280 if( headername == NULL || *headername == '\0' || blk == NULL ) EXRETURN ;
281 fsize = NI_filesize(headername) ; if( fsize <= 10 ) EXRETURN ;
282 sprintf(sname,"file:%s",headername) ; STATUS(sname) ;
283 ns = NI_stream_open( sname , "r" ) ;
284 if( ns == (NI_stream)NULL ) EXRETURN ;
285 if( fsize > NI_BUFSIZE ){
286 fsize = MIN( 4*NI_BUFSIZE , fsize ) ;
287 NI_stream_setbufsize( ns , fsize ) ;
288 }
289
290 /** read one group element from it (e.g., skipping the XML prolog) **/
291
292 while(1){
293 nini = NI_read_element( ns , 9 ) ;
294 if( nini == NULL ){ NI_stream_close(ns); EXRETURN; } /* bad! */
295 if( NI_element_type(nini) == NI_GROUP_TYPE ) break ; /* good */
296 NI_free_element(nini) ; /* not what we want */
297 }
298 NI_stream_close( ns ) ;
299 ngr = (NI_group *)nini ;
300 if( strncmp(ngr->name,"AFNI_",5) != 0 ){ NI_free_element(ngr); EXRETURN; }
301
302 /** actually process element, then exit stage right **/
303
304 THD_dblkatr_from_niml( ngr , blk ) ; /* cf. thd_nimlatr.c */
305 NI_free_element( ngr ) ;
306 EXRETURN ;
307 }
308
309 /*-----------------------------------------------------------------------
310 29 April 1998: erase all attributes from a datablock
311 -------------------------------------------------------------------------*/
312
THD_erase_all_atr(THD_datablock * blk)313 void THD_erase_all_atr( THD_datablock *blk )
314 {
315 int ia ;
316 ATR_any *next_atr ;
317
318 ENTRY("THD_erase_all_atr") ;
319
320 if( !ISVALID_DATABLOCK(blk) || blk->natr == 0 || blk->atr == NULL ) EXRETURN ;
321
322 for( ia=0 ; ia < blk->natr ; ia++ ){
323 next_atr = blk->atr + ia ;
324
325 switch( next_atr->type ){
326 case ATR_FLOAT_TYPE:{
327 ATR_float *aa = (ATR_float *) next_atr ;
328 SINGLE_KILL( blk->kl , aa->name ) ;
329 SINGLE_KILL( blk->kl , aa->fl ) ;
330 }
331 break ;
332
333 case ATR_STRING_TYPE:{
334 ATR_string *aa = (ATR_string *) next_atr ;
335 SINGLE_KILL( blk->kl , aa->name ) ;
336 SINGLE_KILL( blk->kl , aa->ch ) ;
337 }
338 break ;
339
340 case ATR_INT_TYPE:{
341 ATR_int *aa = (ATR_int *) next_atr ;
342 SINGLE_KILL( blk->kl , aa->name ) ;
343 SINGLE_KILL( blk->kl , aa->in ) ;
344 }
345 break ;
346 }
347
348 next_atr->type = ILLEGAL_TYPE ;
349 }
350
351 blk->natr = 0 ;
352 EXRETURN ;
353 }
354
355 /*-----------------------------------------------------------------------
356 29 April 1998: erase a single attribute, given by name
357 -------------------------------------------------------------------------*/
358
THD_erase_one_atr(THD_datablock * blk,char * name)359 void THD_erase_one_atr( THD_datablock *blk , char *name )
360 {
361 ATR_any *next_atr ;
362
363 ENTRY("THD_erase_one_atr") ;
364
365 if( ! ISVALID_DATABLOCK(blk) || name == NULL ||
366 blk->natr == 0 || blk->atr == NULL ) EXRETURN ;
367
368 next_atr = THD_find_atr( blk , name ) ;
369
370 if( next_atr == NULL ) EXRETURN ;
371
372 switch( next_atr->type ){
373 case ATR_FLOAT_TYPE:{
374 ATR_float *aa = (ATR_float *) next_atr ;
375 SINGLE_KILL( blk->kl , aa->name ) ;
376 SINGLE_KILL( blk->kl , aa->fl ) ;
377 }
378 break ;
379
380 case ATR_STRING_TYPE:{
381 ATR_string *aa = (ATR_string *) next_atr ;
382 SINGLE_KILL( blk->kl , aa->name ) ;
383 SINGLE_KILL( blk->kl , aa->ch ) ;
384 }
385 break ;
386
387 case ATR_INT_TYPE:{
388 ATR_int *aa = (ATR_int *) next_atr ;
389 SINGLE_KILL( blk->kl , aa->name ) ;
390 SINGLE_KILL( blk->kl , aa->in ) ;
391 }
392 break ;
393 }
394
395 next_atr->type = ILLEGAL_TYPE ;
396 EXRETURN ;
397 }
398
399 /*-----------------------------------------------------------------------
400 given a datablock and an attribute name, return the pointer to the
401 attribute structure that matches (if none, return NULL)
402 -------------------------------------------------------------------------*/
403
THD_find_atr(THD_datablock * blk,char * name)404 ATR_any * THD_find_atr( THD_datablock *blk , char *name )
405 {
406 int ia ;
407
408 ENTRY("THD_find_atr") ;
409
410 if( ! ISVALID_DATABLOCK(blk) )
411 THD_FATAL_ERROR( "Illegal block type in THD_find_atr" ) ;
412
413 if( blk->natr == 0 || blk->atr == NULL ) RETURN(NULL) ;
414
415 /* loop over attributes and check names */
416
417 for( ia=0 ; ia < blk->natr ; ia++ ){
418 char *aname ;
419 ATR_any *next_atr = &(blk->atr[ia]) ; /* pointer to this atr */
420
421 /* extract pointer to name from next_atr */
422
423 switch( next_atr->type ){
424
425 default: aname = NULL ; break ;
426
427 case ATR_FLOAT_TYPE:{
428 ATR_float *aa = (ATR_float *) next_atr ;
429 aname = aa->name ;
430 }
431 break ;
432
433 case ATR_STRING_TYPE:{
434 ATR_string *aa = (ATR_string *) next_atr ;
435 aname = aa->name ;
436 }
437 break ;
438
439 case ATR_INT_TYPE:{
440 ATR_int *aa = (ATR_int *) next_atr ;
441 aname = aa->name ;
442 }
443 break ;
444 }
445
446 /* check if names match; if so, return the result */
447
448 if( aname != NULL && strcmp(aname,name) == 0 ) RETURN(next_atr) ;
449
450 } /* end of loop over attributes */
451
452 RETURN(NULL) ; /* none matched */
453 }
454
455 /*-----------------------------------------------------------------------*/
456
THD_find_float_atr(THD_datablock * blk,char * name)457 ATR_float * THD_find_float_atr( THD_datablock *blk , char *name )
458 {
459 ATR_any *aa ;
460 aa = THD_find_atr( blk , name ) ;
461
462 if( aa == NULL || aa->type != ATR_FLOAT_TYPE ) return NULL ;
463 else return (ATR_float *) aa ;
464 }
465
466 /*-----------------------------------------------------------------------*/
467
THD_find_int_atr(THD_datablock * blk,char * name)468 ATR_int * THD_find_int_atr( THD_datablock *blk , char *name )
469 {
470 ATR_any *aa ;
471 aa = THD_find_atr( blk , name ) ;
472
473 if( aa == NULL || aa->type != ATR_INT_TYPE ) return NULL ;
474 else return (ATR_int *) aa ;
475 }
476
477 /*-----------------------------------------------------------------------*/
478
THD_find_string_atr(THD_datablock * blk,char * name)479 ATR_string * THD_find_string_atr( THD_datablock *blk , char *name )
480 {
481 ATR_any *aa ;
482 aa = THD_find_atr( blk , name ) ;
483
484 if( aa == NULL || aa->type != ATR_STRING_TYPE ) return NULL ;
485 else return (ATR_string *)aa;
486 }
487
488 /*-----------------------------------------------------------------------
489 given a datablock, set an attribute
490 (if name is same as existing attribute, will overwrite)
491 -------------------------------------------------------------------------*/
492
THD_set_atr(THD_datablock * blk,char * aname,int atype,int acount,void * ar)493 void THD_set_atr( THD_datablock *blk , char *aname ,
494 int atype , int acount , void *ar )
495 {
496 ATR_any *old_atr , *atr ;
497
498 ENTRY("THD_set_atr") ;
499
500 if( ! ISVALID_DATABLOCK(blk) )
501 THD_FATAL_ERROR( "Illegal block type in THD_set_atr" ) ;
502
503 if( acount < 0 || ar == NULL || aname == NULL )
504 THD_FATAL_ERROR( "Illegal input data in THD_set_atr" ) ;
505
506 if( acount == 0 ) EXRETURN ; /* 24 Nov 2009 */
507
508 STATUS(aname) ;
509
510 old_atr = THD_find_atr( blk , aname ) ; /* find matching name */
511
512 if( old_atr != NULL ){ /* if an attribute with this name already is */
513
514 atr = old_atr ;
515
516 switch( old_atr->type ){ /* free data in old attribute */
517
518 default: break ; /* something unpleasant */
519
520 case ATR_FLOAT_TYPE:{
521 ATR_float *aa = (ATR_float *) old_atr ;
522
523 SINGLE_KILL( blk->kl , aa->name ) ;
524 SINGLE_KILL( blk->kl , aa->fl ) ;
525 }
526 break ;
527
528 case ATR_INT_TYPE:{
529 ATR_int *aa = (ATR_int *) old_atr ;
530
531 SINGLE_KILL( blk->kl , aa->name ) ;
532 SINGLE_KILL( blk->kl , aa->in ) ;
533 }
534 break ;
535
536 case ATR_STRING_TYPE:{
537 ATR_string *aa = (ATR_string *) old_atr ;
538
539 SINGLE_KILL( blk->kl , aa->name ) ;
540 SINGLE_KILL( blk->kl , aa->ch ) ;
541 }
542 break ;
543 } /* end of switch */
544
545 } else { /* this is a new attribute name for this datablock */
546
547 int ia ;
548
549 for( ia=0 ; ia < blk->natr ; ia++ ) /* 29 April 1998: look for an */
550 if( blk->atr[ia].type < 0 ) break ; /* unused one before the end */
551
552 if( ia == blk->natr_alloc ){ /* need to extend array */
553 blk->natr_alloc += ATR_ALLINC ;
554 blk->atr = (ATR_any *)
555 RwcRealloc( (char *)blk->atr,
556 sizeof(ATR_any) * blk->natr_alloc );
557 }
558 atr = &(blk->atr[ia]) ;
559 if( ia == blk->natr ) (blk->natr)++ ;
560 }
561
562 /* at this point, atr points to the location to store the data;
563 now, allocate space for the actual data and store it */
564
565 switch( atype ){
566
567 case ATR_FLOAT_TYPE:{
568 ATR_float *new_atr = (ATR_float *) atr ;
569
570 new_atr->type = ATR_FLOAT_TYPE ;
571 new_atr->name = RwcNewString( aname ) ;
572 new_atr->nfl = acount ;
573 new_atr->fl = (float *) RwcMalloc( sizeof(float) * acount ) ;
574 memcpy( new_atr->fl , ar , sizeof(float)*acount ) ;
575
576 ADDTO_KILL( blk->kl , new_atr->name ) ;
577 ADDTO_KILL( blk->kl , new_atr->fl ) ;
578 }
579 break ;
580
581 case ATR_INT_TYPE:{
582 ATR_int *new_atr = (ATR_int *) atr ;
583
584 new_atr->type = ATR_INT_TYPE ;
585 new_atr->name = RwcNewString( aname ) ;
586 new_atr->nin = acount ;
587 new_atr->in = (int *) RwcMalloc( sizeof(int) * acount ) ;
588 memcpy( new_atr->in , ar , sizeof(int)*acount ) ;
589
590 ADDTO_KILL( blk->kl , new_atr->name ) ;
591 ADDTO_KILL( blk->kl , new_atr->in ) ;
592
593 #if 0
594 if(PRINT_TRACING){
595 char str[256] ; int ii ;
596 sprintf(str,"INT atr: name=%s nin=%d vals::",new_atr->name,new_atr->nin) ;
597 STATUS(str) ;
598 for( ii=0 ; ii < acount ; ii++ ) printf(" %d",new_atr->in[ii]) ;
599 printf("\n") ;
600 }
601 #endif
602 }
603 break ;
604
605 case ATR_STRING_TYPE:{
606 ATR_string *new_atr = (ATR_string *) atr ;
607
608 new_atr->type = ATR_STRING_TYPE ;
609 new_atr->name = RwcNewString( aname ) ;
610 new_atr->nch = acount ;
611 new_atr->ch = (char *) RwcMalloc( sizeof(char) * acount ) ;
612 memcpy( new_atr->ch , ar , sizeof(char)*acount ) ;
613 new_atr->ch[acount-1] = '\0' ;
614 /*** fprintf(stderr,"Have %d chars\n", acount);
615 atr_print( (ATR_any *)new_atr, NULL , NULL, '\0', 1) ; ***/
616
617 ADDTO_KILL( blk->kl , new_atr->name ) ;
618 ADDTO_KILL( blk->kl , new_atr->ch ) ;
619 }
620 break ;
621 } /* end of switch */
622
623 EXRETURN ;
624 }
625
626 /*-----------------------------------------------------------------------*/
627
THD_set_float_atr(THD_datablock * blk,char * name,int n,float * fl)628 void THD_set_float_atr( THD_datablock *blk ,
629 char *name , int n , float *fl )
630 {
631 ENTRY("THD_set_float_atr") ;
632 THD_set_atr( blk , name , ATR_FLOAT_TYPE , n , fl ) ;
633 EXRETURN ;
634 }
635
636 /*-----------------------------------------------------------------------*/
637
THD_set_int_atr(THD_datablock * blk,char * name,int n,int * in)638 void THD_set_int_atr( THD_datablock *blk ,
639 char *name , int n , int *in )
640 {
641 ENTRY("THD_set_int_atr") ;
642 THD_set_atr( blk , name , ATR_INT_TYPE , n , in ) ;
643 EXRETURN ;
644 }
645
646 /*-----------------------------------------------------------------------*/
647
THD_set_char_atr(THD_datablock * blk,char * name,int n,char * str)648 void THD_set_char_atr( THD_datablock *blk ,
649 char *name , int n , char *str )
650 {
651 ENTRY("THD_set_char_atr") ;
652 THD_set_atr( blk , name , ATR_STRING_TYPE , n , str ) ;
653 EXRETURN ;
654 }
655
656 /*-----------------------------------------------------------------------*/
657 /*! Remove attributes from a dataset that might contain identifying
658 strings. Can't help against sneaky users who put them into
659 other places, but might be good enough for non-programmers.
660 -------------------------------------------------------------------------*/
661
THD_anonymize_dset(THD_3dim_dataset * dset)662 void THD_anonymize_dset( THD_3dim_dataset *dset ) /* 08 Jul 2005 */
663 {
664 THD_datablock *blk ;
665 int ia ;
666
667 ENTRY("THD_anonymize_dset") ;
668
669 if( !ISVALID_DSET(dset) ) EXRETURN ;
670 blk = dset->dblk ;
671 if( !ISVALID_DATABLOCK(blk) || blk->natr <= 0 ) EXRETURN ;
672
673 for( ia=0 ; ia < blk->natr ; ia++ ){
674 char *aname ;
675 ATR_any *next_atr = &(blk->atr[ia]) ; /* pointer to this atr */
676
677 switch( next_atr->type ){
678
679 default: aname = NULL ; break ;
680
681 case ATR_FLOAT_TYPE:{
682 ATR_float *aa = (ATR_float *) next_atr ;
683 aname = aa->name ;
684 }
685 break ;
686
687 case ATR_STRING_TYPE:{
688 ATR_string *aa = (ATR_string *) next_atr ;
689 aname = aa->name ;
690 }
691 break ;
692
693 case ATR_INT_TYPE:{
694 ATR_int *aa = (ATR_int *) next_atr ;
695 aname = aa->name ;
696 }
697 break ;
698 }
699
700 if( aname == NULL || *aname == '\0' ) continue ;
701
702 if( strstr(aname,"NOTE") != NULL || strstr(aname,"_NAME") != NULL )
703 THD_erase_one_atr( blk , aname ) ;
704 }
705
706 THD_set_string_atr( blk , ATRNAME_LABEL1 , "none" ) ;
707 THD_set_string_atr( blk , ATRNAME_LABEL2 , "none" ) ;
708 THD_set_string_atr( blk , ATRNAME_DATANAME , "none" ) ;
709 THD_erase_one_atr ( blk , ATRNAME_BRICK_KEYWORDS ) ;
710 THD_erase_one_atr ( blk , ATRNAME_KEYWORDS ) ;
711
712 EXRETURN ;
713 }
714
715 /*------------------------------------------------------------------*/
716
THD_copy_atr(ATR_any * atr)717 ATR_any * THD_copy_atr( ATR_any *atr ) /* 03 Aug 2005 */
718 {
719 ATR_any *atr_out=NULL ;
720
721 ENTRY("THD_copy_atr") ;
722
723 if( atr == NULL ) RETURN(NULL) ;
724
725 switch( atr->type ){
726
727 case ATR_FLOAT_TYPE:{
728 ATR_float *aa = (ATR_float *)atr , *qq ;
729 qq = (ATR_float *)RwcMalloc(sizeof(ATR_float)) ;
730 qq->type = ATR_FLOAT_TYPE ;
731 qq->name = RwcNewString( aa->name ) ;
732 qq->nfl = aa->nfl ;
733 qq->fl = (float *) RwcMalloc( sizeof(float) * aa->nfl ) ;
734 memcpy( qq->fl , aa->fl , sizeof(float) * aa->nfl ) ;
735 atr_out = (ATR_any *)qq ;
736 }
737 break ;
738
739 case ATR_STRING_TYPE:{
740 ATR_string *aa = (ATR_string *)atr , *qq ;
741 qq = (ATR_string *)RwcMalloc(sizeof(ATR_string)) ;
742 qq->type = ATR_STRING_TYPE ;
743 qq->name = RwcNewString( aa->name ) ;
744 qq->nch = aa->nch ;
745 qq->ch = (char *) RwcMalloc( sizeof(char) * aa->nch ) ;
746 memcpy( qq->ch , aa->ch , sizeof(char) * aa->nch ) ;
747 atr_out = (ATR_any *)qq ;
748 }
749 break ;
750
751 case ATR_INT_TYPE:{
752 ATR_int *aa = (ATR_int *)atr , *qq ;
753 qq = (ATR_int *)RwcMalloc(sizeof(ATR_int)) ;
754 qq->type = ATR_INT_TYPE ;
755 qq->name = RwcNewString( aa->name ) ;
756 qq->nin = aa->nin ;
757 qq->in = (int *) RwcMalloc( sizeof(int) * aa->nin ) ;
758 memcpy( qq->in , aa->in , sizeof(int) * aa->nin ) ;
759 atr_out = (ATR_any *)qq ;
760 }
761 break ;
762 }
763
764 RETURN(atr_out) ;
765 }
766
767 /*------------------------------------------------------------------*/
768
THD_insert_atr(THD_datablock * blk,ATR_any * atr)769 void THD_insert_atr( THD_datablock *blk , ATR_any *atr ) /* 03 Aug 2005 */
770 {
771 ENTRY("THD_insert_atr") ;
772
773 if( ! ISVALID_DATABLOCK(blk) || atr == NULL ) EXRETURN ;
774
775 switch( atr->type ){
776
777 case ATR_FLOAT_TYPE:{
778 ATR_float *aa = (ATR_float *)atr ;
779 THD_set_atr( blk , aa->name , ATR_FLOAT_TYPE , aa->nfl , aa->fl ) ;
780 }
781 break ;
782
783 case ATR_STRING_TYPE:{
784 ATR_string *aa = (ATR_string *)atr ;
785 THD_set_atr( blk , aa->name , ATR_STRING_TYPE , aa->nch , aa->ch ) ;
786 }
787 break ;
788
789 case ATR_INT_TYPE:{
790 ATR_int *aa = (ATR_int *)atr ;
791 THD_set_atr( blk , aa->name , ATR_INT_TYPE , aa->nin , aa->in ) ;
792 }
793 break ;
794 }
795
796 EXRETURN ;
797 }
798
799 /*------------------------------------------------------------------*/
800
THD_copy_labeltable_atr(THD_datablock * d1,THD_datablock * d2)801 int THD_copy_labeltable_atr( THD_datablock *d1, THD_datablock *d2)
802 {
803 ATR_any *atr=NULL;
804
805 ENTRY("THD_copy_labeltable_atr") ;
806
807 if (!d1 || !d2 || !ISVALID_DATABLOCK(d1) || !ISVALID_DATABLOCK(d2)) RETURN(0);
808 if ((atr = THD_find_atr(d2, "VALUE_LABEL_DTABLE"))) {
809 THD_insert_atr( d1 , THD_copy_atr( atr ) ) ;
810 }
811 if ((atr = THD_find_atr(d2, "ATLAS_LABEL_TABLE"))) {
812 THD_insert_atr( d1 , THD_copy_atr( atr ) ) ;
813 }
814 RETURN(1);
815 }
816