pygame-ce
pygame-ce copied to clipboard
UITextBox <img /> loading has no/improper transparency for images created in Clip Studio Paint
Environment:
- Operating system: Windows 10 21H2
- Python version: CPython 3.11, PyPy 3.9.16
- SDL version: SDL 2.26.4
- this issue also relates to version 2.0.22
- PyGame-ce version: 2.2.1
- this issue also relates to versions 2.2.0.dev2, 2.2.0
Current behavior: Images loaded that were created with Clip Studio Paint have no/improper background transparency, while images that were edited / created with FireAlpaca load properly
Expected behavior: Both sets of images would be the same, and have the RGBA transparent background instead of the default RGB 255 one
Screenshots

Step(s) to reproduce:
Create a pygame_gui.elements.UITextBox element that contains an <img /> tag, where the src points to a file made with CSP (attatched, using the suffix _clipstudio)
Test code: github repo, with test images
Other related info:
Hex provided from @ ImLvna
spacer_firealpaca.png:
spacer_clipstudio.png: 
Might be of use to put these here for further examination
spacer_firealpacca:
spacer_csp:

Even though this will be fixed by pygame_gui changing to use premultiplied alpha, it still indicates a compatibility break somewhere, so I'm going to reopen the issue open for investigation.
I did a bit of digging, and this is definitely an issue on the pygame-ce. More specifically, it's an AVX2 code specific issue that disappears when I add an #undef __AVX2__ in the file src_c/simd_blitters_avx2.c. I suspect the issue lies in the function alphablit_alpha_avx2_argb_no_surf_alpha
What makes the two images different, is that when loaded, all transparent pixels in one of the images have RGBA (255, 255, 255, 0) and in the other it is (0, 0, 0, 0). The blitter should handle both these alpha=0 cases the same, but it is not.
Okay so I have zeroed in on the faulty function, it's actually blit_blend_premultiplied_avx2. This bug disappears when I replace the contents of this function with the contents from either blit_blend_premultiplied_sse2 or blit_blend_premultiplied
Okay so I have zeroed in on the faulty function, it's actually
blit_blend_premultiplied_avx2. This bug disappears when I replace the contents of this function with the contents from eitherblit_blend_premultiplied_sse2orblit_blend_premultiplied
What test code are you using?
What makes the two images different, is that when loaded, all transparent pixels in one of the images have RGBA
(255, 255, 255, 0)and in the other it is(0, 0, 0, 0). The blitter should handle both thesealpha=0cases the same, but it is not.
Assuming (from your posting) that you are using the premultipled blend mode. It should not handle these cases the same, because:
- case 1: RGBA
(255, 255, 255, 0)- This colour/pixel is not a pre-multiplied alpha pixel. - case 2: RGBA:
(0, 0, 0, 0)- This colour/pixel is a pre-multiplied alpha pixel.
Case 2 should work correctly and Case 1 should have undefined behaviour because the source data is invalid. I would verify each pixel for validity, but that would be very slow for a blitter. Assuming Case 2 is working and Case 1 is failing - I'm not concerned.
However, it is not ideal that the behaviour is different between SSE2 and AVX2. Please post the test program you are using with the two images above and I can take a look.
I'm using the test code and images from the github repo linked in OPs post. That code does not explicitly use premultiplied alpha, but that uses pygame-gui which must be using premultiplied alpha internally.