/***************************************************************************** Major portions of this software are copyrighted by the Medical College of Wisconsin, 1994-2000, and are released under the Gnu General Public License, Version 2. See the file README.Copyright for details. ******************************************************************************/ #include "mrilib.h" #include "thd.h" extern THD_3dim_dataset *THD_3dim_from_ROIstring(char *shar); #undef CHECK_FOR_DATA /* 06 Jan 2005: message about empty files */ #define CHECK_FOR_DATA(fn) \ do{ if( fsize == 0 ){ \ if( isfile ) \ fprintf(stderr,"** Can't read ANY data from file '%s'\n",(fn)); \ RETURN(NULL) ; \ }} while(0) /*----------------------------------------------------------------- * this is a list of known filename extensions (as found in THD_open_one_dataset()) 28 Jun 2006 [rickr] -------------------------------------------------------------------*/ static char * file_extension_list[] = { ".HEAD", ".BRIK", ".BRIK.gz", ".mnc", ".mri", ".svl", ".1D", ".3D", ".nii", ".nii.gz", ".nia", ".hdr", ".img", ".mpg", ".mpeg", ".MPG", ".MPEG", ".niml", ".niml.dset" }; /*---------------------------------------------------------------- simply given a pathname, try to open it as a dataset [allow for .HEAD, .BRIK, or just prefix+viewcode filenames] ------------------------------------------------------------------*/ THD_3dim_dataset * THD_open_one_dataset( char *pathname ) { int ii , plen ; char dirname[THD_MAX_NAME] , fullname[THD_MAX_NAME] ; THD_3dim_dataset *dset=NULL ; /* NULL added 23 Feb 2007, from Bernd Feige */ THD_datablock *dblk ; char *sub ; char *fname ; /* to skip directory during HEAD/BRIK search in filename */ int offset ; /* - [rickr 20 Sep 2002] */ long long fsize ; /* 06 Jan 2005, to unsigned 20 Feb 2006 [rickr] */ /* to long long 22 Mar 2007 [RWC] */ int isfile = 1; ENTRY("THD_open_one_dataset") ; /*-- sanity check --*/ if( pathname == NULL || (plen=strlen(pathname)) == 0 || pathname[plen-1] == '/' ) RETURN(NULL) ; /*-- perhaps open the new-fangled way [22 May 2000] --*/ if( getenv("AFNI_USE_THD_open_dataset") != NULL && strstr(pathname,"[") != NULL ){ dset = THD_open_dataset(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } fsize = THD_filesize(pathname) ; /* 06 Jan 2005 */ /* replace fsize == -1 use with isfile variable 28 Feb 2007 [rickr] */ if( fsize == 0 && !THD_is_file(pathname) ) isfile = 0; /*-- perhaps the MINC way --*/ if( STRING_HAS_SUFFIX(pathname,".mnc") ){ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_minc(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /*-- perhaps the ANALYZE way --*/ if( STRING_HAS_SUFFIX(pathname,".hdr") ){ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_analyze(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /*-- perhaps the CTF way [04 Dec 2002] --*/ if( STRING_HAS_SUFFIX(pathname,".mri") ){ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_ctfmri(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } else if( STRING_HAS_SUFFIX(pathname,".svl") ){ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_ctfsam(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /*-- 04 Mar 2003: allow input of .1D files --*/ if( STRING_HAS_SUFFIX(pathname,".1D") ){ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_1D(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } else if( STRING_HAS_SUFFIX(pathname,".3D") ){ /* 21 Mar 2003 */ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_3D(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /*-- 28 Aug 2003: the NIFTI way! --*/ if( STRING_HAS_SUFFIX(pathname,".nii") || STRING_HAS_SUFFIX(pathname,".nii.gz") || STRING_HAS_SUFFIX(pathname,".nia") ){ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_nifti(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /*-- 03 Dec 2003: the MPEG way! --*/ if( STRING_HAS_SUFFIX_CASE(pathname,".mpg") || STRING_HAS_SUFFIX_CASE(pathname,".mpeg") ){ CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */ dset = THD_open_mpeg(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /*-- 26 May 2006 [rickr]: the NIML way! --*/ if( STRING_HAS_SUFFIX(pathname,".niml") ){ CHECK_FOR_DATA(pathname) ; dset = THD_open_niml(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /*-- 26 May 2006 [rickr]: the NI_SURF_DSET way! --*/ if( STRING_HAS_SUFFIX(pathname,".niml.dset") ){ CHECK_FOR_DATA(pathname) ; dset = THD_open_niml(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /* -- Try to read an AFNI dataset and if that fails, there is one more chance -- */ /*-- Must be an AFNI-formatted dataset! -------------*/ /*-- find directory and last names in the pathname --*/ for( ii=plen-1 ; ii >= 0 ; ii-- ) if( pathname[ii] == '/' ) break ; if( ii < 0 ){ strcpy( dirname , "./" ) ; /* fake directory name */ } else { strcpy( dirname , pathname ) ; dirname[ii+1] = '\0' ; } offset = ii + 1 ; /* offset of file within pathname - rickr [20 Sep 2002] */ /*-- perform surgery on the name to make it a valid .HEAD --*/ strcpy( fullname , pathname ) ; fname = fullname + offset ; /* trailing filename (past directory) - rickr */ /* (REPLACE) sub = strstr( fullname , DATASET_HEADER_SUFFIX ) ; * .HEAD ? */ sub = strstr( fname , DATASET_HEADER_SUFFIX ) ; /* .HEAD ? r:fname */ if( sub == NULL ){ /* no! */ sub = strstr( fname , DATASET_BRICK_SUFFIX ) ; /* .BRIK ? r:fname */ if( sub == NULL ){ /* no! */ ii = strlen(fullname) ; if( fullname[ii-1] != '.' ) strcat( fullname , "." ) ; /* tack .HEAD */ strcat( fullname , DATASET_HEADER_SUFFIX ) ; /* onto end */ } else { /* yes! */ strcpy( sub , DATASET_HEADER_SUFFIX ) ; /* replace .BRIK with .HEAD */ } } /*-- open it up? --*/ fsize = THD_filesize(fullname) ; /* 06 Jan 2005 */ if( fsize == 0 && !THD_is_file(fullname) ) isfile = 0; else isfile = 1; /* if it is not a file, check the ROI case 28 Feb 2007 [rickr] */ if( isfile ) { dblk = THD_init_one_datablock( dirname , fullname ) ; if( dblk != NULL ) { dset = THD_3dim_from_block( dblk ) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } } else { /*-- Nothing worked, see if name is that of an atlas based ROI -- */ /* fprintf(stderr,"Here's your moment %s\n", pathname); */ dset = THD_3dim_from_ROIstring(pathname) ; THD_patch_brickim(dset) ; /* 20 Oct 2006 */ RETURN(dset) ; } /* all else failed, give them the famed message */ CHECK_FOR_DATA(fullname) ; RETURN(dset) ; /* not destined to get here */ } /*-------------------------------------------------------------------- Returns -1 if no dataset, otherwise returns view_type. * If sname==NULL, then "./" is used. * pname mustn't be NULL. * If vt is a good view type (>= 0), then we only check that, otherwise we check all possible view types (smallest one found wins). ----------------------------------------------------------------------*/ int THD_is_dataset( char *sname , char *pname , int vt ) /* 17 Mar 2000 */ { THD_3dim_dataset *dset ; int ii , vv ; ENTRY("THD_is_dataset") ; if( pname == NULL ) RETURN(-1) ; dset = EDIT_empty_copy(NULL) ; EDIT_dset_items( dset , ADN_prefix , pname , ADN_none ) ; if( sname != NULL ) EDIT_dset_items( dset , ADN_directory_name , sname , ADN_none ) ; if( vt >= FIRST_VIEW_TYPE && vt <= LAST_VIEW_TYPE ){ EDIT_dset_items( dset , ADN_view_type , vt , ADN_none ) ; ii = THD_is_file(dset->dblk->diskptr->header_name); THD_delete_3dim_dataset(dset,False) ; if( ii ) RETURN(vt) ; RETURN(-1) ; } for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ){ EDIT_dset_items( dset , ADN_view_type , vv , ADN_none ) ; ii = THD_is_file(dset->dblk->diskptr->header_name); if( ii ){ THD_delete_3dim_dataset(dset,False); RETURN(vv); } } THD_delete_3dim_dataset( dset , False ) ; RETURN(-1) ; } /*--------------------------------------------------------------------*/ static int THD_deconflict_nifti( char *pfx ) { int lp , ls ; char suf[9] ; char aa,bb,cc ; if( !THD_is_file(pfx) ) return 0 ; lp = strlen(pfx) ; if( STRING_HAS_SUFFIX(pfx,".nii") ){ ls = lp-4 ; strcpy(suf,".nii") ; } else if( STRING_HAS_SUFFIX(pfx,".nii.gz") ){ ls = lp-7 ; strcpy(suf,".nii.gz") ; } else if( STRING_HAS_SUFFIX(pfx,".hdr") ){ ls = lp-4 ; strcpy(suf,".hdr") ; } else { ls = lp ; strcpy(suf,"\0") ; } for( aa='A' ; aa <= 'Z' ; aa++ ){ for( bb='A' ; bb <= 'Z' ; bb++ ){ for( cc='1' ; cc <= '9' ; cc++ ){ pfx[ls ] = '_' ; pfx[ls+1] = aa ; pfx[ls+2] = bb ; pfx[ls+3] = cc ; pfx[ls+4] = '\0'; strcat(pfx,suf) ; if( ! THD_is_file(pfx) ) return 1 ; }}} if( ls > THD_MAX_PREFIX-45 ) ls = THD_MAX_PREFIX-45 ; pfx[ls++] = '_' ; UNIQ_idcode_fill( pfx+ls ) ; strcat(pfx,suf) ; return 1; } /*--------------------------------------------------------------------*/ /*! Modify the prefix of a dataset to make sure it doesn't conflict with an existing file. Return value is 0 if no change was needed, 1 if a change was made. ----------------------------------------------------------------------*/ int THD_deconflict_prefix( THD_3dim_dataset *dset ) { char pfx[THD_MAX_PREFIX] ; int lp ; char aa,bb,cc ; ENTRY("THD_deconflict_prefix") ; if( !ISVALID_DSET(dset) ) RETURN(0) ; MCW_strncpy( pfx , DSET_PREFIX(dset) , THD_MAX_PREFIX ) ; if( PREFIX_IS_NIFTI(pfx) ){ lp = THD_deconflict_nifti( pfx ) ; if( lp > 0 ) EDIT_dset_items( dset , ADN_prefix , pfx , ADN_none ) ; RETURN(lp) ; } if( ! THD_is_file(dset->dblk->diskptr->header_name) ) RETURN(0) ; lp = strlen(pfx) ; if( lp > THD_MAX_PREFIX-5 ) lp = THD_MAX_PREFIX-5 ; for( aa='A' ; aa <= 'Z' ; aa++ ){ for( bb='A' ; bb <= 'Z' ; bb++ ){ for( cc='1' ; cc <= '9' ; cc++ ){ pfx[lp ] = '_' ; pfx[lp+1] = aa ; pfx[lp+2] = bb ; pfx[lp+3] = cc ; pfx[lp+4] = '\0'; EDIT_dset_items( dset , ADN_prefix , pfx , ADN_none ) ; if( ! THD_is_file(dset->dblk->diskptr->header_name) ) RETURN(1) ; }}} /** ugly brute force final solution: should never happen! **/ if( lp > THD_MAX_PREFIX-35 ) lp = THD_MAX_PREFIX-35 ; pfx[lp++] = '_' ; UNIQ_idcode_fill( pfx+lp ) ; EDIT_dset_items( dset , ADN_prefix , pfx , ADN_none ) ; RETURN(1) ; } /*--------------------------------------------------------------------*/ char * THD_dataset_headname( char *sname , char *pname , int vt ) { THD_3dim_dataset *dset ; char *str ; int ll ; ENTRY("THD_dataset_headname") ; if( pname == NULL ) RETURN(NULL) ; dset = EDIT_empty_copy(NULL) ; EDIT_dset_items( dset , ADN_prefix , pname , ADN_none ) ; if( sname != NULL ) EDIT_dset_items( dset , ADN_directory_name , sname , ADN_none ) ; if( vt >= FIRST_VIEW_TYPE && vt <= LAST_VIEW_TYPE ) EDIT_dset_items( dset , ADN_view_type , vt , ADN_none ) ; ll = strlen(dset->dblk->diskptr->header_name) + 1 ; str = (char *) malloc(sizeof(char)*ll ) ; strcpy( str , dset->dblk->diskptr->header_name ) ; THD_delete_3dim_dataset( dset , False ) ; RETURN(str) ; } /* ------------------------------------------------------------- */ /* given a filename, return one STORAGE_BY_* value from 3ddata.h * 20 Apr 2006 [rickr] */ int storage_mode_from_filename( char * fname ) { ENTRY("storage_mode_from_filename"); if( !fname || !*fname ) RETURN(STORAGE_UNDEFINED); /* STORAGE_BY_SLICES was never implemented :'( */ if( STRING_HAS_SUFFIX(fname, ".HEAD") || STRING_HAS_SUFFIX(fname, ".BRIK") || STRING_HAS_SUFFIX(fname, ".BRIK.gz") ) RETURN(STORAGE_BY_BRICK); if( STRING_HAS_SUFFIX(fname, ".mnc") ) RETURN(STORAGE_BY_MINC); if( 0 ) RETURN(STORAGE_BY_VOLUMES); if( 0 ) /* default is NIFTI */ RETURN(STORAGE_BY_ANALYZE); if( STRING_HAS_SUFFIX(fname, ".mri") ) RETURN(STORAGE_BY_CTFMRI); if( STRING_HAS_SUFFIX(fname, ".svl") ) RETURN(STORAGE_BY_CTFSAM); if( STRING_HAS_SUFFIX(fname, ".1D") ) RETURN(STORAGE_BY_1D); if( STRING_HAS_SUFFIX(fname, ".3D") ) RETURN(STORAGE_BY_3D); if( STRING_HAS_SUFFIX(fname, ".nii") || STRING_HAS_SUFFIX(fname, ".nii.gz") || STRING_HAS_SUFFIX(fname, ".nia") || STRING_HAS_SUFFIX(fname, ".hdr") || STRING_HAS_SUFFIX(fname, ".img") ) RETURN(STORAGE_BY_NIFTI); if( STRING_HAS_SUFFIX_CASE(fname,".mpg") || STRING_HAS_SUFFIX_CASE(fname,".mpeg") )RETURN(STORAGE_BY_MPEG); /* 26 May 2006 [rickr] */ if( STRING_HAS_SUFFIX(fname, ".niml") ) RETURN(STORAGE_BY_NIML); if( STRING_HAS_SUFFIX(fname,".niml.dset") ) RETURN(STORAGE_BY_NI_SURF_DSET); RETURN(STORAGE_UNDEFINED); } /* ---------------------------------------------------- */ /* given a filename, return a pointer to the extension * (from file_extension_list) * 28 Jun 2006 [rickr] */ char * find_filename_extension( char * fname ) { char ** eptr; int c, flen, num_ext; ENTRY("find_filename_extension"); if( !fname || !*fname ) RETURN(NULL); num_ext = sizeof(file_extension_list)/sizeof(char *); flen = strlen(fname); for( c = 0, eptr = file_extension_list; c < num_ext; c++, eptr++ ) if( STRING_HAS_SUFFIX(fname, *eptr) ) RETURN(fname + (flen - strlen(*eptr))); RETURN(NULL); /* not found */ } /* ------------------------------------------------------------- */ /* given a filename, return 1 if it has a know extension that is * not an AFNI extension 20 Apr 2006 [rickr] */ int has_known_non_afni_extension( char * fname ) { int mode; ENTRY("has_known_non_afni_extension"); mode = storage_mode_from_filename(fname); /* UNDEFINED, BRICK and VOLUMES are the unknown or AFNI cases */ if( mode <= STORAGE_UNDEFINED || mode == STORAGE_BY_BRICK || mode == STORAGE_BY_VOLUMES || mode > LAST_STORAGE_MODE ) RETURN(0); RETURN(1); /* otherwise, we recognize it as non-AFNI */ }