SDL_CreateRGBSurfaceFrom
Use this function to allocate a new RGB surface with existing pixel data.
Contents
Syntax
SDL_Surface* SDL_CreateRGBSurfaceFrom(void* pixels,
int width,
int height,
int depth,
int pitch,
Uint32 Rmask,
Uint32 Gmask,
Uint32 Bmask,
Uint32 Amask)
Function Parameters
pixels |
a pointer to existing pixel data |
width |
the width of the surface |
height |
the height of the surface |
depth |
the depth of the surface in bits; see Remarks for details |
pitch |
the length of a row of pixels in bytes |
Rmask |
the red mask for the pixels |
Gmask |
the green mask for the pixels |
Bmask |
the blue mask for the pixels |
Amask |
the alpha mask for the pixels |
Return Value
Returns the new SDL_Surface structure that is created or NULL if it fails; call SDL_GetError() for more information.
Code Examples
// This example shows how to create a SDL_Surface* with the data loaded from an image
// file with the stb_image.h library (https://github.com/nothings/stb/)
// the color format you request stb_image to output,
// use STBI_rgb if you don't want/need the alpha channel
int req_format = STBI_rgb_alpha;
int width, height, orig_format;
unsigned char* data = stbi_load("./test.png", &width, &height, &orig_format, req_format);
if(data == NULL) {
SDL_Log("Loading image failed: %s", stbi_failure_reason());
exit(1);
}
// Set up the pixel format color masks for RGB(A) byte arrays.
// Only STBI_rgb (3) and STBI_rgb_alpha (4) are supported here!
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int shift = (req_format == STBI_rgb) ? 8 : 0;
rmask = 0xff000000 >> shift;
gmask = 0x00ff0000 >> shift;
bmask = 0x0000ff00 >> shift;
amask = 0x000000ff >> shift;
#else // little endian, like x86
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = (req_format == STBI_rgb) ? 0 : 0xff000000;
#endif
int depth, pitch;
if (req_format == STBI_rgb) {
depth = 24;
pitch = 3*width; // 3 bytes per pixel * pixels per row
} else { // STBI_rgb_alpha (RGBA)
depth = 32;
pitch = 4*width;
}
SDL_Surface* surf = SDL_CreateRGBSurfaceFrom((void*)data, width, height, depth, pitch,
rmask, gmask, bmask, amask);
if (surf == NULL) {
SDL_Log("Creating surface failed: %s", SDL_GetError());
stbi_image_free(data);
exit(1);
}
// ... do something useful with the surface ...
// ...
// when you don't need the surface anymore, free it..
SDL_FreeSurface(surf);
// .. *and* the data used by the surface!
stbi_image_free(data);
Remarks
If depth is 4 or 8 bits, an empty palette is allocated for the surface. If depth is greater than 8 bits, the pixel format is set using the [RGBA]mask parameters.
The [RGBA]mask parameters are the bitmasks used to extract that color from a pixel. For instance, Rmask being FF000000 means the red data is stored in the most significant byte. Using zeros for the RGB masks sets a default value, based on the depth. (e.g. SDL_CreateRGBSurface(0,w,h,32,0,0,0,0);) However, using zero for the Amask results in an Amask of 0.
By default surfaces with an alpha mask are set up for blending as with
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND)
You can change this by calling SDL_SetSurfaceBlendMode() and selecting a different blendMode.
No copy is made of the pixel data. Pixel data is not managed automatically; you must free the surface before you free the pixel data.