mirror of https://github.com/SixLabors/ImageSharp
8 changed files with 232 additions and 12 deletions
@ -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<Bgra32>, IPackedVector<uint> |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the blue component.
|
|||
/// </summary>
|
|||
public byte B; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the green component.
|
|||
/// </summary>
|
|||
public byte G; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the red component.
|
|||
/// </summary>
|
|||
public byte R; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the alpha component.
|
|||
/// </summary>
|
|||
public byte A; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="r">The red component.</param>
|
|||
/// <param name="g">The green component.</param>
|
|||
/// <param name="b">The blue component.</param>
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public Bgra32(byte r, byte g, byte b) |
|||
{ |
|||
this.R = r; |
|||
this.G = g; |
|||
this.B = b; |
|||
this.A = 255; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="r">The red component.</param>
|
|||
/// <param name="g">The green component.</param>
|
|||
/// <param name="b">The blue component.</param>
|
|||
/// <param name="a">The alpha component.</param>
|
|||
[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<Bgra32> CreatePixelOperations() => new PixelOperations<Bgra32>(); |
|||
|
|||
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<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToXyzwBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToZyxBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToZyxwBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the packed representation of the Bgra32 struct.
|
|||
/// </summary>
|
|||
public uint Bgra |
|||
{ |
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
get |
|||
{ |
|||
return Unsafe.As<Bgra32, uint>(ref this); |
|||
} |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
set |
|||
{ |
|||
Unsafe.As<Bgra32, uint>(ref this) = value; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public uint PackedValue |
|||
{ |
|||
get => this.Bgra; |
|||
set => this.Bgra = value; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using ImageSharp.PixelFormats; |
|||
|
|||
using Xunit; |
|||
|
|||
public class Bgra32Tests |
|||
{ |
|||
public static readonly TheoryData<byte, byte, byte, byte> ColorData = |
|||
new TheoryData<byte, byte, byte, byte>() |
|||
{ |
|||
{ 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<byte, byte, byte, byte> 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)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue