Skip to content

Commit

Permalink
Set the colorkey or expand the palette for indexed PNG images
Browse files Browse the repository at this point in the history
SDL doesn't support alpha blending using the palette alpha

Fixes #409

(cherry picked from commit c6f46fe)
  • Loading branch information
slouken committed Dec 28, 2023
1 parent a38dd11 commit 9f88b0a
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/IMG_stb.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ SDL_Surface *IMG_LoadSTB_RW(SDL_RWops *src)
rw_callbacks.eof = IMG_LoadSTB_RW_eof;
w = h = format = 0; /* silence warning */
if (use_palette) {
/* Unused palette entries will be opaque white */
SDL_memset(palette_colors, 0xff, sizeof(palette_colors));

pixels = stbi_load_from_callbacks_with_palette(
&rw_callbacks,
src,
Expand Down Expand Up @@ -150,6 +153,8 @@ SDL_Surface *IMG_LoadSTB_RW(SDL_RWops *src)
SDL_PIXELFORMAT_INDEX8
);
if (surface) {
SDL_bool has_colorkey = SDL_FALSE;
int colorkey_index = -1;
SDL_bool has_alpha = SDL_FALSE;
SDL_Palette *palette = surface->format->palette;
if (palette) {
Expand All @@ -162,20 +167,33 @@ SDL_Surface *IMG_LoadSTB_RW(SDL_RWops *src)
palette->colors[i].b = *palette_bytes++;
palette->colors[i].a = *palette_bytes++;
if (palette->colors[i].a != SDL_ALPHA_OPAQUE) {
has_alpha = SDL_TRUE;
if (palette->colors[i].a == SDL_ALPHA_TRANSPARENT && !has_colorkey) {
has_colorkey = SDL_TRUE;
colorkey_index = i;
} else {
/* Partial opacity or multiple colorkeys */
has_alpha = SDL_TRUE;
}
}
}
}
if (has_alpha) {
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
/* SDL doesn't support blitting with the palette alpha, so expand the palette */
SDL_Surface *converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0);
SDL_FreeSurface(surface);
surface = converted;
} else if (has_colorkey) {
SDL_SetColorKey(surface, SDL_TRUE, colorkey_index);
}

/* FIXME: This sucks. It'd be better to allocate the surface first, then
* write directly to the pixel buffer:
* https://github.com/nothings/stb/issues/58
* -flibit
*/
surface->flags &= ~SDL_PREALLOC;
if (surface) {
surface->flags &= ~SDL_PREALLOC;
}
}

} else if (format == STBI_grey || format == STBI_rgb || format == STBI_rgb_alpha) {
Expand Down

0 comments on commit 9f88b0a

Please sign in to comment.