Archived

This topic is now archived and is closed to further replies.

sdlprorammer

SDL_CreateRGBSurfaceFrom

Recommended Posts

sdlprorammer    100
SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); Can anyone explain to me what the parameter "pitch" is? PLEASE don''t use advanced terms... thanks in advance

Share this post


Link to post
Share on other sites
TomasH    360
Quote from the above linked documentation: "pitch is the length of each scanline in bytes."
So if the line is 640 pixels wide, and each pixel is three bytes, then pitch is 640*3.
EDIT: That would be a line in the source image. I.e. the one "pixels" is pointing to.

[edited by - TomasH on May 27, 2004 6:53:13 AM]

Share this post


Link to post
Share on other sites
sdlprorammer    100
thanls for the help!
you said:
"So if the line is 640 pixels wide, and each pixel is three bytes, then pitch is 640*3."
1)"line" refers to "void *pixels"?
2) If we are going to create a surface initialized by the bytes pointed by "void *pixels", then why do we need the RGB and A masks? Those data ( for the color 0 should be included in the bytes of "pixels", shouldn''t they? So??

thanks...

Share this post


Link to post
Share on other sites
TomasH    360
quote:
Original post by sdlprorammer
1)"line" refers to "void *pixels"?


Yes
quote:
Original post by sdlprorammer
2) If we are going to create a surface initialized by the bytes pointed by "void *pixels", then why do we need the RGB and A masks? Those data ( for the color 0 should be included in the bytes of "pixels", shouldn''t they? So??


Because "pixels" just points to raw data - i.e. there is no information on how the data is ordered...

Share this post


Link to post
Share on other sites
sdlprorammer    100
thatnks but...:
>Because "pixels" just points to raw data - i.e. there is no information on how the data is ordered...

Eeeer.. what do u mean? What kind of data are these that can not be ( basiccally ) used?

Share this post


Link to post
Share on other sites
DBX    178
quote:
Original post by TomasH
So if the line is 640 pixels wide, and each pixel is three bytes, then pitch is 640*3.



No, the pitch is the number of bytes from the start of one line to the next. This may or may not be width * bytesperpixel.

quote:

Eeeer.. what do u mean? What kind of data are these that can not be ( basiccally ) used?



Because you know the pixelformat, so you know how the data is stored.

Share this post


Link to post
Share on other sites
sdlprorammer    100
>Because you know the pixelformat, so you know how the data is stored.
Then i don''t need to know RGBA in advance. ... ??.. but the function requires themm..?

Share this post


Link to post
Share on other sites
TomasH    360
quote:
Original post by DBX
quote:
Original post by TomasH
So if the line is 640 pixels wide, and each pixel is three bytes, then pitch is 640*3.



No, the pitch is the number of bytes from the start of one line to the next. This may or may not be width * bytesperpixel.

Oh, yes, of course you''re right. Sorry...

quote:
Original post by sdlprorammer
>Because you know the pixelformat, so you know how the data is stored.
Then i don''t need to know RGBA in advance. ... ??.. but the function requires themm..?

Yes, you should have this information.
SDL_CreateRGBSurfaceFrom is used to take pixel data that you have loaded from a file or created in some other way and use it (or part of it) to create a SDL surface. So if you managed to load the data or create it, you really should know how the data is stored. Right?

Share this post


Link to post
Share on other sites
sdlprorammer    100
>No, the pitch is the number of bytes from the start of one line to the next. This may or may not be width * bytesperpixel.

Then how can i determine what value to pass to the function?????????

>SDL_CreateRGBSurfaceFrom is used to take pixel data that you have loaded from a file or created in some other way and use it (or part of it) to create a SDL surface.
Ok, so far we are OK.

>So if you managed to load the data or create it, you really should know how the data is stored. Right?
But RGBA is what the data contains! ???

Share this post


Link to post
Share on other sites
TomasH    360
quote:
Original post by sdlprorammer
>No, the pitch is the number of bytes from the start of one line to the next. This may or may not be width * bytesperpixel.

Then how can i determine what value to pass to the function?????????

That would depend on how the data is stored. I don''t know what else to say unless you explain your problem more.

quote:
Original post by sdlprorammer
>So if you managed to load the data or create it, you really should know how the data is stored. Right?
But RGBA is what the data contains! ???

I''m not sure what the problem is. The masks? There''s an example for data stored in RGBA-order on this page:
http://sdldoc.csn.ul.ie/sdlcreatergbsurface.php

Share this post


Link to post
Share on other sites
sdlprorammer    100
If the pitch may or may not be width * bytesperpixel, then i shouldn't pass to the function the value width * bytesperpixel, right? then what should i pass?

>I'm not sure what the problem is. The masks? There's an example for data stored in RGBA-order on this page:

Maybe we are talking about different things. So: How will the RGBA values you pass to the function influence the resulting surface? isn't that the color of the resulting surface? And how will the bytes pointed by "pixels" influence the resulting surface? Will those bytes determine the color of each pixel in the resulting surface? Or that comes from the RGBA masks you pass to the function?

[edited by - sdlprorammer on May 27, 2004 1:45:12 PM]

Share this post


Link to post
Share on other sites
DBX    178
The data you pass in can have any width,height,pitch and pixel format you like. THAT is what all the options are for, so you tell SDL what format your data is so it can convert it to RGB, and possibly A.
You should know all this information because it is your data you are passing.

Share this post


Link to post
Share on other sites
TomasH    360
quote:
Original post by sdlprorammer
>I''m not sure what the problem is. The masks? There''s an example for data stored in RGBA-order on this page:

Maybe we are talking about different things. So: How will the RGBA values you pass to the function influence the resulting surface? isn''t that the color of the resulting surface? And how will the bytes pointed by "pixels" influence the resulting surface? Will those bytes determine the color of each pixel in the resulting surface? Or that comes from the RGBA masks you pass to the function?

[edited by - sdlprorammer on May 27, 2004 1:45:12 PM]

pixels - an array of pixels which will be used for the surface (to describe its colors.)
masks - describe how the pixels in the array (and hence the surface) are stored.

Share this post


Link to post
Share on other sites
TravisWells    276
quote:
Original post by sdlprorammer
Then how can i determine what value to pass to the function?????????


You would know since you created the array of bytes, and it is assumed that you know what format it is in. (If not, then it's just junk data. SDL can't help you there)
quote:

But RGBA is what the data contains! ???

If it contains RGBA, then you'd use these masks: (from the manual)

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

SDL_Surfaces don't have to contain this format (RGBA in that order, 8 bits each), that's why you have the masks.
Instead of RGBA at 8 bits each, you might have a RGB 5bits/6bits/5bits format, or BGR 8 bits each, no alpha.
SDL will support it, you just have to tell it how to get the colors out.

Here's why SDL can't figure out what the colors are based on the *pixels. Say your pixel array looks like this:
char pixels[]={100,200,50,255,/* ... More pixels*/ };
Is that Red=100,Green=200,Blue=50,Alpha=255?
Or Red=50, Green=200,Blue=100, Alpha=255?
Or even Red=100,Green=200,Blue=50, Next pixels' Red=255 ...

See? There's plenty of ways to store color data in memory. SDL has to know which one you are using.

As for pitch, imagine you have this format for a 3x3 pixel RGB image;

RGB RGB RGB
RGB RGB RGB
RGB RGB RGB

(Newlines just for formatting. This is just a 1D array in memory)
That's 27 bytes. To load this, you'd use this form:
(Spread out for comments)

surface=SDL_CreateRGBSurfaceFrom(pixeldata, //pointer to the pixels
3,//Width
3,//Height
24,//Depth (bits per pixel)
3*3,//Pitch (width*depth_in_bytes, in this case)
0x0000FF,//Red mask
0x00FF00,//Green mask
0xFF0000,//Blue mask
0); //Alpha mask (no alpha in this format)


Now instead of that format, say you have this one (same size):

RGB RGB RGB X
RGB RGB RGB X
RGB RGB RGB X

It's still a 3x3 image, but each line is padded to a 10-byte boundary (BMP does something like this)
Instead of modifying the data before loading, you can make a simple change to your CreateRGBSurfaceFrom and still use it fine:

surface=SDL_CreateRGBSurfaceFrom(pixeldata, //pointer to the pixels
3,//Width
3,//Height
24,//Depth (bits per pixel)
10 ,//Pitch
0x0000FF,//Red mask
0x00FF00,//Green mask
0xFF0000,//Blue mask
0); //Alpha mask (no alpha in this format)

Now SDL knows that to get from line 0 to line 1, it just adds 10 to the position. The surface will still act the same, you can still blit it,colorkey it, etc. (It'll just take up a tad more memory)

Hope that makes it a bit more clear.




[edited by - TravisWells on May 27, 2004 2:00:03 PM]

Share this post


Link to post
Share on other sites
sdlprorammer    100
Jeez!! MANY MANY MANY thanks to everybody that helped me with my problem! It makes a lot more sence now thanks!

But i do have some smaller questions now:
1) What the "endian" value? that's a term i don't know And why do we use a preproccessor directive instead of a simple if-else statement?

2) Why would i choose CreateRGBSurfaceFrom() instead of LoadBMP()?????

