I have a four byte DWORD that I need to split into four different characters. I thought I knew how to accomplish this but am getting bizarre numbers every time. Here is my code:
// The color memory
int32 col = color_mem[i];
// The four destination characters
char r, g, b, a;
// Copy them in advancing by one byte every time
memcpy(&r, &col, 1);
memcpy(&g, &col + 1, 1);
memcpy(&b, &col + 2, 1);
memcpy(&a, &col + 3, 1);
Ditch the memcpy and use bit manipulation:
r = (col & 0x000000ff);
g = (col & 0x0000ff00) >> 8;
b = (col & 0x00ff0000) >> 16;
a = (col & 0xff000000) >> 24;
ff in the hexadecimal numbers represents a byte of all 1 bits. This and the & - bitwise AND - will make the bytes that you're not interested in - at each position - 0, and keeping the bits that you are interested in.
The >> shifts in zeros from the left, putting the byte that we want in the most significant position, for the actual assignment. A shift of 8 shifts by a width of one byte, 16 is two bytes, and 24 is three bytes.
Visually, looking at ff, you can imagine that we're walking the byte indices towards the left.
When you do pointer arithmetic, the amount of the increment or decrement is multiplied by the size of the type being pointed to. Cast the int32 pointer to a char pointer in order to access char sized parts at some offset from the base address of col.
This technique can be fragile due to differences in endian-ness on different platforms, so I recommend using the more portable bitmask operations supplied in another answer.
// The color memory
int32 col = color_mem[i];
// The four destination characters
char r, g, b, a;
// Copy them in advancing by one byte every time
memcpy(&r, (char*)&col, 1);
memcpy(&g, ((char*)&col) + 1, 1);
memcpy(&b, ((char*)&col) + 2, 1);
memcpy(&a, ((char*)&col) + 3, 1);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With