COTD submitted by Benjamin Contant [bcontant@videotron.ca] (posted 08/20/2001)
DWORD SrcColor = 0;
DWORD DestColor;
BYTE SrcAlpha, SrcRed, SrcGreen, SrcBlue;
BYTE DestAlpha, DestRed, DestGreen, DestBlue;
BYTE RedError, GreenError, BlueError, AlphaError;
for(int i = 0; i < Height; i++)
{
//Reset the error after every line because we don't want
//the error of the last pixel to be used on the first pixel
//of this line
RedError = GreenError = BlueError = AlphaError = 0;
for(int j = 0; j < Width; j++)
{
//Read in the source color
SrcColor = 0;
for(int k = 0; k < SrcBytesPerPixel; k++)
{
SrcColor += (SrcPtr[k] << (k<<3));
}
//Extract the ARGB components
if(SrcAlphaNumBits > 0)
{
SrcAlpha = (SrcColor & SrcAlphaMask) >> SrcAlphaShift;
}
else
{
SrcAlpha = 255;
}
SrcRed = (SrcColor & SrcRedMask) >> SrcRedShift;
SrcGreen = (SrcColor & SrcGreenMask) >> SrcGreenShift;
SrcBlue = (SrcColor & SrcBlueMask) >> SrcBlueShift;
//Add the error while clamping to the max color value
if(SrcAlphaNumBits > 0)
{
SrcAlpha = min(MaxSrcAlpha, SrcAlpha + AlphaError);
}
SrcRed = min(MaxSrcRed, SrcRed + RedError);
SrcGreen = min(MaxSrcGreen, SrcGreen + GreenError);
SrcBlue = min(MaxSrcBlue, SrcBlue + BlueError);
//Calculate the resulting destination colors
if(SrcAlphaNumBits > 0)
{
DestAlpha = SrcAlpha >> AlphaBitDiff;
}
else
{
DestAlpha = SrcAlpha >> (8 - DestAlphaNumBits);
}
DestRed = SrcRed >> RedBitDiff;
DestGreen = SrcGreen >> GreenBitDiff;
DestBlue = SrcBlue >> BlueBitDiff;
//Calculate the error
if(SrcAlphaNumBits > 0)
{
AlphaError = SrcAlpha - (DestAlpha << AlphaBitDiff);
}
else
{
AlphaError = 0;
}
RedError = SrcRed - (DestRed << RedBitDiff);
GreenError = SrcGreen - (DestGreen << GreenBitDiff);
BlueError = SrcBlue - (DestBlue << BlueBitDiff);
//Compose the destination pixel
DestColor = (DestAlpha << DestAlphaShift) +
(DestRed << DestRedShift) +
(DestGreen << DestGreenShift) +
(DestBlue << DestBlueShift);
//Set the destination pixel
BYTE* DestColorPtr = (BYTE*) &DestColor;
for(k = 0; k < DestBytesPerPixel; k++)
{
DestPtr[k] = DestColorPtr[k];
}
//Advance the pointers to the next pixel
DestPtr += DestBytesPerPixel;
SrcPtr += SrcBytesPerPixel;
}
//Advance the pointers to the next line
DestPtr += DestPitch - (Width * DestBytesPerPixel);
SrcPtr += SrcPitch - (Width * SrcBytesPerPixel);
} |