Fixed bug 5037 - Regression 2.0.12 Alpha value of 0 on palette may become opaque
authorSylvain Becker <sylvain.becker@gmail.com>
Tue, 17 Mar 2020 09:35:42 +0100
changeset 13643b68bc68d5cce
parent 13642 f4ae4b91cf38
child 13644 b1ebbd8cafef
Fixed bug 5037 - Regression 2.0.12 Alpha value of 0 on palette may become opaque
(see also bug 3827)
src/render/SDL_render.c
src/video/SDL_pixels.c
src/video/SDL_pixels_c.h
src/video/SDL_surface.c
     1.1 --- a/src/render/SDL_render.c	Tue Mar 17 02:31:47 2020 -0400
     1.2 +++ b/src/render/SDL_render.c	Tue Mar 17 09:35:42 2020 +0100
     1.3 @@ -1165,12 +1165,10 @@
     1.4  
     1.5      /* If Palette contains alpha values, promotes to alpha format */
     1.6      if (fmt->palette) {
     1.7 -        for (i = 0; i < fmt->palette->ncolors; i++) {
     1.8 -            Uint8 alpha_value = fmt->palette->colors[i].a;
     1.9 -            if (alpha_value != 0 && alpha_value != SDL_ALPHA_OPAQUE) {
    1.10 -                needAlpha = SDL_TRUE;
    1.11 -                break;
    1.12 -            }
    1.13 +        SDL_bool is_opaque, has_alpha_channel;
    1.14 +        SDL_DetectPalette(fmt->palette, &is_opaque, &has_alpha_channel);
    1.15 +        if (!is_opaque) {
    1.16 +            needAlpha = SDL_TRUE;
    1.17          }
    1.18      }
    1.19  
     2.1 --- a/src/video/SDL_pixels.c	Tue Mar 17 02:31:47 2020 -0400
     2.2 +++ b/src/video/SDL_pixels.c	Tue Mar 17 09:35:42 2020 +0100
     2.3 @@ -801,6 +801,54 @@
     2.4      return (pixel);
     2.5  }
     2.6  
     2.7 +/* Tell whether palette is opaque, and if it has an alpha_channel */
     2.8 +void
     2.9 +SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel)
    2.10 +{
    2.11 +    int i;
    2.12 +
    2.13 +    {
    2.14 +        SDL_bool all_opaque = SDL_TRUE;
    2.15 +        for (i = 0; i < pal->ncolors; i++) {
    2.16 +            Uint8 alpha_value = pal->colors[i].a;
    2.17 +            if (alpha_value != SDL_ALPHA_OPAQUE) {
    2.18 +                all_opaque = SDL_FALSE;
    2.19 +                break;
    2.20 +            }
    2.21 +        }
    2.22 +
    2.23 +        if (all_opaque) {
    2.24 +            /* Palette is opaque, with an alpha channel */
    2.25 +            *is_opaque = SDL_TRUE;
    2.26 +            *has_alpha_channel = SDL_TRUE;
    2.27 +            return;
    2.28 +        }
    2.29 +    }
    2.30 +
    2.31 +    {
    2.32 +        SDL_bool all_transparent = SDL_TRUE;
    2.33 +        for (i = 0; i < pal->ncolors; i++) {
    2.34 +            Uint8 alpha_value = pal->colors[i].a;
    2.35 +            if (alpha_value != SDL_ALPHA_TRANSPARENT) {
    2.36 +                all_transparent = SDL_FALSE;
    2.37 +                break;
    2.38 +            }
    2.39 +        }
    2.40 +
    2.41 +        if (all_transparent) {
    2.42 +            /* Palette is opaque, without an alpha channel */
    2.43 +            *is_opaque = SDL_TRUE;
    2.44 +            *has_alpha_channel = SDL_FALSE;
    2.45 +            return;
    2.46 +        }
    2.47 +    }
    2.48 +
    2.49 +    /* Palette has alpha values */
    2.50 +    *is_opaque = SDL_FALSE;
    2.51 +    *has_alpha_channel = SDL_TRUE;
    2.52 +}
    2.53 +
    2.54 +
    2.55  /* Find the opaque pixel value corresponding to an RGB triple */
    2.56  Uint32
    2.57  SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b)
     3.1 --- a/src/video/SDL_pixels_c.h	Tue Mar 17 02:31:47 2020 -0400
     3.2 +++ b/src/video/SDL_pixels_c.h	Tue Mar 17 09:35:42 2020 +0100
     3.3 @@ -40,6 +40,7 @@
     3.4  /* Miscellaneous functions */
     3.5  extern void SDL_DitherColors(SDL_Color * colors, int bpp);
     3.6  extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
     3.7 +extern void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel);
     3.8  
     3.9  #endif /* SDL_pixels_c_h_ */
    3.10  
     4.1 --- a/src/video/SDL_surface.c	Tue Mar 17 02:31:47 2020 -0400
     4.2 +++ b/src/video/SDL_surface.c	Tue Mar 17 09:35:42 2020 +0100
     4.3 @@ -1032,22 +1032,16 @@
     4.4       * -> set alpha channel to be opaque */
     4.5      if (surface->format->palette && format->Amask) {
     4.6          SDL_bool set_opaque = SDL_FALSE;
     4.7 -        {
     4.8 -            int i;
     4.9 -            for (i = 0; i < surface->format->palette->ncolors; i++) {
    4.10 -                Uint8 alpha_value = surface->format->palette->colors[i].a;
    4.11 +
    4.12 +        SDL_bool is_opaque, has_alpha_channel;
    4.13 +        SDL_DetectPalette(surface->format->palette, &is_opaque, &has_alpha_channel);
    4.14  
    4.15 -                if (alpha_value != 0 && alpha_value != SDL_ALPHA_OPAQUE) {
    4.16 -                    /* Palette has at least one alpha value. Don't do anything */
    4.17 -                    set_opaque = SDL_FALSE;
    4.18 -                    palette_has_alpha = SDL_TRUE;
    4.19 -                    break;
    4.20 -                }
    4.21 -
    4.22 -                if (alpha_value == 0) {
    4.23 -                    set_opaque = SDL_TRUE;
    4.24 -                }
    4.25 +        if (is_opaque) {
    4.26 +            if (!has_alpha_channel) {
    4.27 +                set_opaque = SDL_TRUE;
    4.28              }
    4.29 +        } else {
    4.30 +            palette_has_alpha = SDL_TRUE;
    4.31          }
    4.32  
    4.33          /* Set opaque and backup palette alpha values */