From 839b001ab7bd13c13e6dfeb78da8af60a75bd1f4 Mon Sep 17 00:00:00 2001 From: Tom Spilman Date: Sun, 22 Sep 2024 11:50:54 -0500 Subject: [PATCH] Fixed image loading to zero transparent pixels at the native code level. --- MonoGame.Framework/Graphics/Texture2D.cs | 2 +- .../Platform/Native/Image.Interop.cs | 1 + .../Platform/Native/Texture2D.Native.cs | 2 + native/monogame/common/MGI.cpp | 40 +++++++++---------- native/monogame/include/api_MGI.h | 2 +- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/MonoGame.Framework/Graphics/Texture2D.cs b/MonoGame.Framework/Graphics/Texture2D.cs index 7ccd54344eb..a1db4e05ef5 100644 --- a/MonoGame.Framework/Graphics/Texture2D.cs +++ b/MonoGame.Framework/Graphics/Texture2D.cs @@ -725,7 +725,7 @@ public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream, /// public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream) { - return FromStream(graphicsDevice, stream, DefaultColorProcessors.ZeroTransparentPixels); + return FromStream(graphicsDevice, stream, null); } /// diff --git a/MonoGame.Framework/Platform/Native/Image.Interop.cs b/MonoGame.Framework/Platform/Native/Image.Interop.cs index 2e6659cd140..0f1e2cacd2e 100644 --- a/MonoGame.Framework/Platform/Native/Image.Interop.cs +++ b/MonoGame.Framework/Platform/Native/Image.Interop.cs @@ -17,6 +17,7 @@ internal static unsafe partial class MGI public static partial void ReadRGBA( byte* data, int dataBytes, + [MarshalAs(UnmanagedType.U1)] bool zeroTransparentPixels, out int width, out int height, out byte* rgba); diff --git a/MonoGame.Framework/Platform/Native/Texture2D.Native.cs b/MonoGame.Framework/Platform/Native/Texture2D.Native.cs index 41dca7c7637..8f08d5eac65 100644 --- a/MonoGame.Framework/Platform/Native/Texture2D.Native.cs +++ b/MonoGame.Framework/Platform/Native/Texture2D.Native.cs @@ -141,6 +141,7 @@ private static unsafe Texture2D PlatformFromStream(GraphicsDevice graphicsDevice MGI.ReadRGBA( (byte*)handle.AddrOfPinnedObject(), dataLength, + colorProcessor == null ? true : false, out width, out height, out rgba); @@ -240,6 +241,7 @@ private unsafe void PlatformReload(Stream stream) MGI.ReadRGBA( (byte*)handle.AddrOfPinnedObject(), dataLength, + true, out width, out height, out rgba); diff --git a/native/monogame/common/MGI.cpp b/native/monogame/common/MGI.cpp index 03cb641d6b4..68fd89fa4b4 100644 --- a/native/monogame/common/MGI.cpp +++ b/native/monogame/common/MGI.cpp @@ -22,23 +22,23 @@ #include "stb_image_write.h" -void MGI_ReadRGBA(mgbyte* data, mgint dataBytes, mgint* width, mgint* height, mgbyte** rgba) +void MGI_ReadRGBA(mgbyte* data, mgint dataBytes, mgbool zeroTransparentPixels, mgint& width, mgint& height, mgbyte*& rgba) { - *width = 0; - *height = 0; - *rgba = nullptr; + width = 0; + height = 0; + rgba = nullptr; int c, w, h; auto image = stbi_load_from_memory(data, dataBytes, &w, &h, &c, 4); if (image == nullptr) { - *width = 0; - *height = 0; + width = 0; + height = 0; return; } // If the original image before conversion had alpha... - if (c == 4) + if (zeroTransparentPixels && c == 4) { // XNA blacks out any pixels with an alpha of zero. for (int i = 0; i < w * h; i += 4) @@ -52,9 +52,9 @@ void MGI_ReadRGBA(mgbyte* data, mgint dataBytes, mgint* width, mgint* height, mg } } - *rgba = image; - *width = w; - *height = h; + rgba = image; + width = w; + height = h; } struct mem_image @@ -92,26 +92,26 @@ static void mem_image_write(void* context, void* data, int size) image->offset = offset; } -void MGI_WriteJpg(mgbyte* data, mgint dataBytes, mgint width, mgint height, mgint quality, mgbyte** jpg, mgint* jpgBytes) +void MGI_WriteJpg(mgbyte* data, mgint dataBytes, mgint width, mgint height, mgint quality, mgbyte*& jpg, mgint& jpgBytes) { - *jpg = nullptr; - *jpgBytes = 0; + jpg = nullptr; + jpgBytes = 0; mem_image image; stbi_write_jpg_to_func(mem_image_write, &image, width, height, 4, data, quality); - *jpg = (mgbyte*)realloc(image.data, image.offset); - *jpgBytes = image.dataBytes; + jpg = (mgbyte*)realloc(image.data, image.offset); + jpgBytes = image.dataBytes; } -void MGI_WritePng(mgbyte* data, mgint dataBytes, mgint width, mgint height, mgbyte** png, mgint* pngBytes) +void MGI_WritePng(mgbyte* data, mgint dataBytes, mgint width, mgint height, mgbyte*& png, mgint& pngBytes) { - *png = nullptr; - *pngBytes = 0; + png = nullptr; + pngBytes = 0; mem_image image; stbi_write_png_to_func(mem_image_write, &image, width, height, 4, data, 4); - *png = (mgbyte*)realloc(image.data, image.offset); - *pngBytes = image.dataBytes; + png = (mgbyte*)realloc(image.data, image.offset); + pngBytes = image.dataBytes; } diff --git a/native/monogame/include/api_MGI.h b/native/monogame/include/api_MGI.h index be36a463bf8..e95613b19f0 100644 --- a/native/monogame/include/api_MGI.h +++ b/native/monogame/include/api_MGI.h @@ -13,6 +13,6 @@ -MG_EXPORT void MGI_ReadRGBA(mgbyte* data, mgint dataBytes, mgint& width, mgint& height, mgbyte*& rgba); +MG_EXPORT void MGI_ReadRGBA(mgbyte* data, mgint dataBytes, mgbool zeroTransparentPixels, mgint& width, mgint& height, mgbyte*& rgba); MG_EXPORT void MGI_WriteJpg(mgbyte* data, mgint dataBytes, mgint width, mgint height, mgint quality, mgbyte*& jpg, mgint& jpgBytes); MG_EXPORT void MGI_WritePng(mgbyte* data, mgint dataBytes, mgint width, mgint height, mgbyte*& png, mgint& pngBytes);