Rapid color replacement for in-memory BMP A function that relatively quick replaces one color with another, in a memory-buffered BMP.
I am trying to improve the performance as much as it is possible. The previous implementation of this function was even faster.. but then I ran into some padding complications.

union
{
    unsigned long ulColor;
    unsigned char byteColor[4];
} oldColor;
union
{
    unsigned long ulColor;
    unsigned char byteColor[4];
} newColor;

typedef unsigned char BYTE;
typedef unsigned short int WORD;
typedef unsigned long int DWORD;
typedef unsigned long long int DDWORD;

DWORD
bitfox_find_xy
(DWORD WIDTH, DWORD xp, DWORD yp)
{
    DWORD w = WIDTH;
    DWORD channels = 3;
    DWORD bpp = 8;
    DWORD single = (channels*bpp)/8;
    DWORD offset = (2+sizeof(BMP)+sizeof(DIB));
    DWORD rowsize = w*single;

    DWORD pixAddress;

    if (rowsize % 4 != 0) rowsize += 4 - (rowsize % 4); // account for padding
    pixAddress = offset + yp*rowsize + xp*single; // finding the address
    return pixAddress;
}
DDWORD
bitfox_color_replace_data
(BYTE *buff, BYTE old_r, BYTE old_g, BYTE old_b, BYTE new_r, BYTE new_g, BYTE new_b)
{
    #define OFFSET_OF_SIZE      0x2
    #define OFFSET_OF_PIXELS    0xA
    #define OFFSET_OF_WIDTH     0x12
    #define OFFSET_OF_HEIGHT    0x16

    DWORD* buffSize     = (DWORD*)&amp;buff[OFFSET_OF_SIZE];
    DWORD* buffPixels   = (DWORD*)&amp;buff[OFFSET_OF_PIXELS];
    DWORD* buffWidth    = (DWORD*)&amp;buff[OFFSET_OF_WIDTH];
    DWORD*  buffHeight  = (DWORD*)&amp;buff[OFFSET_OF_HEIGHT];

    DDWORD pixels_replaced = 0;
    DDWORD ln, col;

    oldColor.byteColor[0] = old_b;  newColor.byteColor[0] = new_b;
    oldColor.byteColor[1] = old_g;  newColor.byteColor[1] = new_g;
    oldColor.byteColor[2] = old_r;  newColor.byteColor[2] = new_r;

    for(ln = 0; ln &lt; *buffHeight; ln++)
    {
        for(col = 0; col &lt;*buffWidth; col++)
        {
            DDWORD offset = bitfox_find_xy(*buffWidth, col, ln);

            if(!memcmp(buff + offset, oldColor.byteColor, 3))
            {
                memcpy(buff + offset, newColor.byteColor, 3);

                pixels_replaced++;
            }
        }
    }
    return pixels_replaced;
}
Computing rowsize inside bitfox_find_xy (that is, for each and every pixel)seems wasteful: row size never changes during the bitfox_color_replace_data invocation, and shall only be computed once.