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 }