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); }