From 38541af055b2e06d14ba9828f5beba070650a187 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 17 Apr 2017 22:56:28 +1000 Subject: [PATCH] Add tests, fix bugs --- src/ImageSharp/Colors/ColorVector.cs | 7 +- .../Colors/ColorEqualityTests.cs | 50 +++--- .../Colors/PackedPixelTests.cs | 45 ++++++ .../Colors/UnPackedPixelTests.cs | 148 ++++++++++++++++++ 4 files changed, 223 insertions(+), 27 deletions(-) create mode 100644 tests/ImageSharp.Tests/Colors/UnPackedPixelTests.cs diff --git a/src/ImageSharp/Colors/ColorVector.cs b/src/ImageSharp/Colors/ColorVector.cs index 3e86e85c75..354553982a 100644 --- a/src/ImageSharp/Colors/ColorVector.cs +++ b/src/ImageSharp/Colors/ColorVector.cs @@ -218,9 +218,10 @@ namespace ImageSharp /// A hexadecimal string representation of the value. public string ToHex() { + // Hex is RRGGBBAA Vector4 vector = this.backingVector * MaxBytes; vector += Half; - uint hexOrder = (uint)((byte)vector.X | (byte)vector.Y << 8 | (byte)vector.Z << 16 | (byte)vector.W << 24); + uint hexOrder = (uint)((byte)vector.W | (byte)vector.Z << 8 | (byte)vector.Y << 16 | (byte)vector.X << 24); return hexOrder.ToString("X8"); } @@ -244,7 +245,7 @@ namespace ImageSharp bytes[startIndex] = (byte)vector.X; bytes[startIndex + 1] = (byte)vector.Y; bytes[startIndex + 2] = (byte)vector.Z; - bytes[startIndex + 2] = (byte)vector.W; + bytes[startIndex + 3] = (byte)vector.W; } /// @@ -267,7 +268,7 @@ namespace ImageSharp bytes[startIndex] = (byte)vector.Z; bytes[startIndex + 1] = (byte)vector.Y; bytes[startIndex + 2] = (byte)vector.X; - bytes[startIndex + 2] = (byte)vector.W; + bytes[startIndex + 3] = (byte)vector.W; } /// diff --git a/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs b/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs index b5b09c8288..42481799f1 100644 --- a/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs +++ b/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs @@ -33,6 +33,7 @@ namespace ImageSharp.Tests.Colors { new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.One), typeof(NormalizedShort4) }, { new Rg32(Vector2.One), new Rg32(Vector2.One), typeof(Rg32) }, { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.One), typeof(Rgba1010102) }, + { new Rgba32(Vector4.One), new Rgba32(Vector4.One), typeof(Rgba32) }, { new Rgba64(Vector4.One), new Rgba64(Vector4.One), typeof(Rgba64) }, { new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.One * 0x7FFF), typeof(Short2) }, { new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.One * 0x7FFF), typeof(Short4) }, @@ -144,6 +145,7 @@ namespace ImageSharp.Tests.Colors { new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.Zero), typeof(NormalizedShort4) }, { new Rg32(Vector2.One), new Rg32(Vector2.Zero), typeof(Rg32) }, { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.Zero), typeof(Rgba1010102) }, + { new Rgba32(Vector4.One), new Rgba32(Vector4.Zero), typeof(Rgba32) }, { new Rgba64(Vector4.One), new Rgba64(Vector4.Zero), typeof(Rgba64) }, { new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.Zero), typeof(Short2) }, { new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.Zero), typeof(Short4) }, @@ -289,10 +291,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(EqualityDataColorSpaces))] public void EqualityObject(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -308,10 +310,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(NotEqualityDataColorSpaces))] public void NotEqualityObject(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -327,10 +329,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(EqualityDataColorSpaces))] public void EqualityOperator(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -346,10 +348,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(NotEqualityDataColorSpaces))] public void NotEqualityOperator(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -364,10 +366,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(AlmostEqualsData))] public void AlmostEquals(object first, object second, Type type, float precision) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -382,10 +384,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(AlmostNotEqualsData))] public void AlmostNotEquals(object first, object second, Type type, float precision) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); diff --git a/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs b/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs index 3e2b6fcd5c..b5e159d9ae 100644 --- a/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs +++ b/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs @@ -711,6 +711,51 @@ namespace ImageSharp.Tests.Colors Assert.Equal(rgba, new byte[] { 25, 0, 128, 0 }); } + [Fact] + public void Rgba32() + { + // Test the limits. + Assert.Equal((uint)0x0, new Rgba32(Vector4.Zero).PackedValue); + Assert.Equal(0xFFFFFFFF, new Rgba32(Vector4.One).PackedValue); + + // Test ToVector4. + Assert.True(Equal(Vector4.One, new Rgba32(Vector4.One).ToVector4())); + Assert.True(Equal(Vector4.Zero, new Rgba32(Vector4.Zero).ToVector4())); + Assert.True(Equal(Vector4.UnitX, new Rgba32(Vector4.UnitX).ToVector4())); + Assert.True(Equal(Vector4.UnitY, new Rgba32(Vector4.UnitY).ToVector4())); + Assert.True(Equal(Vector4.UnitZ, new Rgba32(Vector4.UnitZ).ToVector4())); + Assert.True(Equal(Vector4.UnitW, new Rgba32(Vector4.UnitW).ToVector4())); + + // Test clamping. + Assert.True(Equal(Vector4.Zero, new Rgba32(Vector4.One * -1234.0f).ToVector4())); + Assert.True(Equal(Vector4.One, new Rgba32(Vector4.One * +1234.0f).ToVector4())); + + float x = +0.1f; + float y = -0.3f; + float z = +0.5f; + float w = -0.7f; + Rgba32 rgba32 = new Rgba32(x, y, z, w); + Assert.Equal(0x80001Au, rgba32.PackedValue); + + // Test ordering + byte[] rgb = new byte[3]; + byte[] rgba = new byte[4]; + byte[] bgr = new byte[3]; + byte[] bgra = new byte[4]; + + rgba32.ToXyzBytes(rgb, 0); + Assert.Equal(rgb, new byte[] { 0x1a, 0, 0x80 }); + + rgba32.ToXyzwBytes(rgba, 0); + Assert.Equal(rgba, new byte[] { 0x1a, 0, 0x80, 0 }); + + rgba32.ToZyxBytes(bgr, 0); + Assert.Equal(bgr, new byte[] { 0x80, 0, 0x1a }); + + rgba32.ToZyxwBytes(bgra, 0); + Assert.Equal(bgra, new byte[] { 0x80, 0, 0x1a, 0 }); + } + [Fact] public void Rgba64() { diff --git a/tests/ImageSharp.Tests/Colors/UnPackedPixelTests.cs b/tests/ImageSharp.Tests/Colors/UnPackedPixelTests.cs new file mode 100644 index 0000000000..4fb189ca81 --- /dev/null +++ b/tests/ImageSharp.Tests/Colors/UnPackedPixelTests.cs @@ -0,0 +1,148 @@ +namespace ImageSharp.Tests.Colors +{ + using System.Numerics; + + using Xunit; + + public class UnPackedPixelTests + { + [Fact] + public void Color_Types_From_Bytes_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Floats_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); + ColorVector colorVector = new ColorVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Vector4_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(new Vector4(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F)); + ColorVector colorVector = new ColorVector(new Vector4(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F)); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Vector3_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(new Vector3(24 / 255F, 48 / 255F, 96 / 255F)); + ColorVector colorVector = new ColorVector(new Vector3(24 / 255F, 48 / 255F, 96 / 255F)); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Hex_Produce_Equal_Scaled_Component_OutPut() + { + Color color = Color.FromHex("183060C0"); + ColorVector colorVector = ColorVector.FromHex("183060C0"); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_To_Vector4_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + Assert.Equal(color.ToVector4(), colorVector.ToVector4()); + } + + [Fact] + public void Color_Types_To_RgbBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] rgb = new byte[3]; + byte[] rgbVector = new byte[3]; + + color.ToXyzBytes(rgb, 0); + colorVector.ToXyzBytes(rgbVector, 0); + + Assert.Equal(rgb, rgbVector); + } + + [Fact] + public void Color_Types_To_RgbaBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] rgba = new byte[4]; + byte[] rgbaVector = new byte[4]; + + color.ToXyzwBytes(rgba, 0); + colorVector.ToXyzwBytes(rgbaVector, 0); + + Assert.Equal(rgba, rgbaVector); + } + + [Fact] + public void Color_Types_To_BgrBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] bgr = new byte[3]; + byte[] bgrVector = new byte[3]; + + color.ToZyxBytes(bgr, 0); + colorVector.ToZyxBytes(bgrVector, 0); + + Assert.Equal(bgr, bgrVector); + } + + [Fact] + public void Color_Types_To_BgraBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] bgra = new byte[4]; + byte[] bgraVector = new byte[4]; + + color.ToZyxwBytes(bgra, 0); + colorVector.ToZyxwBytes(bgraVector, 0); + + Assert.Equal(bgra, bgraVector); + } + + [Fact] + public void Color_Types_To_Hex_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + // 183060C0 + Assert.Equal(color.ToHex(), colorVector.ToHex()); + } + } +} \ No newline at end of file