1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-07-02 18:05:26 +03:00

PNG: Make loadPNG() responsible for creating an RGBA surface.

Before this commit loadPNG() could return any surface format and the caller
was responsible for converting it to the desired format. However, in practice
all callers want a surface with an alpha channel and SDL only supports that
with 32bpp surfaces, so RGBA or a permutation thereof. So I changed the
contract for loadPNG() so it is required to return an RGBA surface, and
removed the conversion code in the callers.

The next step is to replace IMG_Load() by a function that calls libpng
directly and loads a fixed 32bpp pixel format. That way, we can drop the
SDL_image dependency and avoid unnecessary pixel format conversions.
This commit is contained in:
Maarten ter Huurne 2011-06-02 06:19:21 +02:00
parent 7877fee3fa
commit 8b17e2ef62
4 changed files with 37 additions and 35 deletions

View File

@ -11,35 +11,10 @@
ASFont::ASFont(const std::string &fontImagePath)
: characters(SFONTPLUS_CHARSET)
{
// Load PNG file into an SDL surface.
SDL_Surface *buf = loadPNG(fontImagePath);
if (!buf) {
surface = NULL;
surface = loadPNG(fontImagePath);
if (!surface) {
return;
}
// Make sure we have a surface that can be blitted using alpha blending.
if (buf->format->BytesPerPixel == 4) {
surface = buf;
SDL_SetAlpha(surface, SDL_SRCALPHA, 255);
} else {
SDL_PixelFormat format32;
memset(&format32, 0, sizeof(format32));
format32.BitsPerPixel = 32;
format32.BytesPerPixel = 4;
format32.Rmask =
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x00FF0000 : 0x000000FF;
format32.Gmask = 0x0000FF00;
format32.Bmask =
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x000000FF : 0x00FF0000;
format32.Amask = 0xFF000000;
format32.Rshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 16 : 0;
format32.Gshift = 8;
format32.Bshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0 : 16;
format32.Ashift = 24;
surface = SDL_ConvertSurface(buf, &format32, SDL_SRCALPHA);
SDL_FreeSurface(buf);
}
assert(surface->format->BytesPerPixel == 4);
SDL_LockSurface(surface);

View File

@ -2,7 +2,35 @@
#include <SDL_image.h>
SDL_Surface *loadPNG(const std::string &path)
{
return IMG_Load(path.c_str());
SDL_Surface *loadPNG(const std::string &path) {
// Load PNG file into an SDL surface.
SDL_Surface *surface = IMG_Load(path.c_str());
if (!surface) {
return NULL;
}
// Make sure we have a surface that can be blitted using alpha blending.
if (surface->format->BytesPerPixel == 4) {
SDL_SetAlpha(surface, SDL_SRCALPHA, 255);
return surface;
} else {
SDL_PixelFormat format32;
memset(&format32, 0, sizeof(format32));
format32.BitsPerPixel = 32;
format32.BytesPerPixel = 4;
format32.Rmask =
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x00FF0000 : 0x000000FF;
format32.Gmask = 0x0000FF00;
format32.Bmask =
SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x000000FF : 0x00FF0000;
format32.Amask = 0xFF000000;
format32.Rshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 16 : 0;
format32.Gshift = 8;
format32.Bshift = SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0 : 16;
format32.Ashift = 24;
SDL_Surface *surface32 =
SDL_ConvertSurface(surface, &format32, SDL_SRCALPHA);
SDL_FreeSurface(surface);
return surface32;
}
}

View File

@ -5,6 +5,8 @@
struct SDL_Surface;
/** Loads an image from a PNG file into a newly allocated 32bpp RGBA surface.
*/
SDL_Surface *loadPNG(const std::string &path);
#endif

View File

@ -90,11 +90,8 @@ void Surface::load(const string &img, const string &skin) {
skinpath = img;
}
SDL_Surface *buf = loadPNG(skinpath);
if (buf!=NULL) {
raw = SDL_DisplayFormatAlpha(buf);
SDL_FreeSurface(buf);
} else {
raw = loadPNG(skinpath);
if (!raw) {
ERROR("Couldn't load surface '%s'\n", img.c_str());
}
}