Pixels of BMP-24bits to Surface (Solved)

Hi!, i have a problem with SDL_CreateRGBSurfaceFrom() and SDL_CreateRGBSurfaceWithFormatFrom() functions, i have been trying to convert an array of pixels to a Surface but SDL dont let me draw well. Pixels are read each 4Bytes, on windows it is a DWORD (32bits) and RGB are 3Bytes, i think thats its the problem but now, what can i do?, am lost, i need to find a way to convert my pixels array to a Surface struct or ignore that byte but that is out of my range. Help plx!

That’s my example:

int data[25]= {
//I try both
//SDL_Surface* menu = SDL_CreateRGBSurfaceWithFormatFrom((void*)data, 5, 5, 24, 35, SDL_PIXELFORMAT_RGB24);
menu = SDL_CreateRGBSurfaceFrom((void*)data, 5, 5, 24, 5*3, 0, 0, 0, 0);
next, i call render copy with dimensions and get this :c


The black ones are the bytes that i cannot reach with code.

It’s not clear from your question what is it you’re trying to do. But let me explain what is happening.

Each value in your data array is 4 bytes. That means that for example your 255 which is 0xff in hex is expanded to 0x000000ff. The first 5 values from your array are thus:

0x0000ff00, 0x000000ff, 0x00000190, 0x000000ff, 0x000000ff

Because this is an Intel or AMD (i.e. it’s x86 or x86_64 architecture), the way these are stored in memory is not exactly that. Each double word has its bytes swapped so instead of this in memory:

00 00 ff 00|00 00 00 ff|00 00 01 90|00 00 00 ff|00 00 00 ff

you get this:

00 ff 00 00|ff 00 00 00|90 01 00 00|ff 00 00 00|ff 00 00 00

Is you call SDL_CreateRGBSurfaceWithFormatFrom with parameters ((void*)data, 5, 5, 24, 35, SDL_PIXELFORMAT_RGB24) what you’re saying is that you want an image that’s:

  • 5 pixels wide
  • 5 pixels tall
  • uses 24 bits (3 bytes) for each RGB value
  • uses exactly 35 bytes per row
  • stores colors in R-G-B order (as opposed to, say, B-G-R)
    So the data below is split into 3-byte chunks like so:
R  G  B  R  G  B  R  G  B  R  G  B  R  G  B  R  G  B
00 ff 00|00 ff 00|00 00 90|01 00 00|ff 00 00|00 ff 00|00 00 ...

Which matches what you’re seeing. Again, I don’t know what you want to achieve with this array but you’re getting what you’ve set up.

1 Like

Oh!, i get it, am using int array, int = 4 bytes, thats my problem, thx for your answer, now i try with char array and all works fine, i gonna tell you what i want to do with this. I have programed a function that reads a BMP24 and return an array with only the pixel data, now i am doing some test and need to removing too the padding bytes from the data and only return RGB data. With this i want to generate a surface that only have the dimensions of my window, 640x480, the purpose is using a big bmp24 image and render only the pixels that i want without read all image every time (big image like 5120x3840 or bigger), when i tried this with SDL_RenderCopy(renderer, this->texture, &this->srcrect, &this->dstrect); renderer reads all texture and the program runs very slow, so lame, but now i will try with this, thx again <3!!!

Sure, this makes sense now. Uncompressed formats like bmp are slow not because of the in-memory size but because of the amount of input/output you have to perform. Your solution may suffer from IO limitations the moment you decide to scroll the visible part because small random disk accesses are slow.

To remedy that you may wat to read slightly more data than immediately visible on the screen to have some margin on each side (if applicable) in memory already. Based on the the movement of the visible part you can read more data from any direction and replace your active surface. Ideally you would divide the entire image space into smallish (64x64?) tiles and you’d keep at least 1-2 tiles from outside of the screen boundaries resident. This is slightly more complex to implement, especially if you want to minimize seeks (i.e. read bursts spanning multiple tiles).

Also keep in mind that BMP data is upside down. :wink: