Fixed bug 5037 - Regression 2.0.12 Alpha value of 0 on palette may become opaque

(see also bug 3827)
This commit is contained in:
Sylvain Becker 2020-03-17 09:35:42 +01:00
parent 36d5845152
commit 838bbf1f7a
4 changed files with 60 additions and 19 deletions

View File

@ -1165,12 +1165,10 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
/* If Palette contains alpha values, promotes to alpha format */ /* If Palette contains alpha values, promotes to alpha format */
if (fmt->palette) { if (fmt->palette) {
for (i = 0; i < fmt->palette->ncolors; i++) { SDL_bool is_opaque, has_alpha_channel;
Uint8 alpha_value = fmt->palette->colors[i].a; SDL_DetectPalette(fmt->palette, &is_opaque, &has_alpha_channel);
if (alpha_value != 0 && alpha_value != SDL_ALPHA_OPAQUE) { if (!is_opaque) {
needAlpha = SDL_TRUE; needAlpha = SDL_TRUE;
break;
}
} }
} }

View File

@ -801,6 +801,54 @@ SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
return (pixel); return (pixel);
} }
/* Tell whether palette is opaque, and if it has an alpha_channel */
void
SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel)
{
int i;
{
SDL_bool all_opaque = SDL_TRUE;
for (i = 0; i < pal->ncolors; i++) {
Uint8 alpha_value = pal->colors[i].a;
if (alpha_value != SDL_ALPHA_OPAQUE) {
all_opaque = SDL_FALSE;
break;
}
}
if (all_opaque) {
/* Palette is opaque, with an alpha channel */
*is_opaque = SDL_TRUE;
*has_alpha_channel = SDL_TRUE;
return;
}
}
{
SDL_bool all_transparent = SDL_TRUE;
for (i = 0; i < pal->ncolors; i++) {
Uint8 alpha_value = pal->colors[i].a;
if (alpha_value != SDL_ALPHA_TRANSPARENT) {
all_transparent = SDL_FALSE;
break;
}
}
if (all_transparent) {
/* Palette is opaque, without an alpha channel */
*is_opaque = SDL_TRUE;
*has_alpha_channel = SDL_FALSE;
return;
}
}
/* Palette has alpha values */
*is_opaque = SDL_FALSE;
*has_alpha_channel = SDL_TRUE;
}
/* Find the opaque pixel value corresponding to an RGB triple */ /* Find the opaque pixel value corresponding to an RGB triple */
Uint32 Uint32
SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b) SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b)

View File

@ -40,6 +40,7 @@ extern void SDL_FreeBlitMap(SDL_BlitMap * map);
/* Miscellaneous functions */ /* Miscellaneous functions */
extern void SDL_DitherColors(SDL_Color * colors, int bpp); extern void SDL_DitherColors(SDL_Color * colors, int bpp);
extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a); extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
extern void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel);
#endif /* SDL_pixels_c_h_ */ #endif /* SDL_pixels_c_h_ */

View File

@ -1032,22 +1032,16 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
* -> set alpha channel to be opaque */ * -> set alpha channel to be opaque */
if (surface->format->palette && format->Amask) { if (surface->format->palette && format->Amask) {
SDL_bool set_opaque = SDL_FALSE; SDL_bool set_opaque = SDL_FALSE;
{
int i;
for (i = 0; i < surface->format->palette->ncolors; i++) {
Uint8 alpha_value = surface->format->palette->colors[i].a;
if (alpha_value != 0 && alpha_value != SDL_ALPHA_OPAQUE) { SDL_bool is_opaque, has_alpha_channel;
/* Palette has at least one alpha value. Don't do anything */ SDL_DetectPalette(surface->format->palette, &is_opaque, &has_alpha_channel);
set_opaque = SDL_FALSE;
palette_has_alpha = SDL_TRUE;
break;
}
if (alpha_value == 0) { if (is_opaque) {
set_opaque = SDL_TRUE; if (!has_alpha_channel) {
} set_opaque = SDL_TRUE;
} }
} else {
palette_has_alpha = SDL_TRUE;
} }
/* Set opaque and backup palette alpha values */ /* Set opaque and backup palette alpha values */