#include "mrilib.h"
#include <signal.h>
/*******************************************************************/
/*! Write an AFNI dataset as a MINC file.
- fname = MINC filename
- dset = AFNI dataset
- flags = logical OR of various masks:
- MINC_FLOATIZE_MASK => force output in float format
- MINC_SWAPIZE_MASK => add -swap_bytes option
Return value is 1 if went OK, 0 if not.
-------------------------------------------------------------------*/
int THD_write_minc( char *fname, THD_3dim_dataset *dset, int flags )
{
static char *pg=NULL ; static int first=1 ;
int nvals,nvox , iv , floatize , ii , datum , good=1 ;
THD_dataxes *dax ;
char axcode[3] ;
float axstep[3] , axstart[3] ;
int axnum[3] ;
char *cmd ;
FILE *fp ;
void *bar ;
float *far=NULL ;
ENTRY("THD_write_minc") ;
/*-- check inputs for goodness --*/
if( !THD_filename_ok(fname) || fname[0] == '-' ){
fprintf(stderr,"** ERROR: Illegal filename for MINC output: %s\n",
(fname != NULL) ? fname : "(null)" ) ;
RETURN(0) ;
}
if( !ISVALID_DSET(dset) ){
fprintf(stderr,
"** ERROR: Illegal input dataset for MINC output: %s\n",
fname ) ;
RETURN(0) ;
}
/*-- find rawtominc program to do the real work --*/
if( first ){
pg = THD_find_executable("rawtominc") ; first = 0 ;
}
if( pg == NULL ){
fprintf(stderr,
"** ERROR: Can't write MINC file without program rawtominc: %s\n",
fname);
RETURN(0) ;
}
/*-- load dataset from disk, if need be --*/
DSET_load(dset) ;
if( !DSET_LOADED(dset) ){
fprintf(stderr,
"** ERROR: Can't write MINC file since dataset isn't loaded: %s\n",
fname) ;
RETURN(0) ;
}
/*-- check sub-bricks for uniformity in type, legal type, etc. --*/
nvals = DSET_NVALS(dset) ;
nvox = DSET_NVOX(dset) ;
floatize = (flags & MINC_FLOATIZE_MASK) != 0 ;
ii = DSET_BRICK_TYPE(dset,0) ;
for( iv=0 ; iv < nvals ; iv++ ){
if( DSET_BRICK_TYPE(dset,iv) == MRI_complex ){
fprintf(stderr,
"** ERROR: Can't write MINC file since dataset is complex: %s\n",
fname) ;
RETURN(0) ;
}
if( DSET_BRICK_TYPE(dset,iv) == MRI_rgb ){
fprintf(stderr,
"** ERROR: Can't write MINC file since dataset is RGB: %s\n",
fname) ;
RETURN(0) ;
}
/* check if must convert to floats */
if( !floatize ){
if( DSET_BRICK_TYPE(dset,iv) == MRI_float ||
DSET_BRICK_FACTOR(dset,iv) != 0.0 ||
DSET_BRICK_TYPE(dset,iv) != ii ){
floatize = 1 ;
fprintf(stderr,
"++ NOTE: Writing MINC file in float format: %s\n",
fname) ;
}
}
}
if( floatize ) datum = MRI_float ;
else datum = ii ;
/*-- load geometry information --*/
dax = dset->daxes ;
axcode[0] = ORIENT_xyz[ dax->xxorient ] ; axnum[0] = dax->nxx ;
axcode[1] = ORIENT_xyz[ dax->yyorient ] ; axnum[1] = dax->nyy ;
axcode[2] = ORIENT_xyz[ dax->zzorient ] ; axnum[2] = dax->nzz ;
axstep[0] = dax->xxdel ; axstart[0] = dax->xxorg ;
axstep[1] = dax->yydel ; axstart[1] = dax->yyorg ;
axstep[2] = dax->zzdel ; axstart[2] = dax->zzorg ;
if( axcode[0] == 'x' || axcode[0] == 'y' ){
axstep[0] = -axstep[0] ; axstart[0] = -axstart[0] ;
}
if( axcode[1] == 'x' || axcode[1] == 'y' ){
axstep[1] = -axstep[1] ; axstart[1] = -axstart[1] ;
}
if( axcode[2] == 'x' || axcode[2] == 'y' ){
axstep[2] = -axstep[2] ; axstart[2] = -axstart[2] ;
}
/*-- start to create command --*/
cmd = AFMALL(char, 65500) ; /* long enough? */
strcpy(cmd,pg) ; /* basic command */
/* -- swap action */
if (flags & MINC_SWAPIZE_MASK) {
sprintf(cmd+strlen(cmd)," -swap_bytes");
}
/* axes orientation */
sprintf(cmd+strlen(cmd)," -%c%c%c",axcode[2],axcode[1],axcode[0]) ;
/* input and output data type */
sprintf(cmd+strlen(cmd)," -%s -o%s",
MRI_TYPE_name[datum],MRI_TYPE_name[datum]) ;
/* axis stuff */
sprintf(cmd+strlen(cmd),
" -%cstep %.3f -%cstep %.3f -%cstep %.3f"
" -%cstart %.3f -%cstart %.3f -%cstart %.3f"
" -xdircos 1 0 0 -ydircos 0 1 0 -zdircos 0 0 1" ,
axcode[0],axstep[0] ,axcode[1],axstep[1] ,axcode[2],axstep[2] ,
axcode[0],axstart[0],axcode[1],axstart[1],axcode[2],axstart[2] ) ;
/*-- do we create a time step attribute? --*/
if( nvals > 1 & DSET_NUM_TIMES(dset) > 1 && DSET_TIMESTEP(dset) > 0.0 ){
float tr = DSET_TIMESTEP(dset) ;
sprintf(cmd+strlen(cmd)," -dattribute time:step=%.3f",tr) ;
sprintf(cmd+strlen(cmd)," -frame_times '") ;
for( iv=0 ; iv < nvals ; iv++ )
sprintf(cmd+strlen(cmd),"%.3f ",iv*tr) ;
strcat(cmd,"'") ;
}
/*-- Is this Talaraich? --*/
if( dset->view_type == VIEW_TALAIRACH_TYPE ){
sprintf(cmd+strlen(cmd)," -sattribute xspace:spacetype=talairach_") ;
sprintf(cmd+strlen(cmd)," -sattribute yspace:spacetype=talairach_") ;
sprintf(cmd+strlen(cmd)," -sattribute zspace:spacetype=talairach_") ;
}
/*-- integer datasets need to be scanned --*/
/*-- and have valid_range set (stupid MINC) --*/
if( !floatize ){
sprintf(cmd+strlen(cmd)," -scan_range") ;
switch( datum ){
case MRI_short:
sprintf(cmd+strlen(cmd)," -range 0 32767") ; break ;
case MRI_byte:
sprintf(cmd+strlen(cmd)," -range 0 255") ; break ;
}
}
/*-- add output file name --*/
sprintf(cmd+strlen(cmd)," %s",fname) ;
/*-- add # sub-bricks, if > 1 --*/
if( nvals > 1 ) sprintf(cmd+strlen(cmd)," %d",nvals) ;
/*-- add number of points along each axis --*/
sprintf(cmd+strlen(cmd)," %d %d %d" , axnum[2],axnum[1],axnum[0] ) ;
/*-- execute the command as a filter --*/
fprintf(stderr,"About to run %s\n", cmd);
signal( SIGPIPE , SIG_IGN ) ; errno = 0 ;
fp = popen( cmd , "w" ) ;
if( fp == NULL ){
fprintf(stderr,"** ERROR: Can't open MINC output filter: %s\a\n",cmd) ;
if( errno != 0 ) perror("** Unix error message") ;
free(cmd) ; RETURN(0) ;
}
/*-- allocate space for floatizing --*/
if( floatize ){
far = (float *) malloc(sizeof(float)*nvox) ;
if( far == NULL ){
fprintf(stderr,
"** ERROR: Can't write MINC file due to lack of memory: %s\n",
fname) ;
free(cmd) ; RETURN(0) ;
}
}
/*-- loop through sub-bricks, convert to floats if needed, write to pipe --*/
for( iv=0 ; iv < nvals ; iv++ ){
bar = DSET_ARRAY(dset,iv) ; errno = 0 ;
if( floatize ){
EDIT_coerce_scale_type( nvox ,
DSET_BRICK_FACTOR(dset,iv) ,
DSET_BRICK_TYPE(dset,iv) , bar ,
MRI_float , far ) ;
ii = fwrite( far , sizeof(float) , nvox , fp ) ;
} else {
ii = fwrite( bar , mri_datum_size(datum) , nvox , fp ) ;
}
DSET_unload_one(dset,iv) ;
if( ii < nvox ){
fprintf(stderr,
"** ERROR: fwrite to MINC failed at iv=%d: %s\n",
iv , fname ) ;
if( errno ) perror("fwrite") ;
if( ii == 0 ){ good=0; break; } /* don't try to continue */
}
}
if( floatize ) free(far) ; /* no longer needed */
/*-- close pipe --*/
ii = pclose(fp) ;
if( ii == -1 ){
perror("** ERROR in MINC write filter") ;
fprintf(stderr,"** MINC filter command was %s\n\a",cmd) ;
free(cmd) ; RETURN(0) ;
}
/*-- and we are done --*/
free(cmd) ; RETURN(good) ;
}
syntax highlighted by Code2HTML, v. 0.9.1