2

Using C++ (GCC specifically, should have put this sooner), I'm storing raw texture data in an array of unsigned bytes, in a RGBA format, with 32 bits per pixel (8 bits per color value with Alpha, so on and so forth...). The thing is, I want to write a function that returns the raw data as a array of Colors, where a Color is a struct defined as the following:

struct Color
{
    uint8 r;
    uint8 g;
    uint8 b;
    uint8 a;
};

Plus functions and whatnot, but those are the only variables in the struct. My thinking is that since each color is 4 bytes long, what I can somehow cast the raw byte array to a Color array that is 1/4 of the original size (in "length" of array, not in absolute size). I think that reinterpret_cast is what I am looking for, but I cannot find anything after a google search that confirms 100% that you can convert it into an array of structs instead of just one struct.

So I guess I am just asking someone to either confirm that this is indeed possible with reinterpret_cast, or if there is a different cast or way to do this. Thanks.

EDIT: My wording is a little weird, so as an arbitrary example I'd like to somehow cast a array of 16 unsigned bytes into an array of 4 Colors.

EDIT: Also I know it's kind of a little late, but I cant seem to find how to cast a small portion of the array at a specific place to a single struct using a reinterpret_cast, if that is possible, without copying to a smaller array and casting like that. So any help with this problem would also be greatly appreciated.

3
  • Besides uint8 doesn't specify a standard type, you might get a victim of padding with what you're trying to do. You should be very sure what you have to apply a reinterpret_cast<>, otherwise your fridge might explode or any other unexpected (== undefined) behavior may occur!! Commented Jun 18, 2014 at 2:07
  • You can arrive at the "reinterpret_cast" option by simply excluding all other types of casts. Const_cast, static_cast and dynamic_cast won't work in your case for sure. Commented Jun 18, 2014 at 2:07
  • Sorry should have been more specific. I have a global include file that defines uint8 as uint8_t, which is defined in GCC (and perhaps others, but I only use GCC) as unsigned char and I'm using GCC. Commented Jun 18, 2014 at 2:32

1 Answer 1

6

as an arbitrary example I'd like to somehow cast a array of 16 unsigned bytes into an array of 4 Colors.

Like this:

#pragma pack(push, 1)
struct Color
{
    uint8 r;
    uint8 g;
    uint8 b;
    uint8 a;
};
#pragma pack(pop)

uint8 bytearray[16];
...
Color *colorarray = reinterpret_cast<Color*>(bytearray);

Then you can do things like this:

for (int idx = 0; idx < 4; ++idx)
{
    Color &c = colorarray[idx];
    // use c.r, c.g, c.b, c.a as needed...
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is how I would do it. Mind that a C++ compiler doesn't have to support #pragma pack, and a particular environment might not even need it. It depends on how standard you want your solution to be.
the pragmas are non-standard. bit fields are standard but don't get you all the way: no way to ensure lack of padding at end. however, as a practical thing one can just static assert the size.
@Praetorian I'm not accusing anyone here of thinking that. I was merely making an observation about other people I've met in my travels across the various help boards.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.