I've also got this working in 32/24/16 and 8 bit colour modes. The multi-byte colour modes are relatively straight forward; 32 bpp is 10 bits each BGR with the top 2 bits (I assume) being used for alpha or something. 24 bpp is 8 bits each BGR, and 16 bpp is 5 bits each RGB with bit 0 ignored.
The one thing that was puzzling me though was the 8 bit colour mode. It didn't seem to fall into any discernible pattern of RGB. Following some experimentation I found that white was represented by the value 0xD7 (215). Huh? After some more experimenting and searching the 'net I discovered that the 8 bit colour palette is 216-colours, which are also web-safe colours!
This article confirmed my suspicions and inspired me to write the following function:
http://www.codeproject.com/Articles/7124/Image-Bit-depth-conversion-from-32-Bit-to-8-Bit
- Code: Select all
#define STANDARD_PALETTE_VAL_DIFF 51
unsigned int get_8bit_colour_index(unsigned int colour_24bit) {
const unsigned char standard_palette[] = { 0x00, 0x33, 0x66, 0x99, 0xCC, 0xFF };
unsigned char result[3] = { 0x00, 0x00, 0x00 };
for (int i = 0; i < 3; i++)
{
unsigned char c = colour_24bit & 0x000000FF;
int pos = c / STANDARD_PALETTE_VAL_DIFF;
if (c % STANDARD_PALETTE_VAL_DIFF != 0) {
if (abs(c - standard_palette[pos]) > abs(c - standard_palette[pos + 1])) {
pos += 1;
}
}
result[i] = pos;
colour_24bit = (colour_24bit >> 8);
}
return (result[0] * 36) + (result[1] * 6) + result[2];
}
What this does is take a standard 24 bit colour number (in BGR remember) and finds it's nearest colour in the 216-colour palette, returning the index position of the colour.
Of course by this point you're probably wondering why you'd use 8 bit colour. Well, it's easy - 1 byte per pixel and, it's fast. Perfect if you're planning on writing arcade style games
I'll be sharing my framebuffer and graphics code soon, just pm me if you'd like to get your hands on it now.
V.