3) >You would know since you created the array of bytes, and it is assumed that you know what format it is in.
Maybe i would when no more crap bytes where added to the image by the program, but how would i know what kind of padding did the particular program do? How could i determine the number of those extra bytes?

thanks again...

[edited by - sdlprorammer on May 27, 2004 2:27:55 PM]

Share this post


Link to post
Share on other sites
TomasH    360
quote:
Original post by sdlprorammer
Jeez!! MANY MANY MANY thanks to everybody that helped me with my problem! It makes a lot more sence now thanks!

But i do have some smaller questions now:
1) What the "endian" value? that''s a term i don''t know And why do we use a preproccessor directive instead of a simple if-else statement?

http://www.cs.umass.edu/~verts/cs32/endian.html
(or just search on google for more informative sites.)
Why a preprocessor directive? Well, because it''s something that can be known at compile time. You could do it with an if-else if you prefered.

quote:

2) Why would i choose CreateRGBSurfaceFrom() instead of LoadBMP()?????


Because LoadBMP can just load BMP files. CreateRGBSurfaceFrom() can be used on data you''ve loaded from any kind of file or created in any other way.
If you just want to load files, you might as well use SDL_image (or some other file loading library): http://www.libsdl.org/projects/SDL_image/

quote:

3) >You would know since you created the array of bytes, and it is assumed that you know what format it is in.
Maybe i would when no more crap bytes where added to the image by the program, but how would i know what kind of padding did the particular program do? How could i determine the number of those extra bytes?


