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*)&buff[OFFSET_OF_SIZE];
DWORD* buffPixels = (DWORD*)&buff[OFFSET_OF_PIXELS];
DWORD* buffWidth = (DWORD*)&buff[OFFSET_OF_WIDTH];
DWORD* buffHeight = (DWORD*)&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 < *buffHeight; ln++)
{
for(col = 0; col <*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;
}