sdl2-compat: Updated for SDL3 colorspace changes

From f815fa476c7e19fd3e6a6716610ff9f92f96613c Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 3 Feb 2024 07:58:17 -0800
Subject: [PATCH] Updated for SDL3 colorspace changes

---
 src/sdl2_compat.c          | 55 ++++++++++++++++++++++++++++++++++++++
 src/sdl2_compat.h          |  8 ++++++
 src/sdl3_include_wrapper.h | 20 ++++----------
 src/sdl3_syms.h            |  5 +---
 4 files changed, 69 insertions(+), 19 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 4f01f5c..8b7d68e 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -2581,6 +2581,61 @@ SDL_ConvertSurfaceFormat(SDL_Surface * src, Uint32 pixel_format, Uint32 flags)
     return SDL3_ConvertSurfaceFormat(src, pixel_format);
 }
 
+#define SDL_YUV_SD_THRESHOLD 576
+
+static SDL_YUV_CONVERSION_MODE SDL_YUV_ConversionMode = SDL_YUV_CONVERSION_BT601;
+
+DECLSPEC void SDLCALL
+SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode)
+{
+    SDL_YUV_ConversionMode = mode;
+}
+
+DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL
+SDL_GetYUVConversionMode(void)
+{
+    return SDL_YUV_ConversionMode;
+}
+
+DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL
+SDL_GetYUVConversionModeForResolution(int width, int height)
+{
+    SDL_YUV_CONVERSION_MODE mode = SDL_GetYUVConversionMode();
+    if (mode == SDL_YUV_CONVERSION_AUTOMATIC) {
+        if (height <= SDL_YUV_SD_THRESHOLD) {
+            mode = SDL_YUV_CONVERSION_BT601;
+        } else {
+            mode = SDL_YUV_CONVERSION_BT709;
+        }
+    }
+    return mode;
+}
+
+static SDL_Colorspace GetColorspaceForFormatAndSize(Uint32 format, int width, int height)
+{
+    if (SDL_ISPIXELFORMAT_FOURCC(format)) {
+        switch (SDL_GetYUVConversionModeForResolution(width, height)) {
+        case SDL_YUV_CONVERSION_JPEG:
+            return SDL_COLORSPACE_BT601_FULL;
+        case SDL_YUV_CONVERSION_BT601:
+            return SDL_COLORSPACE_BT601_LIMITED;
+        case SDL_YUV_CONVERSION_BT709:
+            return SDL_COLORSPACE_BT709_LIMITED;
+        default:
+            break;
+        }
+    }
+    return SDL_COLORSPACE_SRGB;
+}
+
+DECLSPEC int SDLCALL
+SDL_ConvertPixels(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
+{
+    SDL_Colorspace src_colorspace = GetColorspaceForFormatAndSize(src_format, width, height);
+    SDL_Colorspace dst_colorspace = GetColorspaceForFormatAndSize(dst_format, width, height);
+    return SDL3_ConvertPixelsAndColorspace(width, height, src_format, src_colorspace, src, src_pitch, dst_format, dst_colorspace, dst, dst_pitch);
+}
+
 DECLSPEC SDL_Surface * SDLCALL
 SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
 {
diff --git a/src/sdl2_compat.h b/src/sdl2_compat.h
index 239fbc2..e462d8b 100644
--- a/src/sdl2_compat.h
+++ b/src/sdl2_compat.h
@@ -328,4 +328,12 @@ typedef struct SDL2_Vertex {
     SDL_FPoint tex_coord;
 } SDL2_Vertex;
 
+typedef enum
+{
+    SDL_YUV_CONVERSION_JPEG,        /**< Full range JPEG */
+    SDL_YUV_CONVERSION_BT601,       /**< BT.601 (the default) */
+    SDL_YUV_CONVERSION_BT709,       /**< BT.709 */
+    SDL_YUV_CONVERSION_AUTOMATIC    /**< BT.601 for SD content, BT.709 for HD content */
+} SDL_YUV_CONVERSION_MODE;
+
 #endif /* sdl2_compat_h */
diff --git a/src/sdl3_include_wrapper.h b/src/sdl3_include_wrapper.h
index b144c75..947bd95 100644
--- a/src/sdl3_include_wrapper.h
+++ b/src/sdl3_include_wrapper.h
@@ -379,8 +379,6 @@
 #define SDL_GetWindowSizeInPixels IGNORE_THIS_VERSION_OF_SDL_GetWindowSizeInPixels
 #define SDL_GetWindowSurface IGNORE_THIS_VERSION_OF_SDL_GetWindowSurface
 #define SDL_GetWindowTitle IGNORE_THIS_VERSION_OF_SDL_GetWindowTitle
-#define SDL_GetYUVConversionMode IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionMode
-#define SDL_GetYUVConversionModeForResolution IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionModeForResolution
 #define SDL_CloseHaptic IGNORE_THIS_VERSION_OF_SDL_CloseHaptic
 #define SDL_DestroyHapticEffect IGNORE_THIS_VERSION_OF_SDL_DestroyHapticEffect
 #define SDL_HapticEffectSupported IGNORE_THIS_VERSION_OF_SDL_HapticEffectSupported
@@ -625,7 +623,6 @@
 #define SDL_SetWindowSize IGNORE_THIS_VERSION_OF_SDL_SetWindowSize
 #define SDL_SetWindowTitle IGNORE_THIS_VERSION_OF_SDL_SetWindowTitle
 #define SDL_SetWindowsMessageHook IGNORE_THIS_VERSION_OF_SDL_SetWindowsMessageHook
-#define SDL_SetYUVConversionMode IGNORE_THIS_VERSION_OF_SDL_SetYUVConversionMode
 #define SDL_ShowCursor IGNORE_THIS_VERSION_OF_SDL_ShowCursor
 #define SDL_ShowMessageBox IGNORE_THIS_VERSION_OF_SDL_ShowMessageBox
 #define SDL_ShowSimpleMessageBox IGNORE_THIS_VERSION_OF_SDL_ShowSimpleMessageBox
@@ -1000,6 +997,7 @@
 #define SDL_SetSurfaceColorspace IGNORE_THIS_VERSION_OF_SDL_SetSurfaceColorspace
 #define SDL_GetSurfaceColorspace IGNORE_THIS_VERSION_OF_SDL_GetSurfaceColorspace
 #define SDL_ConvertSurfaceFormatAndColorspace IGNORE_THIS_VERSION_OF_SDL_ConvertSurfaceFormatAndColorspace
+#define SDL_CopyProperties IGNORE_THIS_VERSION_OF_SDL_CopyProperties
 
 
 #define SDL_FUNCTION_POINTER_IS_VOID_POINTER 1
@@ -2408,14 +2406,6 @@
 #undef SDL_GetWindowTitle
 #endif
 
-#ifdef SDL_GetYUVConversionMode
-#undef SDL_GetYUVConversionMode
-#endif
-
-#ifdef SDL_GetYUVConversionModeForResolution
-#undef SDL_GetYUVConversionModeForResolution
-#endif
-
 #ifdef SDL_CloseHaptic
 #undef SDL_CloseHaptic
 #endif
@@ -3392,10 +3382,6 @@
 #undef SDL_SetWindowsMessageHook
 #endif
 
-#ifdef SDL_SetYUVConversionMode
-#undef SDL_SetYUVConversionMode
-#endif
-
 #ifdef SDL_ShowCursor
 #undef SDL_ShowCursor
 #endif
@@ -4892,6 +4878,10 @@
 #undef SDL_ConvertSurfaceFormatAndColorspace
 #endif
 
+#ifdef SDL_CopyProperties
+#undef SDL_CopyProperties
+#endif
+
 #undef SDL_ThreadID /* see at top. */
 
 /* undefine these macros, too: redefine as SDL3_xxx, if needed. */
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index f88ec3d..fc0fa87 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -437,7 +437,7 @@ SDL3_SYM(int,GetSurfaceClipRect,(SDL_Surface *a, SDL_Rect *b),(a,b),return)
 SDL3_SYM(int,ConvertEventToRenderCoordinates,(SDL_Renderer *a, SDL_Event *b),(a,b),return)
 SDL3_SYM(SDL_Surface*,ConvertSurface,(SDL_Surface *a, const SDL_PixelFormat *b),(a,b),return)
 SDL3_SYM(SDL_Surface*,ConvertSurfaceFormat,(SDL_Surface *a, Uint32 b),(a,b),return)
-SDL3_SYM_PASSTHROUGH(int,ConvertPixels,(int a, int b, Uint32 c, const void *d, int e, Uint32 f, void *g, int h),(a,b,c,d,e,f,g,h),return)
+SDL3_SYM(int,ConvertPixelsAndColorspace,(int a, int b, Uint32 c, SDL_Colorspace d, const void *e, int f, Uint32 g, SDL_Colorspace h, void *i, int j),(a,b,c,d,e,f,g,h,i,j),return)
 SDL3_SYM_RENAMED(int,FillRect,FillSurfaceRect,(SDL_Surface *a, const SDL_Rect *b, Uint32 c),(a,b,c),return)
 SDL3_SYM_RENAMED(int,FillRects,FillSurfaceRects,(SDL_Surface *a, const SDL_Rect *b, int c, Uint32 d),(a,b,c,d),return)
 SDL3_SYM_RENAMED(int,UpperBlit,BlitSurface,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return)
@@ -584,9 +584,6 @@ SDL3_SYM_PASSTHROUGH(float,powf,(float a, float b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(float,scalbnf,(float a, int b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(double,fmod,(double a, double b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(float,fmodf,(float a, float b),(a,b),return)
-SDL3_SYM_PASSTHROUGH(void,SetYUVConversionMode,(SDL_YUV_CONVERSION_MODE a),(a),)
-SDL3_SYM_PASSTHROUGH(SDL_YUV_CONVERSION_MODE,GetYUVConversionMode,(void),(),return)
-SDL3_SYM_PASSTHROUGH(SDL_YUV_CONVERSION_MODE,GetYUVConversionModeForResolution,(int a, int b),(a,b),return)
 SDL3_SYM_RENAMED(void*,RenderGetMetalLayer,GetRenderMetalLayer,(SDL_Renderer *a),(a),return)
 SDL3_SYM_RENAMED(void*,RenderGetMetalCommandEncoder,GetRenderMetalCommandEncoder,(SDL_Renderer *a),(a),return)
 SDL3_SYM_PASSTHROUGH(double,log10,(double a),(a),return)