SDL: Add testautomation suite for alpha blending

From 594ca1a897e8f168fe0215ee50f8fd13cc83ca78 Mon Sep 17 00:00:00 2001
From: Isaac Aronson <[EMAIL REDACTED]>
Date: Tue, 12 Sep 2023 18:41:36 -0500
Subject: [PATCH] Add testautomation suite for alpha blending

---
 test/testautomation_blit.c   | 206 +++++++++++++++++++++
 test/testautomation_images.c | 348 +++++++++++++++++++++++++++++++++++
 test/testautomation_images.h |   2 +
 test/testautomation_suites.h |   1 +
 4 files changed, 557 insertions(+)
 create mode 100644 test/testautomation_blit.c

diff --git a/test/testautomation_blit.c b/test/testautomation_blit.c
new file mode 100644
index 0000000000000..91b7dd8929f65
--- /dev/null
+++ b/test/testautomation_blit.c
@@ -0,0 +1,206 @@
+/**
+ * SDL_BlitSurface bit-perfect rendering test suite written by Isaac Aronson
+ */
+
+/* Suppress C4996 VS compiler warnings for unlink() */
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#if defined(_MSC_VER) && !defined(_CRT_NONSTDC_NO_DEPRECATE)
+#define _CRT_NONSTDC_NO_DEPRECATE
+#endif
+
+#include <stdio.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_test.h>
+#include "testautomation_images.h"
+
+/* ====== xoroshiro128+ PRNG engine for deterministic blit input ===== */
+Uint64 rotl(uint64_t x, int k) { return (x << k) | (x >> (-k & 63)); }
+Uint64 next(uint64_t state[2]) {
+    Uint64 s0 = state[0], s1 = state[1];
+    Uint64 result = rotl((s0 + s1) * 9, 29) + s0;
+    state[0] = s0 ^ rotl(s1, 29);
+    state[1] = s0 ^ s1 << 9;
+    return result;
+}
+static Uint64 rngState[2] = {1, 2};
+Uint32 getRandomUint32() {
+    return (Uint32)next(rngState);
+}
+/* ================= Test Case Helper Functions ================== */
+/*
+ * Resets PRNG state to initialize tests using PRNG
+ */
+void blitSetUp(void *arg) {
+    rngState[0] = 1;
+    rngState[1] = 2;
+}
+/*
+ * Generates a stream of PRNG pixel data given length
+ */
+Uint32 *getNextRandomBuffer(const int width, const int height) {
+    Uint32* buf = SDL_malloc(sizeof(Uint32) * width * height);
+    for (int i = 0; i < width * height; i++) {
+        buf[i] = getRandomUint32();
+    }
+    return buf;
+}
+/*
+ * Generates a small 15 x 15px surface of PRNG pixel data
+ */
+SDL_Surface* getRandomBlitChunk(Uint32 *pixels, SDL_PixelFormatEnum format) {
+    return SDL_CreateSurfaceFrom(pixels, 15, 15, 15 * 4, format);
+}
+/*
+ * Generates a 800 x 600 surface of PRNG pixel data
+ */
+SDL_Surface* getRandomSVGASurface(Uint32 *pixels, SDL_PixelFormatEnum format) {
+    return SDL_CreateSurfaceFrom(pixels, 800, 600, 800 * 4, format);
+}
+/*
+ * Calculates the FNV-1a hash of input pixel data
+ */
+Uint32 FNVHash(Uint32* buf, unsigned int length) {
+    const Uint32 fnv_prime = 0x811C9DC5;
+    Uint32 hash = 0;
+
+    for (int i = 0; i < length; buf++, i++)
+    {
+        hash *= fnv_prime;
+        hash ^= (*buf);
+    }
+
+    return hash;
+}
+/*
+ * Wraps the FNV-1a hash for an input surface's pixels
+ */
+Uint32 hashSurfacePixels(SDL_Surface * surface) {
+    Uint64 buffer_size = surface->w * surface->h;
+    return FNVHash(surface->pixels, buffer_size);
+}
+/* ================= Test Case Implementation ================== */
+/**
+ * Tests rendering a rainbow gradient background onto a blank surface, then rendering a sprite with complex geometry and
+ * transparency on top of said surface, and comparing the result to known accurate renders with a hash.
+ */
+int blit_testExampleApplicationRender(void *arg) {
+    const int width = 32;
+    const int height = 32;
+    const Uint32 scalar_hash = 0xf47a3f55;
+    const Uint32 x86_simd_hash = 0xe345d7a7;
+    SDL_Surface* dest_surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_ARGB8888);
+    SDL_Surface* rainbow_background = SDLTest_ImageBlendingBackground();
+    SDL_Surface* gearbrain_sprite = SDLTest_ImageBlendingSprite();
+    // Blit background into "screen"
+    SDL_BlitSurface(rainbow_background, NULL, dest_surface, NULL);
+    // Blit example game sprite onto "screen"
+    SDL_BlitSurface(gearbrain_sprite, NULL, dest_surface, NULL);
+    // Check result
+    Uint32 hash = hashSurfacePixels(dest_surface);
+    SDLTest_AssertCheck(hash == scalar_hash || hash == x86_simd_hash,
+                        "Should render identically, expected 0x%x (scalar) or 0x%x (x86_simd), got 0x%x",
+                        scalar_hash, x86_simd_hash, hash);
+    // Clean up
+    SDL_DestroySurface(rainbow_background);
+    SDL_DestroySurface(gearbrain_sprite);
+    SDL_DestroySurface(dest_surface);
+    return TEST_COMPLETED;
+}
+/**
+ * Tests rendering PRNG noise onto a surface of PRNG noise, while also testing color shift operations between the
+ * different source and destination pixel formats, without an alpha shuffle, at SVGA resolution. Compares to known
+ * accurate renders with a hash.
+ */
+int blit_testRandomToRandomSVGA(void *arg) {
+    const int width = 800;
+    const int height = 600;
+    const Uint32 scalar_hash = 0x1f56efad;
+    const Uint32 x86_simd_hash = 0x42140c5f;
+    // Allocate random buffers
+    Uint32 *dest_pixels = getNextRandomBuffer(width, height);
+    Uint32 *src_pixels = getNextRandomBuffer(width, height);
+    // Create surfaces of different pixel formats
+    SDL_Surface* dest_surface = getRandomSVGASurface(dest_pixels, SDL_PIXELFORMAT_BGRA8888);
+    SDL_Surface* src_surface = getRandomSVGASurface(src_pixels, SDL_PIXELFORMAT_RGBA8888);
+    // Blit surfaces
+    SDL_BlitSurface(src_surface, NULL, dest_surface, NULL);
+    // Check result
+    Uint32 hash = hashSurfacePixels(dest_surface);
+    SDLTest_AssertCheck(hash == scalar_hash || hash == x86_simd_hash,
+                        "Should render identically, expected 0x%x (scalar) or 0x%x (x86_simd), got 0x%x",
+                        scalar_hash, x86_simd_hash, hash);
+    // Clean up
+    SDL_DestroySurface(dest_surface);
+    SDL_DestroySurface(src_surface);
+    SDL_free(dest_pixels);
+    SDL_free(src_pixels);
+    return TEST_COMPLETED;
+}
+/**
+ * Tests rendering small chunks of 15 by 15px PRNG noise onto an initially blank SVGA surface, while also testing color
+ * shift operations between the different source and destination pixel formats, including an alpha shuffle. Compares to
+ * known accurate renders with a hash.
+ */
+int blit_testRandomToRandomSVGAMultipleIterations(void *arg) {
+    const int width = 800;
+    const int height = 600;
+    const Uint32 x86_simd_hash = 0x2626be78;
+    const Uint32 scalar_hash = 0xfb2a8ee8;
+    // Create blank source surface
+    SDL_Surface* dest_surface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_ABGR8888);
+
+    // Perform 250k random blits into random areas of the blank surface
+    for (int i = 0; i < 250000; i++) {
+        Uint32 *buf = getNextRandomBuffer(15, 15);
+        SDL_Surface *sourceSurface = getRandomBlitChunk(buf, SDL_PIXELFORMAT_RGBA8888);
+
+        SDL_Rect dest_rect;
+        int location = (int)getRandomUint32();
+        dest_rect.x = location % (width - 15 - 1);
+        dest_rect.y = location % (height - 15 - 1);
+
+        SDL_BlitSurface(sourceSurface, NULL, dest_surface, &dest_rect);
+
+        SDL_DestroySurface(sourceSurface);
+        SDL_free(buf);
+    }
+    // Check result
+    Uint32 hash = hashSurfacePixels(dest_surface);
+    // Clean up
+    SDL_SaveBMP(dest_surface, "250k_scalar.bmp");
+    SDL_DestroySurface(dest_surface);
+    SDLTest_AssertCheck(hash == scalar_hash || hash == x86_simd_hash,
+                        "Should render identically, expected 0x%x (scalar) or 0x%x (x86_simd), got 0x%x",
+                        scalar_hash, x86_simd_hash, hash);
+    return TEST_COMPLETED;
+}
+
+static const SDLTest_TestCaseReference blitTest1 = {
+        (SDLTest_TestCaseFp)blit_testExampleApplicationRender, "blit_testExampleApplicationRender",
+        "Test example application render.", TEST_ENABLED
+};
+static const SDLTest_TestCaseReference blitTest2 = {
+        (SDLTest_TestCaseFp)blit_testRandomToRandomSVGA, "blit_testRandomToRandomSVGA",
+        "Test SVGA noise render.", TEST_ENABLED
+};
+static const SDLTest_TestCaseReference blitTest3 = {
+        (SDLTest_TestCaseFp)blit_testRandomToRandomSVGAMultipleIterations, "blit_testRandomToRandomSVGAMultipleIterations",
+        "Test SVGA noise render (250k iterations).", TEST_ENABLED
+};
+static const SDLTest_TestCaseReference *blitTests[] = {
+        &blitTest1, &blitTest2, &blitTest3, NULL
+};
+
+SDLTest_TestSuiteReference blitTestSuite = {
+        "Blending",
+        blitSetUp,
+        blitTests,
+        NULL
+};
\ No newline at end of file
diff --git a/test/testautomation_images.c b/test/testautomation_images.c
index f3c7b1e63cb2d..9c19ce021449b 100644
--- a/test/testautomation_images.c
+++ b/test/testautomation_images.c
@@ -5927,3 +5927,351 @@ SDL_Surface *SDLTest_ImagePrimitivesBlend(void)
         SDLTest_imagePrimitivesBlend.width * SDLTest_imagePrimitivesBlend.bytes_per_pixel, SDL_PIXELFORMAT_RGB24);
     return surface;
 }
