summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-04-04 21:27:34 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-04-05 20:59:37 +0200
commitd8b871727c363892b14f2eadfad8f6058ec6ab72 (patch)
tree5fa78f2ccf33d88c3376070e90197877f6aef1c7
parent3fb77358ea1e47aa97d81ecc8ffe02a7f2e45a9a (diff)
downloadmana-d8b871727c363892b14f2eadfad8f6058ec6ab72.tar.gz
mana-d8b871727c363892b14f2eadfad8f6058ec6ab72.tar.bz2
mana-d8b871727c363892b14f2eadfad8f6058ec6ab72.tar.xz
mana-d8b871727c363892b14f2eadfad8f6058ec6ab72.zip
Avoid pixel format conversions when applying dyeHEADmaster
The images returned by IMG_Load_RW appear to usually be in the format SDL_PIXELFORMAT_ABGR8888. As such, adjust the code performing the dye to operate on this format rather than always converting the surfaces to SDL_PIXELFORMAT_RGBA8888. This appears to make the loading of dyed images about 30% faster.
-rw-r--r--src/resources/image.cpp41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 328ea9b8..158d5956 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -113,37 +113,40 @@ Resource *Image::load(SDL_RWops *rw)
Resource *Image::load(SDL_RWops *rw, const Dye &dye)
{
- SDL_Surface *tmpImage = IMG_Load_RW(rw, 1);
+ SDL_Surface *surf = IMG_Load_RW(rw, 1);
- if (!tmpImage)
+ if (!surf)
{
logger->log("Error, image load failed: %s", IMG_GetError());
return nullptr;
}
- SDL_PixelFormat rgba;
- rgba.palette = nullptr;
- rgba.BitsPerPixel = 32;
- rgba.BytesPerPixel = 4;
- rgba.Rmask = 0xFF000000; rgba.Rloss = 0; rgba.Rshift = 24;
- rgba.Gmask = 0x00FF0000; rgba.Gloss = 0; rgba.Gshift = 16;
- rgba.Bmask = 0x0000FF00; rgba.Bloss = 0; rgba.Bshift = 8;
- rgba.Amask = 0x000000FF; rgba.Aloss = 0; rgba.Ashift = 0;
+ if (surf->format->format != SDL_PIXELFORMAT_ABGR8888)
+ {
+ logger->log("Warning: image format is %s, not SDL_PIXELFORMAT_ABGR8888. Converting...",
+ SDL_GetPixelFormatName(surf->format->format));
- SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, 0);
- SDL_FreeSurface(tmpImage);
+ SDL_Surface *convertedSurf = SDL_ConvertSurfaceFormat(surf, SDL_PIXELFORMAT_ABGR8888, 0);
+ SDL_FreeSurface(surf);
+ if (!convertedSurf)
+ {
+ logger->log("Error, image convert failed: %s", SDL_GetError());
+ return nullptr;
+ }
+ surf = convertedSurf;
+ }
- auto *pixels = static_cast< Uint32 * >(surf->pixels);
- for (Uint32 *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
+ auto *pixels = static_cast< uint32_t * >(surf->pixels);
+ for (uint32_t *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
{
- int alpha = *pixels & 255;
+ const uint32_t alpha = (*pixels >> 24) & 255;
if (!alpha) continue;
int v[3];
- v[0] = (*pixels >> 24) & 255;
- v[1] = (*pixels >> 16) & 255;
- v[2] = (*pixels >> 8 ) & 255;
+ v[0] = (*pixels) & 255;
+ v[1] = (*pixels >> 8) & 255;
+ v[2] = (*pixels >> 16) & 255;
dye.update(v);
- *pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha;
+ *pixels = (alpha << 24) | (v[2] << 16) | (v[1] << 8) | v[0];
}
Image *image = load(surf);