From 8b17e2ef62bd1528c42e89e5d60bb9ba9ec350ee Mon Sep 17 00:00:00 2001 From: Maarten ter Huurne Date: Thu, 2 Jun 2011 06:19:21 +0200 Subject: [PATCH] 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. --- src/asfont.cpp | 29 ++--------------------------- src/imageio.cpp | 34 +++++++++++++++++++++++++++++++--- src/imageio.h | 2 ++ src/surface.cpp | 7 ++----- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/asfont.cpp b/src/asfont.cpp index c74015d..401bd12 100644 --- a/src/asfont.cpp +++ b/src/asfont.cpp @@ -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); diff --git a/src/imageio.cpp b/src/imageio.cpp index aeebbcb..b9b8921 100644 --- a/src/imageio.cpp +++ b/src/imageio.cpp @@ -2,7 +2,35 @@ #include -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; + } } diff --git a/src/imageio.h b/src/imageio.h index 3e4e48f..54d4640 100644 --- a/src/imageio.h +++ b/src/imageio.h @@ -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 diff --git a/src/surface.cpp b/src/surface.cpp index 264ea3c..20808b8 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -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()); } }