We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5037

Summary: [Regression 2.0.12] Alpha value of 0 on INDEX8 format surfaces is opaque
Product: SDL Reporter: Jason Borden <jasonborden79>
Component: videoAssignee: Sylvain <sylvain.becker>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: major    
Priority: P2 CC: icculus
Version: HG 2.0Keywords: target-2.0.14
Hardware: x86_64   
OS: Linux   
Attachments: Test INDEX8 alpha program

Description Jason Borden 2020-03-16 04:01:26 UTC
Created attachment 4259 [details]
Test INDEX8 alpha program

In 2.0.12 and latest hg snapshot (2.0.13-13624) INDEX8 type surfaces that use a 0 alpha value in their palette will not be transparent like versions 2.0.5 - 2.0.10. Attached is a test program that shows this bug. On versions 2.0.5 - 2.0.10 a green window will be displayed for 10 seconds. On 2.0.12 or 2.0.13-13624 it will show a white window for 5 seconds then a green window for 5 seconds.
Comment 1 Jason Borden 2020-03-16 04:56:12 UTC
The affecting code is in src/video/SDL_surface.c starting around line 1033. I understand considering a surface to be opaque if all palette values are 255 (SDL_ALPHA_OPAQUE), but why also consider it opaque if there's any 0 (SDL_ALPHA_TRANSPARENT)?
Comment 2 Sam Lantinga 2020-03-16 19:14:16 UTC
Sylvain, I think this is related to changes you made for 2.0.12?
Comment 3 Sylvain 2020-03-16 20:36:09 UTC
Yes, this is from previous fixes, maybe a wrong assumption! 
I think this is related to whether a palette is considered RGB or RGBA.
The explanation:

Images with xpm format are often represented with a palette, and there are loaded as index8.
(it's also possible to get/create index8 palette differently).

Sometimes the palette has a no alpha at all (for each entries, the alpha field is 0), but it's not a fully transparent image. It's a RGB, just no alpha channel, and we have to detect it here:

https://hg.libsdl.org/SDL/file/9a8e6854f652/src/video/SDL_surface.c#l1030

https://hg.libsdl.org/SDL/file/9a8e6854f652/src/render/SDL_render.c#l1166

The current implementation is short and does that in 1 loop + break:
It says by default it's RGB, but if there is an alpha value != 0 and != 255, it becomes ARGB.

So a palette with entries that are both 0 or 255 are still RGB.

Another implementation could be :
by default it's ARGB, 
but if all alpha fields are 255 it becomes RGB
or if all alpha fields are 0 it becomes RGB


Maybe this is wrong, and should be changed, what do you think Sam?
Comment 4 Sylvain 2020-03-16 20:50:01 UTC
I can also comment the code here:

https://hg.libsdl.org/SDL/file/9a8e6854f652/src/video/SDL_surface.c#l1054

Blitting using a palette with alpha=0 doesn't work, if we want a RGB blit.
We need to detect and temporarily patch the palette, by setting alpha=255.
This is the "if (set_opaque)" block.

If there is a real alpha value, the loop is "break'ed" and set_opaque is set to false.
(https://hg.libsdl.org/SDL/file/9a8e6854f652/src/video/SDL_surface.c#l1042 )
Comment 5 Jason Borden 2020-03-16 21:45:47 UTC
(In reply to Sylvain from comment #3)

> So a palette with entries that are both 0 or 255 are still RGB.

This is my exact scenario. Index 0 is transparent(0) and all other indices are opaque(255).
  
> Another implementation could be :
> by default it's ARGB, 
> but if all alpha fields are 255 it becomes RGB
> or if all alpha fields are 0 it becomes RGB

This solution would fix my problem and still solve your other issue I think.
Comment 6 Sylvain 2020-03-17 08:36:52 UTC
Ok, thanks I fixed this here:
https://hg.libsdl.org/SDL/rev/b68bc68d5cce

added SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel)
to detect whether the palette is fully opaque or not, and it if has an alpha channel.
all alpha 0 ->    it's opaque without alpha channel
all alpha 255 ->  it's opaque with alpha channel
otherwise
it's not opaque, and it has an alpha channel

I replayed a few test-cases of bug 3827, also your!
Comment 7 Ryan C. Gordon 2020-03-24 23:29:17 UTC
Can we mark this bug resolved now, or is there still some problem after Sylvain's patch?
Comment 8 Jason Borden 2020-03-25 04:36:51 UTC
I have verified that my issue has been fixed, but I'm not sure if Sylvain wanted to do any more testing before closing the issue.
Comment 9 Sylvain 2020-03-25 07:41:33 UTC
It seemed ok for me, so I mark this as fixed!