SDL_image: cmake: support building SDL3_image with both STB and libpng

From fcf9f3b3a4baaea969c8ee1c59a981980ff7d0ba Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Thu, 1 Jan 2026 22:45:57 +0100
Subject: [PATCH] cmake: support building SDL3_image with both STB and libpng

---
 CMakeLists.txt                  | 119 ++++++++++++++++----------------
 build-scripts/release-info.json |  11 ++-
 2 files changed, 67 insertions(+), 63 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 330117bb..873fb7dc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -128,6 +128,7 @@ option(SDLIMAGE_WEBP "Support loading WEBP images" ON)
 option(SDLIMAGE_XCF "Support loading XCF images" ON)
 option(SDLIMAGE_XPM "Support loading XPM images" ON)
 option(SDLIMAGE_XV "Support loading XV images" ON)
+cmake_dependent_option(SDLIMAGE_PNG_LIBPNG "Support loading PNGs using libpng (useful for APNGs)" ON SDLIMAGE_PNG OFF)
 
 cmake_dependent_option(SDLIMAGE_ANI_SAVE "Add ANI save support" ON SDLIMAGE_ANI OFF)
 cmake_dependent_option(SDLIMAGE_AVIF_SAVE "Add AVIF save support" ON SDLIMAGE_AVIF OFF)
@@ -182,13 +183,13 @@ endif()
 cmake_dependent_option(SDLIMAGE_JXL_SHARED "Dynamically load JXL support (requires shared libjxl)"
     ${SDLIMAGE_DEPS_SHARED} SDLIMAGE_JXL OFF)
 
-if(SDLIMAGE_VENDORED AND SDLIMAGE_PNG AND NOT (SDLIMAGE_BACKEND_WIC OR SDLIMAGE_BACKEND_STB OR SDLIMAGE_BACKEND_IMAGEIO))
+if(SDLIMAGE_VENDORED AND SDLIMAGE_PNG)
     set(SDLIMAGE_PNG_VENDORED ON)
 else()
     set(SDLIMAGE_PNG_VENDORED OFF)
 endif()
 cmake_dependent_option(SDLIMAGE_PNG_SHARED "Dynamically load PNG support (requires shared libpng)"
-    ${SDLIMAGE_DEPS_SHARED} "SDLIMAGE_PNG;NOT SDLIMAGE_BACKEND_WIC;NOT SDLIMAGE_BACKEND_STB;NOT SDLIMAGE_BACKEND_IMAGEIO" OFF)
+    ${SDLIMAGE_DEPS_SHARED} "SDLIMAGE_PNG" OFF)
 
 if(SDLIMAGE_VENDORED AND SDLIMAGE_TIF AND NOT (SDLIMAGE_BACKEND_IMAGEIO OR SDLIMAGE_BACKEND_WIC))
     set(SDLIMAGE_TIF_VENDORED ON)
@@ -206,7 +207,7 @@ endif()
 cmake_dependent_option(SDLIMAGE_WEBP_SHARED "Dynamically load WEBP support (requires shared libwebp)"
     ${SDLIMAGE_DEPS_SHARED} SDLIMAGE_WEBP OFF)
 
-if(SDLIMAGE_PNG_VENDORED)
+if(SDLIMAGE_PNG_LIBPNG AND SDLIMAGE_PNG_VENDORED)
     set(SDLIMAGE_ZLIB ON)
 else()
     set(SDLIMAGE_ZLIB OFF)
@@ -459,7 +460,7 @@ if(SDLIMAGE_ZLIB)
         # ZLIB_INCLUDE_DIRS variable is used by vendored libpng
         set(ZLIB_INCLUDE_DIRS "${ZLIB_INCLUDE_DIR}")
         target_include_directories(${ZLIB_LIBRARY} INTERFACE $<BUILD_INTERFACE:${ZLIB_INCLUDE_DIRS}>)
-        if(SDLIMAGE_ZLIB_SHARED OR SDLIMAGE_PNG AND NOT SDLIMAGE_PNG_SHARED)
+        if(SDLIMAGE_ZLIB_SHARED OR (SDLIMAGE_PNG AND NOT SDLIMAGE_PNG_SHARED))
             list(APPEND INSTALL_EXTRA_TARGETS ${ZLIB_LIBRARY})
         endif()
         set_target_properties(${ZLIB_LIBRARY} PROPERTIES EXPORT_NAME external_zlib)
@@ -817,72 +818,68 @@ endif()
 
 list(APPEND SDLIMAGE_BACKENDS PNG)
 set(SDLIMAGE_PNG_ENABLED FALSE)
-if(SDLIMAGE_PNG)
-    if(SDLIMAGE_BACKEND_STB OR SDLIMAGE_BACKEND_WIC OR SDLIMAGE_BACKEND_IMAGEIO)
+if(SDLIMAGE_PNG_LIBPNG)
+    if(SDLIMAGE_PNG_VENDORED)
         set(SDLIMAGE_PNG_ENABLED TRUE)
