diff --git a/src/ImageSharp/PixelFormats/PixelConverter.cs b/src/ImageSharp/PixelFormats/PixelConverter.cs
index 3686092cd2..8fde490fda 100644
--- a/src/ImageSharp/PixelFormats/PixelConverter.cs
+++ b/src/ImageSharp/PixelFormats/PixelConverter.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using System.Buffers.Binary;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.PixelFormats
@@ -16,32 +17,91 @@ namespace SixLabors.ImageSharp.PixelFormats
///
internal static class PixelConverter
{
- public static class Rgba32
+ public static class FromRgba32
{
///
- /// Converts a packed to .
+ /// Converts a packed to .
///
[MethodImpl(InliningOptions.ShortMethod)]
public static uint ToArgb32(uint packedRgba)
{
- // packedRgba = [aa bb gg rr]
- // ROL(8, packedRgba):
+ // packedRgba = [aa bb gg rr]
+ // ROL(8, packedRgba) = [bb gg rr aa]
return (packedRgba << 8) | (packedRgba >> 24);
}
+
+ ///
+ /// Converts a packed to .
+ ///
+ [MethodImpl(InliningOptions.ShortMethod)]
+ public static uint ToBgra32(uint packedRgba)
+ {
+ // packedRgba = [aa bb gg rr]
+ // tmp1 = [aa 00 gg 00]
+ // tmp2 = [00 bb 00 rr]
+ // tmp3=ROL(16, tmp2) = [00 rr 00 bb]
+ // tmp1 + tmp3 = [aa rr gg bb]
+ uint tmp1 = packedRgba & 0xFF00FF00;
+ uint tmp2 = packedRgba & 0x00FF00FF;
+ uint tmp3 = (tmp2 << 16) | (tmp2 >> 16);
+ return tmp1 + tmp3;
+ }
}
- public static class Argb32
+ public static class FromArgb32
{
///
- /// Converts a packed to .
+ /// Converts a packed to .
///
[MethodImpl(InliningOptions.ShortMethod)]
public static uint ToRgba32(uint packedArgb)
{
- // packedArgb = [bb gg rr aa]
- // ROR(8, packedArgb):
+ // packedArgb = [bb gg rr aa]
+ // ROR(8, packedArgb) = [aa bb gg rr]
return (packedArgb >> 8) | (packedArgb << 24);
}
+
+ ///
+ /// Converts a packed to .
+ ///
+ [MethodImpl(InliningOptions.ShortMethod)]
+ public static uint ToBgra32(uint packedArgb)
+ {
+ // packedArgb = [bb gg rr aa]
+ // REVERSE(packedArgb) = [aa rr gg bb]
+ return BinaryPrimitives.ReverseEndianness(packedArgb);
+ }
+ }
+
+ public static class FromBgra32
+ {
+ ///
+ /// Converts a packed to .
+ ///
+ [MethodImpl(InliningOptions.ShortMethod)]
+ public static uint ToArgb32(uint packedBgra)
+ {
+ // packedBgra = [aa rr gg bb]
+ // REVERSE(packedBgra) = [bb gg rr aa]
+ return BinaryPrimitives.ReverseEndianness(packedBgra);
+ }
+
+ ///
+ /// Converts a packed to .
+ ///
+ [MethodImpl(InliningOptions.ShortMethod)]
+ public static uint ToRgba32(uint packedBgra)
+ {
+ // packedRgba = [aa rr gg bb]
+ // tmp1 = [aa 00 gg 00]
+ // tmp2 = [00 rr 00 bb]
+ // tmp3=ROL(16, tmp2) = [00 bb 00 rr]
+ // tmp1 + tmp3 = [aa bb gg rr]
+ uint tmp1 = packedBgra & 0xFF00FF00;
+ uint tmp2 = packedBgra & 0x00FF00FF;
+ uint tmp3 = (tmp2 << 16) | (tmp2 >> 16);
+ return tmp1 + tmp3;
+ }
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
index 02b80de9b4..ad5aee8c7c 100644
--- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
+++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
@@ -178,27 +178,5 @@ namespace SixLabors.ImageSharp.PixelFormats
dp.FromScaledVector4(sp.ToScaledVector4());
}
}
-
- ///
- /// Verifies that the given 'source' and 'destination' spans are at least of 'minLength' size.
- /// Throwing an if the condition is not met.
- ///
- /// The source element type
- /// The destination element type
- /// The source span
- /// The source parameter name
- /// The destination span
- /// The destination parameter name
- /// The minimum length
- protected internal static void GuardSpans(
- ReadOnlySpan source,
- string sourceParamName,
- Span destination,
- string destinationParamName,
- int minLength)
- {
- Guard.MustBeSizedAtLeast(source, minLength, sourceParamName);
- Guard.MustBeSizedAtLeast(destination, minLength, destinationParamName);
- }
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs
index 1be8347c3d..424020e2f2 100644
--- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs
+++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs
@@ -174,7 +174,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion
for (int i = 0; i < this.Count; i++)
{
uint s = Unsafe.Add(ref sBase, i);
- Unsafe.Add(ref dBase, i) = PixelConverter.Rgba32.ToArgb32(s);
+ Unsafe.Add(ref dBase, i) = PixelConverter.FromRgba32.ToArgb32(s);
}
}
@@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion
for (int i = 0; i < this.Count; i++)
{
uint s = Unsafe.Add(ref dBase, i);
- Unsafe.Add(ref dBase, i) = PixelConverter.Rgba32.ToArgb32(s);
+ Unsafe.Add(ref dBase, i) = PixelConverter.FromRgba32.ToArgb32(s);
}
}
diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs
index 83c4e34f2f..9b32f7aeee 100644
--- a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs
+++ b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs
@@ -4,7 +4,7 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.PixelFormats
{
- public class PixelConverterTests
+ public abstract class PixelConverterTests
{
public static readonly TheoryData RgbaData =
new TheoryData
@@ -23,34 +23,103 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
{ 67, 71, 101, 109 }
};
- [Theory]
- [MemberData(nameof(RgbaData))]
- public void Rgba32ToArgb32(byte r, byte g, byte b, byte a)
+ public class FromRgba32 : PixelConverterTests
{
- Rgba32 s = ReferenceImplementations.MakeRgba32(r, g, b, a);
+ [Theory]
+ [MemberData(nameof(RgbaData))]
+ public void ToArgb32(byte r, byte g, byte b, byte a)
+ {
+ Rgba32 s = ReferenceImplementations.MakeRgba32(r, g, b, a);
+
+ // Act:
+ uint actualPacked = PixelConverter.FromRgba32.ToArgb32(s.PackedValue);
+
+ // Assert:
+ uint expectedPacked = ReferenceImplementations.MakeArgb32(r, g, b, a).PackedValue;
+
+ Assert.Equal(expectedPacked, actualPacked);
+ }
+
+ [Theory]
+ [MemberData(nameof(RgbaData))]
+ public void ToBgra32(byte r, byte g, byte b, byte a)
+ {
+ Rgba32 s = ReferenceImplementations.MakeRgba32(r, g, b, a);
+
+ // Act:
+ uint actualPacked = PixelConverter.FromRgba32.ToBgra32(s.PackedValue);
+
+ // Assert:
+ uint expectedPacked = ReferenceImplementations.MakeBgra32(r, g, b, a).PackedValue;
+
+ Assert.Equal(expectedPacked, actualPacked);
+ }
+ }
+
+ public class FromArgb32 : PixelConverterTests
+ {
+ [Theory]
+ [MemberData(nameof(RgbaData))]
+ public void ToRgba32(byte r, byte g, byte b, byte a)
+ {
+ Argb32 s = ReferenceImplementations.MakeArgb32(r, g, b, a);
- // Act:
- uint actualPacked = PixelConverter.Rgba32.ToArgb32(s.PackedValue);
+ // Act:
+ uint actualPacked = PixelConverter.FromArgb32.ToRgba32(s.PackedValue);
- // Assert:
- uint expectedPacked = ReferenceImplementations.ToArgb32(s).PackedValue;
+ // Assert:
+ uint expectedPacked = ReferenceImplementations.MakeRgba32(r, g, b, a).PackedValue;
- Assert.Equal(expectedPacked, actualPacked);
+ Assert.Equal(expectedPacked, actualPacked);
+ }
+
+ [Theory]
+ [MemberData(nameof(RgbaData))]
+ public void ToBgra32(byte r, byte g, byte b, byte a)
+ {
+ Argb32 s = ReferenceImplementations.MakeArgb32(r, g, b, a);
+
+ // Act:
+ uint actualPacked = PixelConverter.FromArgb32.ToBgra32(s.PackedValue);
+
+ // Assert:
+ uint expectedPacked = ReferenceImplementations.MakeBgra32(r, g, b, a).PackedValue;
+
+ Assert.Equal(expectedPacked, actualPacked);
+ }
}
- [Theory]
- [MemberData(nameof(RgbaData))]
- public void Argb32ToRgba32(byte r, byte g, byte b, byte a)
+ public class FromBgra32 : PixelConverterTests
{
- Argb32 s = ReferenceImplementations.MakeArgb32(r, g, b, a);
+ [Theory]
+ [MemberData(nameof(RgbaData))]
+ public void ToArgb32(byte r, byte g, byte b, byte a)
+ {
+ Bgra32 s = ReferenceImplementations.MakeBgra32(r, g, b, a);
- // Act:
- uint actualPacked = PixelConverter.Argb32.ToRgba32(s.PackedValue);
+ // Act:
+ uint actualPacked = PixelConverter.FromBgra32.ToArgb32(s.PackedValue);
- // Assert:
- uint expectedPacked = ReferenceImplementations.ToRgba32(s).PackedValue;
+ // Assert:
+ uint expectedPacked = ReferenceImplementations.MakeArgb32(r, g, b, a).PackedValue;
- Assert.Equal(expectedPacked, actualPacked);
+ Assert.Equal(expectedPacked, actualPacked);
+ }
+
+ [Theory]
+ [MemberData(nameof(RgbaData))]
+ public void ToRgba32(byte r, byte g, byte b, byte a)
+ {
+ Bgra32 s = ReferenceImplementations.MakeBgra32(r, g, b, a);
+
+ // Act:
+ uint actualPacked = PixelConverter.FromBgra32.ToRgba32(s.PackedValue);
+
+ // Assert:
+ uint expectedPacked = ReferenceImplementations.MakeRgba32(r, g, b, a).PackedValue;
+
+ Assert.Equal(expectedPacked, actualPacked);
+ }
}
@@ -85,66 +154,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
d.A = a;
return d;
}
-
- public static Argb32 ToArgb32(Rgba32 s)
- {
- Argb32 d = default;
- d.R = s.R;
- d.G = s.G;
- d.B = s.B;
- d.A = s.A;
- return d;
- }
-
- public static Argb32 ToArgb32(Bgra32 s)
- {
- Argb32 d = default;
- d.R = s.R;
- d.G = s.G;
- d.B = s.B;
- d.A = s.A;
- return d;
- }
-
- public static Rgba32 ToRgba32(Argb32 s)
- {
- Rgba32 d = default;
- d.R = s.R;
- d.G = s.G;
- d.B = s.B;
- d.A = s.A;
- return d;
- }
-
- public static Rgba32 ToRgba32(Bgra32 s)
- {
- Rgba32 d = default;
- d.R = s.R;
- d.G = s.G;
- d.B = s.B;
- d.A = s.A;
- return d;
- }
-
- public static Bgra32 ToBgra32(Rgba32 s)
- {
- Bgra32 d = default;
- d.R = s.R;
- d.G = s.G;
- d.B = s.B;
- d.A = s.A;
- return d;
- }
-
- public static Bgra32 ToBgra32(Argb32 s)
- {
- Bgra32 d = default;
- d.R = s.R;
- d.G = s.G;
- d.B = s.B;
- d.A = s.A;
- return d;
- }
}
}
}
\ No newline at end of file