From a792434a37100133066afb938d42e585da90d987 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 19 Feb 2025 21:57:46 -0800
Subject: [PATCH] Added initial MJPG support using stb_image
---
VisualC-GDK/SDL/SDL.vcxproj | 2 +
VisualC-GDK/SDL/SDL.vcxproj.filters | 2 +
VisualC/SDL/SDL.vcxproj | 2 +
VisualC/SDL/SDL.vcxproj.filters | 6 +
Xcode/SDL/SDL.xcodeproj/project.pbxproj | 44 +-
build-scripts/check_stdlib_usage.py | 1 +
src/SDL_internal.h | 5 +
src/render/SDL_render.c | 13 +-
src/video/SDL_stb.c | 92 +
src/video/SDL_stb_c.h | 31 +
src/video/SDL_surface.c | 5 +
src/video/stb_image.h | 8030 +++++++++++++++++++++++
12 files changed, 8217 insertions(+), 16 deletions(-)
create mode 100644 src/video/SDL_stb.c
create mode 100644 src/video/SDL_stb_c.h
create mode 100644 src/video/stb_image.h
diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index ce0c92a28210a..09563a63d3303 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -595,6 +595,7 @@
<ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
<ClInclude Include="..\..\src\video\SDL_rect_c.h" />
<ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
+ <ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
@@ -870,6 +871,7 @@
<ClCompile Include="..\..\src\video\SDL_pixels.c" />
<ClCompile Include="..\..\src\video\SDL_rect.c" />
<ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
+ <ClCompile Include="..\..\src\video\SDL_stb.c" />
<ClCompile Include="..\..\src\video\SDL_stretch.c" />
<ClCompile Include="..\..\src\video\SDL_surface.c" />
<ClCompile Include="..\..\src\video\SDL_video.c" />
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index 1753f24768b49..dd2c4639cfc94 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -176,6 +176,7 @@
<ClCompile Include="..\..\src\video\SDL_pixels.c" />
<ClCompile Include="..\..\src\video\SDL_rect.c" />
<ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
+ <ClCompile Include="..\..\src\video\SDL_stb.c" />
<ClCompile Include="..\..\src\video\SDL_stretch.c" />
<ClCompile Include="..\..\src\video\SDL_surface.c" />
<ClCompile Include="..\..\src\video\SDL_video.c" />
@@ -436,6 +437,7 @@
<ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
<ClInclude Include="..\..\src\video\SDL_rect_c.h" />
<ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
+ <ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index 02fa7d6097ec4..07a16f707970d 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -493,6 +493,7 @@
<ClInclude Include="..\..\src\video\SDL_pixels_c.h" />
<ClInclude Include="..\..\src\video\SDL_rect_c.h" />
<ClInclude Include="..\..\src\video\SDL_RLEaccel_c.h" />
+ <ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
@@ -705,6 +706,7 @@
<ClCompile Include="..\..\src\video\SDL_pixels.c" />
<ClCompile Include="..\..\src\video\SDL_rect.c" />
<ClCompile Include="..\..\src\video\SDL_RLEaccel.c" />
+ <ClCompile Include="..\..\src\video\SDL_stb.c" />
<ClCompile Include="..\..\src\video\SDL_stretch.c" />
<ClCompile Include="..\..\src\video\SDL_surface.c" />
<ClCompile Include="..\..\src\video\SDL_video.c" />
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index e021390875b02..c0a23b4318d5d 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -672,6 +672,9 @@
<ClInclude Include="..\..\src\video\SDL_egl_c.h">
<Filter>video</Filter>
</ClInclude>
+ <ClInclude Include="..\..\src\video\SDL_stb_c.h">
+ <Filter>video</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\video\SDL_yuv_c.h">
<Filter>video</Filter>
</ClInclude>
@@ -1292,6 +1295,9 @@
<ClCompile Include="..\..\src\video\SDL_rect.c">
<Filter>video</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\video\SDL_stb.c">
+ <Filter>video</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\video\SDL_stretch.c">
<Filter>video</Filter>
</ClCompile>
diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
index bd390d6b3683a..8e4f9fa033929 100644
--- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj
+++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
@@ -516,6 +516,10 @@
F3DDCC5B2AFD42B600B0842B /* SDL_video_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC522AFD42B600B0842B /* SDL_video_c.h */; };
F3DDCC5D2AFD42B600B0842B /* SDL_rect_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */; };
F3E5A6EB2AD5E0E600293D83 /* SDL_properties.c in Sources */ = {isa = PBXBuildFile; fileRef = F3E5A6EA2AD5E0E600293D83 /* SDL_properties.c */; };
+ F3EFA5ED2D5AB97300BCF22F /* SDL_stb_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3EFA5EA2D5AB97300BCF22F /* SDL_stb_c.h */; };
+ F3EFA5EE2D5AB97300BCF22F /* stb_image.h in Headers */ = {isa = PBXBuildFile; fileRef = F3EFA5EC2D5AB97300BCF22F /* stb_image.h */; };
+ F3EFA5EF2D5AB97300BCF22F /* SDL_surface_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F3EFA5EB2D5AB97300BCF22F /* SDL_surface_c.h */; };
+ F3EFA5F02D5AB97300BCF22F /* SDL_stb.c in Sources */ = {isa = PBXBuildFile; fileRef = F3EFA5E92D5AB97300BCF22F /* SDL_stb.c */; };
F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; };
F3F15D7F2D011912007AE210 /* SDL_dialog.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F15D7D2D011912007AE210 /* SDL_dialog.c */; };
F3F15D802D011912007AE210 /* SDL_dialog_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = F3F15D7E2D011912007AE210 /* SDL_dialog_utils.h */; };
@@ -1079,6 +1083,10 @@
F3DDCC522AFD42B600B0842B /* SDL_video_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_video_c.h; sourceTree = "<group>"; };
F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_rect_impl.h; sourceTree = "<group>"; };
F3E5A6EA2AD5E0E600293D83 /* SDL_properties.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_properties.c; sourceTree = "<group>"; };
+ F3EFA5E92D5AB97300BCF22F /* SDL_stb.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_stb.c; sourceTree = "<group>"; };
+ F3EFA5EA2D5AB97300BCF22F /* SDL_stb_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_stb_c.h; sourceTree = "<group>"; };
+ F3EFA5EB2D5AB97300BCF22F /* SDL_surface_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_surface_c.h; sourceTree = "<group>"; };
+ F3EFA5EC2D5AB97300BCF22F /* stb_image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stb_image.h; sourceTree = "<group>"; };
F3F07D59269640160074468B /* SDL_hidapi_luna.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_luna.c; sourceTree = "<group>"; };
F3F15D7C2D011912007AE210 /* SDL_dialog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_dialog.h; sourceTree = "<group>"; };
F3F15D7D2D011912007AE210 /* SDL_dialog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SDL_dialog.c; sourceTree = "<group>"; };
@@ -1586,43 +1594,47 @@
A7D8A60523E2513D00DCD162 /* dummy */,
A7D8A72123E2513E00DCD162 /* khronos */,
A7D8A5EC23E2513D00DCD162 /* offscreen */,
- A7D8A61823E2513D00DCD162 /* uikit */,
- A7D8A76C23E2513E00DCD162 /* yuv2rgb */,
+ A7D8A76B23E2513E00DCD162 /* SDL_blit.h */,
+ A7D8A64C23E2513D00DCD162 /* SDL_blit.c */,
A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */,
A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */,
A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */,
- A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */,
A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */,
- A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */,
+ A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */,
A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */,
+ A7D8A61623E2513D00DCD162 /* SDL_blit_copy.c */,
A7D8A64223E2513D00DCD162 /* SDL_blit_N.c */,
- A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */,
A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */,
- A7D8A64C23E2513D00DCD162 /* SDL_blit.c */,
- A7D8A76B23E2513E00DCD162 /* SDL_blit.h */,
+ A7D8A60223E2513D00DCD162 /* SDL_blit_slow.c */,
A7D8A77323E2513E00DCD162 /* SDL_bmp.c */,
- F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */,
A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */,
- A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */,
+ F3DDCC4D2AFD42B500B0842B /* SDL_clipboard_c.h */,
A7D8A6B623E2513E00DCD162 /* SDL_egl.c */,
+ A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */,
A7D8A76823E2513E00DCD162 /* SDL_fillrect.c */,
- A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */,
A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */,
+ A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */,
+ A7D8A63423E2513D00DCD162 /* SDL_rect.c */,
A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */,
F3DDCC542AFD42B600B0842B /* SDL_rect_impl.h */,
- A7D8A63423E2513D00DCD162 /* SDL_rect.c */,
- A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */,
A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */,
+ A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */,
+ F3EFA5E92D5AB97300BCF22F /* SDL_stb.c */,
+ F3EFA5EA2D5AB97300BCF22F /* SDL_stb_c.h */,
A7D8A60323E2513D00DCD162 /* SDL_stretch.c */,
A7D8A61423E2513D00DCD162 /* SDL_surface.c */,
+ F3EFA5EB2D5AB97300BCF22F /* SDL_surface_c.h */,
A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */,
+ A7D8A60E23E2513D00DCD162 /* SDL_video.c */,
F3DDCC522AFD42B600B0842B /* SDL_video_c.h */,
E4F7981F2AD8D87F00669F54 /* SDL_video_unsupported.c */,
- A7D8A60E23E2513D00DCD162 /* SDL_video.c */,
A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */,
A7D8A64023E2513D00DCD162 /* SDL_vulkan_utils.c */,
- A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */,
A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */,
+ A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */,
+ F3EFA5EC2D5AB97300BCF22F /* stb_image.h */,
+ A7D8A61823E2513D00DCD162 /* uikit */,
+ A7D8A76C23E2513E00DCD162 /* yuv2rgb */,
);
path = video;
sourceTree = "<group>";
@@ -2458,6 +2470,9 @@
A7D8BB6F23E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */,
A7D8AECA23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */,
A7D8AF1223E2514100DCD162 /* SDL_cocoaevents.h in Headers */,
+ F3EFA5ED2D5AB97300BCF22F /* SDL_stb_c.h in Headers */,
+ F3EFA5EE2D5AB97300BCF22F /* stb_image.h in Headers */,
+ F3EFA5EF2D5AB97300BCF22F /* SDL_surface_c.h in Headers */,
A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */,
A7D8AF0623E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */,
A7D8AEB223E2514100DCD162 /* SDL_cocoametalview.h in Headers */,
@@ -2950,6 +2965,7 @@
566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */,
A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */,
A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */,
+ F3EFA5F02D5AB97300BCF22F /* SDL_stb.c in Sources */,
A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */,
A7D8B3DA23E2514300DCD162 /* SDL_bmp.c in Sources */,
A7D8B96E23E2514400DCD162 /* SDL_stdlib.c in Sources */,
diff --git a/build-scripts/check_stdlib_usage.py b/build-scripts/check_stdlib_usage.py
index fa1087ed457f9..34def8d4a3477 100755
--- a/build-scripts/check_stdlib_usage.py
+++ b/build-scripts/check_stdlib_usage.py
@@ -161,6 +161,7 @@ def find_symbols_in_file(file: pathlib.Path) -> int:
"src/libm",
"src/hidapi",
"src/video/khronos",
+ "src/video/stb_image.h",
"include/SDL3",
"build-scripts/gen_audio_resampler_filter.c",
"build-scripts/gen_audio_channel_conversion.c",
diff --git a/src/SDL_internal.h b/src/SDL_internal.h
index ac018f9b28abb..bcd99a6745d83 100644
--- a/src/SDL_internal.h
+++ b/src/SDL_internal.h
@@ -191,6 +191,11 @@
#define SDL_VIDEO_RENDER_SW 1
#endif
+/* STB image conversion */
+#if !defined(SDL_HAVE_STB) && !defined(SDL_LEAN_AND_MEAN)
+#define SDL_HAVE_STB 1
+#endif
+
/* YUV formats
- handling of YUV surfaces
- blitting and conversion functions */
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 2f5679746b92d..9d7562b620f9c 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -1281,7 +1281,14 @@ static SDL_PixelFormat GetClosestSupportedFormat(SDL_Renderer *renderer, SDL_Pix
{
int i;
- if (SDL_ISPIXELFORMAT_FOURCC(format)) {
+ if (format == SDL_PIXELFORMAT_MJPG) {
+ // We'll decode to SDL_PIXELFORMAT_RGBA32
+ for (i = 0; i < renderer->num_texture_formats; ++i) {
+ if (renderer->texture_formats[i] == SDL_PIXELFORMAT_RGBA32) {
+ return renderer->texture_formats[i];
+ }
+ }
+ } else if (SDL_ISPIXELFORMAT_FOURCC(format)) {
// Look for an exact match
for (i = 0; i < renderer->num_texture_formats; ++i) {
if (renderer->texture_formats[i] == format) {
@@ -1443,7 +1450,9 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
texture->next = texture->native;
renderer->textures = texture;
- if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
+ if (texture->format == SDL_PIXELFORMAT_MJPG) {
+ // We have a custom decode + upload path for this
+ } else if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
#ifdef SDL_HAVE_YUV
texture->yuv = SDL_SW_CreateYUVTexture(texture->format, texture->colorspace, w, h);
#else
diff --git a/src/video/SDL_stb.c b/src/video/SDL_stb.c
new file mode 100644
index 0000000000000..f1ddff28ea426
--- /dev/null
+++ b/src/video/SDL_stb.c
@@ -0,0 +1,92 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_internal.h"
+
+#include "SDL_stb_c.h"
+
+
+// We currently only support JPEG, but we could add other image formats if we wanted
+#ifdef SDL_HAVE_STB
+#define malloc SDL_malloc
+#define realloc SDL_realloc
+#define free SDL_free
+#undef memcpy
+#define memcpy SDL_memcpy
+#undef memset
+#define memset SDL_memset
+#undef strcmp
+#define strcmp SDL_strcmp
+#undef strncmp
+#define strncmp SDL_strncmp
+#define strtol SDL_strtol
+
+#define abs SDL_abs
+#define pow SDL_pow
+#define ldexp SDL_scalbn
+
+#define STB_INTERNAL_SDL
+#define STB_IMAGE_STATIC
+#define STBI_FAILURE_USERMSG
+#if defined(SDL_NEON_INTRINSICS)
+#define STBI_NEON
+#endif
+#define STBI_ONLY_JPEG
+#define STBI_NO_GIF
+#define STBI_NO_PNG
+#define STBI_NO_HDR
+#define STBI_NO_LINEAR
+#define STBI_NO_ZLIB
+#define STBI_NO_STDIO
+#define STBI_ASSERT SDL_assert
+#define STB_IMAGE_IMPLEMENTATION
+#include "stb_image.h"
+#endif
+
+bool SDL_ConvertPixels_STB(int width, int height,
+ SDL_PixelFormat src_format, SDL_Colorspace src_colorspace, SDL_PropertiesID src_properties, const void *src, int src_pitch,
+ SDL_PixelFormat dst_format, SDL_Colorspace dst_colorspace, SDL_PropertiesID dst_properties, void *dst, int dst_pitch)
+{
+#ifdef SDL_HAVE_STB
+ if (src_colorspace != dst_colorspace) {
+ return SDL_SetError("SDL_ConvertPixels_STB: colorspace conversion not supported");
+ }
+
+ if (src_format == dst_format) {
+ if (src == dst) {
+ // Nothing to do
+ return true;
+ }
+ }
+
+ int w = 0, h = 0, format = 0;
+ stbi_uc *pixels = stbi_load_from_memory((const stbi_uc *)src, src_pitch, &w, &h, &format, 4);
+ if (!pixels) {
+ return SDL_SetError("Couldn't decode image: %s", stbi_failure_reason());
+ }
+
+ bool result = SDL_ConvertPixelsAndColorspace(w, h, SDL_PIXELFORMAT_RGBA32, src_colorspace, src_properties, pixels, width * 4, dst_format, dst_colorspace, dst_properties, dst, dst_pitch);
+ stbi_image_free(pixels);
+
+ return result;
+#else
+ return SDL_SetError("SDL not built with STB image support");
+#endif
+}
diff --git a/src/video/SDL_stb_c.h b/src/video/SDL_stb_c.h
new file mode 100644
index 0000000000000..bf8cc4da53fc5
--- /dev/null
+++ b/src/video/SDL_stb_c.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_stb_c_h_
+#define SDL_stb_c_h_
+
+#include "SDL_internal.h"
+
+// Image conversion functions
+
+extern bool SDL_ConvertPixels_STB(int width, int height, SDL_PixelFormat src_format, SDL_Colorspace src_colorspace, SDL_PropertiesID src_properties, const void *src, int src_pitch, SDL_PixelFormat dst_format, SDL_Colorspace dst_colorspace, SDL_PropertiesID dst_properties, void *dst, int dst_pitch);
+
+#endif // SDL_stb_c_h_
diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index d8f831c20862c..dfb2d0d077eaa 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -24,6 +24,7 @@
#include "SDL_video_c.h"
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
+#include "SDL_stb_c.h"
#include "SDL_yuv_c.h"
#include "../render/SDL_sysrender.h"
@@ -2277,6 +2278,10 @@ bool SDL_ConvertPixelsAndColorspace(int width, int height,
dst_colorspace = SDL_GetDefaultColorspaceForFormat(dst_format);
}
+ if (src_format == SDL_PIXELFORMAT_MJPG) {
+ return SDL_ConvertPixels_STB(width, height, src_format, src_colorspace, src_properties, src, src_pitch, dst_format, dst_colorspace, dst_properties, dst, dst_pitch);
+ }
+
#ifdef SDL_HAVE_YUV
if (SDL_ISPIXELFORMAT_FOURCC(src_format) && SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
return SDL_ConvertPixels_YUV_to_YUV(width, height, src_format, src_colorspace, src_properties, src, src_pitch, dst_format, dst_colorspace, dst_properties, dst, dst_pitch);
diff --git a/src/video/stb_image.h b/src/video/stb_image.h
new file mode 100644
index 0000000000000..afeef37f1baec
--- /dev/null
+++ b/src/video/stb_image.h
@@ -0,0 +1,8030 @@
+/* stb_image - v2.30 - public domain image loader - http://nothings.org/stb
+ no warranty implied; use at your own risk
+
+ Do this:
+ #define STB_IMAGE_IMPLEMENTATION
+ before you include this file in *one* C or C++ file to create the implementation.
+
+ // i.e. it should look like this:
+ #include ...
+ #include ...
+ #include ...
+ #define STB_IMAGE_IMPLEMENTATION
+ #include "stb_image.h"
+
+ You can #define STBI_ASSERT(x) before the #include to avoid using assert.h.
+ And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free
+
+
+ QUICK NOTES:
+ Primarily of interest to game developers and other people who can
+ avoid problematic images and only need the trivial interface
+
+ JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
+ PNG 1/2/4/8/16-bit-per-channel
+
+ TGA (not sure what subset, if a subset)
+ BMP non-1bpp, non-RLE
+ PSD (composited view only, no extra channels, 8/16 bit-per-channel)
+
+ GIF (*comp always reports as 4-channel)
+ HDR (radiance rgbE format)
+ PIC (Softimage PIC)
+ PNM (PPM and PGM binary only)
+
+ Animated GIF still needs a proper API, but here's one way to do it:
+ http://gist.github.com/urraka/685d9a6340b26b830d49
+
+ - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
+ - decode from arbitrary I/O callbacks
+ - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
+
+ Full documentation under "DOCUMENTATION" below.
+
+
+LICENSE
+
+ See end of file for license information.
+
+RECENT REVISION HISTORY:
+
+ 2.30 (2024-05-31) avoid erroneous gcc warning
+ 2.29 (2023-05-xx) optimizations
+ 2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
+ 2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
+ 2.26 (2020-07-13) many minor fixes
+ 2.25 (2020-02-02) fix warnings
+ 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
+ 2.23 (2019-08-11) fix clang static analysis warning
+ 2.22 (2019-03-04) gif fixes, fix warnings
+ 2.21 (2019-02-25) fix typo in comment
+ 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
+ 2.19 (2018-02-11) fix warning
+ 2.18 (2018-01-30) fix warnings
+ 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
+ 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
+ 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
+ 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
+ 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
+ 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
+ 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
+ RGB-format JPEG; remove white matting in PSD;
+ allocate large structures on the stack;
+ correct channel count for PNG & BMP
+ 2.10 (2016-01-22) avoid warning introduced in 2.09
+ 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
+
+ See end of file for full revision history.
+
+
+ ============================ Contributors =========================
+
+ Image formats Extensions, features
+ Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info)
+ Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info)
+ Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG)
+ Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks)
+ Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG)
+ Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip)
+ Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
+ github:urraka (animated gif) Junggon Kim (PNM comments)
+ Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA)
+ socks-the-fox (16-bit PNG)
+ Jeremy Sawicki (handle all ImageNet JPGs)
+ Optimizations & bugfixes Mikhail Morozov (1-bit BMP)
+ Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
+ Arseny Kapoulkine Simon Breuss (16-bit PNM)
+ John-Mark Allen
+ Carmelo J Fdez-Aguera
+
+ Bug & warning fixes
+ Marc LeBlanc David Woo Guillaume George Martins Mozeiko
+ Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski
+ Phil Jordan Dave Moore Roy Eltham
+ Hayaki Saito Nathan Reed Won Chun
+ Luke Graham Johan Duparc Nick Verigakis the Horde3D community
+ Thomas Ruf Ronny Chevalier github:rlyeh
+ Janez Zemva John Bartholomew Michal Cichon github:romigrou
+ Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
+ Eugene Golushkov Laurent Gomila Cort Stratton github:snagar
+ Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex
+ Cass Everitt Ryamond Barbiero github:grim210
+ Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
+ Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
+ Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
+ Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
+ Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
+ Brad Weinberger Matvey Cherevko github:mosra
+ Luca Sas Alexander Veselov Zack Middleton [reserved]
+ Ryan C. Gordon [reserved] [reserved]
+ DO NOT ADD YOUR NAME HERE
+
+ Jacko Dirks
+
+ To add your name to the credits, pick a random blank space in the middle and fill it.
+ 80% of merge conflicts on stb PRs are due to people adding their name at the end
+ of the credits.
+*/
+
+#ifndef STBI_INCLUDE_STB_IMAGE_H
+#define STBI_INCLUDE_STB_IMAGE_H
+
+// DOCUMENTATION
+//
+// Limitations:
+// - no 12-bit-per-channel JPEG
+// - no JPEGs with arithmetic coding
+// - GIF always returns *comp=4
+//
+// Basic usage (see HDR discussion below for HDR usage):
+// int x,y,n;
+// unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
+// // ... process data if not NULL ...
+// // ... x = width, y = height, n = # 8-bit components per pixel ...
+// // ... replace '0' with '1'..'4' to force that many components per pixel
+// // ... but 'n' will always be the number that it would have been if you said 0
+// stbi_image_free(data);
+//
+// Standard parameters:
+// int *x -- outputs image width in pixels
+// int *y -- outputs image height in pixels
+// int *channels_in_file -- outputs # of image components in image file
+// int desired_channels -- if non-zero, # of image components requested in result
+//
+// The return value from an image loader is an 'unsigned char *' which points
+// to the pixel data, or NULL on an allocation failure or if the image is
+// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels,
+// with each pixel consisting of N interleaved 8-bit components; the first
+// pixel pointed to is top-left-most in the image. There is no padding between
+// image scanlines or between pixels, regardless of format. The number of
+// components N is 'desired_channels' if desired_channels is non-zero, or
+// *channels_in_file otherwise. If desired_channels is non-zero,
+// *channels_in_file has the number of components that _would_ have been
+// output otherwise. E.g. if you set desired_channels to 4, you will always
+// get RGBA output, but you can check *channels_in_file to see if it's trivially
+// opaque because e.g. there were only 3 channels in the source image.
+//
+// An output image with N components has the following components interleaved
+// in this order in each pixel:
+//
+// N=#comp components
+// 1 grey
+// 2 grey, alpha
+// 3 red, green, blue
+// 4 red, green, blue, alpha
+//
+// If image loading fails for any reason, the return value will be NULL,
+// and *x, *y, *channels_in_file will be unchanged. The function
+// stbi_failure_reason() can be queried for an extremely brief, end-user
+// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS
+// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
+// more user-friendly ones.
+//
+// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
+//
+// To query the width, height and component count of an image without having to
+// decode the full file, you can use the stbi_info family of functions:
+//
+// int x,y,n,ok;
+// ok = stbi_info(filename, &x, &y, &n);
+// // returns ok=1 and sets x, y, n if image is a supported format,
+// // 0 otherwise.
+//
+// Note that stb_image pervasively uses ints in its public API for sizes,
+// including sizes of memory buffers. This is now part of the API and thus
+// hard to change without causing breakage. As a result, the various image
+// loaders all have certain limits on image size; these differ somewhat
+// by format but generally boil down to either just under 2GB or just under
+// 1GB. When the decoded image would be larger than this, stb_image decoding
+// will fail.
+//
+// Additionally, stb_image will reject image files that have any of their
+// dimensions set to a larger value than the configurable STBI_MAX_DIMENSIONS,
+// which defaults to 2**24 = 16777216 pixels. Due to the above memory limit,
+// the only way to have an image with such dimensions load correctly
+// is for it to have a rather extreme aspect ratio. Either way, the
+// assumption here is that such larger images are likely to be malformed
+// or malicious. If you do need to load an image with individual dimensions
+// larger than that, and it still fits in the overall size limit, you can
+// #define STBI_MAX_DIMENSIONS on your own to be something larger.
+//
+// ===========================================================================
+//
+// UNICODE:
+//
+// If compiling for Windows and you wish to use Unicode filena
(Patch may be truncated, please check the link at the top of this post.)