What program? You''re the one creating the array, so you get to choose how many extra bytes of padding you want. If you''re loading a file with padding, then information on this should be in the file''s header (or the file format specification.)

Share this post


Link to post
Share on other sites
sdlprorammer    100
Thakd Tomas for your help

Ok, i 've read the article. Here's my simple question:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;

Why is rmask the Bigest byte in Big Ebdian, and not, say bmask etc.? From what i understood, the biggest byte comes first, what if in a pixel the R value in 0 and the B value is 200? Then bmask should be 0xFF000000, right? Or did i missunderstand something?

>CreateRGBSurfaceFrom() can be used on data you've loaded from any kind of file or created in any other way.
If you just want to load files, you might as well use SDL_image (or some other file loading library): http://www.libsdl.org/projects/SDL_image/

ok thanks i think i'll stick with CreateRGBSurfaceFrom()

>..so you get to choose how many extra bytes of padding you want..
But the point is that you don't know in advance what kind of padding the program that wrote the picture used. Say for exaple i have a simple struct in C/C++. Can i know what kind of padding a particular compiler chose to make? I can't. So??

thanks...



[edited by - sdlprorammer on May 27, 2004 4:36:27 PM]

Share this post


Link to post
Share on other sites
TomasH    360
quote:
Original post by sdlprorammer
>..so you get to choose how many extra bytes of padding you want..
But the point is that you don''t know in advance what kind of padding the program that wrote the picture used. Say for exaple i have a simple struct in C/C++. Can i know what kind of padding a particular compiler chose to make? I can''t. So??


Well.. That information should be in the header of the image file. Since you loaded the file into memory, you''ve read the header, and should have all the necessary data.
(I suppose it''s possible that the header for some file format doesn''t hold this information. In this case you should find it in the specification for the file format.)

Share this post


Link to post
Share on other sites
TomasH    360
Oh, sorry, I forgot to answer the other one. I''ll do it below.
About the header; well, an image file is usually organized so that there''s a header before all the pixel data. The header identifies the file format, the dimensions of the image and so on. Exactly how this looks will depend on the file format in question.

quote:
Original post by sdlprorammer
Ok, i ''ve read the article. Here''s my simple question:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;

Why is rmask the Bigest byte in Big Ebdian, and not, say bmask etc.? From what i understood, the biggest byte comes first, what if in a pixel the R value in 0 and the B value is 200? Then bmask should be 0xFF000000, right? Or did i missunderstand something?

Well, that wouldn''t work, would it? That would mean that it would be impossible to know what the order was for the different pixels (since you only specify the masks once - for the whole image.)
Say that you have a number 0x236554.
In a big endian system it would be stored like this: 23 65 54
In a little endian system it would be stored like this: 54 65 23
"Little" and "big" doesn''t have anything to do with the value of the individual bytes, but with the significance of each byte.
If you look at the number 19, the number 1 is in a more significant position than the number 9, since the position of the former represents tens while the position of the latter represents ones. It''s the same thing when it comes to bytes; if you have the three-byte number above, 23 is more significant than 65 which is more significant than 54.

