Sign in to follow this  
toony

packing rgba into a 32bit integer

Recommended Posts

i wrote 2 functions, one for packing 4 individual bytes into a unsigned int variable (a 32bit word), and the other for unpacking this unsigned int into 4 individaul bytes. these bytes can represent the red, green, blue, and alpha colours.

i didn't do any research before as to how this might be done, but while spending enough time facing the black board i kind of got to it quite well imo.

here's the code that i wrote to pack and unpack the colours, please let me know if my implementation is good enough, or if there are faster ways of doing this packing & unpacking.

#include<stdio.h>

typedef unsigned int Uint;
typedef unsigned char Ubyte;

Uint packColour4ub(Ubyte r, Ubyte g, Ubyte b, Ubyte a)
{
Uint colour[4] = {r, g, b, a};
Uint rgba = 0;
Ubyte i = 0, bits = 0;

for (i = 0; i < 4; i++, bits += 8)
rgba += (colour[i] <<= bits);

return rgba;
}

void unpackColour4ub(Uint rgba, Ubyte* colour)
{
Ubyte i = 0, byte = 0xff;
colour[i] = byte & rgba;

for (i = 1; i < 4; i++)
colour[i] = byte & (rgba >>= 8);
}

int main()
{
Ubyte i = 0;
Uint rgba = 0;
Ubyte colour[4] = {0};

printf("%u\n", rgba = packColour4ub(0xaf, 0xb1, 0x1f, 0x4d));
unpackColour4ub(rgba, colour);

for (i = 0; i < 4; i++) // test packed and unpacked colours
printf("%i ", colour[i]);

return getchar();
}

Share this post


Link to post
Share on other sites
I just have a simple object for Colors with a union inside, something like:

union
{
struct
{
u8 b;
u8 g;
u8 r;
u8 a;
};

u8 c8[4];
u32 c32;
};




Don't need to do anything special then, just use the constructors.

Color()		: c32(0) { }
Color(u32 c) : c32(c) { }
... and so on for individual channels, etc.

Share this post


Link to post
Share on other sites
guess i should keep them together in an object way (if i need to keep track of them as well), i'll try an object oriented approach most certainly.

yes |= would also work, but so does +=, and there's no noticeable performance difference between them.


thanks for the ideas.

Share this post


Link to post
Share on other sites
Seems a bit overkill with loops etc. Plus, you are not actually packing to rgba which your variable name hints towards. You are packing to abgr.

A faster "pack" would be:

#define pack_rgba(r, g, b, a) (Uint)(r<<24|g<<16|b<<8|a)



Share this post


Link to post
Share on other sites
Clashie's method is one that I normally use for readability purposes.
The macro is probably more efficient than setting 4 variables, though; and honestly no less readable (unless you actually investigate the macro).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this