float mri_quantile( MRI_IMAGE *im , float alpha ) { int ii , nvox ; float fi , quan ; ENTRY("mri_quantile") ; /*** sanity checks ***/ if( im == NULL ) RETURN( 0.0 ); if( alpha <= 0.0 ) RETURN( (float) mri_min(im) ); if( alpha >= 1.0 ) RETURN( (float) mri_max(im) ); nvox = im->nvox ; switch( im->kind ){ /*** create a float image copy of the data, sort it, then interpolate the percentage points ***/ default:{ MRI_IMAGE *inim ; float *far ; inim = mri_to_float( im ) ; far = MRI_FLOAT_PTR(inim) ; qsort_float( nvox , far ) ; fi = alpha * nvox ; ii = (int) fi ; if( ii >= nvox ) ii = nvox-1 ; fi = fi - ii ; quan = (1.0-fi) * far[ii] + fi * far[ii+1] ; mri_free( inim ) ; } break ; /*** create a short image copy of the data, sort it, then interpolate the percentage points ***/ case MRI_short: case MRI_byte:{ MRI_IMAGE *inim ; short *sar ; inim = mri_to_short( 1.0 , im ) ; sar = MRI_SHORT_PTR(inim) ; qsort_short( nvox , sar ) ; fi = alpha * nvox ; ii = (int) fi ; if( ii >= nvox ) ii = nvox-1 ; fi = fi - ii ; quan = (1.0-fi) * sar[ii] + fi * sar[ii+1] ; mri_free( inim ) ; } break ; } RETURN( quan ); }
void mri_percents( MRI_IMAGE *im , int nper , float per[] ) { register int pp , ii , nvox ; register float fi , frac ; /*** sanity checks ***/ if( im == NULL || per == NULL || nper < 2 ) return ; nvox = im->nvox ; frac = nvox / ((float) nper) ; switch( im->kind ){ /*** create a float image copy of the data, sort it, then interpolate the percentage points ***/ default:{ MRI_IMAGE *inim ; float *far ; inim = mri_to_float( im ) ; far = MRI_FLOAT_PTR(inim) ; qsort_float( nvox , far ) ; per[0] = far[0] ; for( pp=1 ; pp < nper ; pp++ ){ fi = frac * pp ; ii = fi ; fi = fi - ii ; per[pp] = (1.0-fi) * far[ii] + fi * far[ii+1] ; } per[nper] = far[nvox-1] ; mri_free( inim ) ; } break ; /*** create a short image copy of the data, sort it, then interpolate the percentage points ***/ case MRI_short: case MRI_byte:{ MRI_IMAGE *inim ; short *sar ; inim = mri_to_short( 1.0 , im ) ; sar = MRI_SHORT_PTR(inim) ; qsort_short( nvox , sar ) ; per[0] = sar[0] ; for( pp=1 ; pp < nper ; pp++ ){ fi = frac * pp ; ii = fi ; fi = fi - ii ; per[pp] = (1.0-fi) * sar[ii] + fi * sar[ii+1] ; } per[nper] = sar[nvox-1] ; mri_free( inim ) ; } } return ; }
double_pair mri_minmax( 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") ; 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] ) ; byte_max = MAX( byte_max , qar[ii] ) ; } 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++ ){ short_min = MIN( short_min , qar[ii] ) ; short_max = MAX( short_max , qar[ii] ) ; } 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++ ){ float_min = MIN( float_min , qar[ii] ) ; float_max = MAX( float_max , qar[ii] ) ; } dp.a = (double)float_min ; dp.b = (double)float_max ; RETURN(dp) ; } default: ERROR_message("mri_minmax: unknown image kind") ; } RETURN( dp ); }
MRI_IMAGE * mri_transpose_short( MRI_IMAGE * im ) { MRI_IMAGE * om ; short * iar , * oar ; int ii,jj,nx,ny ; ENTRY("mri_transpose_short") ; if( im == NULL || im->kind != MRI_short ) RETURN(NULL) ; nx = im->nx ; ny = im->ny ; om = mri_new( ny , nx , MRI_short ) ; iar = MRI_SHORT_PTR(im) ; oar = MRI_SHORT_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) ; }
MRI_IMAGE *mri_to_rgb( MRI_IMAGE *oldim ) /* 11 Feb 1999 */ { MRI_IMAGE *newim ; register int ii , npix ; register byte * rgb ; ENTRY("mri_to_rgb") ; if( oldim == NULL ) RETURN( NULL ); newim = mri_new_conforming( oldim , MRI_rgb ) ; rgb = MRI_RGB_PTR(newim) ; npix = oldim->nvox ; switch( oldim->kind ){ case MRI_byte:{ byte *qar = MRI_BYTE_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) rgb[3*ii] = rgb[3*ii+1] = rgb[3*ii+2] = qar[ii] ; } break ; case MRI_float:{ float *qar = MRI_FLOAT_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) rgb[3*ii] = rgb[3*ii+1] = rgb[3*ii+2] = qar[ii] ; } break ; case MRI_short:{ short *qar = MRI_SHORT_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ) rgb[3*ii] = rgb[3*ii+1] = rgb[3*ii+2] = qar[ii] ; } break ; case MRI_rgb: memcpy( rgb , MRI_RGB_PTR(oldim) , 3*npix ) ; break ; case MRI_rgba:{ rgba *qar = MRI_RGBA_PTR(oldim) ; for( ii=0 ; ii < npix ; ii++ ){ rgb[3*ii] = qar[ii].r ; rgb[3*ii+1] = qar[ii].g ; rgb[3*ii+2] = qar[ii].b ; } } break ; default: ERROR_message("mri_to_rgb: unrecognized image conversion %d",oldim->kind) ; mri_free(newim) ; RETURN(NULL); } MRI_COPY_AUX(newim,oldim) ; RETURN( newim ); }
void mri_histoshort_all( MRI_IMAGE *im , int *hist ) { register int ih , npix , ii ; short *sar ; ENTRY("mri_histoshort_all") ; if( im == NULL || im->kind != MRI_short || hist == NULL ) EXRETURN ; npix = im->nvox ; sar = MRI_SHORT_PTR(im) ; for( ih=0 ; ih < NUM_SHORT ; ih++ ) hist[ih] = 0 ; for( ii=0 ; ii < npix ; ii++ ) hist[ sar[ii]+OFF_SHORT ] ++ ; EXRETURN ; }
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 ); }
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) ; }
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 ); }
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 ); }
THD_3dim_dataset * THD_localhistog( int nsar , THD_3dim_dataset **insar , int numval , int *rlist , MCW_cluster *nbhd , int do_prob , int verb ) { THD_3dim_dataset *outset=NULL , *inset ; int nvox=DSET_NVOX(insar[0]) ; int ids, iv, bb, nnpt=nbhd->num_pt ; MRI_IMAGE *bbim ; int btyp ; float **outar , **listar ; ENTRY("THD_localhistog") ; /*---- create output dataset ----*/ outset = EDIT_empty_copy(insar[0]) ; EDIT_dset_items( outset , ADN_nvals , numval , ADN_datum_all , MRI_float , ADN_nsl , 0 , ADN_brick_fac , NULL , ADN_none ) ; outar = (float **)malloc(sizeof(float *)*numval) ; for( bb=0 ; bb < numval ; bb++ ){ EDIT_substitute_brick( outset , bb , MRI_float , NULL ) ; outar[bb] = DSET_BRICK_ARRAY(outset,bb) ; } /*---- make mapping between values and arrays to get those values ----*/ listar = (float **)malloc(sizeof(float *)*TWO16) ; for( bb=0 ; bb < TWO16 ; bb++ ) listar[bb] = outar[0] ; for( bb=1 ; bb < numval ; bb++ ){ listar[ rlist[bb] + TWO15 ] = outar[bb] ; } /*----------- loop over datasets, add in counts for all voxels -----------*/ for( ids=0 ; ids < nsar ; ids++ ){ /* dataset loop */ inset = insar[ids] ; DSET_load(inset) ; for( iv=0 ; iv < DSET_NVALS(inset) ; iv++ ){ /* sub-brick loop */ if( verb ) fprintf(stderr,".") ; bbim = DSET_BRICK(inset,iv) ; btyp = bbim->kind ; if( nnpt == 1 ){ /* only 1 voxel in nbhd */ int qq,ii,jj,kk,ib,nb ; switch( bbim->kind ){ case MRI_short:{ short *sar = MRI_SHORT_PTR(bbim) ; for( qq=0 ; qq < nvox ; qq++ ) listar[sar[qq]+TWO15][qq]++ ; } break ; case MRI_byte:{ byte *bar = MRI_BYTE_PTR(bbim) ; for( qq=0 ; qq < nvox ; qq++ ) listar[bar[qq]+TWO15][qq]++ ; } break ; case MRI_float:{ float *far = MRI_FLOAT_PTR(bbim) ; short ss ; for( qq=0 ; qq < nvox ; qq++ ){ ss = SHORTIZE(far[qq]); listar[ss+TWO15][qq]++; } } break ; } } else { /* multiple voxels in nbhd */ AFNI_OMP_START ; #pragma omp parallel { int qq,ii,jj,kk,ib,nb ; void *nar ; short *sar,ss ; byte *bar ; float *far ; nar = malloc(sizeof(float)*nnpt) ; sar = (short *)nar ; bar = (byte *)nar ; far = (float *)nar ; #pragma omp for for( qq=0 ; qq < nvox ; qq++ ){ /* qq=voxel index */ ii = DSET_index_to_ix(inset,qq) ; jj = DSET_index_to_jy(inset,qq) ; kk = DSET_index_to_kz(inset,qq) ; nb = mri_get_nbhd_array( bbim , NULL , ii,jj,kk , nbhd , nar ) ; if( nb == 0 ) continue ; switch( btyp ){ case MRI_short: for( ib=0 ; ib < nb ; ib++ ) listar[sar[ib]+TWO15][qq]++ ; break ; case MRI_byte: for( ib=0 ; ib < nb ; ib++ ) listar[bar[ib]+TWO15][qq]++ ; break ; case MRI_float: for( ib=0 ; ib < nb ; ib++ ){ ss = SHORTIZE(far[ib]); listar[ss+TWO15][qq]++; } break ; } } /* end of voxel loop */ free(nar) ; } /* end of OpenMP */ AFNI_OMP_END ; } } /* end of sub-brick loop */ DSET_unload(inset) ; } /* end of dataset loop */ if( verb ) fprintf(stderr,"\n") ; free(listar) ; /*---- post-process output ---*/ if( do_prob ){ byte **bbar ; int pp ; if( verb ) INFO_message("Conversion to probabilities") ; AFNI_OMP_START ; #pragma omp parallel { int qq , ib ; float pfac , val ; byte **bbar ; #pragma omp for for( qq=0 ; qq < nvox ; qq++ ){ pfac = 0.0001f ; for( ib=0 ; ib < numval ; ib++ ) pfac += outar[ib][qq] ; pfac = 250.0f / pfac ; for( ib=0 ; ib < numval ; ib++ ){ val = outar[ib][qq]*pfac ; outar[ib][qq] = BYTEIZE(val) ; } } } /* end OpenMP */ AFNI_OMP_END ; bbar = (byte **)malloc(sizeof(byte *)*numval) ; for( bb=0 ; bb < numval ; bb++ ){ bbar[bb] = (byte *)malloc(sizeof(byte)*nvox) ; for( pp=0 ; pp < nvox ; pp++ ) bbar[bb][pp] = (byte)outar[bb][pp] ; EDIT_substitute_brick(outset,bb,MRI_byte,bbar[bb]) ; EDIT_BRICK_FACTOR(outset,bb,0.004f) ; } free(bbar) ; } /* end of do_prob */ free(outar) ; RETURN(outset) ; }
int main( int argc , char *argv[] ) { int iarg=1 , ii,nvox , nvals ; THD_3dim_dataset *inset=NULL, *outset=NULL , *mset=NULL ; char *prefix="./blurinmask" ; float fwhm_goal=0.0f ; int fwhm_2D=0 ; byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0 , automask=0 , nmask=0 ; float dx,dy,dz=0.0f , *bar , val ; int floatize=0 ; /* 18 May 2009 */ MRI_IMAGE *immask=NULL ; /* 07 Oct 2009 */ short *mmask=NULL ; short *unval_mmask=NULL ; int nuniq_mmask=0 ; int do_preserve=0 , use_qsar ; /* 19 Oct 2009 */ THD_3dim_dataset *fwhmset=NULL ; MRI_IMAGE *fxim=NULL, *fyim=NULL, *fzim=NULL ; /* 13 Jun 2016 */ int niter_fxyz=0 ; float dmax=0.0f , dmin=0.0f ; /*------- help the pitifully ignorant luser? -------*/ AFNI_SETUP_OMP(0) ; /* 24 Jun 2013 */ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf( "Usage: ~1~\n" "3dBlurInMask [options]\n" "Blurs a dataset spatially inside a mask. That's all. Experimental.\n" "\n" "OPTIONS ~1~\n" "-------\n" " -input ddd = This required 'option' specifies the dataset\n" " that will be smoothed and output.\n" " -FWHM f = Add 'f' amount of smoothness to the dataset (in mm).\n" " **N.B.: This is also a required 'option'.\n" " -FWHMdset d = Read in dataset 'd' and add the amount of smoothness\n" " given at each voxel -- spatially variable blurring.\n" " ** EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL **\n" " -mask mmm = Mask dataset, if desired. Blurring will\n" " occur only within the mask. Voxels NOT in\n" " the mask will be set to zero in the output.\n" " -Mmask mmm = Multi-mask dataset -- each distinct nonzero\n" " value in dataset 'mmm' will be treated as\n" " a separate mask for blurring purposes.\n" " **N.B.: 'mmm' must be byte- or short-valued!\n" " -automask = Create an automask from the input dataset.\n" " **N.B.: only 1 masking option can be used!\n" " -preserve = Normally, voxels not in the mask will be\n" " set to zero in the output. If you want the\n" " original values in the dataset to be preserved\n" " in the output, use this option.\n" " -prefix ppp = Prefix for output dataset will be 'ppp'.\n" " **N.B.: Output dataset is always in float format.\n" " -quiet = Don't be verbose with the progress reports.\n" " -float = Save dataset as floats, no matter what the\n" " input data type is.\n" " **N.B.: If the input dataset is unscaled shorts, then\n" " the default is to save the output in short\n" " format as well. In EVERY other case, the\n" " program saves the output as floats. Thus,\n" " the ONLY purpose of the '-float' option is to\n" " force an all-shorts input dataset to be saved\n" " as all-floats after blurring.\n" "\n" "NOTES ~1~\n" "-----\n" " * If you don't provide a mask, then all voxels will be included\n" " in the blurring. (But then why are you using this program?)\n" " * Note that voxels inside the mask that are not contiguous with\n" " any other voxels inside the mask will not be modified at all!\n" " * Works iteratively, similarly to 3dBlurToFWHM, but without\n" " the extensive overhead of monitoring the smoothness.\n" " * But this program will be faster than 3dBlurToFWHM, and probably\n" " slower than 3dmerge.\n" " * Since the blurring is done iteratively, rather than all-at-once as\n" " in 3dmerge, the results will be slightly different than 3dmerge's,\n" " even if no mask is used here (3dmerge, of course, doesn't take a mask).\n" " * If the original FWHM of the dataset was 'S' and you input a value\n" " 'F' with the '-FWHM' option, then the output dataset's smoothness\n" " will be about sqrt(S*S+F*F). The number of iterations will be\n" " about (F*F/d*d) where d=grid spacing; this means that a large value\n" " of F might take a lot of CPU time!\n" " * The spatial smoothness of a 3D+time dataset can be estimated with a\n" " command similar to the following:\n" " 3dFWHMx -detrend -mask mmm+orig -input ddd+orig\n" ) ; printf( " * The minimum number of voxels in the mask is %d\n",MASK_MIN) ; printf( " * Isolated voxels will be removed from the mask!\n") ; PRINT_AFNI_OMP_USAGE("3dBlurInMask",NULL) ; PRINT_COMPILE_DATE ; exit(0) ; } /*---- official startup ---*/ PRINT_VERSION("3dBlurInMask"); mainENTRY("3dBlurInMask main"); machdep(); AFNI_logger("3dBlurInMask",argc,argv); AUTHOR("RW Cox") ; /*---- loop over options ----*/ while( iarg < argc && argv[iarg][0] == '-' ){ if( strncmp(argv[iarg],"-preserve",5) == 0 ){ /* 19 Oct 2009 */ do_preserve = 1 ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-qui",4) == 0 ){ verb = 0 ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-ver",4) == 0 ){ verb++ ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-input") == 0 || strcmp(argv[iarg],"-dset") == 0 ){ if( inset != NULL ) ERROR_exit("Can't have two -input options") ; if( ++iarg >= argc ) ERROR_exit("Need argument after '-input'") ; inset = THD_open_dataset( argv[iarg] ); CHECK_OPEN_ERROR(inset,argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-prefix'") ; prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Bad name after '-prefix'") ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-Mmask") == 0 ){ /* 07 Oct 2009 */ if( ++iarg >= argc ) ERROR_exit("Need argument after '-Mmask'") ; if( mmask != NULL || mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ; mset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(mset,argv[iarg]) ; DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ; mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset); #if 0 if( !MRI_IS_INT_TYPE(DSET_BRICK_TYPE(mset,0)) ) ERROR_exit("-Mmask dataset is not integer type!") ; #endif immask = mri_to_short( 1.0 , DSET_BRICK(mset,0) ) ; mmask = MRI_SHORT_PTR(immask) ; unval_mmask = UniqueShort( mmask, mask_nx*mask_ny*mask_nz, &nuniq_mmask, 0 ) ; if( unval_mmask == NULL || nuniq_mmask == 0 ) ERROR_exit("-Mmask dataset cannot be processed!?") ; if( nuniq_mmask == 1 && unval_mmask[0] == 0 ) ERROR_exit("-Mmask dataset is all zeros!?") ; if( verb ){ int qq , ww ; for( ii=qq=0 ; ii < nuniq_mmask ; ii++ ) if( unval_mmask[ii] != 0 ) qq++ ; for( ii=ww=0 ; ii < immask->nvox ; ii++ ) if( mmask[ii] != 0 ) ww++ ; INFO_message("%d unique nonzero values in -Mmask; %d nonzero voxels",qq,ww) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ; if( mmask != NULL || mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ; mset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(mset,argv[iarg]) ; DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ; mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset); mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_unload(mset) ; if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ; ii = THD_mask_remove_isolas( mask_nx,mask_ny,mask_nz , mask ) ; if( verb && ii > 0 ) INFO_message("Removed %d isola%s from mask dataset",ii,(ii==1)?"\0":"s") ; nmask = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ; if( verb ) INFO_message("Number of voxels in mask = %d",nmask) ; if( nmask < MASK_MIN ) ERROR_exit("Mask is too small to process") ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-automask") == 0 ){ if( mmask != NULL || mask != NULL ) ERROR_exit("Can't have 2 mask inputs") ; automask = 1 ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-FWHM") == 0 || strcasecmp(argv[iarg],"-FHWM") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); val = (float)strtod(argv[iarg],NULL) ; if( val <= 0.0f ) ERROR_exit("Illegal value after '%s': '%s'", argv[iarg-1],argv[iarg]) ; fwhm_goal = val ; fwhm_2D = 0 ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-FWHMdset") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); if( fwhmset != NULL ) ERROR_exit("You can't use option '-FWHMdset' twice :(") ; fwhmset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(fwhmset,argv[iarg]) ; do_preserve = 1 ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-float",6) == 0 ){ /* 18 May 2009 */ floatize = 1 ; iarg++ ; continue ; } #if 0 if( strcmp(argv[iarg],"-FWHMxy") == 0 || strcmp(argv[iarg],"-FHWMxy") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); val = (float)strtod(argv[iarg],NULL) ; if( val <= 0.0f ) ERROR_exit("Illegal value after '%s': '%s'", argv[iarg-1],argv[iarg]) ; fwhm_goal = val ; fwhm_2D = 1 ; iarg++ ; continue ; } #endif ERROR_exit("Uknown option '%s'",argv[iarg]) ; } /*--- end of loop over options ---*/ /*----- check for stupid inputs, load datasets, et cetera -----*/ if( fwhmset == NULL && fwhm_goal == 0.0f ) ERROR_exit("No -FWHM option given! What do you want?") ; if( fwhmset != NULL && fwhm_goal > 0.0f ){ WARNING_message("-FWHMdset option replaces -FWHM value") ; fwhm_goal = 0.0f ; } if( fwhmset != NULL && mmask != NULL ) ERROR_exit("Sorry: -FWHMdset and -Mmask don't work together (yet)") ; if( inset == NULL ){ if( iarg >= argc ) ERROR_exit("No input dataset on command line?") ; inset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(inset,argv[iarg]) ; } nvox = DSET_NVOX(inset) ; dx = fabs(DSET_DX(inset)) ; if( dx == 0.0f ) dx = 1.0f ; dy = fabs(DSET_DY(inset)) ; if( dy == 0.0f ) dy = 1.0f ; dz = fabs(DSET_DZ(inset)) ; if( dz == 0.0f ) dz = 1.0f ; dmax = MAX(dx,dy) ; if( dmax < dz ) dmax = dz ; /* 13 Jun 2016 */ dmin = MIN(dx,dy) ; if( dmin > dz ) dmin = dz ; if( !floatize ){ /* 18 May 2009 */ if( !THD_datum_constant(inset->dblk) || THD_need_brick_factor(inset) || DSET_BRICK_TYPE(inset,0) != MRI_short ){ if( verb ) INFO_message("forcing output to be stored in float format") ; floatize = 1 ; } else { if( verb ) INFO_message("output dataset will be stored as shorts") ; } } else { if( verb ) INFO_message("output dataset will be stored as floats") ; } #if 0 if( DSET_NZ(inset) == 1 && !fwhm_2D ){ WARNING_message("Dataset is 2D ==> switching from -FWHM to -FWHMxy") ; fwhm_2D = 1 ; } #endif /*--- deal with mask or automask ---*/ if( mask != NULL ){ if( mask_nx != DSET_NX(inset) || mask_ny != DSET_NY(inset) || mask_nz != DSET_NZ(inset) ) ERROR_exit("-mask dataset grid doesn't match input dataset") ; } else if( automask ){ mask = THD_automask( inset ) ; if( mask == NULL ) ERROR_message("Can't create -automask from input dataset?") ; nmask = THD_countmask( DSET_NVOX(inset) , mask ) ; if( verb ) INFO_message("Number of voxels in automask = %d",nmask); if( nmask < MASK_MIN ) ERROR_exit("Automask is too small to process") ; } else if( mmask != NULL ){ if( mask_nx != DSET_NX(inset) || mask_ny != DSET_NY(inset) || mask_nz != DSET_NZ(inset) ) ERROR_exit("-Mmask dataset grid doesn't match input dataset") ; } else { mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ; memset(mask,1,sizeof(byte)*nvox) ; if( verb ) INFO_message("No mask ==> processing all %d voxels",nvox); } /*--- process FWHMdset [13 Jun 2016] ---*/ if( fwhmset != NULL ){ float *fxar,*fyar,*fzar , *fwar ; MRI_IMAGE *fwim ; float fwmax=0.0f , fsx,fsy,fsz ; int ii, nfpos=0 ; if( DSET_NX(inset) != DSET_NX(fwhmset) || DSET_NY(inset) != DSET_NY(fwhmset) || DSET_NZ(inset) != DSET_NZ(fwhmset) ) ERROR_exit("grid dimensions for FWHMdset and input dataset do not match :(") ; STATUS("get fwim") ; DSET_load(fwhmset) ; fwim = mri_scale_to_float(DSET_BRICK_FACTOR(fwhmset,0),DSET_BRICK(fwhmset,0)); fwar = MRI_FLOAT_PTR(fwim); DSET_unload(fwhmset) ; STATUS("process fwar") ; for( ii=0 ; ii < nvox ; ii++ ){ if( mask[ii] && fwar[ii] > 0.0f ){ nfpos++ ; if( fwar[ii] > fwmax ) fwmax = fwar[ii] ; } else { fwar[ii] = 0.0f ; mask[ii] = 0 ; } } if( nfpos < 100 ) ERROR_exit("Cannot proceed: too few (%d) voxels are positive in -FWHMdset!",nfpos) ; niter_fxyz = (int)rintf(2.0f*fwmax*fwmax*FFAC/(0.05f*dmin*dmin)) + 1 ; if( verb ) INFO_message("-FWHMdset: niter=%d npos=%d",niter_fxyz,nfpos) ; STATUS("create fxim etc.") ; fxim = mri_new_conforming(fwim,MRI_float); fxar = MRI_FLOAT_PTR(fxim); fyim = mri_new_conforming(fwim,MRI_float); fyar = MRI_FLOAT_PTR(fyim); fzim = mri_new_conforming(fwim,MRI_float); fzar = MRI_FLOAT_PTR(fzim); fsx = FFAC/(dx*dx*niter_fxyz) ; fsy = FFAC/(dy*dy*niter_fxyz) ; fsz = FFAC/(dz*dz*niter_fxyz) ; /** INFO_message("fsx=%g fsy=%g fsz=%g",fsx,fsy,fsz) ; **/ for( ii=0 ; ii < nvox ; ii++ ){ if( fwar[ii] > 0.0f ){ fxar[ii] = fwar[ii]*fwar[ii] * fsx ; fyar[ii] = fwar[ii]*fwar[ii] * fsy ; fzar[ii] = fwar[ii]*fwar[ii] * fsz ; } else { fxar[ii] = fyar[ii] = fzar[ii] = 0.0f ; } } STATUS("free(fwim)") ; mri_free(fwim) ; } /*--- process input dataset ---*/ STATUS("load input") ; DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; outset = EDIT_empty_copy( inset ) ; /* moved here 04 Jun 2007 */ EDIT_dset_items( outset , ADN_prefix , prefix , ADN_none ) ; EDIT_dset_items( outset , ADN_brick_fac , NULL , ADN_none ) ; /* 11 Sep 2007 */ tross_Copy_History( inset , outset ) ; tross_Make_History( "3dBlurInMask" , argc,argv , outset ) ; nvals = DSET_NVALS(inset) ; use_qsar = (do_preserve || mmask != NULL) ; /* 19 Oct 20090 */ AFNI_OMP_START ; #pragma omp parallel if( nvals > 1 ) { MRI_IMAGE *dsim ; int ids,qit ; byte *qmask=NULL ; register int vv ; MRI_IMAGE *qim=NULL, *qsim=NULL; float *qar=NULL, *dsar, *qsar=NULL; #pragma omp critical (MALLOC) { if( use_qsar ){ qsim = mri_new_conforming(DSET_BRICK(inset,0),MRI_float); qsar = MRI_FLOAT_PTR(qsim); } if( mmask != NULL ){ qmask = (byte *)malloc(sizeof(byte)*nvox) ; qim = mri_new_conforming(immask,MRI_float); qar = MRI_FLOAT_PTR(qim); qim->dx = dx ; qim->dy = dy ; qim->dz = dz ; } } #pragma omp for for( ids=0 ; ids < nvals ; ids++ ){ #pragma omp critical (MALLOC) { dsim = mri_scale_to_float(DSET_BRICK_FACTOR(inset,ids),DSET_BRICK(inset,ids)); DSET_unload_one(inset,ids) ; } dsim->dx = dx ; dsim->dy = dy ; dsim->dz = dz ; dsar = MRI_FLOAT_PTR(dsim) ; /* if needed, initialize qsar with data to be preserved in output */ if( do_preserve ){ for( vv=0 ; vv < nvox ; vv++ ) qsar[vv] = dsar[vv] ; } else if( mmask != NULL ){ for( vv=0 ; vv < nvox ; vv++ ) qsar[vv] = 0.0f ; } if( fwhmset != NULL ){ /* 13 Jun 2016: spatially variable blurring */ for( qit=0 ; qit < niter_fxyz ; qit++ ){ mri_blur3D_variable( dsim , mask , fxim,fyim,fzim ) ; } if( do_preserve ){ for( vv=0 ; vv < nvox ; vv++ ) if( mask[vv] ) qsar[vv] = dsar[vv] ; } } else if( mmask != NULL ){ /* 07 Oct 2009: multiple masks */ int qq ; register short uval ; for( qq=0 ; qq < nuniq_mmask ; qq++ ){ uval = unval_mmask[qq] ; if( uval == 0 ) continue ; for( vv=0 ; vv < nvox ; vv++ ) qmask[vv] = (mmask[vv]==uval) ; /* make mask */ (void)THD_mask_remove_isolas( mask_nx,mask_ny,mask_nz , qmask ) ; nmask = THD_countmask( nvox , qmask ) ; if( verb && ids==0 ) ININFO_message("voxels in Mmask[%d] = %d",uval,nmask) ; if( nmask >= MASK_MIN ){ /* copy data from dataset to qar */ for( vv=0 ; vv < nvox ; vv++ ) if( qmask[vv] ) qar[vv] = dsar[vv] ; /* blur qar (output will be zero where qmask==0) */ mri_blur3D_addfwhm( qim , qmask , fwhm_goal ) ; /** the real work **/ /* copy results back to qsar */ for( vv=0 ; vv < nvox ; vv++ ) if( qmask[vv] ) qsar[vv] = qar[vv] ; } } } else { /* the olden way: 1 mask */ mri_blur3D_addfwhm( dsim , mask , fwhm_goal ) ; /** all the work **/ /* dsim will be zero where mask==0; if we want to preserve the input values, copy dsar into qsar now at all mask!=0 voxels, since qsar contains the original data values */ if( do_preserve ){ for( vv=0 ; vv < nvox ; vv++ ) if( mask[vv] ) qsar[vv] = dsar[vv] ; } } /* if necessary, copy combined results in qsar to dsar for output */ if( use_qsar ){ for( vv=0 ; vv < nvox ; vv++ ) dsar[vv] = qsar[vv] ; } if( floatize ){ EDIT_substitute_brick( outset , ids , MRI_float , dsar ) ; } else { #pragma omp critical (MALLOC) { EDIT_substscale_brick( outset , ids , MRI_float , dsar , MRI_short , 1.0f ) ; mri_free(dsim) ; } } } /* end of loop over sub-bricks */ #pragma omp critical (MALLOC) { if( qsim != NULL ) mri_free(qsim); if( immask != NULL ){ free(qmask); mri_free(qim); } } } /* end OpenMP */ AFNI_OMP_END ; if( mask != NULL ) free( mask) ; if( immask != NULL ) mri_free(immask) ; DSET_unload(inset) ; DSET_write(outset) ; WROTE_DSET(outset) ; exit(0) ; }
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 ); }
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_triple THD_orient_guess( MRI_IMAGE *imm ) { int nvox , ii , nx,ny,nxy,nz , ix,jy,kz , icm,jcm,kcm , nbar ; byte *bar , bp,bm ; float xcm , ycm , zcm , ff , dx,dy,dz ; float xx,yy,zz ; int ni,nj,nk , itop,jtop,ktop , im,ip , jm,jp , km,kp ; float axx,ayy,azz , clip , qx,qy,qz , arr[3] ; int d_LR , d_AP , d_IS ; int_triple it = {-1,-1,-1} ; /*-- check for bad input --*/ if( imm == NULL || imm->nx < 5 || imm->ny < 5 || imm->nz < 5 ) return it ; nx = imm->nx; ny = imm->ny; nz = imm->nz; nxy = nx*ny; nvox = nx*ny*nz; dx = fabs(imm->dx) ; if( dx == 0.0 ) dx = 1.0 ; dy = fabs(imm->dy) ; if( dy == 0.0 ) dy = 1.0 ; dz = fabs(imm->dz) ; if( dz == 0.0 ) dz = 1.0 ; /*-- make mask of NPER levels --*/ bar = (byte *) malloc( sizeof(byte) * nvox ) ; clip = THD_cliplevel( imm , 0.5 ) ; /* start with a binary mask */ switch( imm->kind ){ case MRI_float:{ float *ar = MRI_FLOAT_PTR(imm) ; for( ii=0 ; ii < nvox ; ii++ ) bar[ii] = (ar[ii] >= clip); } break ; case MRI_short:{ short *ar = MRI_SHORT_PTR(imm) ; for( ii=0 ; ii < nvox ; ii++ ) bar[ii] = (ar[ii] >= clip); } break ; case MRI_byte:{ byte *ar = MRI_BYTE_PTR(imm) ; for( ii=0 ; ii < nvox ; ii++ ) bar[ii] = (ar[ii] >= clip); } break ; } nbar = THD_countmask(nvox,bar) ; printf("%d voxels in initial binary mask\n",nbar) ; if( nbar == 0 ){ free(bar); return it; } /* bad */ THD_mask_clust( nx,ny,nz , bar ) ; /* take biggest cluster */ nbar = THD_countmask(nvox,bar) ; printf("%d voxels in final binary mask\n",nbar) ; #ifdef NPER if( nper > 1 ){ float per[NPER+1] ; MRI_IMAGE *qim ; int jj ; qim = mri_new( nbar , 1 , imm->kind ) ; switch(imm->kind){ case MRI_float:{ float *ar=MRI_FLOAT_PTR(imm) , *qar=MRI_FLOAT_PTR(qim) ; for( jj=ii=0 ; ii < nvox ; ii++ ) if( bar[ii] ) qar[jj++] = ar[ii] ; } break ; case MRI_short:{ short *ar=MRI_SHORT_PTR(imm) , *qar=MRI_SHORT_PTR(qim) ; for( jj=ii=0 ; ii < nvox ; ii++ ) if( bar[ii] ) qar[jj++] = ar[ii] ; } break ; case MRI_byte:{ byte *ar=MRI_BYTE_PTR(imm) , *qar=MRI_BYTE_PTR(qim) ; for( jj=ii=0 ; ii < nvox ; ii++ ) if( bar[ii] ) qar[jj++] = ar[ii] ; } break ; } printf("call mri_percents\n") ; mri_percents( qim , nper , per ) ; /* compute nper break points */ mri_free(qim) ; printf("per:") ; for( ii=0 ; ii <= nper ; ii++ ) printf(" %g",per[ii]) ; printf("\n") ; switch( imm->kind ){ case MRI_float:{ float *ar = MRI_FLOAT_PTR(imm) , val ; for( ii=0 ; ii < nvox ; ii++ ){ if( bar[ii] ){ val = ar[ii] ; for( jj=1 ; jj <= nper && val >= per[jj] ; jj++ ) ; /*spin*/ bar[ii] = jj ; } } } break ; case MRI_short:{ short *ar = MRI_SHORT_PTR(imm) , val ; for( ii=0 ; ii < nvox ; ii++ ){ if( bar[ii] ){ val = ar[ii] ; for( jj=1 ; jj <= nper && val >= per[jj] ; jj++ ) ; /*spin*/ bar[ii] = jj ; } } } break ; case MRI_byte:{ byte *ar = MRI_BYTE_PTR(imm) , val ; for( ii=0 ; ii < nvox ; ii++ ){ if( bar[ii] ){ val = ar[ii] ; for( jj=1 ; jj <= nper && val >= per[jj] ; jj++ ) ; /*spin*/ bar[ii] = jj ; } } } break ; } } #endif /* NPER */ /* find center of mass of mask */ xcm = ycm = zcm = ff = 0.0 ; for( ii=0 ; ii < nvox ; ii++ ){ if( bar[ii] ){ ix = (ii % nx) ; xx = ix*dx ; xcm += xx*bar[ii] ; jy = (ii / nx) % ny ; yy = jy*dy ; ycm += yy*bar[ii] ; kz = (ii /nxy) ; zz = kz*dz ; zcm += zz*bar[ii] ; ff += bar[ii] ; } } xcm /= ff ; ycm /= ff ; zcm /= ff ; icm = rint(xcm/dx) ; itop = 2*icm ; if( itop >= nx ) itop = nx-1 ; ni = itop-icm ; jcm = rint(ycm/dy) ; jtop = 2*jcm ; if( jtop >= ny ) jtop = ny-1 ; nj = jtop-jcm ; kcm = rint(zcm/dz) ; ktop = 2*kcm ; if( ktop >= nz ) ktop = nz-1 ; nk = ktop-kcm ; printf("Mask count = %d\n" "icm = %d jcm = %d kcm = %d\n" "ni = %d nj = %d nk = %d\n", (int)ff , icm,jcm,kcm , ni,nj,nk ) ; /** compute asymmetry measures about CM voxel **/ #define BAR(i,j,k) bar[(i)+(j)*nx+(k)*nxy] axx = 0.0 ; for( ix=1 ; ix <= ni ; ix++ ){ im = icm-ix ; ip = icm+ix ; for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){ for( jy=jcm-nj ; jy <= jcm+nj ; jy++ ) axx += abs(BAR(ip,jy,kz) - BAR(im,jy,kz)) ; } } axx /= (ni*nj*nk) ; printf("axx = %g\n",axx) ; ayy = 0.0 ; for( jy=1 ; jy <= nj ; jy++ ){ jm = jcm-jy ; jp = jcm+jy ; for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){ for( ix=icm-ni ; ix <= icm+ni ; ix++ ) ayy += abs(BAR(ix,jp,kz) - BAR(ix,jm,kz)) ; } } ayy /= (ni*nj*nk) ; printf("ayy = %g\n",ayy) ; azz = 0.0 ; for( kz=1 ; kz <= nk ; kz++ ){ km = kcm-kz ; kp = kcm+kz ; for( jy=jcm-nj ; jy <= jcm+nj ; jy++ ){ for( ix=icm-ni ; ix <= icm+ni ; ix++ ) azz += abs(BAR(ix,jy,kp) - BAR(ix,jy,km)) ; } } azz /= (ni*nj*nk) ; printf("azz = %g\n",azz) ; /** least asymettric is L-R direction **/ if( axx < ayy ){ if( axx < azz ) d_LR = 1 ; else d_LR = 3 ; } else { if( ayy < azz ) d_LR = 2 ; else d_LR = 3 ; } printf("axis %d is L-R\n",d_LR) ; arr[0] = axx ; arr[1] = ayy ; arr[2] = azz ; ff = arr[d_LR-1] ; arr[0] /= ff ; arr[1] /= ff ; arr[2] /= ff ; printf("a ratios = %g %g %g\n",arr[0],arr[1],arr[2]) ; /** find asymmetry measures in 1/2 spaces perp to L-R **/ switch( d_LR ){ case 3:{ /* L-R is z-axis */ float axx_jp=0.0, axx_jm=0.0, ayy_ip=0.0, ayy_im=0.0 ; for( ix=1 ; ix <= ni ; ix++ ){ im = icm-ix ; ip = icm+ix ; for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){ for( jy=1 ; jy <= nj ; jy++ ){ axx_jp += abs(BAR(ip,jcm+jy,kz) - BAR(im,jcm+jy,kz)) ; axx_jm += abs(BAR(ip,jcm-jy,kz) - BAR(im,jcm-jy,kz)) ; } } } for( jy=1 ; jy <= nj ; jy++ ){ jm = jcm-jy ; jp = jcm+jy ; for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){ for( ix=1 ; ix <= ni ; ix++ ){ ayy_ip += abs(BAR(icm+ix,jp,kz) - BAR(icm+ix,jm,kz)) ; ayy_im += abs(BAR(icm-ix,jp,kz) - BAR(icm-ix,jm,kz)) ; } } } axx_jp /= (ni*nj*nk) ; axx_jm /= (ni*nj*nk) ; ayy_ip /= (ni*nj*nk) ; ayy_im /= (ni*nj*nk) ; printf("axx_jp=%g axx_jm=%g ayy_ip=%g ayy_im=%g\n", axx_jp,axx_jm , ayy_ip,ayy_im ) ; } /* end of case 3 */ break ; } return it ; }
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) ; }
char * IMREG_main( PLUGIN_interface * plint ) { MCW_idcode * idc ; /* input dataset idcode */ THD_3dim_dataset * old_dset , * new_dset ; /* input and output datasets */ char * new_prefix , * str ; /* strings from user */ int base , ntime , datum , nx,ny,nz , ii,kk , npix ; float dx,dy,dz ; MRI_IMARR * ims_in , * ims_out ; MRI_IMAGE * im , * imbase ; byte ** bptr = NULL , ** bout = NULL ; short ** sptr = NULL , ** sout = NULL ; float ** fptr = NULL , ** fout = NULL ; float * dxar = NULL , * dyar = NULL , * phiar = NULL ; /*--------------------------------------------------------------------*/ /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/ /*--------- go to first input line ---------*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; /* get dataset item */ old_dset = PLUTO_find_dset(idc) ; /* get ptr to dataset */ if( old_dset == NULL ) return "*************************\n" "Cannot find Input Dataset\n" "*************************" ; ntime = DSET_NUM_TIMES(old_dset) ; if( ntime < 2 ) return "*****************************\n" "Dataset has only 1 time point\n" "*****************************" ; ii = DSET_NVALS_PER_TIME(old_dset) ; if( ii > 1 ) return "************************************\n" "Dataset has > 1 value per time point\n" "************************************" ; nx = old_dset->daxes->nxx ; dx = old_dset->daxes->xxdel ; ny = old_dset->daxes->nyy ; dy = old_dset->daxes->yydel ; npix = nx*ny ; nz = old_dset->daxes->nzz ; dz = old_dset->daxes->zzdel ; if( nx != ny || fabs(dx) != fabs(dy) ) { #ifdef IMREG_DEBUG fprintf(stderr,"\nIMREG: nx=%d ny=%d nz=%d dx=%f dy=%f dz=%f\n", nx,ny,nz,dx,dy,dz ) ; #endif return "***********************************\n" "Dataset does not have square slices\n" "***********************************" ; } new_prefix = PLUTO_get_string(plint) ; /* get string item (the output prefix) */ if( ! PLUTO_prefix_ok(new_prefix) ) /* check if it is OK */ return "************************\n" "Output Prefix is illegal\n" "************************" ; /*--------- go to next input line ---------*/ PLUTO_next_option(plint) ; base = PLUTO_get_number(plint) ; if( base >= ntime ) return "********************\n" "Base value too large\n" "********************" ; /*--------- see if the 3rd option line is present --------*/ str = PLUTO_get_optiontag( plint ) ; if( str != NULL ) { float fsig , fdxy , fdph ; fsig = PLUTO_get_number(plint) * 0.42466090 ; fdxy = PLUTO_get_number(plint) ; fdph = PLUTO_get_number(plint) ; mri_align_params( 0 , 0.0,0.0,0.0 , fsig,fdxy,fdph ) ; /* fprintf(stderr,"Set fine params = %f %f %f\n",fsig,fdxy,fdph) ; */ } /*------------- ready to compute new dataset -----------*/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: loading dataset\n") ; #endif DSET_load( old_dset ) ; /*** 1) Copy the dataset in toto ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: Copying dataset\n") ; #endif new_dset = PLUTO_copy_dset( old_dset , new_prefix ) ; if( new_dset == NULL ) return "****************************\n" "Failed to copy input dataset\n" "****************************" ; /*** 2) Make an array of empty images ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: making empty images\n") ; #endif datum = DSET_BRICK_TYPE(new_dset,0) ; INIT_IMARR(ims_in) ; for( ii=0 ; ii < ntime ; ii++ ) { im = mri_new_vol_empty( nx , ny , 1 , datum ) ; ADDTO_IMARR(ims_in,im) ; } imbase = mri_new_vol_empty( nx , ny , 1 , datum ) ; dxar = (float *) malloc( sizeof(float) * ntime ) ; dyar = (float *) malloc( sizeof(float) * ntime ) ; phiar = (float *) malloc( sizeof(float) * ntime ) ; /*** 3) Get pointers to sub-bricks in old and new datasets ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: getting input brick pointers\n") ; #endif switch( datum ) { /* pointer type depends on input datum type */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * ntime ) ; bout = (byte **) malloc( sizeof(byte *) * ntime ) ; for( ii=0 ; ii < ntime ; ii++ ) { bptr[ii] = (byte *) DSET_ARRAY(old_dset,ii) ; bout[ii] = (byte *) DSET_ARRAY(new_dset,ii) ; } break ; case MRI_short: sptr = (short **) malloc( sizeof(short *) * ntime ) ; sout = (short **) malloc( sizeof(short *) * ntime ) ; for( ii=0 ; ii < ntime ; ii++ ) { sptr[ii] = (short *) DSET_ARRAY(old_dset,ii) ; sout[ii] = (short *) DSET_ARRAY(new_dset,ii) ; } #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: sptr[0] = %p sout[0] = %p\n",sptr[0],sout[0]) ; #endif break ; case MRI_float: fptr = (float **) malloc( sizeof(float *) * ntime ) ; fout = (float **) malloc( sizeof(float *) * ntime ) ; for( ii=0 ; ii < ntime ; ii++ ) { fptr[ii] = (float *) DSET_ARRAY(old_dset,ii) ; fout[ii] = (float *) DSET_ARRAY(new_dset,ii) ; } break ; } /*** 4) Loop over slices ***/ PLUTO_popup_meter(plint) ; for( kk=0 ; kk < nz ; kk++ ) { /*** 4a) Setup ims_in images to point to input slices ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- setup input images\n",kk) ; #endif for( ii=0 ; ii < ntime ; ii++ ) { im = IMARR_SUBIMAGE(ims_in,ii) ; switch( datum ) { case MRI_byte: mri_fix_data_pointer( bptr[ii] + kk*npix, im ) ; break ; case MRI_short: mri_fix_data_pointer( sptr[ii] + kk*npix, im ) ; break ; case MRI_float: mri_fix_data_pointer( fptr[ii] + kk*npix, im ) ; break ; } } /*** 4b) Setup im to point to base image ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- setup base image\n",kk) ; #endif switch( datum ) { case MRI_byte: mri_fix_data_pointer( bptr[base] + kk*npix, imbase ) ; break ; case MRI_short: mri_fix_data_pointer( sptr[base] + kk*npix, imbase ) ; break ; case MRI_float: mri_fix_data_pointer( fptr[base] + kk*npix, imbase ) ; break ; } /*** 4c) Register this slice at all times ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- register\n",kk) ; #endif ims_out = mri_align_dfspace( imbase , NULL , ims_in , ALIGN_REGISTER_CODE , dxar,dyar,phiar ) ; if( ims_out == NULL ) fprintf(stderr,"IMREG: mri_align_dfspace return NULL\n") ; /*** 4d) Put the output back in on top of the input; note that the output is always in MRI_float format ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- put output back into dataset\n",kk) ; #endif for( ii=0 ; ii < ntime ; ii++ ) { switch( datum ) { case MRI_byte: im = mri_to_mri( MRI_byte , IMARR_SUBIMAGE(ims_out,ii) ) ; memcpy( bout[ii] + kk*npix , MRI_BYTE_PTR(im) , sizeof(byte)*npix ) ; mri_free(im) ; break ; case MRI_short: #ifdef IMREG_DEBUG if( ii==0 )fprintf(stderr,"IMREG: conversion to short at ii=%d\n",ii) ; #endif im = mri_to_mri( MRI_short , IMARR_SUBIMAGE(ims_out,ii) ) ; #ifdef IMREG_DEBUG if( ii==0 )fprintf(stderr,"IMREG: copying to %p from %p\n",sout[ii] + kk*npix,MRI_SHORT_PTR(im)) ; #endif memcpy( sout[ii] + kk*npix , MRI_SHORT_PTR(im) , sizeof(short)*npix ) ; #ifdef IMREG_DEBUG if( ii==0 )fprintf(stderr,"IMREG: freeing\n") ; #endif mri_free(im) ; break ; case MRI_float: im = IMARR_SUBIMAGE(ims_out,ii) ; memcpy( fout[ii] + kk*npix , MRI_FLOAT_PTR(im) , sizeof(float)*npix ) ; break ; } } PLUTO_set_meter(plint, (100*(kk+1))/nz ) ; /*** 4e) Destroy the output images ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: destroying aligned output\n") ; #endif DESTROY_IMARR( ims_out ) ; } /*** 5) Destroy the empty images and other workspaces ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: destroy workspaces\n") ; #endif mri_clear_data_pointer(imbase) ; mri_free(imbase) ; for( ii=0 ; ii < ntime ; ii++ ) { im = IMARR_SUBIMAGE(ims_in,ii) ; mri_clear_data_pointer(im) ; } DESTROY_IMARR(ims_in) ; FREE_WORKSPACE ; /*------------- let AFNI know about the new dataset ------------*/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: send result to AFNI\n") ; #endif PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ; return NULL ; /* null string returned means all was OK */ }
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 ); }
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_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 ); }
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 ); }
float_pair mri_twoquantiles( MRI_IMAGE *im, float alpha, float beta ) { int ii , nvox ; float fi ; float_pair qt = {0.0f,0.0f} ; float qalph=WAY_BIG,qbeta=WAY_BIG ; ENTRY("mri_twoquantiles") ; /*** sanity checks ***/ if( im == NULL ) RETURN( qt ); if( alpha == beta ){ qt.a = qt.b = mri_quantile(im,alpha) ; RETURN( qt ); } if( alpha <= 0.0f ) qalph = (float) mri_min(im) ; else if( alpha >= 1.0f ) qalph = (float) mri_max(im) ; if( beta <= 0.0f ) qbeta = (float) mri_min(im) ; else if( beta >= 1.0f ) qbeta = (float) mri_max(im) ; if( qalph != WAY_BIG && qbeta != WAY_BIG ){ qt.a = qalph; qt.b = qbeta; RETURN(qt); } nvox = im->nvox ; switch( im->kind ){ /*** create a float image copy of the data, sort it, then interpolate the percentage points ***/ default:{ MRI_IMAGE *inim ; float *far ; inim = mri_to_float( im ) ; far = MRI_FLOAT_PTR(inim) ; qsort_float( nvox , far ) ; if( alpha > 0.0f && alpha < 1.0f ){ fi = alpha * nvox ; ii = (int) fi ; if( ii >= nvox ) ii = nvox-1 ; fi = fi - ii ; qalph = (1.0-fi) * far[ii] + fi * far[ii+1] ; } if( beta > 0.0f && beta < 1.0f ){ fi = beta * nvox ; ii = (int) fi ; if( ii >= nvox ) ii = nvox-1 ; fi = fi - ii ; qbeta = (1.0-fi) * far[ii] + fi * far[ii+1] ; } mri_free( inim ) ; } break ; /*** create a short image copy of the data, sort it, then interpolate the percentage points ***/ case MRI_short: case MRI_byte:{ MRI_IMAGE *inim ; short *sar ; inim = mri_to_short( 1.0 , im ) ; sar = MRI_SHORT_PTR(inim) ; qsort_short( nvox , sar ) ; if( alpha > 0.0f && alpha < 1.0f ){ fi = alpha * nvox ; ii = (int) fi ; if( ii >= nvox ) ii = nvox-1 ; fi = fi - ii ; qalph = (1.0-fi) * sar[ii] + fi * sar[ii+1] ; } if( beta > 0.0f && beta < 1.0f ){ fi = beta * nvox ; ii = (int) fi ; if( ii >= nvox ) ii = nvox-1 ; fi = fi - ii ; qbeta = (1.0-fi) * sar[ii] + fi * sar[ii+1] ; } mri_free( inim ) ; } break ; } qt.a = qalph; qt.b = qbeta; RETURN(qt); }
MRI_IMAGE * mri_dup2D( int nup , MRI_IMAGE *imin ) { MRI_IMAGE *flim , *newim ; float *flar , *newar , *cold , *cnew ; int nx,ny , nxup,nyup , ii,jj,kk, NNmode = 0 ; ENTRY("mri_dup2D") ; /*-- sanity checks --*/ if( nup < 1 || imin == NULL ) RETURN( NULL ); if( nup == 1 ){ newim = mri_to_mri( imin->kind, imin ); RETURN(newim); } /* does the user want neighbor interpolation? 22 Feb 2004 [rickr] */ if ( AFNI_yesenv("AFNI_IMAGE_ZOOM_NN") ) { mri_dup2D_mode(0); NNmode = 1; } /*-- complex-valued images: do each part separately --*/ if( imin->kind == MRI_complex ){ MRI_IMARR *impair ; MRI_IMAGE *rim, *iim, *tim ; impair = mri_complex_to_pair( imin ) ; if( impair == NULL ){ fprintf(stderr,"*** mri_complex_to_pair fails in mri_dup2D!\n"); EXIT(1); } rim = IMAGE_IN_IMARR(impair,0) ; iim = IMAGE_IN_IMARR(impair,1) ; FREE_IMARR(impair) ; tim = mri_dup2D( nup, rim ); mri_free( rim ); rim = tim ; tim = mri_dup2D( nup, iim ); mri_free( iim ); iim = tim ; newim = mri_pair_to_complex( rim , iim ) ; mri_free( rim ) ; mri_free( iim ) ; MRI_COPY_AUX(newim,imin) ; RETURN(newim) ; } /*-- 14 Mar 2002: RGB image up by 2..4, all colors at once --*/ if( imin->kind == MRI_rgb ){ MRI_IMAGE *qqim=NULL ; if ( NNmode ) qqim = mri_dup2D_rgb_NN(imin, nup); /* 22 Feb 2004 [rickr] */ else { switch(nup){ case 4: qqim = mri_dup2D_rgb4(imin); break; /* special purpose fast codes */ case 3: qqim = mri_dup2D_rgb3(imin); break; /* using fixed pt arithmetic */ case 2: qqim = mri_dup2D_rgb2(imin); break; /*-- other factors: do each color separately as a byte image --*/ default:{ MRI_IMARR *imtriple ; MRI_IMAGE *rim, *gim, *bim, *tim ; imtriple = mri_rgb_to_3byte( imin ) ; if( imtriple == NULL ){ fprintf(stderr,"*** mri_rgb_to_3byte fails in mri_dup2D!\n"); RETURN(NULL); } rim = IMAGE_IN_IMARR(imtriple,0) ; gim = IMAGE_IN_IMARR(imtriple,1) ; bim = IMAGE_IN_IMARR(imtriple,2) ; FREE_IMARR(imtriple) ; tim = mri_dup2D( nup, rim ); mri_free(rim); rim = tim; tim = mri_dup2D( nup, gim ); mri_free(gim); gim = tim; tim = mri_dup2D( nup, bim ); mri_free(bim); bim = tim; newim = mri_3to_rgb( rim, gim, bim ) ; mri_free(rim) ; mri_free(gim) ; mri_free(bim) ; MRI_COPY_AUX(newim,imin) ; qqim = newim ; } break ; } } RETURN(qqim) ; } /*-- Special case: byte-valued image upsampled by 2/3/4 [13 Mar 2002] --*/ if( imin->kind == MRI_byte && nup <= 4 ){ void (*usbyte)(int,byte *,byte *) = NULL ; byte *bar=MRI_BYTE_PTR(imin) , *bnew , *cold, *cnew ; nx = imin->nx; ny = imin->ny; nxup = nx*nup; nyup = ny*nup ; newim = mri_new( nxup,nyup , MRI_byte ); bnew = MRI_BYTE_PTR(newim); switch( nup ){ case 2: usbyte = upsample_1by2 ; break ; /* special fast codes */ case 3: usbyte = upsample_1by3 ; break ; case 4: usbyte = upsample_1by4 ; break ; } for( jj=0 ; jj < ny ; jj++ ) /* upsample rows */ usbyte( nx , bar+jj*nx , bnew+jj*nxup ) ; cold = (byte *) malloc( sizeof(byte) * ny ) ; cnew = (byte *) malloc( sizeof(byte) * nyup ) ; for( ii=0 ; ii < nxup ; ii++ ){ /* upsample cols */ for( jj=0 ; jj < ny ; jj++ ) cold[jj] = bnew[ii+jj*nxup] ; usbyte( ny , cold , cnew ) ; for( jj=0 ; jj < nyup ; jj++ ) bnew[ii+jj*nxup] = cnew[jj] ; } free(cold); free(cnew); MRI_COPY_AUX(newim,imin); RETURN(newim); } /*-- otherwise, make sure we operate on a float image --*/ if( imin->kind == MRI_float ) flim = imin ; else flim = mri_to_float( imin ) ; flar = MRI_FLOAT_PTR(flim) ; nx = flim->nx ; ny = flim->ny ; nxup = nx*nup ; nyup = ny*nup ; newim = mri_new( nxup , nyup , MRI_float ) ; newar = MRI_FLOAT_PTR(newim) ; /*-- upsample rows --*/ for( jj=0 ; jj < ny ; jj++ ) usammer( nup , nx , flar + jj*nx , newar + jj*nxup ) ; if( flim != imin ) mri_free(flim) ; /*-- upsample columns --*/ cold = (float *) malloc( sizeof(float) * ny ) ; cnew = (float *) malloc( sizeof(float) * nyup ) ; if( cold == NULL || cnew == NULL ){ fprintf(stderr,"*** mri_dup2D malloc failure!\n"); EXIT(1); } for( ii=0 ; ii < nxup ; ii++ ){ for( jj=0 ; jj < ny ; jj++ ) cold[jj] = newar[ii + jj*nxup] ; usammer( nup , ny , cold , cnew ) ; for( jj=0 ; jj < nyup ; jj++ ) newar[ii+jj*nxup] = cnew[jj] ; } free(cold) ; free(cnew) ; /*-- type convert output, if necessary --*/ switch( imin->kind ){ default: break ; case MRI_byte:{ byte * bar ; MRI_IMAGE * bim ; float fmin , fmax ; bim = mri_new( nxup,nyup , MRI_byte ) ; bar = MRI_BYTE_PTR(bim) ; fmin = mri_min(imin) ; fmax = mri_max(imin) ; for( ii=0 ; ii < newim->nvox ; ii++ ) bar[ii] = (newar[ii] < fmin) ? fmin : (newar[ii] > fmax) ? fmax : newar[ii] ; mri_free(newim) ; newim = bim ; } break ; case MRI_short:{ short * sar ; MRI_IMAGE * sim ; float fmin , fmax ; sim = mri_new( nxup,nyup , MRI_short ) ; sar = MRI_SHORT_PTR(sim) ; fmin = mri_min(imin) ; fmax = mri_max(imin) ; for( ii=0 ; ii < newim->nvox ; ii++ ) sar[ii] = (newar[ii] < fmin) ? fmin : (newar[ii] > fmax) ? fmax : newar[ii] ; mri_free(newim) ; newim = sim ; } break ; case MRI_float:{ float fmin , fmax ; fmin = mri_min(imin) ; fmax = mri_max(imin) ; for( ii=0 ; ii < newim->nvox ; ii++ ) if( newar[ii] < fmin ) newar[ii] = fmin ; else if( newar[ii] > fmax ) newar[ii] = fmax ; } } /*-- finito --*/ MRI_COPY_AUX(newim,imin) ; RETURN( newim ); }