-    else()
-        if(SDLIMAGE_PNG_VENDORED)
-            set(SDLIMAGE_PNG_ENABLED TRUE)
-            message(STATUS "${PROJECT_NAME}: Using vendored libpng")
-            set(PNG_TESTS OFF CACHE BOOL "Build PNG Tests" FORCE)
-            set(SKIP_INSTALL_EXPORT TRUE)
-            sdl_check_project_in_subfolder(external/libpng libpng SDLIMAGE_VENDORED)
-            add_subdirectory(external/libpng external/libpng-build EXCLUDE_FROM_ALL)
-            register_license(zlib external/libpng/LICENSE)
-            if(SDLIMAGE_PNG_SHARED)
-                set(PNG_LIBRARY png_shared)
+        message(STATUS "${PROJECT_NAME}: Using vendored libpng")
+        set(PNG_TESTS OFF CACHE BOOL "Build PNG Tests" FORCE)
+        set(SKIP_INSTALL_EXPORT TRUE)
+        sdl_check_project_in_subfolder(external/libpng libpng SDLIMAGE_VENDORED)
+        add_subdirectory(external/libpng external/libpng-build EXCLUDE_FROM_ALL)
+        register_license(libpng external/libpng/LICENSE)
+        if(SDLIMAGE_PNG_SHARED)
+            set(PNG_LIBRARY png_shared)
+        else()
+            set(PNG_LIBRARY png_static)
+        endif()
+        add_library(PNG::PNG ALIAS ${PNG_LIBRARY})
+        set_property(TARGET ${PNG_LIBRARY} PROPERTY DEBUG_POSTFIX "")
+        target_include_directories(${sdl3_image_target_name} PRIVATE external/libpng)
+        if(SDLIMAGE_PNG_SHARED OR NOT SDLIMAGE_BUILD_SHARED_LIBS)
+            list(APPEND INSTALL_EXTRA_TARGETS ${PNG_LIBRARY})
+        endif()
+        set_target_properties(${PNG_LIBRARY} PROPERTIES EXPORT_NAME external_libpng)
+        add_library(SDL3_image::external_libpng ALIAS ${PNG_LIBRARY})
+        if(NOT SDLIMAGE_PNG_SHARED)
+            list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:${PNG_LIBRARY}>)
+            if(SDLIMAGE_ZLIB_VENDORED)
+                list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:${ZLIB_LIBRARY}>)
             else()
-                set(PNG_LIBRARY png_static)
-            endif()
-            add_library(PNG::PNG ALIAS ${PNG_LIBRARY})
-            set_property(TARGET ${PNG_LIBRARY} PROPERTY DEBUG_POSTFIX "")
-            target_include_directories(${sdl3_image_target_name} PRIVATE external/libpng)
-            if(SDLIMAGE_PNG_SHARED OR NOT SDLIMAGE_BUILD_SHARED_LIBS)
-                list(APPEND INSTALL_EXTRA_TARGETS ${PNG_LIBRARY})
+                list(APPEND PC_REQUIRES zlib)
             endif()
-            set_target_properties(${PNG_LIBRARY} PROPERTIES EXPORT_NAME external_libpng)
-            add_library(SDL3_image::external_libpng ALIAS ${PNG_LIBRARY})
+        endif()
+    elseif(SDLIMAGE_PNG_SHARED AND DEFINED SDLIMAGE_DYNAMIC_PNG AND EXISTS "${SDLIMAGE_DYNAMIC_PNG}")
+        message(STATUS "${PROJECT_NAME}: Using libpng from CMake variable")
+        set(SDLIMAGE_PNG_ENABLED TRUE)
+    else()
+        find_package(PNG ${required})
+        if(PNG_FOUND)
+            message(STATUS "${PROJECT_NAME}: Using system libpng")
+            set(SDLIMAGE_PNG_ENABLED TRUE)
             if(NOT SDLIMAGE_PNG_SHARED)
-                list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:${PNG_LIBRARY}>)
-                if(SDLIMAGE_ZLIB_VENDORED)
-                    list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:${ZLIB_LIBRARY}>)
-                else()
-                    list(APPEND PC_REQUIRES zlib)
-                endif()
+                list(APPEND PC_REQUIRES libpng)
             endif()
-        elseif(SDLIMAGE_PNG_SHARED AND DEFINED SDLIMAGE_DYNAMIC_PNG AND EXISTS "${SDLIMAGE_DYNAMIC_PNG}")
-            message(STATUS "${PROJECT_NAME}: Using libpng from CMake variable")
-            set(SDLIMAGE_PNG_ENABLED TRUE)
         else()
-            find_package(PNG ${required})
-            if(PNG_FOUND)
-                message(STATUS "${PROJECT_NAME}: Using system libpng")
-                set(SDLIMAGE_PNG_ENABLED TRUE)
-                if(NOT SDLIMAGE_PNG_SHARED)
-                    list(APPEND PC_REQUIRES libpng)
-                endif()
-            else()
-                message(${FATAL_ERROR} "libpng NOT found")
-            endif()
+            message(${FATAL_ERROR} "libpng NOT found")
         endif()
