SDL: Update the blit mapping when the palette is set on a surface

From 0b2c80557c2ffeac2c9d4b749d75040dc1bd188d Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 10 Jul 2024 23:20:51 -0700
Subject: [PATCH] Update the blit mapping when the palette is set on a surface

Make sure you do this even if the palette pointer hasn't changed, as the contents may have.

Fixes https://github.com/libsdl-org/SDL/issues/10225
---
 src/video/SDL_surface.c       | 18 ++++++--------
 test/testautomation_surface.c | 46 ++++++++++++++++++++++++++++++++++-
 2 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index a92be28cf3bad..c86f84e722468 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -396,18 +396,16 @@ int SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette)
         return SDL_SetError("SDL_SetSurfacePalette() passed a palette that doesn't match the surface format");
     }
 
-    if (palette == surface->internal->palette) {
-        return 0;
-    }
-
-    if (surface->internal->palette) {
-        SDL_DestroyPalette(surface->internal->palette);
-    }
+    if (palette != surface->internal->palette) {
+        if (surface->internal->palette) {
+            SDL_DestroyPalette(surface->internal->palette);
+        }
 
-    surface->internal->palette = palette;
+        surface->internal->palette = palette;
 
-    if (surface->internal->palette) {
-        ++surface->internal->palette->refcount;
+        if (surface->internal->palette) {
+            ++surface->internal->palette->refcount;
+        }
     }
 
     SDL_InvalidateMap(&surface->internal->map);
diff --git a/test/testautomation_surface.c b/test/testautomation_surface.c
index b5def09c1ff87..41284587b19ab 100644
--- a/test/testautomation_surface.c
+++ b/test/testautomation_surface.c
@@ -852,6 +852,45 @@ static int surface_testFlip(void *arg)
     return TEST_COMPLETED;
 }
 
+static int surface_testPalette(void *arg)
+{
+    SDL_Surface *surface, *output;
+    SDL_Palette *palette;
+    Uint8 *pixels;
+    int offset;
+
+    surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_INDEX8);
+    SDLTest_AssertCheck(surface != NULL, "SDL_CreateSurface()");
+
+    output = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA32);
+    SDLTest_AssertCheck(output != NULL, "SDL_CreateSurface()");
+
+    *(Uint8 *)surface->pixels = 255;
+
+    pixels = (Uint8 *)output->pixels;
+    offset = 0;
+
+    SDL_BlitSurface(surface, NULL, output, NULL);
+    SDLTest_AssertCheck(pixels[offset] == 0xFF,
+                        "Expected pixels[%d] == 0xFF got 0x%.2X", offset, pixels[offset]);
+
+    /* Set the palette color and blit again */
+    palette = SDL_GetSurfacePalette(surface);
+    SDLTest_AssertCheck(palette != NULL, "Expected palette != NULL, got %p", palette);
+    if (palette) {
+        palette->colors[255].r = 0xAA;
+    }
+    SDL_SetSurfacePalette(surface, palette);
+    SDL_BlitSurface(surface, NULL, output, NULL);
+    SDLTest_AssertCheck(pixels[offset] == 0xAA,
+                        "Expected pixels[%d] == 0xAA got 0x%.2X", offset, pixels[offset]);
+
+    SDL_DestroySurface(surface);
+    SDL_DestroySurface(output);
+
+    return TEST_COMPLETED;
+}
+
 
 /* ================= Test References ================== */
 
@@ -915,11 +954,16 @@ static const SDLTest_TestCaseReference surfaceTestFlip = {
     surface_testFlip, "surface_testFlip", "Test surface flipping.", TEST_ENABLED
 };
 
+static const SDLTest_TestCaseReference surfaceTestPalette = {
+    surface_testPalette, "surface_testPalette", "Test surface palette operations.", TEST_ENABLED
+};
+
 /* Sequence of Surface test cases */
 static const SDLTest_TestCaseReference *surfaceTests[] = {
     &surfaceTest1, &surfaceTest2, &surfaceTest3, &surfaceTest4, &surfaceTest5,
     &surfaceTest6, &surfaceTest7, &surfaceTest8, &surfaceTest9, &surfaceTest10,
-    &surfaceTest11, &surfaceTest12, &surfaceTestOverflow, &surfaceTestFlip, NULL
+    &surfaceTest11, &surfaceTest12, &surfaceTestOverflow, &surfaceTestFlip,
+    &surfaceTestPalette, NULL
 };
 
 /* Surface test suite (global) */