Original Post
This is a simple little routine to do very rudimentary antialiasing on an image, given an array of RGBA values. I realize that this routine only works if you are stretching the image 50% to 150% in each direction, but that's OK because for my purposes, that'll do.
Hardware usage is not an option.
It runs a little slower than I'd expect, and I figured I'd post it up here and see if some of you hardcore inner-loop optimizers could help me out a bit.
Thanks a heap!
~BenDilts( void );
struct PIXEL
{
BYTE a;
BYTE b;
BYTE g;
BYTE r;
inline void Blend(const PIXEL *p, float fNewPart)
{
a = (BYTE)(p->a*fNewPart + a*(1-fNewPart));
r = (BYTE)(p->r*fNewPart + r*(1-fNewPart));
g = (BYTE)(p->g*fNewPart + g*(1-fNewPart));
b = (BYTE)(p->b*fNewPart + b*(1-fNewPart));
}
};
STDMETHODIMP CESAntiAliaser::AntiAlias(SAFEARRAY **aData, long lWidth, long lHeight, long lNewWidth, long lNewHeight, SAFEARRAY **aResult)
{
//aData is a byte array containing 32-bit color data for an image, elements are from 0 to lWidth*lHeight*4
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = lNewWidth*lNewHeight*4;
*aResult = SafeArrayCreate(VT_I1/*BYTE*/, 1, rgsabound);
PIXEL *pSrc = NULL;
PIXEL *pDst = NULL;
SafeArrayAccessData(*aData, (void**)&pSrc);
SafeArrayAccessData(*aResult, (void**)&pDst);
PIXEL *pDstCur = pDst;
float fSrcX = 0, fSrcY = 0;
float fDeltaSrcX = (float)lWidth/(float)lNewWidth;
float fDeltaSrcY = (float)lHeight/(float)lNewHeight;
long iSrcX, iSrcY;
float fSrcXMiss, fSrcYMiss;
PIXEL *pCurSrc;
for(long y = 0; y < lNewHeight; y++)
{
for(long x = 0; x < lNewWidth; x++)
{
iSrcX = (int)(fSrcX+.5f);
iSrcY = (int)(fSrcY+.5f);
fSrcXMiss = fSrcX-iSrcX;
fSrcYMiss = fSrcY-iSrcY;
pCurSrc = pSrc + (iSrcX+iSrcY*lWidth);
*pDstCur = *pCurSrc;
if(fSrcXMiss > 0 && iSrcX+1 < lWidth)
pDstCur->Blend(pCurSrc+1, fabsf(fSrcXMiss));
else if(fSrcXMiss < 0 && iSrcX > 0)
pDstCur->Blend(pCurSrc-1, fabsf(fSrcXMiss));
if(fSrcYMiss > 0 && iSrcY+1 < lHeight)
pDstCur->Blend(pCurSrc+lWidth, fabsf(fSrcYMiss));
else if(fSrcYMiss < 0 && iSrcY > 0)
pDstCur->Blend(pCurSrc-lWidth, fabsf(fSrcYMiss));
pDstCur++;
fSrcX += fDeltaSrcX;
}
fSrcX = 0;
fSrcY += fDeltaSrcY;
}
SafeArrayUnaccessData(*aData);
SafeArrayUnaccessData(*aResult);
return S_OK;
}
[edited by - BeanDog on August 4, 2003 12:58:52 PM]