Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed bug 5037 - Regression 2.0.12 Alpha value of 0 on palette may be…
…come opaque

(see also bug 3827)
  • Loading branch information
1bsyl committed Mar 17, 2020
1 parent 36d5845 commit 838bbf1
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 19 deletions.
10 changes: 4 additions & 6 deletions src/render/SDL_render.c
Expand Up @@ -1165,12 +1165,10 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)

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

Expand Down
48 changes: 48 additions & 0 deletions src/video/SDL_pixels.c
Expand Up @@ -801,6 +801,54 @@ SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
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 */
Uint32
SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b)
Expand Down
1 change: 1 addition & 0 deletions src/video/SDL_pixels_c.h
Expand Up @@ -40,6 +40,7 @@ extern void SDL_FreeBlitMap(SDL_BlitMap * map);
/* Miscellaneous functions */
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 void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel);

#endif /* SDL_pixels_c_h_ */

Expand Down
20 changes: 7 additions & 13 deletions src/video/SDL_surface.c
Expand Up @@ -1032,22 +1032,16 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
* -> set alpha channel to be opaque */
if (surface->format->palette && format->Amask) {
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) {
/* Palette has at least one alpha value. Don't do anything */
set_opaque = SDL_FALSE;
palette_has_alpha = SDL_TRUE;
break;
}
SDL_bool is_opaque, has_alpha_channel;
SDL_DetectPalette(surface->format->palette, &is_opaque, &has_alpha_channel);

if (alpha_value == 0) {
set_opaque = SDL_TRUE;
}
if (is_opaque) {
if (!has_alpha_channel) {
set_opaque = SDL_TRUE;
}
} else {
palette_has_alpha = SDL_TRUE;
}

/* Set opaque and backup palette alpha values */
Expand Down

0 comments on commit 838bbf1

Please sign in to comment.