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 extern THD_3dim_dataset *THD_3dim_G_from_ROIstring(char *shar);
11
12 #undef CHECK_FOR_DATA /* 06 Jan 2005: message about empty files */
13 #define CHECK_FOR_DATA(fn) \
14 do{ if( fsize == 0 ){ \
15 if( isfile ) \
16 fprintf(stderr,"** Can't read ANY data from file '%s'\n",(fn)); \
17 RETURN(NULL) ; \
18 }} while(0)
19
20
21 /*-----------------------------------------------------------------
22 * this is a list of known filename extensions
23 (as found in THD_open_one_dataset()) 28 Jun 2006 [rickr]
24 -------------------------------------------------------------------*/
25 static char * file_extension_list[] = {
26 ".HEAD", ".BRIK", ".BRIK.gz",
27 ".mnc",
28 ".mri",
29 ".svl",
30 ".1D", ".1D.dset", ".1D.do", ".txt",
31 ".3D",
32 ".nii", ".nii.gz", ".nia", ".hdr", ".img",
33 ".mpg", ".mpeg", ".MPG", ".MPEG",
34 ".niml", ".niml.dset", ".niml.do",
35 ".gii", ".gii.dset", ".niml.tract" , ".jpg" , ".jpeg" , ".png" , ".heic"
36 };
37
38 /*
39 Return a plausible path to a pathless filename,
40 returns NULL if no file was found.
41 */
Add_plausible_path(char * fname)42 char * Add_plausible_path(char *fname)
43 {
44 char dname[THD_MAX_NAME], ename[THD_MAX_NAME],
45 *elocal=NULL, *eee=NULL, *pp=NULL, *epath=NULL;
46 int epos=0, ll=0, ii=0, id = 0, kk=0;
47 FILE *fp=NULL;
48
49 ENTRY("Add_plausible_path");
50
51 if (!fname) RETURN(NULL);
52
53 /* If file exists as is, go back */
54 if ((fp = fopen( fname , "r"))) {
55 pp = (char *)malloc(sizeof(char)*(strlen(fname)+1));
56 pp = strcpy(pp, fname);
57 fclose(fp);
58 RETURN(pp);
59 }
60
61 ii = strlen(fname);
62 while (ii >=0) {
63 if (fname[ii] == '/') { /* Have path in name, return whole thing,
64 if file exists! */
65 if ((fp = fopen( fname , "r"))) {
66 pp = (char *)malloc(sizeof(char)*(strlen(fname)+1));
67 pp = strcpy(pp, fname);
68 fclose(fp);
69 RETURN(pp);
70 } else {
71 RETURN(NULL);
72 }
73 }
74 --ii;
75 }
76
77 /* have name, try different paths */
78 epath = getenv("AFNI_R_PATH") ;
79 if( epath == NULL ) epath = getenv("AFNI_PLUGINPATH") ;
80 if( epath == NULL ) epath = getenv("AFNI_PLUGIN_PATH") ;
81 if( epath == NULL ) epath = getenv("PATH") ;
82
83
84 /* Next block is based on one in thd_ttatlas_query.c */
85 /*----- copy path list into local memory -----*/
86
87 ll = strlen(epath) ;
88 elocal = AFMALL(char, sizeof(char) * (ll+2) ) ;
89
90 /*----- put a blank at the end -----*/
91
92 strcpy( elocal , epath ) ; elocal[ll] = ' ' ; elocal[ll+1] = '\0' ;
93
94 /*----- replace colons with blanks -----*/
95
96 for( ii=0 ; ii < ll ; ii++ )
97 if( elocal[ii] == ':' ) elocal[ii] = ' ' ;
98
99 /*----- extract blank delimited strings;
100 use as directory names to look for atlas -----*/
101
102 epos = 0 ;
103
104 do{
105 ii = sscanf( elocal+epos , "%s%n" , ename , &id ); /* next substring */
106 if( ii < 1 ) break ; /* none -> done */
107
108 epos += id ; /* char after last scanned */
109
110 ii = strlen(ename) ; /* make sure name has */
111 if( ename[ii-1] != '/' ){ /* a trailing '/' on it */
112 ename[ii] = '/' ; ename[ii+1] = '\0' ;
113 }
114 strcpy(dname,ename) ;
115 strcat(dname,fname) ; /* add file name */
116
117 if ((fp = fopen( dname , "r"))) {
118 pp = (char *)malloc(sizeof(char)*(strlen(dname)+1));
119 pp = strcpy(pp, dname);
120 fclose(fp);
121 RETURN(pp);
122 }
123
124 } while( epos < ll ) ; /* scan until 'epos' is after end of epath */
125
126
127 RETURN(pp);
128 }
129
130 /*----------------------------------------------------------------
131 simply given a pathname, try to open it as a dataset
132 [allow for .HEAD, .BRIK, or just prefix+viewcode filenames]
133 ------------------------------------------------------------------*/
134
THD_open_one_dataset(char * pathname)135 THD_3dim_dataset * THD_open_one_dataset( char *pathname )
136 {
137 int ii , plen ;
138 char dirname[THD_MAX_NAME] , fullname[THD_MAX_NAME] ;
139 THD_3dim_dataset *dset=NULL ; /* NULL added 23 Feb 2007, from Bernd Feige */
140 THD_datablock *dblk ;
141 char *sub ;
142 char *fname ; /* to skip directory during HEAD/BRIK search in filename */
143 int offset ; /* - [rickr 20 Sep 2002] */
144 long long fsize ; /* 06 Jan 2005, to unsigned 20 Feb 2006 [rickr] */
145 /* to long long 22 Mar 2007 [RWC] */
146 int isfile = 1;
147 static char qname[THD_MAX_NAME+222] ;
148
149 ENTRY("THD_open_one_dataset") ;
150
151 /*-- sanity check --*/
152
153 if( pathname == NULL ||
154 (plen=strlen(pathname)) == 0 ||
155 pathname[plen-1] == '/' ) RETURN(NULL) ;
156
157
158 if( pathname[0] == '~' && pathname[1] == '/' ){ /* 13 Feb 2008 */
159 char *eee = getenv("HOME") ;
160 if( eee != NULL ){
161 strcpy(qname,eee); strcat(qname,pathname+1);
162 pathname = qname ;
163 }
164 }
165
166 /*-- perhaps open the new-fangled way [22 May 2000] --*/
167 if( getenv("AFNI_USE_THD_open_dataset") != NULL &&
168 strstr(pathname,"[") != NULL ){
169 dset = THD_open_dataset(pathname) ;
170 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
171 RETURN(dset) ;
172 }
173
174 /*-- other cases that require new-fangled way 23 Jul 2012 [rickr] --*/
175 if( ! strncmp(pathname,"filelist:",9) ){
176 dset = THD_open_dataset(pathname) ;
177 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
178 RETURN(dset) ;
179 }
180
181 fsize = THD_filesize(pathname) ; /* 06 Jan 2005 */
182
183 /* replace fsize == -1 use with isfile variable 28 Feb 2007 [rickr] */
184 if( fsize == 0 && !THD_is_file(pathname) ) isfile = 0;
185
186 /*-- perhaps the MINC way --*/
187
188 if( STRING_HAS_SUFFIX(pathname,".mnc") ){
189 static int first=1 ;
190 if( first ){
191 ERROR_message("MINC-1 dataset open disabled: %s",pathname) ;
192 first = 0 ; RETURN(NULL) ;
193 }
194 }
195
196 /*-- perhaps the ANALYZE way --*/
197
198 if( STRING_HAS_SUFFIX(pathname,".hdr") ){
199 CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */
200 dset = THD_open_analyze(pathname) ;
201 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
202 RETURN(dset) ;
203 }
204
205 /*-- perhaps the CTF way [04 Dec 2002] --*/
206
207 if( STRING_HAS_SUFFIX(pathname,".mri") ){
208 CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */
209 dset = THD_open_ctfmri(pathname) ;
210 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
211 RETURN(dset) ;
212 } else if( STRING_HAS_SUFFIX(pathname,".svl") ){
213 CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */
214 dset = THD_open_ctfsam(pathname) ;
215 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
216 RETURN(dset) ;
217 }
218
219 /*-- 04 Mar 2003: allow input of .1D files --*/
220
221 if( STRING_HAS_SUFFIX(pathname,".1D") ||
222 STRING_HAS_SUFFIX(pathname,".1D.dset") ){
223 CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */
224 dset = THD_open_1D(pathname) ;
225 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
226 RETURN(dset) ;
227 } else if( STRING_HAS_SUFFIX(pathname,".3D") ){ /* 21 Mar 2003 */
228 CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */
229 dset = THD_open_3D(pathname) ;
230 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
231 RETURN(dset) ;
232 }
233
234 /*-- 28 Aug 2003: the NIFTI way! --*/
235
236 if( STRING_HAS_SUFFIX(pathname,".nii") ||
237 STRING_HAS_SUFFIX(pathname,".nii.gz") ||
238 STRING_HAS_SUFFIX(pathname,".nia") ){
239
240 /* let NIFTI decide if the dataset is there 10 Jun 2015 [ricrk] */
241 /* CHECK_FOR_DATA(pathname) ; */ /* 06 Jan 2005 */
242 dset = THD_open_nifti(pathname) ;
243 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
244 THD_report_obliquity(dset) ; /* 20 Dec 2007 */
245 RETURN(dset) ;
246 }
247
248 /*-- 03 Dec 2003: the MPEG way! --*/
249
250 if( STRING_HAS_SUFFIX_CASE(pathname,".mpg") ||
251 STRING_HAS_SUFFIX_CASE(pathname,".mpeg") ){
252
253 CHECK_FOR_DATA(pathname) ; /* 06 Jan 2005 */
254 dset = THD_open_mpeg(pathname) ;
255 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
256 RETURN(dset) ;
257 }
258
259 if( STRING_HAS_SUFFIX_CASE(pathname,".jpg") ||
260 STRING_HAS_SUFFIX_CASE(pathname,".png") ||
261 STRING_HAS_SUFFIX_CASE(pathname,".jpeg") ||
262 STRING_HAS_SUFFIX_CASE(pathname,".heic") ){ /* 06 Jul 2016 */
263
264 CHECK_FOR_DATA(pathname) ;
265 dset = THD_open_image(pathname) ; /* will be loaded, too */
266 THD_patch_brickim(dset) ;
267 RETURN(dset) ;
268 }
269
270 /*-- 26 May 2006 [rickr]: the NIML way! --*/
271
272 if( STRING_HAS_SUFFIX(pathname,".niml") ){
273
274 CHECK_FOR_DATA(pathname) ;
275 dset = THD_open_niml(pathname) ;
276 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
277 RETURN(dset) ;
278 }
279
280 /*-- 26 May 2006 [rickr]: the NI_SURF_DSET way! --*/
281
282 if( STRING_HAS_SUFFIX(pathname,".niml.dset") ){
283
284 CHECK_FOR_DATA(pathname) ;
285 dset = THD_open_niml(pathname) ;
286 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
287 RETURN(dset) ;
288 }
289
290 /*-- 13 Feb 2008 [rickr]: the GIFTI way! --*/
291
292 if( STRING_HAS_SUFFIX(pathname,".gii") ||
293 STRING_HAS_SUFFIX(pathname,".gii.dset") ){
294
295 CHECK_FOR_DATA(pathname) ;
296 dset = THD_open_gifti(pathname) ;
297 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
298 RETURN(dset) ;
299 }
300
301 /* -- Try to read an AFNI dataset and if that fails,
302 there is one more chance -- */
303
304 /*-- Must be an AFNI-formatted dataset! -------------*/
305 /*-- find directory and last names in the pathname --*/
306
307 for( ii=plen-1 ; ii >= 0 ; ii-- ) if( pathname[ii] == '/' ) break ;
308
309 if( ii < 0 ){
310 strcpy( dirname , "./" ) ; /* fake directory name */
311 } else {
312 strcpy( dirname , pathname ) ;
313 dirname[ii+1] = '\0' ;
314 }
315 offset = ii + 1 ; /* offset of file within pathname - rickr [20 Sep 2002] */
316
317 /*-- perform surgery on the name to make it a valid .HEAD --*/
318
319 strcpy( fullname , pathname ) ;
320 fname = fullname + offset ; /* trailing filename (past directory) - rickr */
321
322 /* note: e.g. DATASET_HEADER_SUFFIX does not start with '.' */
323 /* (REPLACE) sub = strstr( fullname , DATASET_HEADER_SUFFIX ) ; * .HEAD ? */
324 sub = strstr( fname , DATASET_DOT_HEADER_SUFFIX ) ; /* .HEAD ? r:fname */
325
326 if( sub == NULL ){ /* no! */
327 sub = strstr( fname , DATASET_DOT_BRICK_SUFFIX ) ; /* .BRIK ? r:fname */
328
329 if( sub == NULL ){ /* no! */
330 ii = strlen(fullname) ;
331 if( fullname[ii-1] != '.' ) strcat( fullname , "." ) ; /* tack .HEAD */
332 strcat( fullname , DATASET_HEADER_SUFFIX ) ; /* onto end */
333
334 } else { /* yes! */
335 strcpy( sub , DATASET_DOT_HEADER_SUFFIX ) ; /* replace .BRIK with .HEAD */
336 }
337 }
338
339 /*-- open it up? --*/
340
341 fsize = THD_filesize(fullname) ; /* 06 Jan 2005 */
342 if( fsize == 0 && !THD_is_file(fullname) ) isfile = 0;
343 else isfile = 1;
344
345 /* if it is not a file, check the ROI case 28 Feb 2007 [rickr] */
346 if( isfile ) {
347 dblk = THD_init_one_datablock( dirname , fullname ) ;
348 if( dblk != NULL ) {
349 dset = THD_3dim_from_block( dblk ) ;
350 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
351 THD_report_obliquity(dset) ; /* 20 Dec 2007 */
352 RETURN(dset) ;
353 }
354 } else {
355 /*-- Nothing worked, see if name is that of an atlas based ROI -- */
356 /* fprintf(stderr,"Here's your moment %s\n", pathname); */
357 dset = THD_3dim_G_from_ROIstring(pathname) ;
358 THD_patch_brickim(dset) ; /* 20 Oct 2006 */
359 RETURN(dset) ;
360 }
361
362 /* all else failed, give them the famed message */
363 CHECK_FOR_DATA(fullname) ;
364
365 RETURN(dset) ; /* not destined to get here */
366 }
367
368 /*--------------------------------------------------------------------
369 Returns -1 if no dataset, otherwise returns view_type.
370 * If sname==NULL, then "./" is used.
371 * pname mustn't be NULL.
372 * If vt is a good view type (>= 0), then we only check that,
373 otherwise we check all possible view types (smallest one
374 found wins).
375 ----------------------------------------------------------------------*/
376
THD_is_dataset(char * sname,char * pname,int vt)377 int THD_is_dataset( char *sname , char *pname , int vt ) /* 17 Mar 2000 */
378 {
379 THD_3dim_dataset *dset ;
380 int ii , vv ;
381
382 ENTRY("THD_is_dataset") ;
383
384 if( pname == NULL ) RETURN(-1) ;
385
386 dset = EDIT_empty_copy(NULL) ;
387 EDIT_dset_items( dset , ADN_prefix , pname , ADN_none ) ;
388
389 if( sname != NULL )
390 EDIT_dset_items( dset , ADN_directory_name , sname , ADN_none ) ;
391
392 if( vt >= FIRST_VIEW_TYPE && vt <= LAST_VIEW_TYPE ){
393 EDIT_dset_items( dset , ADN_view_type , vt , ADN_none ) ;
394 ii = THD_is_file(dset->dblk->diskptr->header_name);
395 THD_delete_3dim_dataset(dset,False) ;
396 if( ii ) RETURN(vt) ;
397 RETURN(-1) ;
398 }
399
400 for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ){
401 EDIT_dset_items( dset , ADN_view_type , vv , ADN_none ) ;
402 ii = THD_is_file(dset->dblk->diskptr->header_name);
403 if( ii ){ THD_delete_3dim_dataset(dset,False); RETURN(vv); }
404 }
405
406 THD_delete_3dim_dataset( dset , False ) ;
407 RETURN(-1) ;
408 }
409
410 /*--------------------------------------------------------------------*/
411
THD_deconflict_nifti(char * brick_name)412 static int THD_deconflict_nifti( char *brick_name )
413 {
414 int lp , ls ; char suf[9] ;
415 char aa,bb,cc ;
416
417 if( !THD_is_file(brick_name) ) return 0 ;
418
419 lp = strlen(brick_name) ;
420 if( STRING_HAS_SUFFIX(brick_name,".nii") ){
421 ls = lp-4 ; strcpy(suf,".nii") ;
422 } else if( STRING_HAS_SUFFIX(brick_name,".nii.gz") ){
423 ls = lp-7 ; strcpy(suf,".nii.gz") ;
424 } else if( STRING_HAS_SUFFIX(brick_name,".hdr") ){
425 ls = lp-4 ; strcpy(suf,".hdr") ;
426 } else {
427 ls = lp ; strcpy(suf,"\0") ;
428 }
429
430 for( aa='A' ; aa <= 'Z' ; aa++ ){
431 for( bb='A' ; bb <= 'Z' ; bb++ ){
432 for( cc='1' ; cc <= '9' ; cc++ ){
433 brick_name[ls ] = '_' ;
434 brick_name[ls+1] = aa ;
435 brick_name[ls+2] = bb ;
436 brick_name[ls+3] = cc ;
437 brick_name[ls+4] = '\0';
438 strcat(brick_name,suf) ;
439 if( ! THD_is_file(brick_name) ) return 1 ;
440 }}}
441
442 if( ls > THD_MAX_NAME-45 ) ls = THD_MAX_NAME-45 ;
443 brick_name[ls++] = '_' ;
444 UNIQ_idcode_fill( brick_name+ls ) ;
445 strcat(brick_name,suf) ;
446 return 1;
447 }
448
449 /*--------------------------------------------------------------------*/
450 /*! Modify the prefix of a dataset to make sure it doesn't conflict
451 with an existing file. Return value is 0 if no change was
452 needed, 1 if a change was made.
453 ----------------------------------------------------------------------*/
454
THD_deconflict_prefix(THD_3dim_dataset * dset)455 int THD_deconflict_prefix( THD_3dim_dataset *dset )
456 {
457 char pfx[THD_MAX_PREFIX] ; int lp ;
458 char aa,bb,cc ;
459
460 ENTRY("THD_deconflict_prefix") ;
461
462 if( !ISVALID_DSET(dset) ) RETURN(0) ;
463
464 MCW_strncpy( pfx , DSET_PREFIX(dset) , THD_MAX_PREFIX ) ;
465
466 if( PREFIX_IS_NIFTI(pfx) ){
467 /* adjust brick_name */
468 EDIT_dset_items( dset , ADN_prefix , pfx , ADN_none ) ;
469
470 /* deconflict brick_name (to include path) */
471 lp = THD_deconflict_nifti( dset->dblk->diskptr->brick_name ) ;
472
473 /* reset names from adjusted brick_name */
474 if( lp > 0 ) EDIT_dset_items( dset , ADN_prefix ,
475 dset->dblk->diskptr->brick_name , ADN_none );
476 RETURN(lp) ;
477 }
478
479 if( ! THD_is_file(dset->dblk->diskptr->header_name) ) RETURN(0) ;
480
481 lp = strlen(pfx) ;
482 if( lp > THD_MAX_PREFIX-5 ) lp = THD_MAX_PREFIX-5 ;
483
484 for( aa='A' ; aa <= 'Z' ; aa++ ){
485 for( bb='A' ; bb <= 'Z' ; bb++ ){
486 for( cc='1' ; cc <= '9' ; cc++ ){
487 pfx[lp ] = '_' ;
488 pfx[lp+1] = aa ;
489 pfx[lp+2] = bb ;
490 pfx[lp+3] = cc ;
491 pfx[lp+4] = '\0';
492 EDIT_dset_items( dset , ADN_prefix , pfx , ADN_none ) ;
493 if( ! THD_is_file(dset->dblk->diskptr->header_name) ) RETURN(1) ;
494 }}}
495
496 /** ugly brute force final solution: should never happen! **/
497
498 if( lp > THD_MAX_PREFIX-35 ) lp = THD_MAX_PREFIX-35 ;
499 pfx[lp++] = '_' ; UNIQ_idcode_fill( pfx+lp ) ;
500 EDIT_dset_items( dset , ADN_prefix , pfx , ADN_none ) ;
501 RETURN(1) ;
502 }
503
504 /*--------------------------------------------------------------------*/
505
THD_dataset_headname(char * sname,char * pname,int vt)506 char * THD_dataset_headname( char *sname , char *pname , int vt )
507 {
508 THD_3dim_dataset *dset ;
509 char *str ; int ll ;
510
511 ENTRY("THD_dataset_headname") ;
512
513 if( pname == NULL ) RETURN(NULL) ;
514
515 dset = EDIT_empty_copy(NULL) ;
516 EDIT_dset_items( dset , ADN_prefix , pname , ADN_none ) ;
517
518 if( sname != NULL )
519 EDIT_dset_items( dset , ADN_directory_name , sname , ADN_none ) ;
520
521 if( vt >= FIRST_VIEW_TYPE && vt <= LAST_VIEW_TYPE )
522 EDIT_dset_items( dset , ADN_view_type , vt , ADN_none ) ;
523
524 ll = strlen(dset->dblk->diskptr->header_name) + 1 ;
525 str = (char *) malloc(sizeof(char)*ll ) ;
526 strcpy( str , dset->dblk->diskptr->header_name ) ;
527
528 THD_delete_3dim_dataset( dset , False ) ;
529 RETURN(str) ;
530 }
531
532
533 /* ------------------------------------------------------------- */
534 /* given a filename, return one STORAGE_BY_* value from 3ddata.h
535 * 20 Apr 2006 [rickr] */
storage_mode_from_filename(char * fname)536 int storage_mode_from_filename( char * fname )
537
538 {
539 ENTRY("storage_mode_from_filename");
540
541 if( !fname || !*fname ) RETURN(STORAGE_UNDEFINED);
542
543 /* STORAGE_BY_SLICES was never implemented :'( */
544
545 if( STRING_HAS_SUFFIX(fname, ".HEAD") ||
546 STRING_HAS_SUFFIX(fname, ".BRIK") ||
547 STRING_HAS_SUFFIX(fname, ".BRIK.gz") ) RETURN(STORAGE_BY_BRICK);
548
549
550 if( 0 ) RETURN(STORAGE_BY_VOLUMES);
551
552 if( 0 ) /* default is NIFTI */ RETURN(STORAGE_BY_ANALYZE);
553
554 if( STRING_HAS_SUFFIX(fname, ".mri") ) RETURN(STORAGE_BY_CTFMRI);
555
556 if( STRING_HAS_SUFFIX(fname, ".svl") ) RETURN(STORAGE_BY_CTFSAM);
557
558 if( STRING_HAS_SUFFIX(fname, ".1D") ||
559 STRING_HAS_SUFFIX(fname, ".1D.dset")) RETURN(STORAGE_BY_1D);
560
561 if( STRING_HAS_SUFFIX(fname, ".3D") ) RETURN(STORAGE_BY_3D);
562
563 if( STRING_HAS_SUFFIX(fname, ".nii") ||
564 STRING_HAS_SUFFIX(fname, ".nii.gz") ||
565 STRING_HAS_SUFFIX(fname, ".nia") ||
566 STRING_HAS_SUFFIX(fname, ".hdr") ||
567 STRING_HAS_SUFFIX(fname, ".img") ) RETURN(STORAGE_BY_NIFTI);
568
569 if( STRING_HAS_SUFFIX_CASE(fname,".mpg") ||
570 STRING_HAS_SUFFIX_CASE(fname,".mpeg") )RETURN(STORAGE_BY_MPEG);
571
572 /* 26 May 2006 [rickr] */
573 if( STRING_HAS_SUFFIX(fname, ".niml") ) RETURN(STORAGE_BY_NIML);
574
575 if( STRING_HAS_SUFFIX(fname,".niml.dset") ) RETURN(STORAGE_BY_NI_SURF_DSET);
576 if( STRING_HAS_SUFFIX(fname,".tract.dset") ) RETURN(STORAGE_BY_NI_TRACT);
577
578 if( STRING_HAS_SUFFIX(fname,".gii") ||
579 STRING_HAS_SUFFIX(fname,".gii.dset") ) RETURN(STORAGE_BY_GIFTI);
580
581 RETURN(STORAGE_UNDEFINED);
582 }
583
584 /* ------------------------------------------------------------- */
585 /* return whether the given storage mode suggests a surface type
586 *
587 * Note that 3D, 1D and NIML do not imply either way, life is hard.
588 * For now, return as true for them.
589 *
590 * returns 0 or 1 as boolean 04 Apr 2012 [rickr] */
is_surface_storage_mode(int smode)591 int is_surface_storage_mode( int smode )
592
593 {
594 ENTRY("is_surface_storage_mode");
595
596 if ( smode == STORAGE_BY_1D ||
597 smode == STORAGE_BY_3D ||
598 smode == STORAGE_BY_NIML ||
599 smode == STORAGE_BY_NI_SURF_DSET ||
600 smode == STORAGE_BY_GIFTI
601 ) RETURN(1);
602
603 RETURN(0);
604 }
605
606
storage_mode_from_prefix(char * fname)607 int storage_mode_from_prefix( char * fname )
608 {
609 int sm=STORAGE_UNDEFINED;
610
611 ENTRY("storage_mode_from_prefix");
612
613 if( !fname || !*fname ) RETURN(STORAGE_UNDEFINED);
614 sm = storage_mode_from_filename(fname);
615 if( sm != STORAGE_UNDEFINED ) RETURN(sm);
616
617 if (fname[strlen(fname)-1] == '.') {
618 if( STRING_HAS_SUFFIX(fname, "+orig.") ||
619 STRING_HAS_SUFFIX(fname, "+acpc.") ||
620 STRING_HAS_SUFFIX(fname, "+tlrc.") ) sm = STORAGE_BY_BRICK;
621 } else {
622 if( STRING_HAS_SUFFIX(fname, "+orig") ||
623 STRING_HAS_SUFFIX(fname, "+acpc") ||
624 STRING_HAS_SUFFIX(fname, "+tlrc") ) sm = STORAGE_BY_BRICK;
625 }
626
627 RETURN(sm);
628 }
629
630 /* There is also: storage_mode_str() */
storage_mode_name(int mode)631 char *storage_mode_name(int mode) {
632 switch (mode) {
633 case STORAGE_UNDEFINED:
634 return("UNDEFINED");
635 case STORAGE_BY_BRICK:
636 return("BRIK");
637 case STORAGE_BY_VOLUMES:
638 return("VOLUMES");
639 case STORAGE_BY_ANALYZE:
640 return("ANALYZE");
641 case STORAGE_BY_CTFMRI:
642 return("CTFMRI");
643 case STORAGE_BY_CTFSAM:
644 return("CTFSAM");
645 case STORAGE_BY_1D:
646 return("1D");
647 case STORAGE_BY_3D:
648 return("3D");
649 case STORAGE_BY_NIFTI:
650 return("NIFTI");
651 case STORAGE_BY_MPEG:
652 return("MPEG");
653 case STORAGE_BY_NIML:
654 return("NIML");
655 case STORAGE_BY_NI_SURF_DSET:
656 return("NI_SURF_DSET");
657 case STORAGE_BY_NI_TRACT:
658 return("NI_TRACT");
659 case STORAGE_BY_GIFTI:
660 return("GIFTI");
661 }
662 return("UNDEFINED");
663 }
664
665 /* ---------------------------------------------------- */
666 /* given a filename, return a pointer to the extension
667 * (from file_extension_list)
668 * 28 Jun 2006 [rickr] */
669
find_filename_extension(char * fname)670 char * find_filename_extension( char * fname )
671 {
672 char ** eptr;
673 int c, flen, num_ext;
674
675 ENTRY("find_filename_extension");
676
677 if( !fname || !*fname ) RETURN(NULL);
678
679 num_ext = sizeof(file_extension_list)/sizeof(char *);
680 flen = strlen(fname);
681
682 for( c = 0, eptr = file_extension_list; c < num_ext; c++, eptr++ )
683 if( STRING_HAS_SUFFIX(fname, *eptr) )
684 RETURN(fname + (flen - strlen(*eptr)));
685
686 RETURN(NULL); /* not found */
687 }
688
689
690 /* ------------------------------------------------------------- */
691 /* given a filename, return 1 if it has a know extension that is
692 * not an AFNI extension 20 Apr 2006 [rickr] */
693
has_known_non_afni_extension(char * fname)694 int has_known_non_afni_extension( char * fname )
695 {
696 int mode;
697
698 ENTRY("has_known_non_afni_extension");
699
700 mode = storage_mode_from_filename(fname);
701
702 /* UNDEFINED, BRICK and VOLUMES are the unknown or AFNI cases */
703 if( mode <= STORAGE_UNDEFINED ||
704 mode == STORAGE_BY_BRICK ||
705 mode == STORAGE_BY_VOLUMES ||
706 mode > LAST_STORAGE_MODE ) RETURN(0);
707
708 RETURN(1); /* otherwise, we recognize it as non-AFNI */
709 }
710
711 /* --------------------------------------------------------------- */
712 /* return 1 if smode is for a writable format 5 Mar 2012 [rickr] */
713
is_writable_storage_mode(int smode)714 int is_writable_storage_mode( int smode )
715 {
716 ENTRY("has_writable_extension");
717
718 switch (smode) {
719 case STORAGE_UNDEFINED: RETURN(0);
720 case STORAGE_BY_ANALYZE: RETURN(0); /* returns NIFTI */
721 case STORAGE_BY_CTFMRI: RETURN(0);
722 case STORAGE_BY_CTFSAM: RETURN(0);
723 case STORAGE_BY_MPEG: RETURN(0);
724
725 case STORAGE_BY_BRICK: RETURN(1);
726 case STORAGE_BY_VOLUMES: RETURN(1);
727 case STORAGE_BY_1D: RETURN(1);
728 case STORAGE_BY_3D: RETURN(1);
729 case STORAGE_BY_NIFTI: RETURN(1);
730 case STORAGE_BY_NIML: RETURN(1);
731 case STORAGE_BY_NI_SURF_DSET: RETURN(1);
732 case STORAGE_BY_NI_TRACT: RETURN(1);
733 case STORAGE_BY_GIFTI: RETURN(1);
734 }
735
736 RETURN(0); /* not writable */
737 }
738
739 /* ---------------------------------------------------- */
740 /* given a filename, return a string excluding known
741 afni extensions (from file_extension_list)
742 DO NOT FREE output.
743 06 Feb 2012 [ZSS] */
744
without_afni_filename_extension(char * fname)745 char * without_afni_filename_extension( char * fname )
746 {
747 char ** eptr;
748 static char onames[5][THD_MAX_NAME+1];
749 static int icall=0;
750 int c, flen, num_ext;
751
752 ENTRY("without_afni_filename_extension");
753
754 if( !fname || !*fname ) RETURN(NULL);
755 ++icall;
756 if (icall > 4) icall = 0;
757 onames[icall][0]='\0';
758
759 if (strlen(fname) >= THD_MAX_NAME) {
760 WARNING_message("Filename too long for without_afni_filename_extension()"
761 "Returing fname");
762 RETURN(fname);
763 }
764 num_ext = sizeof(file_extension_list)/sizeof(char *);
765 flen = strlen(fname);
766
767 for( c = 0, eptr = file_extension_list; c < num_ext; c++, eptr++ ) {
768 if( STRING_HAS_SUFFIX(fname, *eptr) ) {
769 flen = flen - strlen(*eptr);
770 strncpy(onames[icall], fname, flen);
771 onames[icall][flen]='\0';
772 RETURN(onames[icall]);
773 }
774 }
775 RETURN(fname); /* not found */
776 }
777
without_afni_filename_view_and_extension(char * fname)778 char * without_afni_filename_view_and_extension( char * fname )
779 {
780 char *noext;
781 static char onames[5][THD_MAX_NAME+1];
782 static int icall=0;
783 int flen;
784
785 ENTRY("without_afni_filename_view_and_extension");
786
787 if( !fname || !*fname ) RETURN(NULL);
788 ++icall;
789 if (icall > 4) icall = 0;
790 onames[icall][0]='\0';
791
792 if ((noext = without_afni_filename_extension(fname))) {
793 flen = strlen(noext);
794 if (fname[strlen(noext)-1] == '.') {
795 if( STRING_HAS_SUFFIX(noext, "+orig.") ||
796 STRING_HAS_SUFFIX(noext, "+acpc.") ||
797 STRING_HAS_SUFFIX(noext, "+tlrc.") ) {
798 flen = flen - 6;
799 strncpy(onames[icall], noext, flen);
800 onames[icall][flen]='\0';
801 }
802 } else if( STRING_HAS_SUFFIX(noext, "+orig") ||
803 STRING_HAS_SUFFIX(noext, "+acpc") ||
804 STRING_HAS_SUFFIX(noext, "+tlrc") ) {
805 flen = flen - 5;
806 strncpy(onames[icall], noext, flen);
807 onames[icall][flen]='\0';
808 } else {
809 strncpy(onames[icall], noext, flen);
810 onames[icall][flen]='\0';
811 }
812
813 RETURN(onames[icall]);
814 }
815
816 RETURN(fname); /* not found */
817 }
818
819 /*--------------------------------------------------------------*/
820 /* Add prefix and/or suffix to filename fname taking care
821 to leave the path undisturbed and known extensions preserved */
822
modify_afni_prefix(char * fname,char * pref,char * suf)823 char * modify_afni_prefix( char * fname , char *pref, char *suf)
824 {
825 char ** eptr;
826 static char onames[9][THD_MAX_NAME+1];
827 static int icall=0;
828 int c, isl, icp, flen, num_ext;
829
830 ENTRY("modify_afni_prefix");
831
832 if( !fname || !*fname ) RETURN(NULL);
833 ++icall;
834 if (icall > 8) icall = 0;
835 onames[icall][0]='\0';
836
837
838 if (!suf && !pref) {
839 /* nothing to do */
840 RETURN(fname);
841 }
842
843 if (pref && strlen(pref)) {
844 flen = strlen(fname);
845 if (flen+strlen(pref) >= THD_MAX_NAME) {
846 WARNING_message("Filename too long for modify_afni_prefix()"
847 "Returing fname");
848 RETURN(fname);
849 }
850
851 /* find last '/' */
852 isl=flen-1;
853 while(isl>=0) {
854 if (fname[isl] == '/') break;
855 --isl;
856 }
857 for (icp=0; icp<=isl; ++icp) onames[icall][icp]=fname[icp];
858 onames[icall][icp]='\0';
859 strcat(onames[icall], pref);
860 strcat(onames[icall],fname+isl+1);
861
862 fname = onames[icall];
863 ++icall; if (icall > 8) icall = 0;
864 onames[icall][0]='\0';
865 }
866
867 if (suf && strlen(suf)) {
868 flen = strlen(fname);
869 if (flen+strlen(suf) >= THD_MAX_NAME) {
870 WARNING_message("Filename too long for modify_afni_prefix()"
871 "Returing fname");
872 RETURN(fname);
873 }
874
875 /* remove the extension */
876 num_ext = sizeof(file_extension_list)/sizeof(char *);
877 for( c = 0, eptr = file_extension_list; c < num_ext; c++, eptr++ ) {
878 if( STRING_HAS_SUFFIX(fname, *eptr) ) {
879 flen = flen - strlen(*eptr);
880 strncpy(onames[icall], fname, flen); onames[icall][flen]='\0';
881 strcat(onames[icall], suf);
882 strcat(onames[icall], *eptr);
883 break;
884 }
885 }
886 if (onames[icall][0] == '\0') {
887 /* no extensions, just append */
888 strcat(onames[icall],fname);
889 strcat(onames[icall], suf);
890 }
891
892 RETURN(onames[icall]);
893 }
894
895 /* should not get here, but be nice anyway */
896 RETURN(fname); /* not found */
897
898 }
899