Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Regression 2.0.12] Alpha value of 0 on INDEX8 format surfaces is opaque #3593

Closed
SDLBugzilla opened this issue Feb 11, 2021 · 0 comments
Closed

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: HG 2.0
Reported for operating system, platform: Linux, x86_64

Comments on the original bug report:

On 2020-03-16 04:01:26 +0000, Jason Borden wrote:

Created attachment 4259
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.

On 2020-03-16 04:56:12 +0000, Jason Borden wrote:

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)?

On 2020-03-16 19:14:16 +0000, Sam Lantinga wrote:

Sylvain, I think this is related to changes you made for 2.0.12?

On 2020-03-16 20:36:09 +0000, Sylvain wrote:

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?

On 2020-03-16 20:50:01 +0000, Sylvain wrote:

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 )

On 2020-03-16 21:45:47 +0000, Jason Borden wrote:

(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.

On 2020-03-17 08:36:52 +0000, Sylvain wrote:

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!

On 2020-03-24 23:29:17 +0000, Ryan C. Gordon wrote:

Can we mark this bug resolved now, or is there still some problem after Sylvain's patch?

On 2020-03-25 04:36:51 +0000, Jason Borden wrote:

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.

On 2020-03-25 07:41:33 +0000, Sylvain wrote:

It seemed ok for me, so I mark this as fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant