From 3f9d8b662700d6237c6219faac2532285306d5ef Mon Sep 17 00:00:00 2001 From: Ankith Date: Sat, 17 May 2025 12:32:55 +0530 Subject: [PATCH] Fix SRCALPHA TGA image saving --- src_c/image.c | 20 ++++++++++---------- test/image_test.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src_c/image.c b/src_c/image.c index e4f9cf70f9..c7dd0b26df 100644 --- a/src_c/image.c +++ b/src_c/image.c @@ -1690,7 +1690,7 @@ SaveTGA_RW(SDL_Surface *surface, SDL_RWops *out, int rle) int alpha = 0; struct TGAheader h; int srcbpp; - Uint8 surf_alpha; + SDL_BlendMode surf_blendmode; int have_surf_colorkey = 0; Uint32 surf_colorkey; SDL_Rect r; @@ -1721,7 +1721,10 @@ SaveTGA_RW(SDL_Surface *surface, SDL_RWops *out, int rle) SDL_PixelFormatEnum output_format; #endif - SDL_GetSurfaceAlphaMod(surface, &surf_alpha); + if (!PG_GetSurfaceBlendMode(surface, &surf_blendmode)) { + return -1; + } + if ((have_surf_colorkey = SDL_HasColorKey(surface))) { SDL_GetColorKey(surface, &surf_colorkey); } @@ -1811,11 +1814,9 @@ SaveTGA_RW(SDL_Surface *surface, SDL_RWops *out, int rle) } } - /* Temporarily remove colorkey and alpha from surface so copies are - opaque */ - SDL_SetSurfaceAlphaMod(surface, SDL_ALPHA_OPAQUE); - if (have_surf_colorkey) { - SDL_SetColorKey(surface, SDL_FALSE, surf_colorkey); + /* Temporarily set SDL_BLENDMODE_NONE so that copies are opaque */ + if (!PG_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE)) { + goto error; } r.x = 0; @@ -1847,9 +1848,8 @@ SaveTGA_RW(SDL_Surface *surface, SDL_RWops *out, int rle) } /* restore flags */ - SDL_SetSurfaceAlphaMod(surface, surf_alpha); - if (have_surf_colorkey) { - SDL_SetColorKey(surface, SDL_TRUE, surf_colorkey); + if (!PG_SetSurfaceBlendMode(surface, surf_blendmode)) { + goto error; } free(rlebuf); diff --git a/test/image_test.py b/test/image_test.py index a8750e7df9..7a4cb27c5e 100644 --- a/test/image_test.py +++ b/test/image_test.py @@ -4,6 +4,7 @@ import io import os import pathlib +import random import tempfile import unittest from concurrent.futures import ThreadPoolExecutor @@ -414,6 +415,39 @@ def test_save_tga(self): # clean up the temp file, even if test fails os.remove(temp_filename) + def test_save_tga_srcalpha(self): + WIDTH = 10 + HEIGHT = 10 + s = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA) + pixels = [ + [ + ( + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255), + ) + for _ in range(WIDTH) + ] + for _ in range(HEIGHT) + ] + for y in range(HEIGHT): + for x in range(WIDTH): + s.set_at((x, y), pixels[y][x]) + + with tempfile.NamedTemporaryFile(suffix=".tga", delete=False) as f: + temp_filename = f.name + + try: + pygame.image.save(s, temp_filename) + s2 = pygame.image.load(temp_filename) + for y in range(HEIGHT): + for x in range(WIDTH): + self.assertEqual(s2.get_at((x, y)), pixels[y][x]) + finally: + # clean up the temp file, even if test fails + os.remove(temp_filename) + def test_save_pathlib(self): surf = pygame.Surface((1, 1)) surf.fill((23, 23, 23))