/*****************************************************************************
Major portions of this software are copyrighted by the Medical College
of Wisconsin, 1994-2000, and are released under the Gnu General Public
License, Version 2. See the file README.Copyright for details.
******************************************************************************/
#include "mrilib.h"
/*** NOT 7D SAFE ***/
/*! Return far[] if (i,j) is inside the image, otherwise return 0. */
#define FINS(i,j) ( ( (i)<0 || (j)<0 || (i)>=nx || (j)>=ny ) \
? 0.0 : far[(i)+(j)*nx] )
/*-------------------------------------------------------------------*/
/*! Invert a 2D matrix, dude. */
static void invert2d( float axx, float axy, float ayx, float ayy ,
float *bxx, float *bxy, float *byx, float *byy )
{
float det = axx*ayy - axy*ayx ;
if( det == 0.0 ){ *bxx=*byy=*bxy=*byx = 0.0 ; return ; }
*bxx = ayy / det ;
*byy = axx / det ;
*bxy = -axy / det ;
*byx = -ayx / det ;
return ;
}
/*-------------------------------------------------------------------*/
/*! Affine transform a 2D image, using bilinear interpolation:
If flag == 0
[ xout ] = [ axx axy ] [ xin ]
[ yout ] = [ ayx ayy ] [ yin ]
If flag == 1
[ xin ] = [ axx axy ] [ xout ]
[ yin ] = [ ayx ayy ] [ yout ]
These are index coordinates, not spatial.
----------------------------------------------------------------------*/
MRI_IMAGE *mri_aff2d_byte( MRI_IMAGE *im, int flag ,
float axx, float axy, float ayx, float ayy )
{
float bxx,bxy,byx,byy , xbase,ybase , xx,yy , fx,fy ;
float f_j00,f_jp1 , wt_00,wt_p1 ;
int ii,jj , nx,ny , ix,jy ;
MRI_IMAGE *newImg ;
byte *far , *nar ;
ENTRY("mri_aff2d_byte") ;
if( im == NULL || !MRI_IS_2D(im) || im->kind != MRI_byte ){
fprintf(stderr,"*** mri_aff2d_byte only works on 2D byte images!\n");
RETURN( NULL );
}
if( flag == 0 ){
invert2d( axx,axy,ayx,ayy , &bxx,&bxy,&byx,&byy ) ;
} else {
bxx = axx ; bxy = axy ; byx = ayx ; byy = ayy ;
}
if( (bxx == 0.0 && bxy == 0.0) || (byx == 0.0 && byy == 0.0) ){
fprintf(stderr,"*** mri_aff2d_byte: input matrix is singular!\n") ;
RETURN( NULL );
}
nx = im->nx ; ny = im->ny ;
xbase = 0.5*nx*(1.0-bxx) - 0.5*ny*bxy ;
ybase = 0.5*ny*(1.0-byy) - 0.5*nx*byx ;
far = MRI_BYTE_PTR(im) ; /* input image data */
newImg = mri_new( nx , nx , MRI_byte ) ; /* output image */
nar = MRI_BYTE_PTR(newImg) ; /* output image data */
/*** loop over output points and warp to them ***/
for( jj=0 ; jj < nx ; jj++ ){
xx = xbase-bxx + bxy * jj ;
yy = ybase-byx + byy * jj ;
for( ii=0 ; ii < nx ; ii++ ){
xx += bxx ; /* get x,y in original image */
yy += byx ;
ix = (xx >= 0.0) ? ((int) xx) : ((int) xx)-1 ; /* floor */
jy = (yy >= 0.0) ? ((int) yy) : ((int) yy)-1 ;
fx = xx-ix ; wt_00 = 1.0 - fx ; wt_p1 = fx ;
if( ix >= 0 && ix < nx-1 && jy >= 0 && jy < ny-1 ){
byte *fy00 , *fyp1 ;
fy00 = far + (ix + jy*nx) ; fyp1 = fy00 + nx ;
f_j00 = wt_00 * fy00[0] + wt_p1 * fy00[1] ;
f_jp1 = wt_00 * fyp1[0] + wt_p1 * fyp1[1] ;
} else {
f_j00 = wt_00 * FINS(ix,jy ) + wt_p1 * FINS(ix+1,jy ) ;
f_jp1 = wt_00 * FINS(ix,jy+1) + wt_p1 * FINS(ix+1,jy+1) ;
}
fy = yy-jy ; nar[ii+jj*nx] = (1.0-fy) * f_j00 + fy * f_jp1 ;
}
}
MRI_COPY_AUX(newImg,im) ;
RETURN( newImg ) ;
}
/*----------------------------------------------------------------------*/
/*! Same as FINS(), but for the R component of an RGB image. */
#define RINS(i,j) ( ( (i)<0 || (j)<0 || (i)>=nx || (j)>=ny ) \
? 0.0 : far[3*((i)+(j)*nx)] )
/*! Same as FINS(), but for the G component of an RGB image. */
#define GINS(i,j) ( ( (i)<0 || (j)<0 || (i)>=nx || (j)>=ny ) \
? 0.0 : far[3*((i)+(j)*nx)+1] )
/*! Same as FINS(), but for the B component of an RGB image. */
#define BINS(i,j) ( ( (i)<0 || (j)<0 || (i)>=nx || (j)>=ny ) \
? 0.0 : far[3*((i)+(j)*nx)+2] )
/*----------------------------------------------------------------------*/
/*! Same as mri_aff2d_byte(), but for RGB images [11 Dec 2000].
------------------------------------------------------------------------*/
MRI_IMAGE *mri_aff2d_rgb( MRI_IMAGE *im, int flag ,
float axx, float axy, float ayx, float ayy )
{
float bxx,bxy,byx,byy , xbase,ybase , xx,yy , fx,fy ;
float f_j00r,f_jp1r , f_j00g,f_jp1g , f_j00b,f_jp1b , wt_00,wt_p1 ;
int jj , nx,ny , ix,jy ;
MRI_IMAGE *newImg ;
byte *far , *nar ;
register int ii ;
ENTRY("mri_aff2d_rgb") ;
if( im == NULL || !MRI_IS_2D(im) || im->kind != MRI_rgb ){
fprintf(stderr,"*** mri_aff2d_rgb only works on 2D RGB images!\n");
RETURN( NULL );
}
if( flag == 0 ){
invert2d( axx,axy,ayx,ayy , &bxx,&bxy,&byx,&byy ) ;
} else {
bxx = axx ; bxy = axy ; byx = ayx ; byy = ayy ;
}
if( (bxx == 0.0 && bxy == 0.0) || (byx == 0.0 && byy == 0.0) ){
fprintf(stderr,"*** mri_aff2d_byte: input matrix is singular!\n") ;
RETURN( NULL );
}
nx = im->nx ; ny = im->ny ;
xbase = 0.5*nx*(1.0-bxx) - 0.5*ny*bxy ;
ybase = 0.5*ny*(1.0-byy) - 0.5*nx*byx ;
far = MRI_RGB_PTR(im) ; /* input image data */
newImg = mri_new( nx , nx , MRI_rgb ) ; /* output image */
nar = MRI_RGB_PTR(newImg) ; /* output image data */
/*** loop over output points and warp to them ***/
for( jj=0 ; jj < nx ; jj++ ){
xx = xbase-bxx + bxy * jj ;
yy = ybase-byx + byy * jj ;
for( ii=0 ; ii < nx ; ii++ ){
xx += bxx ; /* get x,y in original image */
yy += byx ;
ix = (xx >= 0.0) ? ((int) xx) : ((int) xx)-1 ; /* floor */
jy = (yy >= 0.0) ? ((int) yy) : ((int) yy)-1 ;
fx = xx-ix ; wt_00 = 1.0 - fx ; wt_p1 = fx ;
if( ix >= 0 && ix < nx-1 && jy >= 0 && jy < ny-1 ){
byte *fy00 , *fyp1 ;
fy00 = far + 3*(ix+jy*nx) ; fyp1 = fy00 + 3*nx ;
f_j00r = wt_00 * fy00[0] + wt_p1 * fy00[3] ;
f_j00g = wt_00 * fy00[1] + wt_p1 * fy00[4] ;
f_j00b = wt_00 * fy00[2] + wt_p1 * fy00[5] ;
f_jp1r = wt_00 * fyp1[0] + wt_p1 * fyp1[3] ;
f_jp1g = wt_00 * fyp1[1] + wt_p1 * fyp1[4] ;
f_jp1b = wt_00 * fyp1[2] + wt_p1 * fyp1[5] ;
} else {
f_j00r = wt_00 * RINS(ix,jy ) + wt_p1 * RINS(ix+1,jy ) ;
f_j00g = wt_00 * GINS(ix,jy ) + wt_p1 * GINS(ix+1,jy ) ;
f_j00b = wt_00 * BINS(ix,jy ) + wt_p1 * BINS(ix+1,jy ) ;
f_jp1r = wt_00 * RINS(ix,jy+1) + wt_p1 * RINS(ix+1,jy+1) ;
f_jp1g = wt_00 * GINS(ix,jy+1) + wt_p1 * GINS(ix+1,jy+1) ;
f_jp1b = wt_00 * BINS(ix,jy+1) + wt_p1 * BINS(ix+1,jy+1) ;
}
fy = yy-jy ;
nar[3*ii+ 3*jj*nx ] = (1.0-fy) * f_j00r + fy * f_jp1r ;
nar[3*ii+(3*jj*nx+1)] = (1.0-fy) * f_j00g + fy * f_jp1g ;
nar[3*ii+(3*jj*nx+2)] = (1.0-fy) * f_j00b + fy * f_jp1b ;
}
}
MRI_COPY_AUX(newImg,im) ;
RETURN( newImg );
}
syntax highlighted by Code2HTML, v. 0.9.1