00001 #include "mrilib.h"
00002 
00003 #ifndef DONT_INCLUDE_ANALYZE_STRUCT
00004 #define DONT_INCLUDE_ANALYZE_STRUCT
00005 #endif
00006 #include "nifti1_io.h"   
00007 
00008 
00009 
00010 
00011 
00012 THD_3dim_dataset * THD_open_nifti( char *pathname )
00013 {
00014    THD_3dim_dataset *dset=NULL ;
00015    nifti_image *nim ;
00016    int ntt , nbuc , nvals ;
00017    int use_qform = 0 , use_sform = 0 ;
00018    int statcode = 0 , datum , iview , ibr ;
00019    THD_ivec3 orixyz , nxyz ;
00020    THD_fvec3 dxyz , orgxyz ;
00021    THD_mat33 R ;
00022    char *ppp , prefix[THD_MAX_PREFIX] ;
00023 
00024 ENTRY("THD_open_nifti") ;
00025 
00026    
00027 
00028    { 
00029       char * ept = my_getenv("AFNI_NIFTI_DEBUG");
00030       if( ept != NULL ) nifti_set_debug_level(atoi(ept));
00031    }
00032 
00033    nim = nifti_image_read( pathname, 0 ) ;
00034 
00035    if( nim == NULL || nim->nifti_type == 0 ) RETURN(NULL) ;
00036 
00037    
00038 
00039    
00040 
00041    if( nim->nx < 2 || nim->ny < 2 ) RETURN(NULL) ;
00042 
00043    
00044 
00045 
00046    ntt = nim->nt ; nbuc = nim->nu ;
00047    if( ntt > 1 && nbuc > 1 ){
00048      fprintf(stderr,
00049              "** AFNI can't deal with 5 dimensional NIfTI dataset file %s\n",
00050              pathname ) ;
00051      RETURN(NULL) ;
00052    }
00053    nvals = MAX(ntt,nbuc) ;
00054 
00055    
00056 
00057 
00058 
00059    switch( nim->datatype ){
00060      default:
00061        fprintf(stderr,
00062                "** AFNI can't handle NIFTI datatype=%d (%s) in file %s\n",
00063                nim->datatype, nifti_datatype_string(nim->datatype), pathname );
00064        RETURN(NULL) ;
00065      break ;
00066 
00067      case DT_UINT8:     datum = (nim->scl_slope != 0.0) ? MRI_float : MRI_byte  ; break ;
00068      case DT_INT16:     datum = (nim->scl_slope != 0.0) ? MRI_float : MRI_short ; break ;
00069 
00070      case DT_FLOAT32:   datum = MRI_float   ; break ;
00071      case DT_COMPLEX64: datum = MRI_complex ; break ;
00072      case DT_RGB24:     datum = MRI_rgb     ; break ;
00073 
00074      case DT_INT8:      
00075      case DT_UINT16:
00076      case DT_INT32:
00077      case DT_UINT32:
00078      case DT_FLOAT64:
00079        fprintf(stderr,
00080               "** AFNI converts NIFTI_datatype=%d (%s) in file %s to FLOAT32\n",
00081               nim->datatype, nifti_datatype_string(nim->datatype), pathname );
00082        datum = MRI_float ;
00083      break ;
00084 
00085 #if 0
00086      case DT_COMPLEX128:  
00087        fprintf(stderr,
00088                "** AFNI convert NIFTI_datatype=%d (%s) in file %s to COMPLEX64\n",
00089                nim->datatype, nifti_datatype_string(nim->datatype), pathname );
00090        datum = MRI_complex ;
00091      break ;
00092 #endif
00093    }
00094 
00095    
00096 
00097    if( nim->intent_code >= NIFTI_FIRST_STATCODE &&
00098        nim->intent_code <= NIFTI_LAST_STATCODE    ){
00099 
00100      if( nim->intent_code > FUNC_PT_TYPE ){
00101        fprintf(stderr,
00102                "** AFNI doesn't understand NIFTI statistic type %d (%s) in file %s\n",
00103                nim->intent_code , nifti_intent_string(nim->intent_code) , pathname ) ;
00104      } else {
00105        statcode = nim->intent_code ;
00106        if( nbuc > 1 ){
00107          fprintf(stderr,
00108                  "** AFNI doesn't support NIFTI voxel-dependent statistic parameters"
00109                  " in file %s\n" , pathname ) ;
00110          statcode = 0 ;
00111        }
00112      }
00113    }
00114 
00115 
00116   
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129    if ((nim->qform_code > 0) && (nim->sform_code > 0) ) {
00130      use_qform = 1 ;
00131      use_sform = 0 ;
00132    } else if (nim->qform_code > 0) {
00133      use_qform = 1 ;
00134      use_sform = 0 ;
00135    } else if (nim->sform_code > 0) { 
00136      use_qform = 0 ;
00137      use_sform = 1 ;
00138    } else {
00139      use_qform = 0 ;
00140      use_sform = 0 ;
00141      fprintf(stderr,
00142              "** NO spatial transform (neither preferred qform nor sform), in NIfTI dataset file:\n %s\nUsing senseless defaults.\n",
00143              pathname ) ;
00144    }
00145 
00146 
00147    if (use_qform) {
00148 
00149      float orgx, orgy, orgz ;
00150 
00151      
00152 
00153 
00154      LOAD_MAT(R, -nim->qto_xyz.m[0][0] ,  
00155                  -nim->qto_xyz.m[0][1] ,  
00156                  -nim->qto_xyz.m[0][2] ,  
00157                  -nim->qto_xyz.m[1][0] ,  
00158                  -nim->qto_xyz.m[1][1] ,  
00159                  -nim->qto_xyz.m[1][2] ,  
00160                   nim->qto_xyz.m[2][0] ,  
00161                   nim->qto_xyz.m[2][1] ,  
00162                   nim->qto_xyz.m[2][2]  ) ;
00163 
00164      orixyz = THD_matrix_to_orientation( R ) ;   
00165    
00166      iview = ((nim->qform_code == NIFTI_XFORM_TALAIRACH ) ||
00167               (nim->qform_code == NIFTI_XFORM_MNI_152 ))
00168              ? VIEW_TALAIRACH_TYPE : VIEW_ORIGINAL_TYPE ;
00169 
00170 
00171      
00172 
00173      if (ORIENT_xyz[orixyz.ijk[0]] == 'z' )  {
00174        orgx = nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
00175      } else {
00176        orgx = - nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
00177      }
00178 
00179      if (ORIENT_xyz[orixyz.ijk[1]] == 'z' )  {
00180        orgy = nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
00181      } else {
00182        orgy = - nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
00183      }
00184 
00185      if (ORIENT_xyz[orixyz.ijk[2]] == 'z' )  {
00186        orgz = nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
00187      } else {
00188        orgz = - nim->qto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
00189      }
00190 
00191 
00192      LOAD_FVEC3( orgxyz ,  orgx ,
00193                            orgy ,
00194                            orgz  ) ;
00195 #if 0
00196      LOAD_FVEC3( orgxyz , -nim->qto_xyz.m[0][3] ,    
00197                         -nim->qto_xyz.m[1][3] ,    
00198                          nim->qto_xyz.m[2][3]  ) ;
00199 #endif
00200 
00201      
00202 
00203      if( nim->xyz_units == NIFTI_UNITS_METER ){
00204        nim->dx *= 1000.0 ; nim->dy *= 1000.0 ; nim->dz *= 1000.0 ;
00205      } else if(  nim->xyz_units == NIFTI_UNITS_MICRON ){
00206        nim->dx *= 0.001  ; nim->dy *= 0.001  ; nim->dz *= 0.001  ;
00207      }
00208 
00209      LOAD_FVEC3( dxyz , (ORIENT_sign[orixyz.ijk[0]]=='+') ? nim->dx : -nim->dx ,
00210                         (ORIENT_sign[orixyz.ijk[1]]=='+') ? nim->dy : -nim->dy ,
00211                         (ORIENT_sign[orixyz.ijk[2]]=='+') ? nim->dz : -nim->dz  ) ;
00212 
00213    } else if (use_sform) {
00214 
00215      int orimap[7] = { 6 , 1 , 0 , 2 , 3 , 4 , 5 } ;
00216      int oritmp[3] ;
00217      float dxtmp, dytmp, dztmp ;
00218      float xmax, ymax, zmax ;
00219      float orgx, orgy, orgz ;
00220      float fig_merit, ang_merit ;
00221 
00222      
00223 
00224      nifti_mat44_to_orientation(nim->sto_xyz, &oritmp[0], &oritmp[1], &oritmp[2] ) ;
00225 
00226      
00227 
00228      LOAD_IVEC3( orixyz , orimap[oritmp[0]] ,
00229                           orimap[oritmp[1]] ,
00230                           orimap[oritmp[2]] ) ;
00231 
00232      
00233 
00234      iview = ((nim->sform_code == NIFTI_XFORM_TALAIRACH ) ||
00235               (nim->sform_code == NIFTI_XFORM_MNI_152 ))
00236              ? VIEW_TALAIRACH_TYPE : VIEW_ORIGINAL_TYPE ;
00237 
00238      
00239 
00240      if (ORIENT_xyz[orixyz.ijk[0]] == 'z' )  {
00241        orgx = nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
00242      } else {
00243        orgx = - nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[0]] - 1][3] ;
00244      }
00245 
00246      if (ORIENT_xyz[orixyz.ijk[1]] == 'z' )  {
00247        orgy = nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
00248      } else {
00249        orgy = - nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[1]] - 1][3] ;
00250      }
00251 
00252      if (ORIENT_xyz[orixyz.ijk[2]] == 'z' )  {
00253        orgz = nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
00254      } else {
00255        orgz = - nim->sto_xyz.m[ORIENT_xyzint[orixyz.ijk[2]] - 1][3] ;
00256      }
00257 
00258 
00259      LOAD_FVEC3( orgxyz ,  orgx ,
00260                            orgy ,
00261                            orgz  ) ;
00262 
00263 #if 0
00264      LOAD_FVEC3( orgxyz , -nim->sto_xyz.m[0][3] ,    
00265                           -nim->sto_xyz.m[1][3] ,    
00266                            nim->sto_xyz.m[2][3] ) ;
00267 #endif
00268 
00269 #define MAXNUM(a,b) ( (a) > (b) ? (a):(b))
00270 #define MAX3(a,b,c) ( (MAXNUM(a,b)) > (MAXNUM(a,c)) ? (MAXNUM(a,b)):(MAXNUM(a,c)))
00271 #define MINNUM(a,b) ( (a) < (b) ? (a):(b))
00272 #define MIN3(a,b,c) ( (MINNUM(a,b)) < (MINNUM(a,c)) ? (MINNUM(a,b)):(MINNUM(a,c)))
00273 
00274      dxtmp = sqrt ( nim->sto_xyz.m[0][0] * nim->sto_xyz.m[0][0] +
00275                     nim->sto_xyz.m[1][0] * nim->sto_xyz.m[1][0] +
00276                     nim->sto_xyz.m[2][0] * nim->sto_xyz.m[2][0] ) ;
00277 
00278      xmax = MAX3(fabs(nim->sto_xyz.m[0][0]),fabs(nim->sto_xyz.m[1][0]),fabs(nim->sto_xyz.m[2][0])) / dxtmp ;
00279  
00280      dytmp = sqrt ( nim->sto_xyz.m[0][1] * nim->sto_xyz.m[0][1] +
00281                     nim->sto_xyz.m[1][1] * nim->sto_xyz.m[1][1] +
00282                     nim->sto_xyz.m[2][1] * nim->sto_xyz.m[2][1] ) ;
00283  
00284      ymax = MAX3(fabs(nim->sto_xyz.m[0][1]),fabs(nim->sto_xyz.m[1][1]),fabs(nim->sto_xyz.m[2][1])) / dytmp ;
00285 
00286      dztmp = sqrt ( nim->sto_xyz.m[0][2] * nim->sto_xyz.m[0][2] +
00287                     nim->sto_xyz.m[1][2] * nim->sto_xyz.m[1][2] +
00288                     nim->sto_xyz.m[2][2] * nim->sto_xyz.m[2][2] ) ;
00289 
00290      zmax = MAX3(fabs(nim->sto_xyz.m[0][2]),fabs(nim->sto_xyz.m[1][2]),fabs(nim->sto_xyz.m[2][2])) / dztmp ;
00291 
00292      fig_merit = MIN3(xmax,ymax,zmax) ;
00293      ang_merit = acos (fig_merit) * 180.0 / 3.141592653 ;
00294 
00295      if (fabs(ang_merit) > .01) {
00296        fprintf(stderr, "qform not present, sform used.\n"
00297                        "sform was not exact, and the worst axis is\n"
00298                        "%f degrees from plumb.\n",ang_merit ) ;
00299      }
00300 
00301      if( nim->xyz_units == NIFTI_UNITS_METER ){
00302        dxtmp *= 1000.0 ; dytmp *= 1000.0 ; dztmp *= 1000.0 ;
00303      } else if(  nim->xyz_units == NIFTI_UNITS_MICRON ){
00304        dxtmp *= 0.001  ; dytmp *= 0.001  ; dztmp *= 0.001  ;
00305      }
00306 
00307      LOAD_FVEC3( dxyz , (ORIENT_sign[orixyz.ijk[0]]=='+') ? dxtmp : -dxtmp ,
00308                         (ORIENT_sign[orixyz.ijk[1]]=='+') ? dytmp : -dytmp ,
00309                         (ORIENT_sign[orixyz.ijk[2]]=='+') ? dztmp : -dztmp ) ;
00310 
00311    } else { 
00312 
00313      float dxtmp, dytmp, dztmp ;
00314 
00315      
00316  
00317 
00318      dxtmp = ((nim->pixdim[1] > 0) ? nim->pixdim[1] : 1) ;
00319      dytmp = ((nim->pixdim[2] > 0) ? nim->pixdim[2] : 1) ;
00320      dztmp = ((nim->pixdim[3] > 0) ? nim->pixdim[3] : 1) ;
00321 
00322      if( nim->xyz_units == NIFTI_UNITS_METER ){
00323        dxtmp *= 1000.0 ; dytmp *= 1000.0 ; dztmp *= 1000.0 ;
00324      } else if(  nim->xyz_units == NIFTI_UNITS_MICRON ){
00325        dxtmp *= 0.001  ; dytmp *= 0.001  ; dztmp *= 0.001  ;
00326      }
00327 
00328      
00329 
00330      LOAD_IVEC3( orixyz , 1 ,
00331                           2 ,
00332                           4 ) ;
00333 
00334      LOAD_FVEC3( dxyz , (ORIENT_sign[orixyz.ijk[0]]=='+') ? dxtmp : -dxtmp ,
00335                         (ORIENT_sign[orixyz.ijk[1]]=='+') ? dytmp : -dytmp ,
00336                         (ORIENT_sign[orixyz.ijk[2]]=='+') ? dztmp : -dztmp ) ;
00337 
00338      iview = VIEW_ORIGINAL_TYPE ;
00339 
00340      
00341 
00342      LOAD_FVEC3( orgxyz , 0 ,
00343                           0 ,
00344                           0 ) ;
00345    }
00346 
00347 
00348    
00349 
00350    dset = EDIT_empty_copy(NULL) ;
00351 
00352    ppp  = THD_trailname(pathname,0) ;               
00353    MCW_strncpy( prefix , ppp , THD_MAX_PREFIX ) ;   
00354 
00355    nxyz.ijk[0] = nim->nx ;                          
00356    nxyz.ijk[1] = nim->ny ;
00357    nxyz.ijk[2] = nim->nz ;
00358 
00359    dset->idcode.str[0] = 'N' ;  
00360    dset->idcode.str[1] = 'I' ;
00361    dset->idcode.str[2] = 'I' ;
00362 
00363    MCW_hash_idcode( pathname , dset ) ;  
00364 
00365    EDIT_dset_items( dset ,
00366                       ADN_prefix      , prefix ,
00367                       ADN_datum_all   , datum ,
00368                       ADN_nxyz        , nxyz ,
00369                       ADN_xyzdel      , dxyz ,
00370                       ADN_xyzorg      , orgxyz ,
00371                       ADN_xyzorient   , orixyz ,
00372                       ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
00373                       ADN_view_type   , iview ,
00374                       ADN_type        , (statcode != 0) ? HEAD_FUNC_TYPE
00375                                                         : HEAD_ANAT_TYPE ,
00376                     ADN_none ) ;
00377 
00378    
00379 
00380    if( ntt < 2 ){
00381      EDIT_dset_items( dset ,
00382                         ADN_nvals     , nbuc ,
00383                         ADN_datum_all , datum ,
00384                         ADN_func_type , (statcode != 0) ? FUNC_BUCK_TYPE
00385                                                         : ANAT_BUCK_TYPE ,
00386                       ADN_none ) ;
00387 
00388    } else {  
00389 
00390           if( nim->time_units == NIFTI_UNITS_MSEC ) nim->dt *= 0.001 ;
00391      else if( nim->time_units == NIFTI_UNITS_USEC ) nim->dt *= 1.e-6 ;
00392      EDIT_dset_items( dset ,
00393                         ADN_nvals     , ntt ,
00394                         ADN_ntt       , ntt ,
00395                         ADN_datum_all , datum ,
00396                         ADN_ttorg     , 0.0 ,
00397                         ADN_ttdel     , nim->dt ,
00398                         ADN_ttdur     , 0.0 ,
00399                         ADN_tunits    , UNITS_SEC_TYPE ,
00400                         ADN_func_type , (statcode != 0) ? FUNC_FIM_TYPE
00401                                                         : ANAT_EPI_TYPE ,
00402                       ADN_none ) ;
00403 
00404      
00405 
00406      if( nim->slice_dim      == 3               && 
00407          nim->slice_code     >  0               && 
00408          nim->slice_duration >  0.0             && 
00409          nim->slice_start    >= 0               && 
00410          nim->slice_start    < nim->nz          &&
00411          nim->slice_end      > nim->slice_start &&
00412          nim->slice_end      < nim->nz             ){
00413 
00414        float *toff=(float *)calloc(sizeof(float),nim->nz) , tsl ;
00415        int kk ;
00416 
00417             if( nim->time_units == NIFTI_UNITS_MSEC ) nim->slice_duration *= 0.001;
00418        else if( nim->time_units == NIFTI_UNITS_USEC ) nim->slice_duration *= 1.e-6;
00419 
00420        
00421 
00422        switch( nim->slice_code ){
00423          case NIFTI_SLICE_SEQ_INC:
00424            tsl = 0.0 ;
00425            for( kk=nim->slice_start ; kk <= nim->slice_end ; kk++ ){
00426              toff[kk] = tsl ; tsl += nim->slice_duration ;
00427            }
00428          break ;
00429          case NIFTI_SLICE_SEQ_DEC:
00430            tsl = 0.0 ;
00431            for( kk=nim->slice_end ; kk >= nim->slice_end ; kk-- ){
00432              toff[kk] = tsl ; tsl += nim->slice_duration ;
00433            }
00434          break ;
00435          case NIFTI_SLICE_ALT_INC:
00436            tsl = 0.0 ;
00437            for( kk=nim->slice_start ; kk <= nim->slice_end ; kk+=2 ){
00438              toff[kk] = tsl ; tsl += nim->slice_duration ;
00439            }
00440            for( kk=nim->slice_start+1 ; kk <= nim->slice_end ; kk+=2 ){
00441              toff[kk] = tsl ; tsl += nim->slice_duration ;
00442            }
00443          break ;
00444          case NIFTI_SLICE_ALT_INC2:
00445            tsl = 0.0 ;
00446            for( kk=nim->slice_start+1 ; kk <= nim->slice_end ; kk+=2 ){
00447              toff[kk] = tsl ; tsl += nim->slice_duration ;
00448            }
00449            for( kk=nim->slice_start ; kk <= nim->slice_end ; kk+=2 ){
00450              toff[kk] = tsl ; tsl += nim->slice_duration ;
00451            }
00452          break ;
00453          case NIFTI_SLICE_ALT_DEC:
00454            tsl = 0.0 ;
00455            for( kk=nim->slice_end ; kk >= nim->slice_start ; kk-=2 ){
00456              toff[kk] = tsl ; tsl += nim->slice_duration ;
00457            }
00458            for( kk=nim->slice_end-1 ; kk >= nim->slice_start ; kk-=2 ){
00459              toff[kk] = tsl ; tsl += nim->slice_duration ;
00460            }
00461          break ;
00462          case NIFTI_SLICE_ALT_DEC2:
00463            tsl = 0.0 ;
00464            for( kk=nim->slice_end-1 ; kk >= nim->slice_start ; kk-=2 ){
00465              toff[kk] = tsl ; tsl += nim->slice_duration ;
00466            }
00467            for( kk=nim->slice_end ; kk >= nim->slice_start ; kk-=2 ){
00468              toff[kk] = tsl ; tsl += nim->slice_duration ;
00469            }
00470          break ;
00471        }
00472 
00473        EDIT_dset_items( dset ,
00474                           ADN_nsl     , nim->nz       ,
00475                           ADN_zorg_sl , orgxyz.xyz[2] ,
00476                           ADN_dz_sl   , dxyz.xyz[2]   ,
00477                           ADN_toff_sl , toff          ,
00478                         ADN_none ) ;
00479 
00480        free(toff) ;
00481 
00482      } 
00483 
00484    } 
00485 
00486    
00487 
00488    if( statcode != 0 ){
00489      for( ibr=0 ; ibr < nvals ; ibr++ )
00490        EDIT_STATAUX4(dset,ibr,statcode,nim->intent_p1,nim->intent_p2,nim->intent_p3,0) ;
00491    }
00492 
00493    
00494 
00495    dset->dblk->diskptr->storage_mode = STORAGE_BY_NIFTI ;
00496    strcpy( dset->dblk->diskptr->brick_name , pathname ) ;
00497    dset->dblk->diskptr->byte_order = nim->byteorder ;
00498 
00499 #if 0
00500    for( ibr=0 ; ibr < nvals ; ibr++ ){     
00501      sprintf(prefix,"%s[%d]",tname,ibr) ;
00502      EDIT_BRICK_LABEL( dset , ibr , prefix ) ;
00503    }
00504 #endif
00505 
00506 
00507 
00508 
00509 
00510    { int ee ;  
00511 
00512      
00513 
00514      for( ee=0 ; ee < nim->num_ext ; ee++ )
00515        if( nim->ext_list[ee].ecode == NIFTI_ECODE_AFNI &&
00516            nim->ext_list[ee].esize > 32                &&
00517            nim->ext_list[ee].edata != NULL               ) break ;
00518 
00519      
00520 
00521      if( ee < nim->num_ext ){
00522        char *buf = nim->ext_list[ee].edata , *rhs , *cpt ;
00523        int  nbuf = nim->ext_list[ee].esize - 8 ;
00524        NI_stream ns ;
00525        void     *nini ;
00526        NI_group *ngr , *nngr ;
00527 
00528        
00529 
00530        if( buf != NULL && nbuf > 32 && strncmp(buf,"<?xml",5)==0 ){
00531          if( buf[nbuf-1] != '\0' ) buf[nbuf-1] = '\0' ;         
00532          cpt = strstr(buf,"?>") ;                    
00533          if( cpt != NULL ){                          
00534            ns = NI_stream_open( "str:" , "r" ) ;
00535            NI_stream_setbuf( ns , cpt+2 ) ;        
00536            nini = NI_read_element(ns,1) ;                 
00537            NI_stream_close(ns) ;
00538            if( NI_element_type(nini) == NI_GROUP_TYPE ){   
00539              ngr = (NI_group *)nini ;
00540              if( strcmp(ngr->name,"AFNI_attributes") == 0 ){    
00541                nngr = ngr ;
00542              } else {                   
00543                int nn ; void **nnini ;
00544                nn = NI_search_group_deep( ngr , "AFNI_attributes" , &nnini ) ;
00545                if( nn <= 0 ) nngr = NULL ;
00546                else        { nngr = (NI_group *)nnini[0]; NI_free(nnini); }
00547              }
00548 
00549              if( NI_element_type(nngr) == NI_GROUP_TYPE ){ 
00550                rhs = NI_get_attribute( nngr , "self_idcode" ) ;
00551                if( rhs == NULL )
00552                  rhs = NI_get_attribute( nngr , "AFNI_idcode" ) ;
00553                if( rhs != NULL )    
00554                  MCW_strncpy( dset->idcode.str , rhs , MCW_IDSIZE ) ;
00555                rhs = NI_get_attribute( nngr , "NIfTI_nums" ) ;    
00556                if( rhs != NULL ){                       
00557                  char buf[128] ;                              
00558                  sprintf(buf,"%d,%d,%d,%d,%d,%d" ,             
00559                    nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->datatype );
00560                  if( strcmp(buf,rhs) != 0 ){
00561                    static int nnn=0 ;
00562                    if(nnn==0){fprintf(stderr,"\n"); nnn=1;}
00563                    fprintf(stderr,
00564                      "** WARNING: NIfTI file %s dimensions altered since "
00565                                  "AFNI extension was added\n",pathname ) ;
00566                  }
00567                }
00568                THD_dblkatr_from_niml( nngr , dset->dblk ); 
00569                THD_datablock_apply_atr( dset ) ;   
00570              }
00571              NI_free_element( ngr ) ;          
00572 
00573            } 
00574          } 
00575        } 
00576      } 
00577    } 
00578 
00579    
00580 
00581    nifti_image_free(nim) ; RETURN(dset) ;
00582 }
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 void THD_load_nifti( THD_datablock *dblk )
00592 {
00593    THD_diskptr *dkptr ;
00594    int nx,ny,nz,nxy,nxyz,nxyzv , nerr=0,ibr,nv, nslice ;
00595    int datum, need_copy=0 ;
00596    void *ptr ;
00597    nifti_image *nim ;
00598    nifti_brick_list NBL ;  
00599 
00600 ENTRY("THD_load_nifti") ;
00601 
00602    
00603 
00604    if( !ISVALID_DATABLOCK(dblk)                        ||
00605        dblk->diskptr->storage_mode != STORAGE_BY_NIFTI ||
00606        dblk->brick == NULL                               ) EXRETURN ;
00607 
00608    dkptr = dblk->diskptr ;
00609 
00610    STATUS("calling nifti_image_read_bricks") ;
00611    NBL.nbricks = 0 ;
00612    nim = nifti_image_read_bricks( dkptr->brick_name, 0,NULL , &NBL ) ;
00613    if( nim == NULL || NBL.nbricks <= 0 ) EXRETURN ;
00614 
00615    datum = DBLK_BRICK_TYPE(dblk,0) ;  
00616 
00617    
00618 
00619 
00620    switch( nim->datatype ){
00621      case DT_INT16:
00622      case DT_UINT8:      need_copy = (datum == MRI_float) ; break ;
00623 
00624      case DT_FLOAT32:
00625      case DT_COMPLEX64:
00626      case DT_RGB24:      need_copy = 0 ; break ;
00627 
00628      case DT_INT8:       
00629      case DT_UINT16:     
00630      case DT_INT32:      
00631      case DT_UINT32:
00632      case DT_FLOAT64:    need_copy = 1 ; break ;
00633 #if 0
00634      case DT_COMPLEX128: need_copy = 1 ; break ;
00635 #endif
00636    }
00637 
00638    
00639 
00640    nx = dkptr->dimsizes[0] ;
00641    ny = dkptr->dimsizes[1] ;  nxy   = nx * ny   ;
00642    nz = dkptr->dimsizes[2] ;  nxyz  = nxy * nz  ;
00643    nv = dkptr->nvals       ;  if( nv > NBL.nbricks ) nv = NBL.nbricks ;
00644    nxyzv = nxyz * nv ; nslice = nz*nv ;
00645 
00646    dblk->malloc_type = DATABLOCK_MEM_MALLOC ;
00647 
00648    
00649 
00650    if( !need_copy ){
00651 
00652      STATUS("copying brick pointers directly") ;
00653      for( ibr=0 ; ibr < nv ; ibr++ ){
00654        mri_fix_data_pointer( NBL.bricks[ibr] ,DBLK_BRICK(dblk,ibr) ) ;
00655        NBL.bricks[ibr] = NULL ;  
00656 
00657        if( AFNI_yesenv("AFNI_FLOATSCAN") ){  
00658          if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_float )
00659            nerr += thd_floatscan( DBLK_BRICK_NVOX(dblk,ibr) ,
00660                                   DBLK_ARRAY(dblk,ibr)        ) ;
00661          else if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_complex )
00662            nerr += thd_complexscan( DBLK_BRICK_NVOX(dblk,ibr) ,
00663                                     DBLK_ARRAY(dblk,ibr)        ) ;
00664        }
00665      }
00666      if( nerr > 0 ) fprintf(stderr ,
00667                     "** %s: found %d float errors -- see program float_scan\n",
00668                     dkptr->brick_name , nerr ) ;
00669 
00670    } else { 
00671 
00672      register int ii ; void *nbuf ;
00673 
00674      STATUS("converting input bricks to floats") ;
00675      for( ibr=0 ; ibr < nv ; ibr++ ){
00676 
00677        if( DBLK_ARRAY(dblk,ibr) == NULL ){                     
00678          ptr = AFMALL(void, DBLK_BRICK_BYTES(dblk,ibr) ) ;     
00679          mri_fix_data_pointer( ptr ,  DBLK_BRICK(dblk,ibr) ) ; 
00680        }
00681        ptr = DBLK_ARRAY(dblk,ibr) ; if( ptr == NULL ) break ;  
00682 
00683        nbuf = NBL.bricks[ibr] ;              
00684 
00685        
00686 
00687 #undef  CPF
00688 #define CPF(ityp) do{ ityp *sar = (ityp *)nbuf ; float *far = (float *)ptr ;   \
00689                       for( ii=0 ; ii < nxyz ; ii++ ) far[ii] = (float)sar[ii]; \
00690                   } while(0)
00691 
00692        
00693 
00694        switch( nim->datatype ){
00695          case DT_UINT8:    CPF(unsigned char)  ; break ;
00696          case DT_INT8:     CPF(signed char)    ; break ;
00697          case DT_INT16:    CPF(signed short)   ; break ;
00698          case DT_UINT16:   CPF(unsigned short) ; break ;
00699          case DT_INT32:    CPF(signed int)     ; break ;
00700          case DT_UINT32:   CPF(unsigned int)   ; break ;
00701          case DT_FLOAT64:  CPF(double)         ; break ;
00702 #if 0
00703          case DT_COMPLEX128: break ;
00704 #endif
00705        }
00706 
00707        free(NBL.bricks[ibr]) ; NBL.bricks[ibr] = NULL ;
00708      }
00709    }
00710 
00711    nifti_free_NBL( &NBL ) ;  
00712 
00713    
00714 
00715    if( nim->scl_slope != 0.0 ){       
00716      STATUS("scaling sub-bricks") ;
00717      for( ibr=0 ; ibr < nv ; ibr++ ){
00718        if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_float ){
00719          float *far = (float *) DBLK_ARRAY(dblk,ibr) ; int ii ;
00720          for( ii=0 ; ii < nxyz ; ii++ )
00721            far[ii] = nim->scl_slope * far[ii] + nim->scl_inter ;
00722        } else if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_complex ){
00723          complex *car = (complex *) DBLK_ARRAY(dblk,ibr) ; int ii ;
00724          for( ii=0 ; ii < nxyz ; ii++ ){
00725            car[ii].r = nim->scl_slope * car[ii].r + nim->scl_inter ;
00726            car[ii].i = nim->scl_slope * car[ii].i + nim->scl_inter ;
00727          }
00728        }
00729      }
00730    }
00731 
00732    
00733 
00734    nifti_image_free(nim) ; EXRETURN ;
00735 }