+
+/* Rainbow gradient background */
+
+static const SDLTest_SurfaceImage_t SDLTest_imageRainbowBackground = {
+        32,
+        32,
+        4,
+        "\000\016\377\377\000\031\377\377\000\045\377\377\000\061\377\377\000\075\377\377\000\111\377\377\000\125\377"
+        "\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250"
+        "\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000"
+        "\374\377\377\000\377\356\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\216\377\000\377\167\377"
+        "\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\000\031\377\377\000\045\377"
+        "\377\000\061\377\377\000\075\377\377\000\111\377\377\000\125\377\377\000\141\377\377\000\155\377\377\000\170"
+        "\377\377\000\204\377\377\000\220\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000"
+        "\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\373\377\377\000\377\357\377\000\377\326\377"
+        "\000\377\276\377\000\377\247\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\110\377\000\377\060"
+        "\377\000\377\030\377\003\377\003\377\027\377\000\377\000\045\377\377\000\061\377\377\000\075\377\377\000\111"
+        "\377\377\000\125\377\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000"
+        "\235\377\377\000\251\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377"
+        "\000\360\377\377\000\374\377\377\000\377\357\377\000\377\325\377\000\377\276\377\000\377\246\377\000\377\216"
+        "\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\002\377\002\377\030\377"
+        "\000\377\060\377\000\377\000\061\377\377\000\075\377\377\000\111\377\377\000\125\377\377\000\141\377\377\000"
+        "\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377"
+        "\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357"
+        "\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377"
+        "\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\061\377\000\377\110\377\000\377\000"
+        "\075\377\377\000\111\377\377\000\125\377\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377"
+        "\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377"
+        "\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377"
+        "\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003"
+        "\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\000\111\377\377\000\125\377\377"
+        "\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377"
+        "\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374"
+        "\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000"
+        "\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377"
+        "\107\377\000\377\140\377\000\377\167\377\000\377\000\125\377\377\000\141\377\377\000\155\377\377\000\171\377"
+        "\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314"
+        "\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000"
+        "\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377"
+        "\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\137\377\000\377\170\377\000"
+        "\377\217\377\000\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234"
+        "\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000"
+        "\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377"
+        "\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000"
+        "\377\060\377\000\377\110\377\000\377\140\377\000\377\167\377\000\377\220\377\000\377\247\377\000\377\000\155"
+        "\377\377\000\170\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000"
+        "\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377"
+        "\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107"
+        "\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377"
+        "\000\377\170\377\000\377\217\377\000\377\250\377\000\377\277\377\000\377\000\171\377\377\000\204\377\377\000"
+        "\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377"
+        "\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246"
+        "\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377"
+        "\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247"
+        "\377\000\377\300\377\000\377\327\377\000\377\000\205\377\377\000\220\377\377\000\235\377\377\000\250\377\377"
+        "\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377"
+        "\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377"
+        "\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110"
+        "\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377"
+        "\357\377\000\377\000\221\377\377\000\234\377\377\000\251\377\377\000\264\377\377\000\300\377\377\000\314\377"
+        "\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377"
+        "\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000"
+        "\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377"
+        "\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\000\234\377"
+        "\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360"
+        "\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000"
+        "\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377"
+        "\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000"
+        "\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\000\250\377\377\000\264\377\377\000\300"
+        "\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000"
+        "\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377"
+        "\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000"
+        "\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367"
+        "\000\377\377\337\000\377\377\307\000\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000"
+        "\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377"
+        "\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003"
+        "\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377"
+        "\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\340\000\377\377\307\000\377\377"
+        "\260\000\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377"
+        "\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137"
+        "\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377"
+        "\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360"
+        "\377\000\377\377\367\000\377\377\337\000\377\377\310\000\377\377\257\000\377\377\230\000\377\000\314\377\377"
+        "\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276"
+        "\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377"
+        "\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217"
+        "\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377"
+        "\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\000\330\377\377\000\344\377\377\000\360\377"
+        "\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377"
+        "\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060"
+        "\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377"
+        "\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000"
+        "\377\377\200\000\377\377\151\000\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377"
+        "\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000"
+        "\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377"
+        "\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000"
+        "\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\201\000\377\377\150\000\377\377\121"
+        "\000\377\000\360\377\377\000\373\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000"
+        "\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377"
+        "\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000"
+        "\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260"
+        "\000\377\377\230\000\377\377\200\000\377\377\151\000\377\377\120\000\377\377\071\000\377\000\374\377\377\000"
+        "\377\357\377\000\377\325\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377"
+        "\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000"
+        "\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377"
+        "\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377"
+        "\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\000\377\356\377\000\377\326\377\000\377\276\377"
+        "\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027"
+        "\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377"
+        "\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377"
+        "\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377"
+        "\377\041\000\377\377\012\000\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167"
+        "\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377"
+        "\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327"
+        "\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377"
+        "\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015"
+        "\377\000\377\276\377\000\377\247\377\000\377\216\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377"
+        "\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170"
+        "\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377"
+        "\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000"
+        "\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\016\377\377\000\046\377\000\377\246\377\000\377"
+        "\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027"
+        "\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377"
+        "\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000"
+        "\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011"
+        "\000\377\377\000\015\377\377\000\047\377\377\000\076\377\000\377\216\377\000\377\167\377\000\377\137\377\000"
+        "\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377"
+        "\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000"
+        "\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150"
+        "\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015\377\377\000\046\377\377"
+        "\000\076\377\377\000\126\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377"
+        "\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000"
+        "\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307"
+        "\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377"
+        "\041\000\377\377\011\000\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\126\377\377\000\155\377"
+        "\000\377\137\377\000\377\110\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000"
+        "\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377"
+        "\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377"
+        "\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015\377"
+        "\377\000\046\377\377\000\076\377\377\000\125\377\377\000\156\377\377\000\205\377\000\377\107\377\000\377\060"
+        "\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377"
+        "\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377"
+        "\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377"
+        "\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\126"
+        "\377\377\000\155\377\377\000\206\377\377\000\235\377\000\377\060\377\000\377\030\377\002\377\002\377\027\377"
+        "\000\377\060\377\000\377\107\377\000\377\137\377\000\377\167\377\000\377\217\377\000\377\247\377\000\377\277"
+        "\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\340\000\377\377\310\000\377\377\260\000\377"
+        "\377\230\000\377\377\201\000\377\377\151\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000"
+        "\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\125\377\377\000\155\377\377\000\205\377\377\000"
+        "\235\377\377\000\264\377\000\377\027\377\003\377\003\377\030\377\000\377\061\377\000\377\110\377\000\377\140"
+        "\377\000\377\170\377\000\377\220\377\000\377\250\377\000\377\300\377\000\377\327\377\000\377\360\377\000\377"
+        "\377\367\000\377\377\337\000\377\377\307\000\377\377\257\000\377\377\230\000\377\377\200\000\377\377\150\000"
+        "\377\377\120\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\016\377\377\000\047\377\377\000"
+        "\076\377\377\000\126\377\377\000\156\377\377\000\206\377\377\000\235\377\377\000\266\377\377\000\315\377\003"
+        "\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\167\377\000\377\217\377\000\377"
+        "\247\377\000\377\277\377\000\377\327\377\000\377\357\377\000\377\377\367\000\377\377\337\000\377\377\307\000"
+        "\377\377\260\000\377\377\230\000\377\377\200\000\377\377\151\000\377\377\121\000\377\377\071\000\377\377\041"
+        "\000\377\377\012\000\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\126\377\377\000\155\377\377"
+        "\000\205\377\377\000\235\377\377\000\264\377\377\000\315\377\377\000\344\377"
+};
+
+/**
+ * \brief Returns the blending rendering background test image as an SDL_Surface.
+ */
+SDL_Surface *SDLTest_ImageBlendingBackground(void)
+{
+    SDL_Surface *surface = SDL_CreateSurfaceFrom(
+            (void *)SDLTest_imageRainbowBackground.pixel_data,
+            SDLTest_imageRainbowBackground.width,
+            SDLTest_imageRainbowBackground.height,
+            SDLTest_imageRainbowBackground.width * SDLTest_imageRainbowBackground.bytes_per_pixel,
+            SDL_PIXELFORMAT_ARGB8888);
+    return surface;
+}
+
+/* Complex sprite with gradient transparency */
+
+static const SDLTest_SurfaceImage_t SDLTest_imageTransparentSprite = {
+        32,
+        32,
+        4,
+        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+        "\000\101\205\101\000\143\152\143\000\143\151\143\003\145\151\145\034\146\150\146\111\146\150\146\132\145\150"
+        "\146\014\146\150\146\000\146\150\146\000\147\147\147\000\145\150\145\042\146\147\146\137\146\150\146\111\145"
+        "\151\145\056\144\152\144\017\151\145\151\000\067\215\076\000\000\000\000\000\000\000\000\000\000\000\000\000"
+        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\125\166\126\000\177\120"
+        "\176\000\147\147\147\117\147\147\147\230\147\147\147\242\147\147\147\233\147\147\147\111\377\000\377\000\143"
+        "\152\143\000\143\152\143\005\146\147\146\120\147\147\147\155\147\147\147\144\147\147\147\135\144\151\144\057"
+        "\176\126\174\000\110\200\113\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\126\164\127\000\205\115\204\000\146\147\146\154\147"
+        "\147\147\260\147\147\147\243\147\147\147\234\147\147\147\211\146\150\146\047\335\017\335\000\146\150\146\052"
+        "\147\147\147\160\147\147\147\154\147\147\147\144\147\147\147\135\146\150\146\064\203\123\201\000\132\161\134"
+        "\000\135\156\136\000\146\151\145\000\150\146\150\000\135\155\135\000\144\151\144\000\000\000\000\000\000\000"
+        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\152\144\000\126\165\131\000\147\147\147\000\146"
+        "\147\146\000\143\152\143\000\204\120\203\000\156\142\156\000\146\147\146\135\147\147\147\256\147\147\147\243"
+        "\147\147\147\233\147\147\147\224\147\147\147\171\146\150\146\134\147\147\147\155\147\147\147\164\147\147\147"
+        "\154\147\147\147\144\147\147\147\135\146\150\146\065\161\140\161\000\143\152\143\000\120\165\123\001\143\153"
+        "\143\014\143\152\143\013\152\146\153\000\145\147\145\000\146\146\146\000\000\000\000\000\000\000\000\000\000"
+        "\000\000\000\133\161\133\000\101\207\104\000\150\146\150\000\146\150\146\045\146\150\146\046\141\154\141\003"
+        "\147\147\147\000\150\146\150\000\146\150\146\126\147\147\147\256\147\147\147\243\147\147\147\233\147\147\147"
+        "\223\147\147\147\214\147\147\147\206\147\147\147\174\147\147\147\163\147\147\147\154\147\147\147\144\147\147"
+        "\147\135\146\150\146\101\142\153\142\014\143\152\143\013\145\150\145\043\147\150\147\060\147\147\147\050\147"
+        "\147\147\013\147\152\147\000\143\150\143\000\133\161\134\000\000\000\000\000\000\000\000\000\150\146\150\000"
+        "\147\147\147\000\147\147\147\046\147\147\147\264\147\147\147\301\147\147\147\202\146\150\146\072\146\150\146"
+        "\071\147\147\147\222\147\147\147\255\147\147\147\243\147\147\147\234\147\147\147\225\147\147\147\216\147\147"
+        "\147\206\147\147\147\176\147\147\147\165\147\147\147\155\147\147\147\144\147\147\147\134\147\147\147\123\146"
+        "\150\146\103\146\147\146\074\147\147\147\074\147\147\147\064\147\147\147\054\147\147\147\040\146\150\146\011"
+        "\152\145\152\000\132\162\133\000\000\000\000\000\000\000\000\000\147\147\147\000\146\150\146\024\147\147\147"
+        "\243\147\147\147\336\147\147\147\325\147\147\147\316\147\147\147\275\147\147\147\264\147\147\147\265\147\147"
+        "\147\254\147\147\147\24

(Patch may be truncated, please check the link at the top of this post.)