Max Ehrlich
Max Ehrlich

Reputation: 2525

C++ container performance for image representation

I am working on a program that needs to write raw image data to a memory buffer. Currently my implementation looks like this:

std::unique_ptr<unsigned char[]> _Screen;
...
_Screen.reset(new unsigned char[width * height * 3]);
std::fill(_Screen.get(), _Screen.get() + (width * height), 0);
...
_Screen[(j * _ScreenWidth + i) * 3] = red;
_Screen[(j * _ScreenWidth + i) * 3 + 1] = green;
_Screen[(j * _ScreenWidth + i) * 3 + 2] = blue;

I would really like to use some STL containers here if possible. I don't know the size of the screen until runtime, so std::array is out. It should be possible to redefine screen using a std::vector<unsigned char> as follows:

std::vector<unsigned char> _Screen
...
_Screen.resize(width * height * 3);

But I am wondering if the element access will be any slower than using the C-style array? (I am assuming the reallocation will be slower but that is OK for this application).

I was also wondering if it would make more sense to do something like the following:

struct Pixel
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};
...
std::vector<Pixel> _Screen;
...
_Screen.resize(width * height);
...
_Screen[(j * _ScreenWidth + i)].red = red;
_Screen[(j * _ScreenWidth + i)].green = green;
_Screen[(j * _ScreenWidth + i)].blue = blue;    

But I am going to need to convert to a single array of unsigned char eventually so while this represents the data better during my computation, I'm not sure how hard that would be. Will using the struct approach be any slower and is it safe to convert to the unsigned char later using something like:

unsigned char *screen = reinterpret_cast<unsigned char *>(_Screen.data());

Upvotes: 0

Views: 393

Answers (1)

Lochemage
Lochemage

Reputation: 3974

std::vector is basically a C style array already, it just manages the allocation of the block. If you initialize the size of the vector then it allocates the size once, and then you can just access the internal array buffer and mess with the data directly if you want, or you can use the overloaded bracket operators. In the end though, I don't believe you will lose any noticeable performance with doing this. It is up to what looks good to you.

As for your second question, you probably are better off sticking to the first iteration just to avoid complications. However, if your Pixel struct is simply three unsigned chars, memory-wise it is in the same format as an array of 3 uchar's already, so there is little difference, you could still just iterate through the entire memory block char by char and put it back into the image, and vica-versa.

Upvotes: 1

Related Questions