MRI_IMAGE * cx_scramble( MRI_IMAGE * ima , MRI_IMAGE * imb , float alpha , float beta ) { int ii , npix ; double r1,r2 , t1,t2 , rr,tt ; complex * ar , * br , * cr ; double aa,aa1 , bb,bb1 ; MRI_IMAGE * imc ; if( ima == NULL || ima->kind != MRI_complex || imb == NULL || imb->kind != MRI_complex || ima->nx != imb->nx || ima->ny != imb->ny || alpha < 0.0 || alpha > 1.0 || beta < 0.0 || beta > 1.0 ) return NULL ; npix = ima->nvox ; ar = MRI_COMPLEX_PTR(ima) ; br = MRI_COMPLEX_PTR(imb) ; imc = mri_new_conforming( ima , MRI_complex ) ; cr = MRI_COMPLEX_PTR(imc) ; aa = alpha ; aa1 = 1.0 - aa ; bb = beta ; bb1 = 1.0 - bb ; for( ii=0 ; ii < npix ; ii++ ){ r1 = CABS(ar[ii]) ; r2 = CABS(br[ii]) ; rr = pow(r1,aa)*pow(r2,aa1) ; t1 = CARG(ar[ii]) ; t2 = CARG(br[ii]) ; tt = t1-t2 ; if( tt < -PI ) t2 -= 2.0*PI ; else if( tt > PI ) t2 += 2.0*PI ; tt = bb*t1 + bb1*t2 ; cr[ii].r = rr * cos(tt) ; cr[ii].i = rr * sin(tt) ; } return imc ; }
MRI_IMAGE * mri_fft2D( MRI_IMAGE * im , int mode ) { MRI_IMAGE * cxim , * outim ; int nx,ny , nxup,nyup , ii,jj ; complex * cxar , * outar , * cpt , * opt ; float fac ; if( im == NULL ) return NULL ; /* convert input to complex */ cxim = mri_to_complex(im) ; cxar = MRI_COMPLEX_PTR(cxim) ; /* compute size of output */ nx = cxim->nx ; nxup = csfft_nextup_even(nx) ; ny = cxim->ny ; nyup = csfft_nextup_even(ny) ; /* create output array */ outim = mri_new( nxup , nyup , MRI_complex ) ; outar = MRI_COMPLEX_PTR(outim) ; /* copy input to output, zero padding along the way */ opt = outar ; cpt = cxar ; for( jj=0 ; jj < ny ; jj++ ){ for( ii=0 ; ii < nx ; ii++ ){opt->r=cpt->r; opt->i=cpt->i; opt++; cpt++;} for( ; ii < nxup ; ii++ ){opt->r=opt->i=0.0; opt++;} } for( ; jj < nyup ; jj++ ){opt->r=opt->i=0.0; opt++;} mri_free(cxim) ; /* row FFTs */ for( jj=0 ; jj < ny ; jj++ ) csfft_cox( mode , nxup , outar+jj*nxup ) ; /* column FFTs */ cxar = (complex *) malloc(sizeof(complex)*nyup) ; for( ii=0 ; ii < nxup ; ii++ ){ for( jj=0 ; jj < nyup ; jj++ ) cxar[jj] = outar[ii+jj*nxup] ; csfft_cox( mode , nyup , cxar ) ; for( jj=0 ; jj < nyup ; jj++ ) outar[ii+jj*nxup] = cxar[jj] ; } fac = sqrt(1.0/(nxup*nyup)) ; for( ii=0 ; ii < nxup*nyup ; ii++ ){ outar[ii].r *= fac ; outar[ii].i *= fac ; } free(cxar) ; return outim ; }
MRI_IMAGE * mri_pair_to_complex( MRI_IMAGE * rim , MRI_IMAGE * iim ) { MRI_IMAGE * cim , * rfim , * ifim ; register complex * car ; register float * rar , * iar ; register int ii , nvox ; ENTRY("mri_pair_to_complex") ; if( rim == NULL || iim == NULL || rim->nvox != iim->nvox ) RETURN( NULL ); cim = mri_new_conforming( rim , MRI_complex ) ; car = MRI_COMPLEX_PTR(cim) ; rfim = (rim->kind == MRI_float) ? rim : mri_to_float( rim ) ; ifim = (iim->kind == MRI_float) ? iim : mri_to_float( iim ) ; rar = MRI_FLOAT_PTR(rfim) ; iar = MRI_FLOAT_PTR(ifim) ; nvox = rfim->nvox ; for( ii=0 ; ii < nvox ; ii++ ){ car[ii].r = rar[ii] ; car[ii].i = iar[ii] ; } if( rfim != rim ) mri_free( rfim ) ; if( ifim != iim ) mri_free( ifim ) ; RETURN( cim ); }
MRI_IMARR * mri_complex_to_pair( MRI_IMAGE * cim ) { MRI_IMARR * imarr ; MRI_IMAGE * rim , * iim ; register int ii , nvox ; register float * rar , * iar ; register complex * car ; ENTRY("mri_complex_to_pair") ; if( cim == NULL || cim->kind != MRI_complex ) RETURN( NULL ); rim = mri_new_conforming( cim , MRI_float ) ; rar = MRI_FLOAT_PTR(rim) ; iim = mri_new_conforming( cim , MRI_float ) ; iar = MRI_FLOAT_PTR(iim) ; car = MRI_COMPLEX_PTR(cim) ; nvox = cim->nvox ; for( ii=0 ; ii < nvox ; ii++ ){ rar[ii] = car[ii].r ; iar[ii] = car[ii].i ; } INIT_IMARR(imarr) ; ADDTO_IMARR(imarr,rim) ; ADDTO_IMARR(imarr,iim) ; RETURN( imarr ); }
MRI_IMAGE * mri_transpose_complex( MRI_IMAGE * im ) { MRI_IMAGE * om ; complex * iar , * oar ; int ii,jj,nx,ny ; ENTRY("mri_transpose_complex") ; if( im == NULL || im->kind != MRI_complex ) RETURN(NULL) ; nx = im->nx ; ny = im->ny ; om = mri_new( ny , nx , MRI_complex ) ; iar = MRI_COMPLEX_PTR(im) ; oar = MRI_COMPLEX_PTR(om) ; for( jj=0 ; jj < ny ; jj++ ) for( ii=0 ; ii < nx ; ii++ ) oar[jj+ii*ny] = iar[ii+jj*nx] ; MRI_COPY_AUX(om,im) ; RETURN(om) ; }
double mri_maxabs( MRI_IMAGE * im ) { register int ii , npix ; byte byte_max = 0 ; int int_max = 0 ; double double_max = 0.0 ; ENTRY("mri_maxabs") ; npix = im->nvox ; switch( im->kind ){ case MRI_byte:{ byte *qar = MRI_BYTE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) byte_max = MAX( byte_max , qar[ii] ) ; RETURN( (double) byte_max ); } case MRI_short:{ short *qar = MRI_SHORT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) int_max = MAX( int_max , abs(qar[ii]) ) ; RETURN( (double) int_max ); } case MRI_int:{ int *qar = MRI_INT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) int_max = MAX( int_max , abs(qar[ii]) ) ; RETURN( (double) int_max ); } case MRI_float:{ float *qar = MRI_FLOAT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) double_max = MAX( double_max , fabs(qar[ii]) ) ; RETURN( double_max ); } case MRI_double:{ double *qar = MRI_DOUBLE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) double_max = MAX( double_max , fabs(qar[ii]) ) ; RETURN( double_max ); } case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) double_max = MAX( double_max , CABS(qar[ii]) ) ; RETURN( double_max ); } case MRI_rgb: RETURN( mri_max( im ) ); default: ERROR_message("mri_max: unknown image kind") ; } RETURN( 0 ); }
intfloat mri_indmin_nz( MRI_IMAGE *im ) { register int ii , npix ; byte byte_min = 255 ; short short_min = 32767 ; /* 23 Oct 1998: changed from 0 */ int int_min = 2147483647 ; /* ditto */ float float_min = 1.e+38 ; /* changed from -9999999.0 */ double double_min = 1.e+38 ; /* ditto */ intfloat result = { -1 , 0.0f } ; int imin=-1 ; ENTRY("mri_indmin_nz") ; npix = im->nvox ; switch( im->kind ){ case MRI_byte:{ byte *qar = MRI_BYTE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0 ) continue ; if( qar[ii] < byte_min ){ byte_min = qar[ii]; imin = ii; } } result.i = imin; result.a = (float)byte_min; RETURN(result); } case MRI_short:{ short *qar = MRI_SHORT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0 ) continue ; if( qar[ii] < short_min ){ short_min = qar[ii]; imin = ii; } } result.i = imin; result.a = (float)short_min; RETURN(result); } case MRI_int:{ int *qar = MRI_INT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0 ) continue ; if( qar[ii] < int_min ){ int_min = qar[ii]; imin = ii; } } result.i = imin; result.a = (float)int_min; RETURN(result); } case MRI_float:{ float *qar = MRI_FLOAT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0.0f ) continue ; if( qar[ii] < float_min ){ float_min = qar[ii]; imin = ii; } } result.i = imin; result.a = float_min; RETURN(result); } case MRI_double:{ double *qar = MRI_DOUBLE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0.0 ) continue ; if( qar[ii] < double_min ){ double_min = qar[ii]; imin = ii; } } result.i = imin; result.a = (float)double_min; RETURN(result); } case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(im) ; float aval ; for( ii=0 ; ii < npix ; ii++ ){ aval = CABS(qar[ii]) ; if( aval == 0.0f ) continue ; if( aval < float_min ){ float_min = aval; imin = ii; } } result.i = imin; result.a = float_min; RETURN(result); } case MRI_rgb:{ byte *rgb = MRI_RGB_PTR(im) ; double val , bot=255.0 ; for( ii=0 ; ii < npix ; ii++ ){ /* scale to brightness */ val = 0.299 * rgb[3*ii] /* between 0 and 255 */ + 0.587 * rgb[3*ii+1] + 0.114 * rgb[3*ii+2] ; if( val != 0.0 && val < bot ){ bot = val; imin = ii; } } result.i = imin; result.a = (float)bot; RETURN(result); } } RETURN(result); }
double_pair mri_minmax_nz( MRI_IMAGE *im ) { register int ii , npix ; byte byte_min = 255 ; short short_min = 32767 ; int int_min = 2147483647 ; float float_min = 1.e+38 ; double double_min = 1.e+38 ; byte byte_max = 0 ; short short_max = -32767 ; int int_max = -2147483647 ; float float_max = -1.e+38 ; double double_max = -1.e+38 ; double_pair dp = {0.0,0.0} ; ENTRY("mri_minmax_nz") ; npix = im->nvox ; switch( im->kind ){ case MRI_byte:{ byte *qar = MRI_BYTE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0 ) continue ; byte_min = MIN( byte_min , qar[ii] ) ; byte_max = MAX( byte_max , qar[ii] ) ; } if( byte_min <= byte_max ){ dp.a = (double)byte_min ; dp.b = (double)byte_max ; } RETURN(dp) ; } case MRI_short:{ short *qar = MRI_SHORT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0 ) continue ; short_min = MIN( short_min , qar[ii] ) ; short_max = MAX( short_max , qar[ii] ) ; } if( short_min <= short_max ){ dp.a = (double)short_min ; dp.b = (double)short_max ; } RETURN(dp) ; } case MRI_float:{ float *qar = MRI_FLOAT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ){ if( qar[ii] == 0 ) continue ; float_min = MIN( float_min , qar[ii] ) ; float_max = MAX( float_max , qar[ii] ) ; } if( float_min <= float_max ){ dp.a = (double)float_min ; dp.b = (double)float_max ; } RETURN(dp) ; } case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(im) ; float aval ; for( ii=0 ; ii < npix ; ii++ ){ aval = CABS(qar[ii]) ; if( aval == 0.0f ) continue ; float_min = MIN( float_min , aval ) ; float_max = MAX( float_max , aval ) ; } if( float_min <= float_max ){ dp.a = (double)float_min ; dp.b = (double)float_max ; } RETURN(dp) ; } case MRI_rgb:{ byte *rgb = MRI_RGB_PTR(im) ; double val ; for( ii=0 ; ii < npix ; ii++ ){ /* scale to brightness */ val = 0.299 * rgb[3*ii] /* between 0 and 255 */ + 0.587 * rgb[3*ii+1] + 0.114 * rgb[3*ii+2] ; if( val == 0.0f ) continue ; float_min = MIN( float_min , val ) ; float_max = MAX( float_max , val ) ; } if( float_min <= float_max ){ dp.a = (double)float_min ; dp.b = (double)float_max ; } RETURN(dp) ; } default: ERROR_message("mri_minmax_nz: unknown image kind") ; } RETURN( dp ); }
double mri_min( MRI_IMAGE *im ) { register int ii , npix ; byte byte_min = 255 ; short short_min = 32767 ; int int_min = 2147483647 ; float float_min = 1.e+38 ; double double_min = 1.e+38 ; ENTRY("mri_min") ; npix = im->nvox ; switch( im->kind ){ case MRI_byte:{ byte *qar = MRI_BYTE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) byte_min = MIN( byte_min , qar[ii] ) ; RETURN( (double) byte_min ); } case MRI_short:{ short *qar = MRI_SHORT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) short_min = MIN( short_min , qar[ii] ) ; RETURN( (double) short_min ); } case MRI_int:{ int *qar = MRI_INT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) int_min = MIN( int_min , qar[ii] ) ; RETURN( (double) int_min ); } case MRI_float:{ float *qar = MRI_FLOAT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) float_min = MIN( float_min , qar[ii] ) ; RETURN( (double) float_min ); } case MRI_double:{ double *qar = MRI_DOUBLE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) double_min = MIN( double_min , qar[ii] ) ; RETURN( double_min ); } case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) float_min = MIN( float_min , CABS(qar[ii]) ) ; RETURN( float_min ); } case MRI_rgb:{ byte *rgb = MRI_RGB_PTR(im) ; double val , bot=255.9 ; for( ii=0 ; ii < npix ; ii++ ){ /* scale to brightness */ val = 0.299 * rgb[3*ii] /* between 0 and 255 */ + 0.587 * rgb[3*ii+1] + 0.114 * rgb[3*ii+2] ; if( val < bot ) bot = val ; } RETURN( bot ); } default: ERROR_message("mri_min: unknown image kind") ; } RETURN( 0 ); }
double mri_max( MRI_IMAGE *im ) { register int ii , npix ; byte byte_max = 0 ; short short_max = -32767 ; /* 23 Oct 1998: changed from 0 */ int int_max = -2147483647 ; /* ditto */ float float_max = -1.e+38 ; /* changed from -9999999.0 */ double double_max = -1.e+38 ; /* ditto */ ENTRY("mri_max") ; npix = im->nvox ; switch( im->kind ){ case MRI_byte:{ byte *qar = MRI_BYTE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) byte_max = MAX( byte_max , qar[ii] ) ; RETURN( (double) byte_max ); } case MRI_short:{ short *qar = MRI_SHORT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) short_max = MAX( short_max , qar[ii] ) ; RETURN( (double) short_max ); } case MRI_int:{ int *qar = MRI_INT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) int_max = MAX( int_max , qar[ii] ) ; RETURN( (double) int_max ); } case MRI_float:{ float *qar = MRI_FLOAT_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) float_max = MAX( float_max , qar[ii] ) ; RETURN( (double) float_max ); } case MRI_double:{ double *qar = MRI_DOUBLE_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) double_max = MAX( double_max , qar[ii] ) ; RETURN( double_max ); } case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(im) ; for( ii=0 ; ii < npix ; ii++ ) float_max = MAX( float_max , CABS(qar[ii]) ) ; RETURN( float_max ); } case MRI_rgb:{ byte *rgb = MRI_RGB_PTR(im) ; double val , top=0.0 ; for( ii=0 ; ii < npix ; ii++ ){ /* scale to brightness */ val = 0.299 * rgb[3*ii] /* between 0 and 255 */ + 0.587 * rgb[3*ii+1] + 0.114 * rgb[3*ii+2] ; if( val > top ) top = val ; } RETURN( top ); } default: ERROR_message("mri_max: unknown image kind") ; } RETURN( 0.0 ); }
MRI_IMAGE *mri_to_short( double scl , MRI_IMAGE *oldim ) { MRI_IMAGE *newim ; register int ii , npix ; register double scale , val ; register short *sar ; ENTRY("mri_to_short") ; if( oldim == NULL ) RETURN( NULL ); /* 09 Feb 1999 */ newim = mri_new_conforming( oldim , MRI_short ) ; sar = MRI_SHORT_PTR(newim) ; npix = oldim->nvox ; if( scl == 0.0 ){ switch( oldim->kind ){ case MRI_int: case MRI_float: case MRI_double: case MRI_complex: scale = mri_maxabs( oldim ) ; if( scale != 0.0 ) scale = 10000.0 / scale ; #ifdef MRI_DEBUG fprintf( stderr , "mri_to_short: scale factor = %e\n" , scale ) ; #endif break ; default: scale = 1.0 ; break ; } } else { scale = scl ; } switch( oldim->kind ){ case MRI_rgb:{ byte *rgb = MRI_RGB_PTR(oldim) ; float rfac=0.299*scale , gfac=0.587*scale , bfac=0.114*scale ; for( ii=0 ; ii < npix ; ii++ ) sar[ii] = (short)( rfac * rgb[3*ii] + gfac * rgb[3*ii+1] + bfac * rgb[3*ii+2] ) ; } break ; case MRI_byte:{ byte *qar = MRI_BYTE_PTR(oldim) ; if( scale != 1.0 ) for( ii=0 ; ii < npix ; ii++ ){ val = scale * qar[ii] ; sar[ii] = SHORTIZE(val) ; } else for( ii=0 ; ii < npix ; ii++ ) sar[ii] = (short) qar[ii] ; break ; } case MRI_short:{ short *qar = MRI_SHORT_PTR(oldim) ; if( scale != 1.0 ) for( ii=0 ; ii < npix ; ii++ ){ val = scale * qar[ii] ; sar[ii] = SHORTIZE(val) ; } else (void) memcpy( sar , qar , sizeof(short)*npix ) ; break ; } case MRI_int:{ int *qar = MRI_INT_PTR(oldim) ; if( scale != 1.0 ) for( ii=0 ; ii < npix ; ii++ ){ val = scale * qar[ii] ; sar[ii] = SHORTIZE(val) ; } else for( ii=0 ; ii < npix ; ii++ ) sar[ii] = SHORTIZE(qar[ii]) ; break ; } case MRI_float:{ float *qar = MRI_FLOAT_PTR(oldim) ; if( scale != 1.0 ) for( ii=0 ; ii < npix ; ii++ ){ val = scale * qar[ii] ; sar[ii] = SHORTIZE(val) ; } else for( ii=0 ; ii < npix ; ii++ ) sar[ii] = SHORTIZE(qar[ii]) ; break ; } case MRI_double:{ double *qar = MRI_DOUBLE_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) sar[ii] = scale * qar[ii] ; break ; } case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) sar[ii] = scale * CABS(qar[ii]) ; break ; } default: fprintf( stderr , "mri_to_short: unrecognized image kind\n" ) ; MRI_FATAL_ERROR ; } MRI_COPY_AUX(newim,oldim) ; RETURN( newim ); }
MRI_IMAGE *mri_to_complex_ext( MRI_IMAGE *oldim, int xnew, int ynew, int altern ) { MRI_IMAGE *newim ; complex *nar ; int oldx,oldy , itop,jtop , ii,jj , jbold,jbnew ; ENTRY("mri_to_complex_ext") ; if( oldim == NULL ) RETURN( NULL ); /* 09 Feb 1999 */ if( ! MRI_IS_2D(oldim) ){ fprintf(stderr,"\n*** mri_to_complex_ext only works on 2D images\n") ; RETURN( NULL ); } oldx = oldim->nx ; oldy = oldim->ny ; itop = (xnew<oldx) ? xnew : oldx ; /* smallest x dimension */ jtop = (ynew<oldy) ? ynew : oldy ; /* smallest y dimension */ newim = mri_new( xnew , ynew , MRI_complex ) ; nar = MRI_COMPLEX_PTR(newim) ; /*** copy 0..itop by 0..jtop from old into new ***/ for( jj=0 ; jj < jtop ; jj++ ){ jbold = oldx * jj ; jbnew = xnew * jj ; for( ii=0 ; ii < itop ; ii++ ){ nar[ii+jbnew].i = 0.0 ; switch( oldim->kind ){ default: break ; case MRI_byte:{ byte *qar = MRI_BYTE_PTR(oldim) ; nar[ii+jbnew].r = qar[ii+jbold] ; } break ; case MRI_short:{ short *qar = MRI_SHORT_PTR(oldim) ; nar[ii+jbnew].r = qar[ii+jbold] ; } break ; case MRI_int:{ int *qar = MRI_INT_PTR(oldim) ; nar[ii+jbnew].r = qar[ii+jbold] ; } break ; case MRI_float:{ float *qar = MRI_FLOAT_PTR(oldim) ; nar[ii+jbnew].r = qar[ii+jbold] ; } break ; case MRI_double:{ double *qar = MRI_DOUBLE_PTR(oldim) ; nar[ii+jbnew].r = qar[ii+jbold] ; } break ; case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(oldim) ; nar[ii+jbnew] = qar[ii+jbold] ; } break ; } } } /*** if old image is smaller in x, extend all x rows with zeros ***/ if( oldx < xnew ){ for( jj=0 ; jj < jtop ; jj++ ){ jbnew = jj * xnew ; for( ii=oldx ; ii < xnew ; ii++ ){ nar[ii+jbnew].r = 0.0 ; nar[ii+jbnew].i = 0.0 ; } } } /*** if old image is smaller in y, fill out last rows with zeros ***/ for( jj=oldy ; jj < ynew ; jj++ ){ jbnew = jj * xnew ; for( ii=0 ; ii < xnew ; ii++ ){ nar[ii+jbnew].r = 0.0 ; nar[ii+jbnew].i = 0.0 ; } } if( altern ){ for( jj=0 ; jj < ynew ; jj++ ){ jbnew = jj * xnew ; for( ii=0 ; ii < xnew ; ii++ ){ if( (ii+jj)%2 ){ nar[ii+jbnew].r = - nar[ii+jbnew].r ; nar[ii+jbnew].i = - nar[ii+jbnew].i ; } } } } MRI_COPY_AUX(newim,oldim) ; RETURN( newim ); }
int main( int argc , char * argv[] ) { /* --- variable declarations --- */ THD_3dim_dataset * dset ; THD_diskptr * dskptr; int nx, ny, nz, nv, itim; Boolean verbose, nsize; int ok; MRI_IMAGE * im, * im2d, * tim2d; MRI_TYPE kind; int ibr, iz, count, izz,izsub ; int zfirst, zlast, tfirst, tlast; char input_filename[THD_MAX_NAME], prefix_filename[THD_MAX_NAME], output_filename[THD_MAX_NAME], str[THD_MAX_NAME]; /* --- get user command line inputs --- */ F3D_initialize_user_data (argc, argv, &verbose, &nsize, &zfirst, &zlast, &tfirst, &tlast, input_filename, prefix_filename ); /* --- open 3d data set --- */ dset = THD_open_one_dataset( input_filename ) ; if( dset == NULL ) FatalError ("Unable to open input file") ; if ( verbose ) printf("EPsim: 3d Dataset File = %s\n" , input_filename ) ; /* --- load data block --- */ ok = THD_load_datablock( dset->dblk ); if ( !ok ) FatalError ("Unable to load data block") ; /* --- get data dimensions --- */ dskptr = dset->dblk->diskptr; nx = dskptr->dimsizes[0]; ny = dskptr->dimsizes[1]; nz = dskptr->dimsizes[2]; nv = dskptr->nvals; if ( verbose ) printf ("EPsim: nx=%d ny=%d nz=%d nv=%d\n", nx, ny, nz, nv); /* --- check for valid user inputs --- */ if (zfirst < 1) zfirst = 1; if (zlast > nz) zlast = nz; if (tfirst < 1) tfirst = 1; if (tlast > nv) tlast = nv; if (zfirst > nz) FatalError ("No data selected -- zfirst too large."); if (zlast < 1) FatalError ("No data selected -- zlast too small."); if (tfirst > nv) FatalError ("No data selected -- tfirst too large."); if (tlast < 1) FatalError ("No data selected -- tlast too small."); /* --- get data type --- */ kind = IMAGE_IN_IMARR ( dset->dblk->brick, 0 ) -> kind; if ( verbose ) printf ("EPsim: datum = %s \n", MRI_TYPE_name[kind]); /* --- create 2d data pointer --- */ im2d = mri_new_vol_empty ( nx, ny, 1, kind ); /*** open channel to AFNI ***/ sprintf( buf , "tcp:%s:%d" , host , get_port_named("CONTROL_PORT") ) ; ioc = iochan_init( buf , "create" ) ; if( ioc == NULL ) FatalError("Cannot open control channel to AFNI") ; if( verbose ) printf("EPsim: waiting for AFNI") ; fflush(stdout) ; while(1){ iz = iochan_goodcheck( ioc , 1000 ) ; if( iz < 0 ) FatalError("control channel failed") ; if( iz > 0 ) break ; if( verbose ){ printf(".") ; fflush(stdout) ; } } if( verbose ){ printf("!\n") ; fflush(stdout) ; } if( use_shm ) strcpy( buf , SHM_NAME ) ; else sprintf(buf , "tcp:%s:%d" , host , get_port_named("AFNI_PLUGOUT_TCP_BASE") ) ; if( use_child ){ jj = strlen(buf) ; sprintf(buf+jj,"\ncat epsim.out") ; } else if( use_3T ){ jj = strlen(buf) ; sprintf(buf+jj,"\n3T_toafni -dummy < %s" , fname_3T ) ; } if( verbose ) printf("sending control data: %s\n",buf) ; jj = iochan_sendall( ioc , buf , strlen(buf)+1 ) ; if( jj < 0 ) FatalError("send control data failed") ; iochan_sleep(LONG_DELAY) ; /* wait a bit */ while( ! iochan_clearcheck(ioc,LONG_DELAY) ) /* loop until cleared */ iochan_sleep(LONG_DELAY) ; if( verbose ) printf("EPsim: closing control channel\n") ; IOCHAN_CLOSE(ioc) ; /*** now open data channel ***/ ioc = iochan_init( buf , "create" ) ; if( ioc == NULL ) FatalError("Cannot open data channel to AFNI") ; if( verbose ) printf("EPsim: waiting for AFNI") ; fflush(stdout) ; while(1){ iz = iochan_goodcheck( ioc , 1000 ) ; if( iz < 0 ) FatalError("data channel failed") ; if( iz > 0 ) break ; if( verbose ){ printf(".") ; fflush(stdout) ; } } if( verbose ){ printf("!\n") ; fflush(stdout) ; } if( use_child ){ FILE * fp = fopen( "epsim.out" , "w" ) ; if( fp == NULL ){fprintf(stderr,"Can't open epsim.out!\n");IOCHAN_CLOSE(ioc);exit(1);} fprintf( fp , "ZNUM %d\n" "ZDELTA %g\n" "XYFOV %g %g\n" "ZFIRST %g%c\n" "ZORDER seq\n" "XYZAXES %s %s %s\n" "ACQUISITION_TYPE %s\n" , nz , fabs(dset->daxes->zzdel) , fabs(dset->daxes->xxdel)*nx , fabs(dset->daxes->yydel)*ny , fabs(dset->daxes->zzorg) , ORIENT_first[dset->daxes->zzorient] , ORIENT_shortstr[dset->daxes->xxorient] , ORIENT_shortstr[dset->daxes->yyorient] , ORIENT_shortstr[dset->daxes->zzorient] , ( ((zlast-zfirst)>0) ? "2D+zt" : "2D+z" ) ) ; fclose(fp) ; if( verbose ) printf("EPsim: wrote epsim.out file\n") ; sprintf( buf , "XYMATRIX %d %d\n" "DATUM %s\n" , nx , ny , MRI_TYPE_name[kind] ) ; } else if( use_3T ){ sprintf( buf , "XYMATRIX %d %d\n" "DATUM %s\n" , nx , ny , MRI_TYPE_name[kind] ) ; } else { sprintf( buf , "ZNUM %d\n" "ZDELTA %g\n" "XYFOV %g %g\n" "ZFIRST %g%c\n" "ZORDER seq\n" "XYZAXES %s %s %s\n" "ACQUISITION_TYPE %s\n" "XYMATRIX %d %d\n" "DATUM %s\n" , nz , fabs(dset->daxes->zzdel) , fabs(dset->daxes->xxdel)*nx , fabs(dset->daxes->yydel)*ny , fabs(dset->daxes->zzorg) , ORIENT_first[dset->daxes->zzorient] , ORIENT_shortstr[dset->daxes->xxorient] , ORIENT_shortstr[dset->daxes->yyorient] , ORIENT_shortstr[dset->daxes->zzorient] , ( ((zlast-zfirst)>0) ? "2D+zt" : "2D+z" ) , nx , ny , MRI_TYPE_name[kind] ) ; } nbytes = im2d->nvox * im2d->pixel_size ; for( itim=0 ; itim < ntimes ; itim++ ){ count = 0; if( use_3T ) izsub = (nz%2 == 0) ? (nz-1) : (nz) ; for ( ibr = tfirst-1 ; ibr < tlast ; ibr++ ) { for ( iz = zfirst-1 ; iz < zlast ; iz++ ) { /* --- set 2d data pointer into 3d data set --- */ im = IMAGE_IN_IMARR ( dset->dblk->brick, ibr ); if( use_3T ){ izz = 2*iz ; if( izz >= nz ) izz -= izsub ; /* alt ordering */ } else { izz = iz ; /* seq ordering */ } switch ( kind ) { case MRI_byte : mri_set_data_pointer(im2d, MRI_BYTE_PTR(im) + iz*nx*ny) ; break; case MRI_short : mri_set_data_pointer(im2d, MRI_SHORT_PTR(im) + iz*nx*ny) ; break; case MRI_int : mri_set_data_pointer(im2d, MRI_INT_PTR(im) + iz*nx*ny) ; break; case MRI_float : mri_set_data_pointer(im2d, MRI_FLOAT_PTR(im) + iz*nx*ny) ; break; case MRI_double : mri_set_data_pointer(im2d, MRI_DOUBLE_PTR(im) + iz*nx*ny) ; break; case MRI_complex : mri_set_data_pointer(im2d, MRI_COMPLEX_PTR(im) + iz*nx*ny) ; break; case MRI_rgb : mri_set_data_pointer(im2d, MRI_RGB_PTR(im) + 3*iz*nx*ny) ; break; default : FatalError ("Illegal data type encountered."); } #if 0 /* --- create 2d data file name --- */ strcpy ( output_filename, prefix_filename ); if ( nv > 1 ) sprintf ( str, "%02d.%04d", izz+1, ibr+1 ); else if ( nz > 999 ) sprintf ( str, ".%04d", izz+1 ); else sprintf ( str, ".%03d", izz+1 ); strcat ( output_filename, str ); #endif if( first ){ if( verbose ) printf("EPsim: sending this data as header info in image channel:\n%s\n",buf) ; jj = iochan_sendall( ioc , buf , strlen(buf)+1 ) ; if( jj < 0 ) FatalError("send header info failed") ; first = 0 ; } if ( verbose ) printf ( "EPsim: sending 2D image izz=%d ibr=%d\n", izz,ibr ); jj = iochan_sendall( ioc , mri_data_pointer(im2d) , nbytes ) ; if( jj < 0 ) FatalError("send image failed") ; iochan_sleep( delay ) ; #if 0 if ( !nsize ) ok = mri_write ( output_filename, im2d ); else { tim2d = mri_nsize (im2d); ok = mri_write ( output_filename, tim2d); mri_free (tim2d); } #endif count ++ ; } /* --- iz --- */ } /* --- ibr --- */ sleep(20) ; } /* -- itim --*/ if ( verbose ) printf ("Sent %d 2D images. \n", count); if( verbose ){ printf("Waiting for AFNI") ; fflush(stdout) ; } while(1){ jj = iochan_clearcheck(ioc,1000) ; if( jj ) break ; if( verbose ){ printf(".") ; fflush(stdout) ; } } if( verbose ) printf("!\n") ; iochan_sleep(100) ; IOCHAN_CLOSE(ioc) ; exit(0) ; }
MRI_IMAGE * mri_cat2D( int mx , int my , int gap , void *gapval , MRI_IMARR *imar ) { int nx , ny , ii , jj , kind , ij , nxout , nyout , ijoff , jout,iout ; MRI_IMAGE *imout , *imin=NULL ; void *vout ; ENTRY("mri_cat2D") ; /*--- sanity checks ---*/ if( mx < 1 || my < 1 || imar == NULL || (!OK_wrap && imar->num < mx*my) ) RETURN( NULL ); if( gap < 0 || (gap > 0 && gapval == NULL) ) RETURN( NULL ); for( ij=0 ; ij < mx*my ; ij++ ){ /* find first non-empty image */ imin = IMARR_SUBIMAGE(imar,ij%imar->num) ; if( imin != NULL ) break ; } if( ij == mx*my ) RETURN( NULL ); /* all are empty! */ kind = imin->kind ; nx = imin->nx ; ny = imin->ny ; if( mx==1 && my==1 ){ /* 1x1 case (shouldn't happen) */ imout = mri_to_mri( kind , imin ) ; /* Just copy input to output */ RETURN( imout ); } for( ij=0 ; ij < mx*my ; ij++ ){ /* check for consistency */ imin = IMARR_SUBIMAGE(imar,ij%imar->num) ; if( imin != NULL && (imin->kind != kind || imin->nx != nx || imin->ny != ny) ) RETURN( NULL ); } nxout = mx * nx + (mx-1) * gap ; nyout = my * ny + (my-1) * gap ; imout = mri_new( nxout , nyout , kind ) ; vout = mri_data_pointer( imout ) ; ij = 0 ; for( jj=0 ; jj < my ; jj++ ){ /* loop over rows */ for( ii=0 ; ii < mx ; ii++ , ij++ ){ /* loop over columns */ if (WrapZero && ij >= imar->num) imin = NULL; else imin = IMARR_SUBIMAGE(imar,ij%imar->num) ; ijoff = ii * (nx+gap) + jj * (ny+gap) * nxout ; /*--- NULL image ==> fill this spot with zeroes ---*/ if( imin == NULL || mri_data_pointer(imin) == NULL ){ switch( kind ){ case MRI_byte:{ byte *pout = ((byte *) vout); for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) (void) memset( pout+ijoff , 0 , sizeof(byte)*nx ) ; } break ; case MRI_rgb:{ /* 11 Feb 1999 */ byte *pout = ((byte *) vout); for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) (void) memset( pout+(3*ijoff) , 0 , sizeof(byte)*(3*nx) ) ; } break ; case MRI_short:{ short *pout = ((short *) vout); for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) (void) memset( pout+ijoff , 0 , sizeof(short)*nx ) ; } break ; case MRI_int:{ int *pout = ((int *) vout); for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) (void) memset( pout+ijoff , 0 , sizeof(int)*nx ) ; } break ; case MRI_float:{ float *pout = ((float *) vout); for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) for( iout=0 ; iout < nx ; iout++ ) pout[iout+ijoff] = 0 ; } break ; case MRI_double:{ double *pout = ((double *) vout); for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) for( iout=0 ; iout < nx ; iout++ ) pout[iout+ijoff] = 0 ; } break ; case MRI_complex:{ complex *pout = ((complex *) vout); for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) for( iout=0 ; iout < nx ; iout++ ) pout[iout+ijoff].r = pout[iout+ijoff].i = 0 ; } break ; } /*--- Copy input image data into place ---*/ } else { switch( kind ){ case MRI_byte:{ byte *pout = ((byte *) vout) , *pin = (byte *) MRI_BYTE_PTR(imin) ; for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) memcpy( pout+ijoff , pin , sizeof(byte)*nx ) , pin += nx ; } break ; case MRI_rgb:{ /* 11 Feb 1999 */ byte *pout = ((byte *) vout) , *pin = (byte *) MRI_RGB_PTR(imin) ; for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) memcpy( pout+(3*ijoff) , pin , sizeof(byte)*(3*nx) ) , pin += 3*nx ; } break ; case MRI_short:{ short *pout = ((short *) vout) , *pin = (short *) MRI_SHORT_PTR(imin) ; for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) memcpy( pout+ijoff , pin , sizeof(short)*nx ) , pin += nx ; } break ; case MRI_int:{ int *pout = ((int *) vout) , *pin = (int *) MRI_INT_PTR(imin) ; for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) memcpy( pout+ijoff , pin , sizeof(int)*nx ) , pin += nx ; } break ; case MRI_float:{ float *pout = ((float *) vout) , *pin = (float *) MRI_FLOAT_PTR(imin) ; for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) memcpy( pout+ijoff , pin , sizeof(float)*nx ) , pin += nx ; } break ; case MRI_double:{ double *pout = ((double *) vout) , *pin = (double *) MRI_DOUBLE_PTR(imin) ; for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) memcpy( pout+ijoff , pin , sizeof(double)*nx ) , pin += nx ; } break ; case MRI_complex:{ complex *pout = ((complex *) vout) , *pin = (complex *) MRI_COMPLEX_PTR(imin) ; for( jout=0 ; jout < ny ; jout++ , ijoff+=nxout ) memcpy( pout+ijoff , pin , sizeof(complex)*nx ) , pin += nx ; } break ; } } } } /******************* Deal with the gaps *******************/ if( gap > 0 ){ /**** put value into gap after each row ****/ ii = nxout * gap ; for( jj=0 ; jj < my-1 ; jj++ ){ ijoff = (ny + jj * (ny+gap)) * nxout ; switch( kind ){ case MRI_byte:{ byte gval = *((byte *)gapval) , *pout = ((byte *) vout) ; for( ij=0 ; ij < ii ; ij++ ) pout[ij+ijoff] = gval ; } break ; case MRI_rgb:{ /* 11 Feb 1999 */ byte rval = *(((byte *)gapval) ) , gval = *(((byte *)gapval)+1) , bval = *(((byte *)gapval)+2) , *pout = ((byte *) vout) ; for( ij=0 ; ij < ii ; ij++ ){ pout[3*(ij+ijoff) ] = rval ; pout[3*(ij+ijoff)+1] = gval ; pout[3*(ij+ijoff)+2] = bval ; } } break ; case MRI_short:{ short gval = *((short *)gapval) , *pout = ((short *) vout) ; for( ij=0 ; ij < ii ; ij++ ) pout[ij+ijoff] = gval ; } break ; case MRI_float:{ float gval = *((float *)gapval) , *pout = ((float *) vout) ; for( ij=0 ; ij < ii ; ij++ ) pout[ij+ijoff] = gval ; } break ; case MRI_int:{ int gval = *((int *)gapval) , *pout = ((int *) vout) ; for( ij=0 ; ij < ii ; ij++ ) pout[ij+ijoff] = gval ; } break ; case MRI_double:{ double gval = *((double *)gapval) , *pout = ((double *) vout) ; for( ij=0 ; ij < ii ; ij++ ) pout[ij+ijoff] = gval ; } break ; case MRI_complex:{ complex gval = *((complex *)gapval) , *pout = ((complex *) vout) ; for( ij=0 ; ij < ii ; ij++ ) pout[ij+ijoff] = gval ; } break ; } } /**** put value into gap after each column ****/ for( ii=0 ; ii < mx-1 ; ii++ ){ ijoff = nx + ii*(nx+gap) ; switch( kind ){ case MRI_byte:{ byte gval = *((byte *)gapval) , *pout = ((byte *) vout) ; for( ij=0 ; ij < gap ; ij++ , ijoff++ ) for( jj=0 ; jj < nyout ; jj++ ) pout[jj*nxout+ijoff] = gval ; } break ; case MRI_rgb:{ /* 11 Feb 1999 */ byte rval = *(((byte *)gapval) ) , gval = *(((byte *)gapval)+1) , bval = *(((byte *)gapval)+2) , *pout = ((byte *) vout) ; for( ij=0 ; ij < gap ; ij++ , ijoff++ ) for( jj=0 ; jj < nyout ; jj++ ){ pout[3*(jj*nxout+ijoff) ] = rval ; pout[3*(jj*nxout+ijoff)+1] = gval ; pout[3*(jj*nxout+ijoff)+2] = bval ; } } break ; case MRI_short:{ short gval = *((short *)gapval) , *pout = ((short *) vout) ; for( ij=0 ; ij < gap ; ij++ , ijoff++ ) for( jj=0 ; jj < nyout ; jj++ ) pout[jj*nxout+ijoff] = gval ; } break ; case MRI_float:{ float gval = *((float *)gapval) , *pout = ((float *) vout) ; for( ij=0 ; ij < gap ; ij++ , ijoff++ ) for( jj=0 ; jj < nyout ; jj++ ) pout[jj*nxout+ijoff] = gval ; } break ; case MRI_int:{ int gval = *((int *)gapval) , *pout = ((int *) vout) ; for( ij=0 ; ij < gap ; ij++ , ijoff++ ) for( jj=0 ; jj < nyout ; jj++ ) pout[jj*nxout+ijoff] = gval ; } break ; case MRI_double:{ double gval = *((double *)gapval) , *pout = ((double *) vout) ; for( ij=0 ; ij < gap ; ij++ , ijoff++ ) for( jj=0 ; jj < nyout ; jj++ ) pout[jj*nxout+ijoff] = gval ; } break ; case MRI_complex:{ complex gval = *((complex *)gapval) , *pout = ((complex *) vout) ; for( ij=0 ; ij < gap ; ij++ , ijoff++ ) for( jj=0 ; jj < nyout ; jj++ ) pout[jj*nxout+ijoff] = gval ; } break ; } } } RETURN( imout ); }
MRI_IMAGE *mri_to_complex( MRI_IMAGE *oldim ) { MRI_IMAGE *newim ; register int ii , npix ; register complex *nar ; ENTRY("mri_to_complex") ; if( oldim == NULL ) RETURN( NULL ); /* 09 Feb 1999 */ newim = mri_new_conforming( oldim , MRI_complex ) ; npix = oldim->nvox ; nar = MRI_COMPLEX_PTR(newim) ; switch( oldim->kind ){ case MRI_byte:{ byte *qar = MRI_BYTE_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) nar[ii].r = qar[ii] ; } break ; case MRI_short:{ short *qar = MRI_SHORT_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) nar[ii].r = qar[ii] ; } break ; case MRI_int:{ int *qar = MRI_INT_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) nar[ii].r = qar[ii] ; } break ; case MRI_float:{ float *qar = MRI_FLOAT_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) nar[ii].r = qar[ii] ; } break ; case MRI_double:{ double *qar = MRI_DOUBLE_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) nar[ii].r = qar[ii] ; } break ; case MRI_complex:{ complex *qar = MRI_COMPLEX_PTR(oldim) ; (void) memcpy( nar , qar , sizeof(complex)*npix ) ; } break ; case MRI_rgb:{ /* 16 Jun 2000 */ byte *rgb = MRI_RGB_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ){ /* scale to brightness */ nar[ii].r = 0.299 * rgb[3*ii] /* between 0 and 255 */ + 0.587 * rgb[3*ii+1] + 0.114 * rgb[3*ii+2] ; } } break ; default: fprintf( stderr , "mri_to_complex: unrecognized image kind\n" ) ; MRI_FATAL_ERROR ; } if( oldim->kind != MRI_complex ){ for( ii=0 ; ii < npix ; ii++ ) nar[ii].i = 0.0 ; } MRI_COPY_AUX(newim,oldim) ; RETURN( newim ); }
static MRI_IMAGE * mri_fft_3D( int Sign, MRI_IMAGE *inim, int Lxx,int Lyy,int Lzz, int alt ) { MRI_IMAGE *outim ; int ii,jj,kk , nx,ny,nxy,nz , nbig , fx,fy,fz,fxy , joff,koff ; complex *cbig , *car , *far ; if( inim->kind != MRI_complex ) return NULL ; /* input data and its dimensions */ car = MRI_COMPLEX_PTR(inim) ; nx = inim->nx ; ny = inim->ny ; nz = inim->nz ; nxy = nx*ny ; /* output dimensions and data */ fx = (Lxx == 0) ? nx : (Lxx > nx) ? csfft_nextup_even(Lxx) : csfft_nextup_even(nx); fy = (Lyy == 0) ? ny : (Lyy > ny) ? csfft_nextup_even(Lyy) : csfft_nextup_even(ny); fz = (Lzz == 0) ? nz : (Lzz > nz) ? csfft_nextup_even(Lzz) : csfft_nextup_even(nz); fxy = fx*fy ; outim = mri_new_vol( fx,fy,fz , MRI_complex ) ; /* zero filled */ far = MRI_COMPLEX_PTR(outim) ; /* buffer space */ nbig = MAX(fx,fy) ; nbig = MAX(nbig,fz) ; nbig = 4*nbig + 512 ; cbig = (complex *)malloc(sizeof(complex)*nbig) ; /* copy input data into output image */ for( kk=0 ; kk < nz ; kk++ ) for( jj=0 ; jj < ny ; jj++ ) memcpy( far + jj*fx + kk*fxy, car + jj*nx + kk*nxy, sizeof(complex)*nx ); /* x-direction FFTs */ if( Lxx > 1 ){ for( kk=0 ; kk < fz ; kk++ ){ koff = kk*fxy ; for( jj=0 ; jj < fy ; jj++ ){ joff = koff + jj*fx ; for( ii=0 ; ii < fx ; ii++ ) cbig[ii] = far[ii+joff] ; if( alt > 0 ) ALTERN(fx) ; csfft_cox( Sign , fx , cbig ) ; if( alt < 0 ) ALTERN(fx) ; for( ii=0 ; ii < fx ; ii++ ) far[ii+joff] = cbig[ii] ; } } } /* y-direction FFTs */ if( Lyy > 1 ){ for( kk=0 ; kk < fz ; kk++ ){ koff = kk*fxy ; for( ii=0 ; ii < fx ; ii++ ){ joff = koff + ii ; for( jj=0 ; jj < fy ; jj++ ) cbig[jj] = far[jj*fx+joff] ; /* copy data */ if( alt > 0 ) ALTERN(fy) ; csfft_cox( Sign , fy , cbig ) ; /* FFT in buffer */ if( alt < 0 ) ALTERN(fy) ; for( jj=0 ; jj < fy ; jj++ ) far[jj*fx+joff] = cbig[jj] ; /* copy back */ } } } /* z-direction FFTs */ if( Lzz > 1 ){ for( jj=0 ; jj < fy ; jj++ ){ joff = jj*fx ; for( ii=0 ; ii < fx ; ii++ ){ koff = joff + ii ; for( kk=0 ; kk < fz ; kk++ ) cbig[kk] = far[kk*fxy+koff] ; if( alt > 0 ) ALTERN(fz) ; csfft_cox( Sign , fz , cbig ) ; if( alt < 0 ) ALTERN(fz) ; for( kk=0 ; kk < fz ; kk++ ) far[kk*fxy+koff] = cbig[kk] ; } } } free(cbig) ; MRI_COPY_AUX(outim,inim) ; return outim ; }
int main( int argc , char *argv[] ) { THD_3dim_dataset *dset_in=NULL , *dset_out ; int Lxx=-1 , Lyy=-1 , Lzz=-1 , Mode=FFT_ABS , Sign=-1 , do_alt=0 ; char *prefix = "FFTout" ; int iarg ; MRI_IMAGE *inim , *outim ; float fac ; int nx,ny,nz ; THD_ivec3 iv ; if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){ printf( "Usage: 3dFFT [options] dataset\n" "\n" "* Does the FFT of the input dataset in 3 directions (x,y,z) and\n" " produces the output dataset.\n" "\n" "* Why you'd want to do this is an interesting question.\n" "\n" "* Program 3dcalc can operate on complex-valued datasets, but\n" " only on one component at a time (cf. the '-cx2r' option).\n" "\n" "* Most other AFNI programs can only operate on real-valued\n" " datasets.\n" "\n" "* You could use 3dcalc (twice) to split a complex-valued dataset\n" " into two real-valued datasets, do your will on those with other\n" " AFNI programs, then merge the results back into a complex-valued\n" " dataset with 3dTwotoComplex.\n" "\n" "Options\n" "=======\n" " -abs = Outputs the magnitude of the FFT [default]\n" " -phase = Outputs the phase of the FFT (-PI..PI == no unwrapping!)\n" " -complex = Outputs the complex-valued FFT\n" " -inverse = Does the inverse FFT instead of the forward FFT\n" "\n" " -Lx xx = Use FFT of length 'xx' in the x-direction\n" " -Ly yy = Use FFT of length 'yy' in the y-direction\n" " -Lz zz = Use FFT of length 'zz' in the z-direction\n" " * Set a length to 0 to skip the FFT in that direction\n" "\n" " -altIN = Alternate signs of input data before FFT, to bring\n" " zero frequency from edge of FFT-space to center of grid\n" " for cosmetic purposes.\n" " -altOUT = Alternate signs of output data after FFT. If you\n" " use '-altI' on the forward transform, then you should\n" " use '-altO' an the inverse transform, to get the\n" " signs of the recovered image correct.\n" " **N.B.: You cannot use '-altIN' and '-altOUT' in the same run!\n" "\n" " -input dd = Read the input dataset from 'dd', instead of\n" " from the last argument on the command line.\n" "\n" " -prefix pp = Use 'pp' for the output dataset prefix.\n" "\n" "Notes\n" "=====\n" " * In the present avatar, only 1 sub-brick will be processed.\n" "\n" " * The program can only do FFT lengths that are factorable\n" " into a product of powers of 2, 3, and 5, and are even.\n" " + The largest power of 3 that is allowed is 3^3 = 27.\n" " + The largest power of 5 that is allowed is 5^3 = 125.\n" " + e.g., FFT of length 3*5*8=120 is possible.\n" " + e.g., FFT of length 4*31 =124 is not possible.\n" "\n" " * The 'x', 'y', and 'z' axes here refer to the order the\n" " data is stored, not DICOM coordinates; cf. 3dinfo.\n" "\n" " * If you force (via '-Lx' etc.) an FFT length that is not\n" " allowed, the program will stop with an error message.\n" "\n" " * If you force an FFT length that is shorter than an dataset\n" " axis dimension, the program will stop with an error message.\n" "\n" " * If you don't force an FFT length along a particular axis,\n" " the program will pick the smallest legal value that is\n" " greater than or equal to the corresponding dataset dimension.\n" " + e.g., 124 would be increased to 128.\n" "\n" " * If an FFT length is longer than an axis length, then the\n" " input data in that direction is zero-padded at the end.\n" "\n" " * For -abs and -phase, the output dataset is in float format.\n" "\n" " * If you do the forward and inverse FFT, then you should get back\n" " the original dataset, except for roundoff error and except that\n" " the new dataset axis dimensions may be longer than the original.\n" "\n" " * Forward FFT = sum_{k=0..N-1} [ exp(-2*PI*i*k/N) * data(k) ]\n" "\n" " * Inverse FFT = sum_{k=0..N-1} [ exp(+2*PI*i*k/N) * data(k) ] / N\n" "\n" " * Started a long time ago, but only finished in Aug 2009 at the\n" " request of John Butman, because he asked so nicely. (Now pay up!)\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } PRINT_VERSION("3dFFT") ; mainENTRY("3dFFT main") ; machdep() ; AUTHOR("RW Cox") ; AFNI_logger("3dFFT",argc,argv) ; /*--- scan args ---*/ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncasecmp(argv[iarg],"-altI",5) == 0 ){ do_alt = 1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-altOUT",5) == 0 ){ do_alt = -1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-inverse",4) == 0 ){ Sign = +1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-abs",4) == 0 ){ Mode = FFT_ABS ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-phase",4) == 0 ){ Mode = FFT_PHASE ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-complex",4) == 0 ){ Mode = FFT_COMPLEX ; iarg++ ; continue ; } if( strlen(argv[iarg]) == 3 && strncmp(argv[iarg],"-L",2) == 0 ){ int lll=-1 , mmm ; char *ept ; iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after option %s",argv[iarg-1]) ; lll = strtol( argv[iarg] , &ept , 10 ) ; if( *ept != '\0' ) ERROR_exit("bad argument after option %s",argv[iarg-1]) ; if( lll > 0 && (mmm = csfft_nextup_even(lll)) != lll ) ERROR_exit( "'%s %d' is not a legal FFT length here: next largest legal value = %d" , argv[iarg-1] , lll , mmm ) ; switch( argv[iarg-1][2] ){ case 'x': case 'X': Lxx = lll ; break ; case 'y': case 'Y': Lyy = lll ; break ; case 'z': case 'Z': Lzz = lll ; break ; default: ERROR_exit("unknown option '%s'",argv[iarg-1]) ; } iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-prefix",4) == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after %s\n",argv[iarg-1]) ; prefix = strdup( argv[iarg] ) ; if( !THD_filename_ok(prefix) ) ERROR_exit("bad argument after %s\n",argv[iarg-1]) ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-input",4) == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after %s\n",argv[iarg-1]) ; dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]); iarg++ ; continue ; } ERROR_exit("unknown option '%s'\n",argv[iarg]) ; } /* check for simple errors */ if( Lxx == 0 && Lyy == 0 && Lzz == 0 ) ERROR_exit("-Lx, -Ly, -Lz all given as zero?!") ; /* open input dataset */ if( dset_in == NULL ){ if( iarg >= argc ) ERROR_exit("no input dataset on command line?!\n") ; dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]); } nx = DSET_NX(dset_in) ; ny = DSET_NY(dset_in) ; nz = DSET_NZ(dset_in) ; if( DSET_NVALS(dset_in) > 1 ) WARNING_message("only 3dFFT-ing sub-brick #0 of input dataset") ; /* establish actual FFT lengths now (0 ==> no FFT) */ if( nx == 1 ) Lxx = 0 ; /* can't FFT if dataset is shrimpy! */ if( ny == 1 ) Lyy = 0 ; if( nz == 1 ) Lzz = 0 ; if( Lxx < 0 ) Lxx = csfft_nextup_even(nx) ; /* get FFT length from */ if( Lyy < 0 ) Lyy = csfft_nextup_even(ny) ; /* dataset dimensions */ if( Lzz < 0 ) Lzz = csfft_nextup_even(nz) ; INFO_message("x-axis length=%d ; FFT length=%d %s",nx,Lxx,(Lxx==0)?"==> none":"\0") ; INFO_message("y-axis length=%d ; FFT length=%d %s",ny,Lyy,(Lyy==0)?"==> none":"\0") ; INFO_message("z-axis length=%d ; FFT length=%d %s",nz,Lzz,(Lzz==0)?"==> none":"\0") ; if( Lxx > 0 && Lxx < nx ) ERROR_exit("x-axis FFT length too short for data!") ; if( Lyy > 0 && Lyy < ny ) ERROR_exit("y-axis FFT length too short for data!") ; if( Lzz > 0 && Lzz < nz ) ERROR_exit("z-axis FFT length too short for data!") ; /* extract sub-brick #0 */ DSET_load(dset_in) ; CHECK_LOAD_ERROR(dset_in) ; inim = mri_to_complex( DSET_BRICK(dset_in,0) ) ; /* convert input to complex */ fac = DSET_BRICK_FACTOR(dset_in,0) ; if( fac > 0.0f && fac != 1.0f ){ /* scale it if needed */ int ii , nvox = nx*ny*nz ; complex *car = MRI_COMPLEX_PTR(inim) ; for( ii=0 ; ii < nvox ; ii++ ){ car[ii].r *= fac ; car[ii].i *= fac ; } } DSET_unload(dset_in) ; /* input data is all copied now */ /* FFT to get output image */ csfft_scale_inverse(1) ; /* scale by 1/N for inverse FFTs */ outim = mri_fft_3D( Sign , inim , Lxx,Lyy,Lzz , do_alt ) ; mri_free(inim) ; /* post-process output? */ switch( Mode ){ case FFT_ABS:{ MRI_IMAGE *qim = mri_complex_abs(outim) ; mri_free(outim) ; outim = qim ; } break ; case FFT_PHASE:{ MRI_IMAGE *qim = mri_complex_phase(outim) ; mri_free(outim) ; outim = qim ; } break ; } /* create and write output dataset */ dset_out = EDIT_empty_copy( dset_in ) ; tross_Copy_History( dset_in , dset_out ) ; tross_Make_History( "3dFFT" , argc,argv , dset_out ) ; LOAD_IVEC3( iv , outim->nx , outim->ny , outim->nz ) ; EDIT_dset_items( dset_out , ADN_prefix , prefix , ADN_nvals , 1 , ADN_ntt , 0 , ADN_nxyz , iv , /* change dimensions, possibly */ ADN_none ) ; EDIT_BRICK_FACTOR( dset_out , 0 , 0.0 ) ; EDIT_substitute_brick( dset_out , 0 , outim->kind , mri_data_pointer(outim) ) ; DSET_write(dset_out) ; WROTE_DSET(dset_out) ; DSET_unload(dset_out) ; exit(0) ; }
MRI_IMAGE * FD_brick_to_mri( int kslice , int ival , FD_brick * br ) { MRI_IMAGE * im ; /* output */ register int ii,di,ei , jj,dj,ej , base , pp ; char * iar ; /* brick in the input */ MRI_TYPE typ ; /** desire a fake image **/ if( ival < 0 ){ im = mri_new( br->n1 , br->n2 , MRI_short ) ; im->dx = br->del1 ; im->dy = br->del2 ; im->dz = br->del3 ; return im ; } /** otherwise, get ready for a real image **/ if( ival >= br->dset->dblk->nvals ) return NULL ; iar = DSET_ARRAY(br->dset,ival) ; if( iar == NULL ){ /* if data needs to be loaded from disk */ (void) THD_load_datablock( br->dset->dblk ) ; iar = DSET_ARRAY(br->dset,ival) ; if( iar == NULL ) return NULL ; } typ = DSET_BRICK_TYPE(br->dset,ival) ; im = mri_new( br->n1 , br->n2 , typ ) ; im->dx = br->del1 ; im->dy = br->del2 ; im->dz = br->del3 ; switch( typ ){ default: /* don't know what to do --> return nada */ mri_free( im ) ; return NULL ; case MRI_byte:{ register byte * ar = MRI_BYTE_PTR(im) ; register byte * bar = (byte *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_short:{ register short * ar = MRI_SHORT_PTR(im) ; register short * bar = (short *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_float:{ register float * ar = MRI_FLOAT_PTR(im) ; register float * bar = (float *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_int:{ register int * ar = MRI_INT_PTR(im) ; register int * bar = (int *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_double:{ register double * ar = MRI_DOUBLE_PTR(im) ; register double * bar = (double *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_complex:{ register complex * ar = MRI_COMPLEX_PTR(im) ; register complex * bar = (complex *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_rgb:{ /* 15 Apr 2002 */ register rgbyte * ar = (rgbyte *) MRI_RGB_PTR(im) ; register rgbyte * bar = (rgbyte *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; } if( DSET_BRICK_FACTOR(br->dset,ival) != 0.0 ){ MRI_IMAGE * qim ; STATUS(" scaling to float"); qim = mri_scale_to_float( DSET_BRICK_FACTOR(br->dset,ival) , im ) ; mri_free(im) ; im = qim ; } return im ; }
MRI_IMAGE * FD_brick_to_series( int ixyz , FD_brick *br ) { MRI_IMAGE *im ; /* output */ int nv , ival ; char *iar ; /* brick in the input */ MRI_TYPE typ ; int ix,jy,kz , ind ; THD_ivec3 ind_fd , ind_ds ; if( ixyz < 0 || ixyz >= br->n1 * br->n2 * br->n3 ) return NULL ; /** otherwise, get ready for a real image **/ ix = ixyz % br->n1 ; jy = ( ixyz % (br->n1 * br->n2) ) / br->n1 ; kz = ixyz / (br->n1 * br->n2) ; LOAD_IVEC3( ind_fd , ix,jy,kz ) ; ind_ds = THD_fdind_to_3dind( br , ind_fd ) ; ix = ind_ds.ijk[0] ; jy = ind_ds.ijk[1] ; kz = ind_ds.ijk[2] ; ind = (kz * br->dset->daxes->nyy + jy) * br->dset->daxes->nxx + ix ; nv = br->dset->dblk->nvals ; iar = DSET_ARRAY(br->dset,0) ; if( iar == NULL ){ /* if data needs to be loaded from disk */ (void) THD_load_datablock( br->dset->dblk ) ; iar = DSET_ARRAY(br->dset,0) ; if( iar == NULL ) return NULL ; } /* 15 Sep 2004: allow for nonconstant datum */ if( !DSET_datum_constant(br->dset) ){ /* only for stupid users */ float *ar ; im = mri_new( nv , 1 , MRI_float ) ; ar = MRI_FLOAT_PTR(im) ; for( ival = 0 ; ival < nv ; ival++ ) ar[ival] = THD_get_voxel( br->dset , ind , ival ) ; goto image_done ; } /* the older (more efficient) way */ typ = DSET_BRICK_TYPE(br->dset,0) ; im = mri_new( nv , 1 , typ ) ; #if 0 mri_zero_image(im) ; /* 18 Oct 2001 */ #endif switch( typ ){ default: /* don't know what to do --> return nada */ mri_free( im ) ; return NULL ; case MRI_byte:{ byte *ar = MRI_BYTE_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (byte *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_short:{ short *ar = MRI_SHORT_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (short *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_float:{ float *ar = MRI_FLOAT_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (float *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_int:{ int *ar = MRI_INT_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (int *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_double:{ double *ar = MRI_DOUBLE_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (double *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_complex:{ complex *ar = MRI_COMPLEX_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (complex *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; /* 15 Apr 2002: RGB types */ case MRI_rgb:{ rgbyte *ar = (rgbyte *) MRI_RGB_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (rgbyte *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; case MRI_rgba:{ rgba *ar = (rgba *) MRI_RGBA_PTR(im) , *bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (rgba *) DSET_ARRAY(br->dset,ival) ; if( bar != NULL ) ar[ival] = bar[ind] ; } } break ; } if( THD_need_brick_factor(br->dset) ){ MRI_IMAGE *qim ; qim = mri_mult_to_float( br->dset->dblk->brick_fac , im ) ; mri_free(im) ; im = qim ; } /* at this point, the image is ready to ship out; but first, maybe attach a time origin and spacing */ image_done: if( br->dset->taxis != NULL ){ /* 21 Oct 1996 */ float zz , tt ; zz = br->dset->daxes->zzorg + kz * br->dset->daxes->zzdel ; tt = THD_timeof( 0 , zz , br->dset->taxis ) ; im->xo = tt ; im->dx = br->dset->taxis->ttdel ; /* origin and delta */ if( br->dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */ im->xo *= 0.001 ; im->dx *= 0.001 ; } } else { im->xo = 0.0 ; im->dx = 1.0 ; /* 08 Nov 1996 */ } return im ; }
int mri_write_ascii( char *fname, MRI_IMAGE *im ) { int ii , jj , nx , ny ; FILE *imfile ; ENTRY("mri_write_ascii") ; if( im == NULL || im->nz > 1 ) RETURN( 0 ) ; /* stoopid user */ if( fname == NULL || *fname == '\0' ) fname = "-" ; /* to stdout */ imfile = fopen_maybe(fname) ; if( imfile == NULL ) RETURN(0) ; ii = mri_floatscan( im ) ; /* 05 Apr 2010 */ if( ii > 0 ) WARNING_message("Zeroed %d float error%s while writing 1D file %s", ii , (ii > 1) ? "s" : "\0" , fname ) ; nx = im->nx ; ny = im->ny ; for( jj=0 ; jj < ny ; jj++ ){ switch( im->kind ){ default: break ; case MRI_float:{ float *iar = MRI_FLOAT_PTR(im) + (jj*nx) ; for( ii=0 ; ii < nx ; ii++ ) fprintf(imfile," %14g",iar[ii]) ; } break ; case MRI_short:{ short *iar = MRI_SHORT_PTR(im) + (jj*nx) ; for( ii=0 ; ii < nx ; ii++ ) fprintf(imfile," %6d",iar[ii]) ; } break ; case MRI_byte:{ byte *iar = MRI_BYTE_PTR(im) + (jj*nx) ; for( ii=0 ; ii < nx ; ii++ ) fprintf(imfile," %3d",iar[ii]) ; } break ; case MRI_int:{ int *iar = MRI_INT_PTR(im) + (jj*nx) ; for( ii=0 ; ii < nx ; ii++ ) fprintf(imfile," %6d",iar[ii]) ; } break ; case MRI_double:{ double *iar = MRI_DOUBLE_PTR(im) + (jj*nx) ; for( ii=0 ; ii < nx ; ii++ ) fprintf(imfile," %16g",iar[ii]) ; } break ; case MRI_complex:{ complex *iar = MRI_COMPLEX_PTR(im) + (jj*nx) ; for( ii=0 ; ii < nx ; ii++ ) fprintf(imfile," %-1.7g;%-1.7g",iar[ii].r,iar[ii].i) ; } break ; case MRI_rgb:{ byte *iar = MRI_RGB_PTR(im) + (3*jj*nx) ; for( ii=0 ; ii < nx ; ii++ ) fprintf(imfile," %3d %3d %3d",iar[3*ii],iar[3*ii+1],iar[3*ii+2]) ; } break ; } fprintf(imfile,"\n") ; } fclose_maybe(imfile) ; RETURN( 1 ); }
MRI_IMAGE * mri_valpad_2D( int nxbot , int nxtop , int nybot , int nytop , MRI_IMAGE *fim, byte val) { int nxold,nyold , nxnew,nynew , nx,ny ; int ii,jj , iibot,iitop , jjbot,jjtop ; MRI_IMAGE *vim ; ENTRY("mri_valpad_2D") ; /*- check for user stupidity -*/ if( fim == NULL ) RETURN(NULL) ; nx = fim->nx ; ny = fim->ny ; /*- special case: just copy input -*/ if( nxbot == 0 && nybot == 0 && nxtop == 0 && nytop == 0 ){ vim = mri_copy( fim ) ; RETURN(vim) ; } nxold = nx ; nxnew = nxold + nxbot + nxtop ; /* dimensions */ nyold = ny ; nynew = nyold + nybot + nytop ; iibot = MAX(0,-nxbot) ; iitop = MIN(nxold,nxold+nxtop) ; /* range of data */ jjbot = MAX(0,-nybot) ; jjtop = MIN(nyold,nyold+nytop) ; /* in old dataset */ if( nxnew < 1 || iibot >= iitop || /* check for reasonable sizes */ nynew < 1 || jjbot >= jjtop ){ /* and ranges of dataset */ fprintf(stderr,"*** mri_zeropad: can't cut image down to nothing!\n") ; RETURN(NULL) ; } vim = mri_new( nxnew , nynew , fim->kind ) ; MRI_COPY_AUX(vim,fim) ; memset( mri_data_pointer(vim) , val , nxnew*nynew*mri_datum_size(vim->kind) ) ; /* macros for computing 1D subscripts from 2D indices */ #undef SNEW /* in case was defined in some stupid .h file */ #undef SOLD #define SNEW(i,j) ((i+nxbot)+(j+nybot)*nxnew) #define SOLD(i,j) (i+j*nxold) switch( fim->kind ){ /* copy rows of old into new */ default: fprintf(stderr,"*** mri_zeropad: unknown input datum=%d\n",fim->kind) ; mri_free(vim) ; RETURN(NULL) ; case MRI_byte:{ byte *bnew = MRI_BYTE_PTR(vim), *bold = MRI_BYTE_PTR(fim) ; for( jj=jjbot ; jj < jjtop ; jj++ ) for( ii=iibot ; ii < iitop ; ii++ ) bnew[SNEW(ii,jj)] = bold[SOLD(ii,jj)] ; } break ; case MRI_rgb:{ byte *bnew = MRI_RGB_PTR(vim), *bold = MRI_RGB_PTR(fim) ; for( jj=jjbot ; jj < jjtop ; jj++ ) for( ii=iibot ; ii < iitop ; ii++ ){ bnew[3*SNEW(ii,jj) ] = bold[3*SOLD(ii,jj) ] ; bnew[3*SNEW(ii,jj)+1] = bold[3*SOLD(ii,jj)+1] ; bnew[3*SNEW(ii,jj)+2] = bold[3*SOLD(ii,jj)+2] ; } } break ; case MRI_short:{ short *bnew = MRI_SHORT_PTR(vim), *bold = MRI_SHORT_PTR(fim) ; for( jj=jjbot ; jj < jjtop ; jj++ ) for( ii=iibot ; ii < iitop ; ii++ ) bnew[SNEW(ii,jj)] = bold[SOLD(ii,jj)] ; } break ; case MRI_int:{ int *bnew = MRI_INT_PTR(vim), *bold = MRI_INT_PTR(fim) ; for( jj=jjbot ; jj < jjtop ; jj++ ) for( ii=iibot ; ii < iitop ; ii++ ) bnew[SNEW(ii,jj)] = bold[SOLD(ii,jj)] ; } break ; case MRI_float:{ float *bnew = MRI_FLOAT_PTR(vim), *bold = MRI_FLOAT_PTR(fim) ; for( jj=jjbot ; jj < jjtop ; jj++ ) for( ii=iibot ; ii < iitop ; ii++ ) bnew[SNEW(ii,jj)] = bold[SOLD(ii,jj)] ; } break ; case MRI_double:{ double *bnew = MRI_DOUBLE_PTR(vim), *bold = MRI_DOUBLE_PTR(fim) ; for( jj=jjbot ; jj < jjtop ; jj++ ) for( ii=iibot ; ii < iitop ; ii++ ) bnew[SNEW(ii,jj)] = bold[SOLD(ii,jj)] ; } break ; case MRI_complex:{ complex *bnew = MRI_COMPLEX_PTR(vim), *bold = MRI_COMPLEX_PTR(fim) ; for( jj=jjbot ; jj < jjtop ; jj++ ) for( ii=iibot ; ii < iitop ; ii++ ) bnew[SNEW(ii,jj)] = bold[SOLD(ii,jj)] ; } break ; } /* end of switch on datum type */ RETURN(vim) ; }