From e306c715a6115e0b8ff67819f5d313c59600ab63 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 16 May 2017 02:31:05 +0200 Subject: [PATCH] Bgra32 --- src/ImageSharp/PixelFormats/Bgr24.cs | 2 +- src/ImageSharp/PixelFormats/Bgra32.cs | 146 ++++++++++++++++++ src/ImageSharp/PixelFormats/IPixel.cs | 2 +- src/ImageSharp/PixelFormats/Rgb24.cs | 2 +- src/ImageSharp/PixelFormats/Rgba32.cs | 14 +- .../PixelFormats/Bgr24Tests.cs | 4 +- .../PixelFormats/Bgra32Tests.cs | 70 +++++++++ .../PixelFormats/Rgb24Tests.cs | 4 +- 8 files changed, 232 insertions(+), 12 deletions(-) create mode 100644 src/ImageSharp/PixelFormats/Bgra32.cs create mode 100644 tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index 2555c13a47..386320495a 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -41,7 +41,7 @@ public override bool Equals(object obj) { - return obj.GetType() == typeof(Bgr24) && this.Equals((Bgr24)obj); + return obj?.GetType() == typeof(Bgr24) && this.Equals((Bgr24)obj); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs new file mode 100644 index 0000000000..582a0cd924 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -0,0 +1,146 @@ +namespace ImageSharp +{ + using System; + using System.Numerics; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + using ImageSharp.PixelFormats; + + [StructLayout(LayoutKind.Sequential)] + public struct Bgra32 : IPixel, IPackedVector + { + /// + /// Gets or sets the blue component. + /// + public byte B; + + /// + /// Gets or sets the green component. + /// + public byte G; + + /// + /// Gets or sets the red component. + /// + public byte R; + + /// + /// Gets or sets the alpha component. + /// + public byte A; + + /// + /// Initializes a new instance of the struct. + /// + /// The red component. + /// The green component. + /// The blue component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Bgra32(byte r, byte g, byte b) + { + this.R = r; + this.G = g; + this.B = b; + this.A = 255; + } + + + /// + /// Initializes a new instance of the struct. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The alpha component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Bgra32(byte r, byte g, byte b, byte a) + { + this.R = r; + this.G = g; + this.B = b; + this.A = a; + } + + public PixelOperations CreatePixelOperations() => new PixelOperations(); + + public bool Equals(Bgra32 other) + { + return this.R == other.R && this.G == other.G && this.B == other.B && this.A == other.A; + } + + public override bool Equals(object obj) => obj?.GetType() == typeof(Bgra32) && this.Equals((Bgra32)obj); + + public override int GetHashCode() + { + unchecked + { + int hashCode = this.B; + hashCode = (hashCode * 397) ^ this.G; + hashCode = (hashCode * 397) ^ this.R; + hashCode = (hashCode * 397) ^ this.A; + return hashCode; + } + } + + public void PackFromVector4(Vector4 vector) + { + throw new NotImplementedException(); + } + + public Vector4 ToVector4() + { + throw new NotImplementedException(); + } + + public void PackFromBytes(byte x, byte y, byte z, byte w) + { + throw new NotImplementedException(); + } + + public void ToXyzBytes(Span bytes, int startIndex) + { + throw new NotImplementedException(); + } + + public void ToXyzwBytes(Span bytes, int startIndex) + { + throw new NotImplementedException(); + } + + public void ToZyxBytes(Span bytes, int startIndex) + { + throw new NotImplementedException(); + } + + public void ToZyxwBytes(Span bytes, int startIndex) + { + throw new NotImplementedException(); + } + + /// + /// Gets or sets the packed representation of the Bgra32 struct. + /// + public uint Bgra + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return Unsafe.As(ref this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + Unsafe.As(ref this) = value; + } + } + + /// + public uint PackedValue + { + get => this.Bgra; + set => this.Bgra = value; + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index 4e777cadf7..07b0e03e82 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -49,7 +49,7 @@ namespace ImageSharp.PixelFormats /// The z-component. /// The w-component. void PackFromBytes(byte x, byte y, byte z, byte w); - + /// /// Expands the packed representation into a given byte array. /// Output is expanded to X-> Y-> Z order. Equivalent to R-> G-> B in diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index ff2b237ad8..d52c868925 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -41,7 +41,7 @@ namespace ImageSharp.PixelFormats public override bool Equals(object obj) { - return obj.GetType() == typeof(Rgb24) && this.Equals((Rgb24)obj); + return obj?.GetType() == typeof(Rgb24) && this.Equals((Rgb24)obj); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index ba46332fbf..32df4de7e4 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -179,7 +179,11 @@ namespace ImageSharp } /// - public uint PackedValue { get => this.Rgba; set => this.Rgba = value; } + public uint PackedValue + { + get => this.Rgba; + set => this.Rgba = value; + } /// /// Compares two objects for equality. @@ -330,10 +334,10 @@ namespace ImageSharp { unchecked { - int hashCode = this.R.GetHashCode(); - hashCode = (hashCode * 397) ^ this.G.GetHashCode(); - hashCode = (hashCode * 397) ^ this.B.GetHashCode(); - hashCode = (hashCode * 397) ^ this.A.GetHashCode(); + int hashCode = this.R; + hashCode = (hashCode * 397) ^ this.G; + hashCode = (hashCode * 397) ^ this.B; + hashCode = (hashCode * 397) ^ this.A; return hashCode; } } diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs index 3711631637..dcb75245d8 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs @@ -52,8 +52,8 @@ namespace ImageSharp.Tests [InlineData(1, 255, 0, 0, 255, 0)] public void WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) { - var a = new Rgb24(1, 2, 3); - var b = new Rgb24(1, 2, 4); + var a = new Rgb24(r1, g1, b1); + var b = new Rgb24(r2, g2, b2); Assert.False(a.Equals(b)); Assert.False(a.Equals((object)b)); diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs new file mode 100644 index 0000000000..82be9e8102 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs @@ -0,0 +1,70 @@ +namespace ImageSharp.Tests +{ + using ImageSharp.PixelFormats; + + using Xunit; + + public class Bgra32Tests + { + public static readonly TheoryData ColorData = + new TheoryData() + { + { 1, 2, 3, 4 }, { 4, 5, 6, 7 }, { 0, 255, 42, 0 }, { 1, 2, 3, 255 } + }; + + [Theory] + [MemberData(nameof(ColorData))] + public void Constructor(byte b, byte g, byte r, byte a) + { + var p = new Bgra32(r, g, b, a); + + Assert.Equal(r, p.R); + Assert.Equal(g, p.G); + Assert.Equal(b, p.B); + Assert.Equal(a, p.A); + } + + [Fact] + public unsafe void ByteLayoutIsSequentialBgra() + { + var color = new Bgra32(1, 2, 3, 4); + byte* ptr = (byte*)&color; + + Assert.Equal(3, ptr[0]); + Assert.Equal(2, ptr[1]); + Assert.Equal(1, ptr[2]); + Assert.Equal(4, ptr[3]); + } + + public class Equality + { + public static TheoryData ColorData = Bgra32Tests.ColorData; + + [Theory] + [MemberData(nameof(ColorData))] + public void WhenTrue(byte b, byte g, byte r, byte a) + { + var x = new Bgra32(r, g, b, a); + var y = new Bgra32(r, g, b, a); + + Assert.True(x.Equals(y)); + Assert.True(x.Equals((object)y)); + Assert.Equal(x.GetHashCode(), y.GetHashCode()); + } + + [Theory] + [InlineData(1, 2, 3, 4, 1, 2, 3, 5)] + [InlineData(0, 0, 255, 0, 0, 0, 244, 0)] + [InlineData(0, 255, 0, 0, 0, 244, 0, 0)] + [InlineData(1, 255, 0, 0, 0, 255, 0, 0)] + public void WhenFalse(byte b1, byte g1, byte r1, byte a1, byte b2, byte g2, byte r2, byte a2) + { + var x = new Bgra32(r1, g1, b1, a1); + var y = new Bgra32(r2, g2, b2, a2); + + Assert.False(x.Equals(y)); + Assert.False(x.Equals((object)y)); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs index 934d83bbb7..6118e4432c 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs @@ -54,8 +54,8 @@ namespace ImageSharp.Tests [InlineData(1, 255, 0, 0, 255, 0)] public void WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) { - var a = new Rgb24(1, 2, 3); - var b = new Rgb24(1, 2, 4); + var a = new Rgb24(r1, g1, b1); + var b = new Rgb24(r2, g2, b2); Assert.False(a.Equals(b)); Assert.False(a.Equals((object)b));