Problem with SDL_CreateRGBSurface()

Hello!

I need some help with a program I’m writing. I’m doing a function that
it supposed to resize an image to twice the size (i.e. double the
pixels). To do this, I must first create a new surface that has twice
the width and height of the original surface. This is where my problem
starts. What I basically have is:

void CreateImageSurface(SDL_Surface *surface, int width, int height) {
Uint32 rmask, gmask, bmask, amask;

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

surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24,
rmask, gmask, bmask, amask);
}

I then call from anywhere in my program first:

SDL_Surface *new_image;

And then:

CreateImageSurface(new_image, 640, 480);

But when I try to blit to the new created surface, nothing happens. It’s
just black. And if I use SDL_FillRect() on the new surface, the program
will exit with “segmentation fault” error and dump.

Can anyone tell me what I am doing wrong?

Best regards
// David Karlgren

David Karlgren wrote:

rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24, rmask,
gmask, bmask, amask);

Your masks are for a 32bpp surface but you attempt to create a 24bpp one.
I am not sure what SDL would do in this case, but I suppose the weird
surface format would cause all sorts of problems.
See what kind of surface SDL_CreateRGBSurface() actually returns (it’s
format, in particluar), if any.

-Alex.

[…]

void CreateImageSurface(SDL_Surface *surface, int width, int height)
{
Uint32 rmask, gmask, bmask, amask;
[…]
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24,
rmask, gmask, bmask, amask);
}
[…]

This function just changes it’s copy of the argument ‘surface’ and
then returns, leaking a surface while not affecting anything in the
calling context.

The normal, straightforward way of doing it in C would be:On Thursday 08 December 2005 15.00, David Karlgren wrote:


SDL_Surface *CreateImageSurface(int width, int height)
{

return SDL_CreateRGBSurface(SDL_SWSURFACE,
width, height, 24,
rmask, gmask, bmask, amask);
}

SDL_Surface *new_image = CreateImageSurface(640, 480);

Though I don’t see why you would in this case, you can do it the way
you’re trying to do it:


void CreateImageSurface(SDL_Surface **surface, int width, int height)
{

*surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
width, height, 24,
rmask, gmask, bmask, amask);
}

SDL_Surface *new_image;

CreateImageSurface(&new_image, 640, 480);

(Oh, and BTW, this has nothing whatsoever to do with SDL - it’s basic
C stuff.)

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se

Alex Volkov wrote:

David Karlgren wrote:

rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24, rmask,

gmask, bmask, amask);

Your masks are for a 32bpp surface but you attempt to create a 24bpp one.
I am not sure what SDL would do in this case, but I suppose the weird
surface format would cause all sorts of problems.
See what kind of surface SDL_CreateRGBSurface() actually returns (it’s
format, in particluar), if any.

-Alex.

Thanks a lot for the help Alex, I understand fully now that I have been
doing wrong. :slight_smile:

Best regards
David Karlgren>


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


www.terrorpunksyndicate.org
www.myspace.com/terrorpunksyndicate

(Oh, and BTW, this has nothing whatsoever to do with SDL - it’s basic
C stuff.)

Thank you, but no I think it did have with SDL to do because like Alex
Volkov wrote it was the maskdata (the

0xff000000 graphic data) which I didn’t fully understand.

David Karlgren>

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


www.terrorpunksyndicate.org
www.myspace.com/terrorpunksyndicate

(Oh, and BTW, this has nothing whatsoever to do with SDL - it’s
basic

C stuff.)

Thank you, but no I think it did have with SDL to do because like
Alex Volkov wrote it was the maskdata (the
0xff000000 graphic data) which I didn’t fully understand.

Well, I assume that the real code is different from the code you
posted, which AFAICT would segfault or do nothing regardless.

Anyway, incorrect masks should never result in a segfault, I think.
You’d be getting either weird colors (one channel missing), a fully
transparent surface (alpha channel missing), or maybe some other
weird results - not a black surface. Then again, you would get a
black surface if realized something’s wrong and gave up…

Oh well. Now you have a few things to try! :wink:

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Thursday 08 December 2005 17.38, David K wrote:

Does a change to the arguments of SDL_CreateRGBSurface() fix the problem??
I’d be very suprised!

Olofson is right man. When you tell the pointer, that you get in a function
as an argument, to point to something else, you’re only changing that
particular pointer; the one which you feed as an argument will still be
pointing to the same address he was before you called the function.

The only reason why your code might work this way is because when you declare
the pointer, it might point by default to the next piece of unused memory
that incidentally is the same that is created by your function. Just try to
assign new_image to NULL when you declare it, and see if it booms.

In case you really want your function to be used that way – instead of the
more intuitive surface = CreateIma…(); – you may use Olofson approach, or
you may use references, in case you are using C++.

By the way, you should also do error testing, never delay this for when your
code works, do it while you program! In this case, you should’ve tested if
surface was NULL when you call the SDL function to see if it was succesfully
created (this is documented behavior).

Cheers,
RicardoEm Quinta 08 Dezembro 2005 16:38, o David K escreveu:

(Oh, and BTW, this has nothing whatsoever to do with SDL - it’s basic
C stuff.)

Thank you, but no I think it did have with SDL to do because like Alex
Volkov wrote it was the maskdata (the

0xff000000 graphic data) which I didn’t fully understand.

David Karlgren


The reason computer chips are so small is computers don’t eat much.