-        if(SDLIMAGE_PNG_ENABLED)
-            if(SDLIMAGE_PNG_SHARED)
-                if(NOT DEFINED SDLIMAGE_DYNAMIC_PNG)
-                    target_include_directories(${sdl3_image_target_name} PRIVATE
-                        $<TARGET_PROPERTY:PNG::PNG,INCLUDE_DIRECTORIES>
-                        $<TARGET_PROPERTY:PNG::PNG,INTERFACE_INCLUDE_DIRECTORIES>
-                        $<TARGET_PROPERTY:PNG::PNG,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-                    )
-                    if(SDLIMAGE_PNG_VENDORED)
-                      add_dependencies(${sdl3_image_target_name} PNG::PNG)
-                    endif()
+    endif()
+    if(SDLIMAGE_PNG_ENABLED)
+        if(SDLIMAGE_PNG_SHARED)
+            if(NOT DEFINED SDLIMAGE_DYNAMIC_PNG)
+                target_include_directories(${sdl3_image_target_name} PRIVATE
+                    $<TARGET_PROPERTY:PNG::PNG,INCLUDE_DIRECTORIES>
+                    $<TARGET_PROPERTY:PNG::PNG,INTERFACE_INCLUDE_DIRECTORIES>
+                    $<TARGET_PROPERTY:PNG::PNG,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+                )
+                if(SDLIMAGE_PNG_VENDORED)
+                  add_dependencies(${sdl3_image_target_name} PNG::PNG)
                 endif()
-                target_get_dynamic_library(SDLIMAGE_DYNAMIC_PNG PNG::PNG)
-                message(STATUS "Dynamic libpng: ${SDLIMAGE_DYNAMIC_PNG}")
-                target_compile_definitions(${sdl3_image_target_name} PRIVATE "LOAD_LIBPNG_DYNAMIC=\"${SDLIMAGE_DYNAMIC_PNG}\"")
-            else()
-                target_link_libraries(${sdl3_image_target_name} PRIVATE PNG::PNG)
             endif()
+            target_get_dynamic_library(SDLIMAGE_DYNAMIC_PNG PNG::PNG)
+            message(STATUS "Dynamic libpng: ${SDLIMAGE_DYNAMIC_PNG}")
+            target_compile_definitions(${sdl3_image_target_name} PRIVATE "LOAD_LIBPNG_DYNAMIC=\"${SDLIMAGE_DYNAMIC_PNG}\"")
+        else()
+            target_link_libraries(${sdl3_image_target_name} PRIVATE PNG::PNG)
         endif()
     endif()
     if(SDLIMAGE_PNG_ENABLED)
diff --git a/build-scripts/release-info.json b/build-scripts/release-info.json
index be647002..3e28671b 100644
--- a/build-scripts/release-info.json
+++ b/build-scripts/release-info.json
@@ -162,6 +162,8 @@
         "-DSDLIMAGE_XCF=ON",
         "-DSDLIMAGE_XPM=ON",
         "-DSDLIMAGE_XV=ON",
+        "-DSDLIMAGE_STB=OFF",
+        "-DSDLIMAGE_ZLIB_SHARED=OFF",
         "-DSDLIMAGE_RELOCATABLE=ON",
         "-DSDLIMAGE_SAMPLES=OFF",
         "-DSDLIMAGE_TESTS=OFF",
@@ -185,7 +187,9 @@
           "share/licenses/SDL3_image/optional/LICENSE.dav1d.txt",
           "share/licenses/SDL3_image/optional/LICENSE.libpng.txt",
           "share/licenses/SDL3_image/optional/LICENSE.tiff.txt",
-          "share/licenses/SDL3_image/optional/LICENSE.webp.txt"
+          "share/licenses/SDL3_image/optional/LICENSE.webp.txt",
+          "share/licenses/SDL3_image/optional/LICENSE.libpng.txt",
+          "share/licenses/SDL3_image/optional/LICENSE.zlib.txt"
         ]
       },
       "files-devel": {
@@ -208,7 +212,9 @@
           "share/licenses/SDL3_image/optional/LICENSE.dav1d.txt",
           "share/licenses/SDL3_image/optional/LICENSE.libpng.txt",
           "share/licenses/SDL3_image/optional/LICENSE.tiff.txt",
-          "share/licenses/SDL3_image/optional/LICENSE.webp.txt"
+          "share/licenses/SDL3_image/optional/LICENSE.webp.txt",
+          "share/licenses/SDL3_image/optional/LICENSE.libpng.txt",
+          "share/licenses/SDL3_image/optional/LICENSE.zlib.txt"
         ]
       }
     },
@@ -262,6 +268,7 @@
         "-DSDLIMAGE_LBM=ON",
         "-DSDLIMAGE_PCX=ON",
         "-DSDLIMAGE_PNG=ON",
+        "-DSDLIMAGE_PNG_LIBPNG=OFF",
         "-DSDLIMAGE_PNM=ON",
         "-DSDLIMAGE_QOI=ON",
         "-DSDLIMAGE_SVG=ON",