Fixed bug 5037 - Regression 2.0.12 Alpha value of 0 on palette may become opaque (see also bug 3827)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 59c2f49..dfa70bc 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -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;
}
}
diff --git a/src/video/SDL_pixels.c b/src/video/SDL_pixels.c
index f02a2bd..77de36c 100644
--- a/src/video/SDL_pixels.c
+++ b/src/video/SDL_pixels.c
@@ -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)
diff --git a/src/video/SDL_pixels_c.h b/src/video/SDL_pixels_c.h
index c4baf41..8f511c0 100644
--- a/src/video/SDL_pixels_c.h
+++ b/src/video/SDL_pixels_c.h
@@ -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_ */
diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index 3795b94..77a6bc8 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -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 */