diff --git a/src/Avalonia.Base/Media/Imaging/PixelFormatReaders.cs b/src/Avalonia.Base/Media/Imaging/PixelFormatReaders.cs index fc7c174ed6..c90c4cb5ac 100644 --- a/src/Avalonia.Base/Media/Imaging/PixelFormatReaders.cs +++ b/src/Avalonia.Base/Media/Imaging/PixelFormatReaders.cs @@ -228,6 +228,44 @@ static unsafe class PixelFormatReader public void Reset(IntPtr address) => _address = (Rgba64*)address; } + + public unsafe struct Rgb24PixelFormatReader : IPixelFormatReader + { + private byte* _address; + public Rgba8888Pixel ReadNext() + { + var addr = _address; + _address += 3; + return new Rgba8888Pixel + { + R = addr[0], + G = addr[1], + B = addr[2], + A = 255, + }; + } + + public void Reset(IntPtr address) => _address = (byte*)address; + } + + public unsafe struct Bgr24PixelFormatReader : IPixelFormatReader + { + private byte* _address; + public Rgba8888Pixel ReadNext() + { + var addr = _address; + _address += 3; + return new Rgba8888Pixel + { + R = addr[2], + G = addr[1], + B = addr[0], + A = 255, + }; + } + + public void Reset(IntPtr address) => _address = (byte*)address; + } public static void Transcode(IntPtr dst, IntPtr src, PixelSize size, int strideSrc, int strideDst, PixelFormat format) @@ -242,6 +280,10 @@ static unsafe class PixelFormatReader Transcode(dst, src, size, strideSrc, strideDst); else if (format == PixelFormats.Gray16) Transcode(dst, src, size, strideSrc, strideDst); + else if (format == PixelFormats.Rgb24) + Transcode(dst, src, size, strideSrc, strideDst); + else if (format == PixelFormats.Bgr24) + Transcode(dst, src, size, strideSrc, strideDst); else if (format == PixelFormats.Gray32Float) Transcode(dst, src, size, strideSrc, strideDst); else if (format == PixelFormats.Rgba64) @@ -258,7 +300,9 @@ static unsafe class PixelFormatReader || format == PixelFormats.Gray8 || format == PixelFormats.Gray16 || format == PixelFormats.Gray32Float - || format == PixelFormats.Rgba64; + || format == PixelFormats.Rgba64 + || format == PixelFormats.Bgr24 + || format == PixelFormats.Rgb24; } public static void Transcode(IntPtr dst, IntPtr src, PixelSize size, int strideSrc, int strideDst) where TReader : struct, IPixelFormatReader diff --git a/src/Avalonia.Base/Platform/PixelFormat.cs b/src/Avalonia.Base/Platform/PixelFormat.cs index 99fe17055d..95f49bdb25 100644 --- a/src/Avalonia.Base/Platform/PixelFormat.cs +++ b/src/Avalonia.Base/Platform/PixelFormat.cs @@ -13,7 +13,9 @@ namespace Avalonia.Platform Gray8, Gray16, Gray32Float, - Rgba64 + Rgba64, + Rgb24, + Bgr24 } public record struct PixelFormat @@ -35,6 +37,8 @@ namespace Avalonia.Platform else if (FormatEnum == PixelFormatEnum.Rgb565 || FormatEnum == PixelFormatEnum.Gray16) return 16; + else if (FormatEnum is PixelFormatEnum.Bgr24 or PixelFormatEnum.Rgb24) + return 24; else if (FormatEnum == PixelFormatEnum.Rgba64) return 64; @@ -70,5 +74,7 @@ namespace Avalonia.Platform public static PixelFormat Gray8 { get; } = new PixelFormat(PixelFormatEnum.Gray8); public static PixelFormat Gray16 { get; } = new PixelFormat(PixelFormatEnum.Gray16); public static PixelFormat Gray32Float { get; } = new PixelFormat(PixelFormatEnum.Gray32Float); + public static PixelFormat Rgb24 { get; } = new PixelFormat(PixelFormatEnum.Rgb24); + public static PixelFormat Bgr24 { get; } = new PixelFormat(PixelFormatEnum.Bgr24); } } diff --git a/tests/Avalonia.RenderTests/Media/BitmapTests.cs b/tests/Avalonia.RenderTests/Media/BitmapTests.cs index 4ba0c82b87..6916d0c130 100644 --- a/tests/Avalonia.RenderTests/Media/BitmapTests.cs +++ b/tests/Avalonia.RenderTests/Media/BitmapTests.cs @@ -143,6 +143,8 @@ namespace Avalonia.Direct2D1.RenderTests.Media InlineData(PixelFormatEnum.Gray4), InlineData(PixelFormatEnum.Gray8), InlineData(PixelFormatEnum.Gray16), + InlineData(PixelFormatEnum.Rgb24), + InlineData(PixelFormatEnum.Bgr24), InlineData(PixelFormatEnum.Gray32Float), InlineData(PixelFormatEnum.Rgba64), InlineData(PixelFormatEnum.Rgba64, AlphaFormat.Premul),