Share this post


Link to post
Share on other sites
TravisWells    276
quote:
Original post by sdlprorammer
and BTW, what kind of header are you reffering to? It''s .jpeg or .bmp files and perhaps much more


BMP you can figure it out from the header (Don''t remember the details, haven''t written my own BMP functions in a while)
JPEG isn''t RGB/RGBA, so it doesn''t matter. You have to decode the JPEG anyway, so you just decode into whatever format you want (RGB,RGBX,RGBA,BGR,BGRA,BGRX,ARGB,XRGB... etc) then tell SDL that.

Share this post


Link to post
Share on other sites
TravisWells    276
Endianess matters because SDL uses a common optimization to stuff a pixel into a single long int.

Say your pixel is this, RGBA 8 bits format:

01 02 03 00

That''s RED: 1 GREEN: 2 BLUE: 3 ALPHA: 0

Now if you load that into a long int on a PC, it''ll look like the number 197121 (1*1 + 2*256 + 3*65536 + 0*16777216)
Load it on a Mac (or a Sparc) and you get 16909056 (1*16777216 + 2*65536 + 3*256 + 0*1)

Your masks have to depend on endianess because while the actual bytes on file don''t move around going PC->Mac or Mac->PC (They''ll still be [1,2,3,0]), the way that they laid out in an integer will change.

Share this post


Link to post
Share on other sites
sdlprorammer    100
thanks for the help! But my question is not completely answered

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
#endif

According to that code, if the byte order is in Big Endian, then you the first byte you read is for the red color, the second for green and so on. According to the code there are only 2 possible ways to read the picture:
1) Read the bytes in RGBA order
2) read the bytes in ABGR orde
---

And i adk:
1) What if the picture stores its bytes in a different order ( say GARB )??
2) A .bmp file is a .bmp and doesn''t change. What i don''t understand is why if we are on a PC which uses Big Endian we have to read the bytes in one way, whereas if we are on a Mac we have to read the bytes in a different way. ?? Since it''s SDL, the program, that reads the bytes, why doesn''t it form the long intger from the bytes in one way, so that it knows what happens? i mean, SDL ( the function anyway ) will read the bytes freom the picture in one order. That order will be the same in a PC and in a Mac, right? ( i think that''s where i am wrong - please explain ). Because if the order that the function uses to read the bytes was not the same, we would care about Endians. So??

Thanks...

Share this post


Link to post
Share on other sites
TomasH    360
quote:
Original post by sdlprorammer

According to that code, if the byte order is in Big Endian, then you the first byte you read is for the red color, the second for green and so on. According to the code there are only 2 possible ways to read the picture:
1) Read the bytes in RGBA order
2) read the bytes in ABGR orde


That''s because that code is written only for reading pixels which are in RGBA order, nothing else.

quote:

1) What if the picture stores its bytes in a different order ( say GARB )??


Then you''ll have to use different masks.

quote:

2) A .bmp file is a .bmp and doesn''t change. What i don''t understand is why if we are on a PC which uses Big Endian we have to read the bytes in one way, whereas if we are on a Mac we have to read the bytes in a different way. ??


Because we don''t treat them as just a bunch of bytes; we treat them as pixels consisting of three or four bytes.

quote:

Since it''s SDL, the program, that reads the bytes, why doesn''t it form the long intger from the bytes in one way, so that it knows what happens? i mean, SDL ( the function anyway ) will read the bytes freom the picture in one order. That order will be the same in a PC and in a Mac, right? ( i think that''s where i am wrong - please explain ). Because if the order that the function uses to read the bytes was not the same, we would care about Endians. So??


That''s the point of the mask. Since SDL has no way of knowing if the file is in big endian or little endian format, it can''t just form integers from it. Yes, the bytes will be read in the same order whether it''s on a big endian or little endian machine. However, since they are stored in memory in different orders, we need to use the masks. If you have four bytes like this:
0x11223344
And read them into memory, they will of course be stored in that order. But if you treat those four bytes as a single unit (a pixel or a 32 bit number) and want to check the value of the first byte, a little endian machine would give us 0x44, and a big endian machine would give 0x11. If we used a mask like this:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN 
mask = 0xff000000;
#else
mask = 0x000000ff;
#endif

then we would get 0x11 on both machines.

Share this post


Link to post
Share on other sites