SDL: Add elf-dlopen-note test

From 281ac6c3bb619f614616a82891c3e39d3f05ceea Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Sat, 11 Oct 2025 02:08:18 +0200
Subject: [PATCH] Add elf-dlopen-note test

---
 test/CMakeLists.txt   |  1 +
 test/testdlopennote.c | 77 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)
 create mode 100644 test/testdlopennote.c

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8e210fdb153cf..53dddabb2cb8c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -356,6 +356,7 @@ add_sdl_test_executable(testaudio MAIN_CALLBACKS NEEDS_RESOURCES TESTUTILS SOURC
 add_sdl_test_executable(testcolorspace SOURCES testcolorspace.c)
 add_sdl_test_executable(testfile NONINTERACTIVE SOURCES testfile.c)
 add_sdl_test_executable(testcontroller TESTUTILS SOURCES testcontroller.c gamepadutils.c ${gamepad_image_headers} DEPENDS generate-gamepad_image_headers)
+add_sdl_test_executable(testdlopennote TESTUTILS SOURCES testdlopennote.c)
 add_sdl_test_executable(testgeometry TESTUTILS SOURCES testgeometry.c)
 add_sdl_test_executable(testgl SOURCES testgl.c)
 add_sdl_test_executable(testgles SOURCES testgles.c)
diff --git a/test/testdlopennote.c b/test/testdlopennote.c
new file mode 100644
index 0000000000000..ec53c225059fe
--- /dev/null
+++ b/test/testdlopennote.c
@@ -0,0 +1,77 @@
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_main.h>
+
+#ifdef SDL_PLATFORM_WINDOWS
+#define PNG_SHARED_LIBRARY "libpng16-16.dll"
+#elif defined(SDL_PLATFORM_APPLE)
+#define PNG_SHARED_LIBRARY "libpng16.16.dylib"
+#else
+#define PNG_SHARED_LIBRARY "libpng16.so.16"
+#endif
+
+SDL_ELF_NOTE_DLOPEN(
+    "png",
+    "Support for loading PNG images using libpng",
+    SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
+    PNG_SHARED_LIBRARY
+);
+
+typedef int png_sig_cmp_fn(const unsigned char *sig, size_t start, size_t num_to_check);
+
+static struct {
+    SDL_SharedObject *library;
+    png_sig_cmp_fn *png_sig_cmp;
+} libpng16;
+
+static bool libpng_init(void)
+{
+    libpng16.library = SDL_LoadObject(PNG_SHARED_LIBRARY);
+    if (!libpng16.library) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load libpng library \"" PNG_SHARED_LIBRARY "\"");
+        return false;
+    }
+    libpng16.png_sig_cmp = (png_sig_cmp_fn *)SDL_LoadFunction(libpng16.library, "png_sig_cmp");
+    return libpng16.png_sig_cmp != NULL;
+}
+
+static void libpng_quit(void)
+{
+    SDL_UnloadObject(libpng16.library);
+    SDL_zero(libpng16);
+}
+
+static bool is_png(const char *path)
+{
+    unsigned char header[8];
+    size_t count;
+    bool result;
+    SDL_IOStream *io = SDL_IOFromFile(path, "rb");
+    if (io == NULL) {
+        return false;
+    }
+    count = SDL_ReadIO(io, header, sizeof(header));
+    result = libpng16.png_sig_cmp(header, 0, count) == 0;
+    SDL_CloseIO(io);
+    return result;
+}
+
+int main(int argc, char *argv[])
+{
+    int i;
+
+    /* Enable standard application logging */
+    SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
+
+    if (argc < 2) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Usage: %s IMAGE [IMAGE [IMAGE ... ]]", argv[0]);
+        return 1;
+    }
+    if (!libpng_init()) {
+        return 1;
+    }
+    for (i = 1; i < argc; i++) {
+        SDL_Log("\"%s\" is a png: %s", argv[i], is_png(argv[i]) ? "YES" : "NO");
+    }
+    libpng_quit();
+    return 0;
+}