00001
00002
00003
00004
00005
00006
00007 #include "mrilib.h"
00008 #include "thd.h"
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 void THD_read_all_atr( char *headername , THD_datablock *blk )
00025 {
00026 ATR_any *next_atr ;
00027 int code , ii ;
00028 FILE *header_file ;
00029
00030 ENTRY("THD_read_all_atr") ;
00031
00032 if( ! ISVALID_DATABLOCK(blk) )
00033 THD_FATAL_ERROR( "Illegal datablock type in THD_read_all_atr" ) ;
00034
00035 blk->natr = 0 ;
00036 blk->natr_alloc = 0 ;
00037 blk->atr = NULL ;
00038
00039
00040
00041 if( STRING_HAS_SUFFIX(headername,".mnc") ) EXRETURN ;
00042 if( STRING_HAS_SUFFIX(headername,".nii") ) EXRETURN ;
00043 if( STRING_HAS_SUFFIX(headername,".nii.gz") ) EXRETURN ;
00044 if( STRING_HAS_SUFFIX(headername,".mri") ) EXRETURN ;
00045 if( STRING_HAS_SUFFIX(headername,".ctf") ) EXRETURN ;
00046 if( STRING_HAS_SUFFIX(headername,".hdr") ) EXRETURN ;
00047 if( STRING_HAS_SUFFIX(headername,".mpg") ) EXRETURN ;
00048
00049
00050
00051 header_file = fopen( headername , "r" ) ;
00052 if( header_file == NULL ) EXRETURN ;
00053
00054
00055
00056 { char buf[1024] , *cpt ; int nbuf ;
00057 nbuf = fread( buf , 1 , 1023 , header_file ) ;
00058 if( nbuf > 0 ){
00059 buf[nbuf] = '\0' ;
00060 cpt = strstr( buf , "<AFNI_" ) ;
00061 if( cpt != NULL ){
00062 fclose( header_file ) ;
00063 THD_read_niml_atr( headername , blk ) ;
00064 EXRETURN ;
00065 }
00066 }
00067 rewind( header_file ) ;
00068 }
00069
00070
00071
00072 do{
00073 char aname[THD_MAX_NAME] , atypestr[THD_MAX_NAME] ;
00074 int atype , acount ;
00075
00076 atypestr[0] = aname[0] = '\0' ; acount = 0 ;
00077
00078 code = fscanf( header_file ,
00079 " type = %s name = %s count = %d" ,
00080 atypestr , aname , &acount ) ;
00081
00082 code = (code != 3 || acount < 1) ? FAIL : SUCCESS ;
00083 if( code == FAIL ) break ;
00084
00085 for( atype=FIRST_ATR_TYPE ; atype <= LAST_ATR_TYPE ; atype++ )
00086 if( strcmp(atypestr,ATR_typestr[atype]) == 0 ) break ;
00087
00088 if( atype > LAST_ATR_TYPE ){
00089 code = FAIL ;
00090 break ;
00091 }
00092
00093 if( blk->natr == blk->natr_alloc ){
00094 blk->natr_alloc += ATR_ALLINC ;
00095 blk->atr = (ATR_any *)
00096 XtRealloc( (char *)blk->atr,
00097 sizeof(ATR_any) * blk->natr_alloc );
00098 }
00099 next_atr = &(blk->atr[blk->natr]) ;
00100 (blk->natr)++ ;
00101
00102 switch( atype ){
00103
00104 case ATR_FLOAT_TYPE:{
00105 ATR_float *new_atr = (ATR_float *) next_atr ;
00106 char bbb[256] ;
00107
00108 new_atr->type = ATR_FLOAT_TYPE ;
00109 new_atr->name = XtNewString( aname ) ;
00110 new_atr->nfl = acount ;
00111 new_atr->fl = (float *) XtMalloc( sizeof(float) * acount ) ;
00112
00113 code = 0 ;
00114 for( ii=0 ; ii < acount ; ii++ ){
00115 #if 0
00116 code += fscanf( header_file , "%f" , &(new_atr->fl[ii]) ) ;
00117 #else
00118 bbb[0] = '\0' ; fscanf( header_file , "%255s" , bbb ) ;
00119 if( bbb[0] != '\0' ){
00120 new_atr->fl[ii] = strtod( bbb , NULL ) ;
00121 code++ ;
00122 }
00123 #endif
00124 }
00125 code = (code != acount) ? FAIL : SUCCESS ;
00126
00127 ADDTO_KILL( blk->kl , new_atr->name ) ;
00128 ADDTO_KILL( blk->kl , new_atr->fl ) ;
00129 }
00130 break ;
00131
00132 case ATR_INT_TYPE:{
00133 ATR_int *new_atr = (ATR_int *) next_atr ;
00134
00135 new_atr->type = ATR_INT_TYPE ;
00136 new_atr->name = XtNewString( aname ) ;
00137 new_atr->nin = acount ;
00138 new_atr->in = (int *) XtMalloc( sizeof(int) * acount ) ;
00139
00140 code = 0 ;
00141 for( ii=0 ; ii < acount ; ii++ ){
00142 code += fscanf( header_file , "%d" , &(new_atr->in[ii]) ) ;
00143 }
00144 code = (code != acount) ? FAIL : SUCCESS ;
00145
00146 ADDTO_KILL( blk->kl , new_atr->name ) ;
00147 ADDTO_KILL( blk->kl , new_atr->in ) ;
00148 }
00149 break ;
00150
00151 case ATR_STRING_TYPE:{
00152 ATR_string *new_atr = (ATR_string *) next_atr ;
00153
00154 new_atr->type = ATR_STRING_TYPE ;
00155 new_atr->name = XtNewString( aname ) ;
00156 new_atr->nch = acount ;
00157 new_atr->ch = (char *) XtMalloc( sizeof(char) * acount ) ;
00158
00159 fscanf( header_file , " '" ) ;
00160
00161 code = 0 ;
00162 for( ii=0 ; ii < acount ; ii++ ){
00163 code += fscanf( header_file , "%c" , &(new_atr->ch[ii]) ) ;
00164 }
00165 code = (code != acount) ? FAIL : SUCCESS ;
00166
00167 THD_unzblock( acount , new_atr->ch ) ;
00168
00169 ADDTO_KILL( blk->kl , new_atr->name ) ;
00170 ADDTO_KILL( blk->kl , new_atr->ch ) ;
00171 }
00172 break ;
00173 }
00174
00175 if( code == FAIL ) break ;
00176 } while(1) ;
00177
00178 fclose( header_file ) ; EXRETURN ;
00179 }
00180
00181
00182
00183
00184
00185 void THD_read_niml_atr( char *headername , THD_datablock *blk )
00186 {
00187 NI_stream ns ;
00188 void *nini ;
00189 NI_group *ngr ;
00190 char sname[2048] ;
00191 long fsize ;
00192
00193 ENTRY("THD_read_niml_atr") ;
00194
00195
00196
00197 if( headername == NULL || *headername == '\0' || blk == NULL ) EXRETURN ;
00198 fsize = NI_filesize(headername) ; if( fsize <= 10 ) EXRETURN ;
00199 sprintf(sname,"file:%s",headername) ; STATUS(sname) ;
00200 ns = NI_stream_open( sname , "r" ) ;
00201 if( ns == (NI_stream)NULL ) EXRETURN ;
00202 if( fsize > NI_BUFSIZE ){
00203 fsize = MIN( 4*NI_BUFSIZE , fsize ) ;
00204 NI_stream_setbufsize( ns , fsize ) ;
00205 }
00206
00207
00208
00209 while(1){
00210 nini = NI_read_element( ns , 9 ) ;
00211 if( nini == NULL ){ NI_stream_close(ns); EXRETURN; }
00212 if( NI_element_type(nini) == NI_GROUP_TYPE ) break ;
00213 NI_free_element(nini) ;
00214 }
00215 NI_stream_close( ns ) ;
00216 ngr = (NI_group *)nini ;
00217 if( strncmp(ngr->name,"AFNI_",5) != 0 ){ NI_free_element(ngr); EXRETURN; }
00218
00219
00220
00221 THD_dblkatr_from_niml( ngr , blk ) ;
00222 NI_free_element( ngr ) ;
00223 EXRETURN ;
00224 }
00225
00226
00227
00228
00229
00230 void THD_erase_all_atr( THD_datablock *blk )
00231 {
00232 int ia ;
00233 ATR_any *next_atr ;
00234
00235 if( !ISVALID_DATABLOCK(blk) || blk->natr == 0 || blk->atr == NULL ) return ;
00236
00237 for( ia=0 ; ia < blk->natr ; ia++ ){
00238 next_atr = blk->atr + ia ;
00239
00240 switch( next_atr->type ){
00241 case ATR_FLOAT_TYPE:{
00242 ATR_float *aa = (ATR_float *) next_atr ;
00243 SINGLE_KILL( blk->kl , aa->name ) ;
00244 SINGLE_KILL( blk->kl , aa->fl ) ;
00245 }
00246 break ;
00247
00248 case ATR_STRING_TYPE:{
00249 ATR_string *aa = (ATR_string *) next_atr ;
00250 SINGLE_KILL( blk->kl , aa->name ) ;
00251 SINGLE_KILL( blk->kl , aa->ch ) ;
00252 }
00253 break ;
00254
00255 case ATR_INT_TYPE:{
00256 ATR_int *aa = (ATR_int *) next_atr ;
00257 SINGLE_KILL( blk->kl , aa->name ) ;
00258 SINGLE_KILL( blk->kl , aa->in ) ;
00259 }
00260 break ;
00261 }
00262
00263 next_atr->type = ILLEGAL_TYPE ;
00264 }
00265
00266 blk->natr = 0 ;
00267 return ;
00268 }
00269
00270
00271
00272
00273
00274 void THD_erase_one_atr( THD_datablock *blk , char *name )
00275 {
00276 ATR_any *next_atr ;
00277
00278 if( ! ISVALID_DATABLOCK(blk) || name == NULL ||
00279 blk->natr == 0 || blk->atr == NULL ) return ;
00280
00281 next_atr = THD_find_atr( blk , name ) ;
00282
00283 if( next_atr == NULL ) return ;
00284
00285 switch( next_atr->type ){
00286 case ATR_FLOAT_TYPE:{
00287 ATR_float *aa = (ATR_float *) next_atr ;
00288 SINGLE_KILL( blk->kl , aa->name ) ;
00289 SINGLE_KILL( blk->kl , aa->fl ) ;
00290 }
00291 break ;
00292
00293 case ATR_STRING_TYPE:{
00294 ATR_string *aa = (ATR_string *) next_atr ;
00295 SINGLE_KILL( blk->kl , aa->name ) ;
00296 SINGLE_KILL( blk->kl , aa->ch ) ;
00297 }
00298 break ;
00299
00300 case ATR_INT_TYPE:{
00301 ATR_int *aa = (ATR_int *) next_atr ;
00302 SINGLE_KILL( blk->kl , aa->name ) ;
00303 SINGLE_KILL( blk->kl , aa->in ) ;
00304 }
00305 break ;
00306 }
00307
00308 next_atr->type = ILLEGAL_TYPE ;
00309 return ;
00310 }
00311
00312
00313
00314
00315
00316
00317 ATR_any * THD_find_atr( THD_datablock *blk , char *name )
00318 {
00319 int ia ;
00320
00321 ENTRY("THD_find_atr") ;
00322
00323 if( ! ISVALID_DATABLOCK(blk) )
00324 THD_FATAL_ERROR( "Illegal block type in THD_find_atr" ) ;
00325
00326 if( blk->natr == 0 || blk->atr == NULL ) RETURN(NULL) ;
00327
00328
00329
00330 for( ia=0 ; ia < blk->natr ; ia++ ){
00331 char *aname ;
00332 ATR_any *next_atr = &(blk->atr[ia]) ;
00333
00334
00335
00336 switch( next_atr->type ){
00337
00338 default: aname = NULL ; break ;
00339
00340 case ATR_FLOAT_TYPE:{
00341 ATR_float *aa = (ATR_float *) next_atr ;
00342 aname = aa->name ;
00343 }
00344 break ;
00345
00346 case ATR_STRING_TYPE:{
00347 ATR_string *aa = (ATR_string *) next_atr ;
00348 aname = aa->name ;
00349 }
00350 break ;
00351
00352 case ATR_INT_TYPE:{
00353 ATR_int *aa = (ATR_int *) next_atr ;
00354 aname = aa->name ;
00355 }
00356 break ;
00357 }
00358
00359
00360
00361 if( aname != NULL && strcmp(aname,name) == 0 ) RETURN(next_atr) ;
00362
00363 }
00364
00365 RETURN(NULL) ;
00366 }
00367
00368
00369
00370 ATR_float * THD_find_float_atr( THD_datablock *blk , char *name )
00371 {
00372 ATR_any *aa ;
00373 aa = THD_find_atr( blk , name ) ;
00374
00375 if( aa == NULL || aa->type != ATR_FLOAT_TYPE ) return NULL ;
00376 else return (ATR_float *) aa ;
00377 }
00378
00379
00380
00381 ATR_int * THD_find_int_atr( THD_datablock *blk , char *name )
00382 {
00383 ATR_any *aa ;
00384 aa = THD_find_atr( blk , name ) ;
00385
00386 if( aa == NULL || aa->type != ATR_INT_TYPE ) return NULL ;
00387 else return (ATR_int *) aa ;
00388 }
00389
00390
00391
00392 ATR_string * THD_find_string_atr( THD_datablock *blk , char *name )
00393 {
00394 ATR_any *aa ;
00395 aa = THD_find_atr( blk , name ) ;
00396
00397 if( aa == NULL || aa->type != ATR_STRING_TYPE ) return NULL ;
00398 else return (ATR_string *)aa;
00399 }
00400
00401
00402
00403
00404
00405
00406 void THD_set_atr( THD_datablock *blk , char *aname ,
00407 int atype , int acount , void *ar )
00408 {
00409 ATR_any *old_atr , *atr ;
00410
00411 ENTRY("THD_set_atr") ;
00412
00413 if( ! ISVALID_DATABLOCK(blk) )
00414 THD_FATAL_ERROR( "Illegal block type in THD_set_atr" ) ;
00415
00416 if( acount < 0 || ar == NULL || aname == NULL )
00417 THD_FATAL_ERROR( "Illegal input data in THD_set_atr" ) ;
00418
00419 old_atr = THD_find_atr( blk , aname ) ;
00420
00421 if( old_atr != NULL ){
00422
00423 atr = old_atr ;
00424
00425 switch( old_atr->type ){
00426
00427 default: break ;
00428
00429 case ATR_FLOAT_TYPE:{
00430 ATR_float *aa = (ATR_float *) old_atr ;
00431
00432 SINGLE_KILL( blk->kl , aa->name ) ;
00433 SINGLE_KILL( blk->kl , aa->fl ) ;
00434 }
00435 break ;
00436
00437 case ATR_INT_TYPE:{
00438 ATR_int *aa = (ATR_int *) old_atr ;
00439
00440 SINGLE_KILL( blk->kl , aa->name ) ;
00441 SINGLE_KILL( blk->kl , aa->in ) ;
00442 }
00443 break ;
00444
00445 case ATR_STRING_TYPE:{
00446 ATR_string *aa = (ATR_string *) old_atr ;
00447
00448 SINGLE_KILL( blk->kl , aa->name ) ;
00449 SINGLE_KILL( blk->kl , aa->ch ) ;
00450 }
00451 break ;
00452 }
00453
00454 } else {
00455
00456 int ia ;
00457
00458 for( ia=0 ; ia < blk->natr ; ia++ )
00459 if( blk->atr[ia].type < 0 ) break ;
00460
00461 if( ia == blk->natr_alloc ){
00462 blk->natr_alloc += ATR_ALLINC ;
00463 blk->atr = (ATR_any *)
00464 XtRealloc( (char *)blk->atr,
00465 sizeof(ATR_any) * blk->natr_alloc );
00466 }
00467 atr = &(blk->atr[ia]) ;
00468 if( ia == blk->natr ) (blk->natr)++ ;
00469 }
00470
00471
00472
00473
00474 switch( atype ){
00475
00476 case ATR_FLOAT_TYPE:{
00477 ATR_float *new_atr = (ATR_float *) atr ;
00478
00479 new_atr->type = ATR_FLOAT_TYPE ;
00480 new_atr->name = XtNewString( aname ) ;
00481 new_atr->nfl = acount ;
00482 new_atr->fl = (float *) XtMalloc( sizeof(float) * acount ) ;
00483 memcpy( new_atr->fl , ar , sizeof(float)*acount ) ;
00484
00485 ADDTO_KILL( blk->kl , new_atr->name ) ;
00486 ADDTO_KILL( blk->kl , new_atr->fl ) ;
00487 }
00488 break ;
00489
00490 case ATR_INT_TYPE:{
00491 ATR_int *new_atr = (ATR_int *) atr ;
00492
00493 new_atr->type = ATR_INT_TYPE ;
00494 new_atr->name = XtNewString( aname ) ;
00495 new_atr->nin = acount ;
00496 new_atr->in = (int *) XtMalloc( sizeof(int) * acount ) ;
00497 memcpy( new_atr->in , ar , sizeof(int)*acount ) ;
00498
00499 ADDTO_KILL( blk->kl , new_atr->name ) ;
00500 ADDTO_KILL( blk->kl , new_atr->in ) ;
00501
00502 #if 0
00503 if(PRINT_TRACING){
00504 char str[256] ; int ii ;
00505 sprintf(str,"INT atr: name=%s nin=%d vals::",new_atr->name,new_atr->nin) ;
00506 STATUS(str) ;
00507 for( ii=0 ; ii < acount ; ii++ ) printf(" %d",new_atr->in[ii]) ;
00508 printf("\n") ;
00509 }
00510 #endif
00511 }
00512 break ;
00513
00514 case ATR_STRING_TYPE:{
00515 ATR_string *new_atr = (ATR_string *) atr ;
00516
00517 new_atr->type = ATR_STRING_TYPE ;
00518 new_atr->name = XtNewString( aname ) ;
00519 new_atr->nch = acount ;
00520 new_atr->ch = (char *) XtMalloc( sizeof(char) * acount ) ;
00521 memcpy( new_atr->ch , ar , sizeof(char)*acount ) ;
00522 new_atr->ch[acount-1] = '\0' ;
00523
00524 ADDTO_KILL( blk->kl , new_atr->name ) ;
00525 ADDTO_KILL( blk->kl , new_atr->ch ) ;
00526 }
00527 break ;
00528 }
00529
00530 EXRETURN ;
00531 }
00532
00533
00534
00535 void THD_set_float_atr( THD_datablock *blk ,
00536 char *name , int n , float *fl )
00537 {
00538 THD_set_atr( blk , name , ATR_FLOAT_TYPE , n , fl ) ;
00539 }
00540
00541
00542
00543 void THD_set_int_atr( THD_datablock *blk ,
00544 char *name , int n , int *in )
00545 {
00546 THD_set_atr( blk , name , ATR_INT_TYPE , n , in ) ;
00547 }
00548
00549
00550
00551 void THD_set_char_atr( THD_datablock *blk ,
00552 char *name , int n , char *str )
00553 {
00554 THD_set_atr( blk , name , ATR_STRING_TYPE , n , str ) ;
00555 }
00556
00557
00558
00559
00560
00561
00562
00563 void THD_anonymize_dset( THD_3dim_dataset *dset )
00564 {
00565 THD_datablock *blk ;
00566 int ia ;
00567
00568 ENTRY("THD_anonymize_dset") ;
00569
00570 if( !ISVALID_DSET(dset) ) EXRETURN ;
00571 blk = dset->dblk ;
00572 if( !ISVALID_DATABLOCK(blk) || blk->natr <= 0 ) EXRETURN ;
00573
00574 for( ia=0 ; ia < blk->natr ; ia++ ){
00575 char *aname ;
00576 ATR_any *next_atr = &(blk->atr[ia]) ;
00577
00578 switch( next_atr->type ){
00579
00580 default: aname = NULL ; break ;
00581
00582 case ATR_FLOAT_TYPE:{
00583 ATR_float *aa = (ATR_float *) next_atr ;
00584 aname = aa->name ;
00585 }
00586 break ;
00587
00588 case ATR_STRING_TYPE:{
00589 ATR_string *aa = (ATR_string *) next_atr ;
00590 aname = aa->name ;
00591 }
00592 break ;
00593
00594 case ATR_INT_TYPE:{
00595 ATR_int *aa = (ATR_int *) next_atr ;
00596 aname = aa->name ;
00597 }
00598 break ;
00599 }
00600
00601 if( aname == NULL || *aname == '\0' ) continue ;
00602
00603 if( strstr(aname,"NOTE") != NULL || strstr(aname,"_NAME") != NULL )
00604 THD_erase_one_atr( blk , aname ) ;
00605 }
00606
00607 THD_set_string_atr( blk , ATRNAME_LABEL1 , "none" ) ;
00608 THD_set_string_atr( blk , ATRNAME_LABEL2 , "none" ) ;
00609 THD_set_string_atr( blk , ATRNAME_DATANAME , "none" ) ;
00610 THD_erase_one_atr ( blk , ATRNAME_BRICK_KEYWORDS ) ;
00611 THD_erase_one_atr ( blk , ATRNAME_KEYWORDS ) ;
00612
00613 EXRETURN ;
00614 }
00615
00616
00617
00618 ATR_any * THD_copy_atr( ATR_any *atr )
00619 {
00620 ATR_any *atr_out=NULL ;
00621
00622 ENTRY("THD_copy_atr") ;
00623
00624 if( atr == NULL ) RETURN(NULL) ;
00625
00626 switch( atr->type ){
00627
00628 case ATR_FLOAT_TYPE:{
00629 ATR_float *aa = (ATR_float *)atr , *qq ;
00630 qq = (ATR_float *)XtMalloc(sizeof(ATR_float)) ;
00631 qq->type = ATR_FLOAT_TYPE ;
00632 qq->name = XtNewString( aa->name ) ;
00633 qq->nfl = aa->nfl ;
00634 qq->fl = (float *) XtMalloc( sizeof(float) * aa->nfl ) ;
00635 memcpy( qq->fl , aa->fl , sizeof(float) * aa->nfl ) ;
00636 atr_out = (ATR_any *)qq ;
00637 }
00638 break ;
00639
00640 case ATR_STRING_TYPE:{
00641 ATR_string *aa = (ATR_string *)atr , *qq ;
00642 qq = (ATR_string *)XtMalloc(sizeof(ATR_string)) ;
00643 qq->type = ATR_STRING_TYPE ;
00644 qq->name = XtNewString( aa->name ) ;
00645 qq->nch = aa->nch ;
00646 qq->ch = (char *) XtMalloc( sizeof(char) * aa->nch ) ;
00647 memcpy( qq->ch , aa->ch , sizeof(char) * aa->nch ) ;
00648 atr_out = (ATR_any *)qq ;
00649 }
00650 break ;
00651
00652 case ATR_INT_TYPE:{
00653 ATR_int *aa = (ATR_int *)atr , *qq ;
00654 qq = (ATR_int *)XtMalloc(sizeof(ATR_int)) ;
00655 qq->type = ATR_INT_TYPE ;
00656 qq->name = XtNewString( aa->name ) ;
00657 qq->nin = aa->nin ;
00658 qq->in = (int *) XtMalloc( sizeof(int) * aa->nin ) ;
00659 memcpy( qq->in , aa->in , sizeof(int) * aa->nin ) ;
00660 atr_out = (ATR_any *)qq ;
00661 }
00662 break ;
00663 }
00664
00665 RETURN(atr_out) ;
00666 }
00667
00668
00669
00670 void THD_insert_atr( THD_datablock *blk , ATR_any *atr )
00671 {
00672 ENTRY("THD_insert_atr") ;
00673
00674 if( ! ISVALID_DATABLOCK(blk) || atr == NULL ) EXRETURN ;
00675
00676 switch( atr->type ){
00677
00678 case ATR_FLOAT_TYPE:{
00679 ATR_float *aa = (ATR_float *)atr ;
00680 THD_set_atr( blk , aa->name , ATR_FLOAT_TYPE , aa->nfl , aa->fl ) ;
00681 }
00682 break ;
00683
00684 case ATR_STRING_TYPE:{
00685 ATR_string *aa = (ATR_string *)atr ;
00686 THD_set_atr( blk , aa->name , ATR_STRING_TYPE , aa->nch , aa->ch ) ;
00687 }
00688 break ;
00689
00690 case ATR_INT_TYPE:{
00691 ATR_int *aa = (ATR_int *)atr ;
00692 THD_set_atr( blk , aa->name , ATR_INT_TYPE , aa->nin , aa->in ) ;
00693 }
00694 break ;
00695 }
00696
00697 EXRETURN ;
00698 }