#include "mrilib.h"
/****************************************************************************
Functions for dealing with data extracted from a neighborhood of a voxel
in a dataset.
-- 19 Aug 2005 - RWCox
*****************************************************************************/
#undef INMASK
#define INMASK(i) ( mask == NULL || mask[i] != 0 )
/*---------------------------------------------------------------------------*/
/*! Extract a nbhd from a dataset sub-brick.
The 3-index of a voxel from the row is in (xx,yy,zz). The result
is a 1D MRI_IMAGE *im, with im->nx = number of points extracted.
If mask!=NULL, then it is a mask of allowed points.
-----------------------------------------------------------------------------*/
MRI_IMAGE * THD_get_dset_nbhd( THD_3dim_dataset *dset, int ival, byte *mask,
int xx, int yy, int zz, MCW_cluster *nbhd )
{
int kind , nx,ny,nz,nxy , npt , nout , aa,bb,cc,kk,ii ;
void *brick ;
MRI_IMAGE *im ;
float fac ;
ENTRY("THD_get_dset_nbhd") ;
if( dset == NULL || nbhd == NULL || nbhd->num_pt <= 0 ) RETURN(NULL) ;
if( ival < 0 || ival >= DSET_NVALS(dset) ) RETURN(NULL) ;
im = mri_get_nbhd( DSET_BRICK(dset,ival) , mask , xx,yy,zz , nbhd ) ;
if( im == NULL ) RETURN(NULL) ;
fac = DSET_BRICK_FACTOR(dset,ival) ;
if( fac != 0.0f && fac != 1.0f ){
MRI_IMAGE *qim = mri_scale_to_float( fac , im ) ;
mri_free(im) ; im = qim ;
}
RETURN(im) ;
}
/*-------------------------------------------------------------------------*/
MRI_IMARR * THD_get_dset_indexed_nbhd( THD_3dim_dataset *dset,
int ival, byte *mask,
int xx, int yy, int zz,
MCW_cluster *nbhd )
{
int kind , nx,ny,nz,nxy , npt , nout , aa,bb,cc,kk,ii ;
void *brick ;
MRI_IMAGE *im , *qm ;
MRI_IMARR *imar ;
float fac ;
ENTRY("THD_get_dset_nbhd") ;
if( dset == NULL || nbhd == NULL || nbhd->num_pt <= 0 ) RETURN(NULL) ;
if( ival < 0 || ival >= DSET_NVALS(dset) ) RETURN(NULL) ;
imar = mri_get_indexed_nbhd( DSET_BRICK(dset,ival), mask, xx,yy,zz, nbhd );
if( imar == NULL ) RETURN(NULL) ;
fac = DSET_BRICK_FACTOR(dset,ival) ;
if( fac == 0.0f || fac == 1.0f ) RETURN(imar) ;
im = IMARR_SUBIM(imar,0) ;
qm = mri_scale_to_float( fac , im ) ; mri_free(im) ;
IMARR_SUBIM(imar,0) = qm ;
RETURN(imar) ;
}
/*-------------------------------------------------------------------------*/
static byte SearchAboutMaskedVoxel = 0;
void SetSearchAboutMaskedVoxel(int v)
{
SearchAboutMaskedVoxel = v;
}
/*---------------------------------------------------------------------------*/
MRI_IMAGE * mri_get_nbhd( MRI_IMAGE *inim , byte *mask ,
int xx, int yy, int zz, MCW_cluster *nbhd )
{
int kind , nx,ny,nz,nxy,nxyz , npt , nout , aa,bb,cc,kk,ii ;
MRI_IMAGE *im ;
void *brick ;
ENTRY("mri_get_nbhd") ;
if( inim == NULL || nbhd == NULL ) RETURN(NULL) ;
nx = inim->nx ;
ny = inim->ny ; nxy = nx*ny ;
nz = inim->nz ; nxyz = nxy*nz ; npt = nbhd->num_pt ; nout = 0 ;
kk = xx + yy*nx + zz*nxy ;
if (SearchAboutMaskedVoxel) {
if( npt == 0 || kk < 0 || kk >= nxyz ) RETURN(NULL) ;
} else {
if( npt == 0 || kk < 0 || kk >= nxyz || !INMASK(kk) ) RETURN(NULL) ;
}
kind = inim->kind ;
brick = mri_data_pointer(inim) ; if( brick == NULL ) RETURN(NULL) ;
im = mri_new( npt , 1 , kind ) ;
/*-- extract data, based on kind of data in sub-brick --*/
switch( kind ){
default: break ; /* bad bad bad */
case MRI_short:{
short *rr = MRI_SHORT_PTR(im) , *vv = (short *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ) rr[nout++] = vv[kk] ;
}
}
break ;
case MRI_byte:{
byte *rr = MRI_BYTE_PTR(im) , *vv = (byte *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ) rr[nout++] = vv[kk] ;
}
}
break ;
case MRI_float:{
float *rr = MRI_FLOAT_PTR(im) , *vv = (float *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ) rr[nout++] = vv[kk] ;
}
}
break ;
case MRI_complex:{
complex *rr = MRI_COMPLEX_PTR(im) , *vv = (complex *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ) rr[nout++] = vv[kk] ;
}
}
break ;
case MRI_rgb:{
byte *rr = MRI_BYTE_PTR(im) , *vv = (byte *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ){
rr[3*nout ] = vv[3*kk ] ;
rr[3*nout+1] = vv[3*kk+1] ;
rr[3*nout+2] = vv[3*kk+2] ; nout++ ;
}
}
}
break ;
}
if( nout == 0 ){ mri_free(im) ; RETURN(NULL) ; }
im->nx = im->nvox = nout ; RETURN(im) ;
}
/*---------------------------------------------------------------------------*/
MRI_IMARR * mri_get_indexed_nbhd( MRI_IMAGE *inim , byte *mask ,
int xx, int yy, int zz, MCW_cluster *nbhd )
{
int kind , nx,ny,nz,nxy,nxyz , npt , nout , aa,bb,cc,kk,ii ;
MRI_IMAGE *im , *jm ; int *jar ;
MRI_IMARR *imar ;
void *brick ;
ENTRY("mri_get_indexed_nbhd") ;
if( inim == NULL || nbhd == NULL ) RETURN(NULL) ;
nx = inim->nx ;
ny = inim->ny ; nxy = nx*ny ;
nz = inim->nz ; nxyz = nxy*nz ; npt = nbhd->num_pt ; nout = 0 ;
kk = xx + yy*nx + zz*nxy ;
if (SearchAboutMaskedVoxel) {
if( npt == 0 || kk < 0 || kk >= nxyz ) RETURN(NULL);
} else {
if( npt == 0 || kk < 0 || kk >= nxyz || !INMASK(kk) ) RETURN(NULL);
}
kind = inim->kind ;
brick = mri_data_pointer(inim) ; if( brick == NULL ) RETURN(NULL);
im = mri_new( npt , 1 , kind ) ;
jm = mri_new( npt , 1 , MRI_int ) ; jar = MRI_INT_PTR(jm) ;
/*-- extract data, based on kind of data in sub-brick --*/
switch( kind ){
default: break ; /* bad bad bad user */
case MRI_short:{
short *rr = MRI_SHORT_PTR(im) , *vv = (short *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ){ jar[nout] = kk; rr[nout++] = vv[kk]; }
}
}
break ;
case MRI_byte:{
byte *rr = MRI_BYTE_PTR(im) , *vv = (byte *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ){ jar[nout] = kk; rr[nout++] = vv[kk]; }
}
}
break ;
case MRI_float:{
float *rr = MRI_FLOAT_PTR(im) , *vv = (float *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ){ jar[nout] = kk; rr[nout++] = vv[kk]; }
}
}
break ;
case MRI_complex:{
complex *rr = MRI_COMPLEX_PTR(im) , *vv = (complex *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ){ jar[nout] = kk; rr[nout++] = vv[kk]; }
}
}
break ;
case MRI_rgb:{
byte *rr = MRI_BYTE_PTR(im) , *vv = (byte *)brick ;
for( ii=0 ; ii < npt ; ii++ ){
aa = xx + nbhd->i[ii] ; if( aa < 0 || aa >= nx ) continue ;
bb = yy + nbhd->j[ii] ; if( bb < 0 || bb >= ny ) continue ;
cc = zz + nbhd->k[ii] ; if( cc < 0 || cc >= nz ) continue ;
kk = aa + bb*nx + cc*nxy ;
if( INMASK(kk) ){
jar[nout] = kk ;
rr[3*nout ] = vv[3*kk ] ;
rr[3*nout+1] = vv[3*kk+1] ;
rr[3*nout+2] = vv[3*kk+2] ; nout++ ;
}
}
}
break ;
}
if( nout == 0 ){ mri_free(im); mri_free(jm); RETURN(NULL); }
jm->nx = jm->nvox = im->nx = im->nvox = nout ;
INIT_IMARR(imar) ;
ADDTO_IMARR(imar,im) ; ADDTO_IMARR(imar,jm) ; RETURN(imar) ;
}
syntax highlighted by Code2HTML, v. 0.9.1