Browse Source

Merge branch 'refs/heads/pr/63'

af/merge-core
James Jackson-South 9 years ago
parent
commit
892ccd96f7
  1. 8
      src/ImageSharp/Colors/Spaces/CieLab.cs
  2. 8
      src/ImageSharp/Colors/Spaces/CieXyz.cs
  3. 10
      src/ImageSharp/Colors/Spaces/Cmyk.cs
  4. 8
      src/ImageSharp/Colors/Spaces/Hsl.cs
  5. 8
      src/ImageSharp/Colors/Spaces/Hsv.cs
  6. 184
      tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs

8
src/ImageSharp/Colors/Spaces/CieLab.cs

@ -161,7 +161,7 @@ namespace ImageSharp.Colors.Spaces
/// <inheritdoc/>
public bool Equals(CieLab other)
{
return this.AlmostEquals(other, Constants.Epsilon);
return this.backingVector.Equals(other.backingVector);
}
/// <inheritdoc/>
@ -169,9 +169,9 @@ namespace ImageSharp.Colors.Spaces
{
Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
return result.X < precision
&& result.Y < precision
&& result.Z < precision;
return result.X <= precision
&& result.Y <= precision
&& result.Z <= precision;
}
}
}

8
src/ImageSharp/Colors/Spaces/CieXyz.cs

@ -152,7 +152,7 @@ namespace ImageSharp.Colors.Spaces
/// <inheritdoc/>
public bool Equals(CieXyz other)
{
return this.AlmostEquals(other, Constants.Epsilon);
return this.backingVector.Equals(other.backingVector);
}
/// <inheritdoc/>
@ -160,9 +160,9 @@ namespace ImageSharp.Colors.Spaces
{
Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
return result.X < precision
&& result.Y < precision
&& result.Z < precision;
return result.X <= precision
&& result.Y <= precision
&& result.Z <= precision;
}
}
}

10
src/ImageSharp/Colors/Spaces/Cmyk.cs

@ -162,7 +162,7 @@ namespace ImageSharp.Colors.Spaces
/// <inheritdoc/>
public bool Equals(Cmyk other)
{
return this.AlmostEquals(other, Constants.Epsilon);
return this.backingVector.Equals(other.backingVector);
}
/// <inheritdoc/>
@ -170,10 +170,10 @@ namespace ImageSharp.Colors.Spaces
{
Vector4 result = Vector4.Abs(this.backingVector - other.backingVector);
return result.X < precision
&& result.Y < precision
&& result.Z < precision
&& result.W < precision;
return result.X <= precision
&& result.Y <= precision
&& result.Z <= precision
&& result.W <= precision;
}
}
}

8
src/ImageSharp/Colors/Spaces/Hsl.cs

@ -181,7 +181,7 @@ namespace ImageSharp.Colors.Spaces
/// <inheritdoc/>
public bool Equals(Hsl other)
{
return this.AlmostEquals(other, Constants.Epsilon);
return this.backingVector.Equals(other.backingVector);
}
/// <inheritdoc/>
@ -189,9 +189,9 @@ namespace ImageSharp.Colors.Spaces
{
Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
return result.X < precision
&& result.Y < precision
&& result.Z < precision;
return result.X <= precision
&& result.Y <= precision
&& result.Z <= precision;
}
}
}

8
src/ImageSharp/Colors/Spaces/Hsv.cs

@ -174,7 +174,7 @@ namespace ImageSharp.Colors.Spaces
/// <inheritdoc/>
public bool Equals(Hsv other)
{
return this.AlmostEquals(other, Constants.Epsilon);
return this.backingVector.Equals(other.backingVector);
}
/// <inheritdoc/>
@ -182,9 +182,9 @@ namespace ImageSharp.Colors.Spaces
{
Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
return result.X < precision
&& result.Y < precision
&& result.Z < precision;
return result.X <= precision
&& result.Y <= precision
&& result.Z <= precision;
}
}
}

184
tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Tests.Colors
{
using System;
using System.Numerics;
using ImageSharp.Colors.Spaces;
using Xunit;
/// <summary>
@ -37,6 +38,38 @@ namespace ImageSharp.Tests.Colors
{ new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.One * 0x7FFF), typeof(Short4) },
};
public static readonly TheoryData<object, object, Type> EqualityDataColorSpaces =
new TheoryData<object, object, Type>()
{
{ new Bgra32(0, 0, 0), new Bgra32(0, 0, 0), typeof(Bgra32) },
{ new Bgra32(0, 0, 0, 0), new Bgra32(0, 0, 0, 0), typeof(Bgra32) },
{ new Bgra32(100, 100, 0, 0), new Bgra32(100, 100, 0, 0), typeof(Bgra32) },
{ new Bgra32(255, 255, 255), new Bgra32(255, 255, 255), typeof(Bgra32) },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab) },
{ new CieLab(1f, 1f, 1f), new CieLab(1f, 1f, 1f), typeof(CieLab) },
{ new CieLab(0f, -100f, -100f), new CieLab(0f, -100f, -100f), typeof(CieLab) },
{ new CieLab(0f, 100f, -100f), new CieLab(0f, 100f, -100f), typeof(CieLab) },
{ new CieLab(0f, -100f, 100f), new CieLab(0f, -100f, 100f), typeof(CieLab) },
{ new CieLab(0f, -100f, 50f), new CieLab(0f, -100f, 50f), typeof(CieLab) },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380f), typeof(CieXyz) },
{ new CieXyz(780f, 780f, 780f), new CieXyz(780f, 780f, 780f), typeof(CieXyz) },
{ new CieXyz(380f, 780f, 780f), new CieXyz(380f, 780f, 780f), typeof(CieXyz) },
{ new CieXyz(50f, 20f, 60f), new CieXyz(50f, 20f, 60f), typeof(CieXyz) },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0f), typeof(Cmyk) },
{ new Cmyk(1f, 1f, 1f, 1f), new Cmyk(1f, 1f, 1f, 1f), typeof(Cmyk) },
{ new Cmyk(10f, 10f, 10f, 10f), new Cmyk(10f, 10f, 10f, 10f), typeof(Cmyk) },
{ new Cmyk(.4f, .5f, .1f, .2f), new Cmyk(.4f, .5f, .1f, .2f), typeof(Cmyk) },
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0f), typeof(Hsl) },
{ new Hsl(360f, 1f, 1f), new Hsl(360f, 1f, 1f), typeof(Hsl) },
{ new Hsl(100f, .5f, .1f), new Hsl(100f, .5f, .1f), typeof(Hsl) },
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0f), typeof(Hsv) },
{ new Hsv(360f, 1f, 1f), new Hsv(360f, 1f, 1f), typeof(Hsv) },
{ new Hsv(100f, .5f, .1f), new Hsv(100f, .5f, .1f), typeof(Hsv) },
{ new YCbCr(0, 0, 0), new YCbCr(0, 0, 0), typeof(YCbCr) },
{ new YCbCr(255, 255, 255), new YCbCr(255, 255, 255), typeof(YCbCr) },
{ new YCbCr(100, 100, 0), new YCbCr(100, 100, 0), typeof(YCbCr) },
};
public static readonly TheoryData<object, object, Type> NotEqualityDataNulls =
new TheoryData<object, object, Type>()
{
@ -61,6 +94,18 @@ namespace ImageSharp.Tests.Colors
{ new Short4(Vector4.One * 0x7FFF), null, typeof(Short4) },
};
public static readonly TheoryData<object, object, Type> NotEqualityDataNullsColorSpaces =
new TheoryData<object, object, Type>()
{
{ new Bgra32(0, 0, 0), null, typeof(Bgra32) },
{ new CieLab(0f, 0f, 0f), null, typeof(CieLab) },
{ new CieXyz(380f, 380f, 380f), null, typeof(CieXyz) },
{ new Cmyk(0f, 0f, 0f, 0f), null, typeof(Cmyk) },
{ new Hsl(0f, 0f, 0f), null, typeof(Hsl) },
{ new Hsv(360f, 1f, 1f), null, typeof(Hsv) },
{ new YCbCr(0, 0, 0), null, typeof(YCbCr) },
};
public static readonly TheoryData<object, object, Type> NotEqualityDataDifferentObjects =
new TheoryData<object, object, Type>()
{
@ -70,6 +115,16 @@ namespace ImageSharp.Tests.Colors
{ new Rgba1010102(Vector4.One), new Bgra5551(Vector4.Zero), null },
};
public static readonly TheoryData<object, object, Type> NotEqualityDataDifferentObjectsColorSpaces =
new TheoryData<object, object, Type>()
{
// Valid objects of different types but not equal
{ new Bgra32(0, 0, 0), new CieLab(0f, 0f, 0f), null },
{ new CieXyz(380f, 380f, 380f), new Cmyk(0f, 0f, 0f, 0f), null },
{ new Hsl(0f, 0f, 0f), new Hsv(360f, 1f, 1f), null },
{ new YCbCr(0, 0, 0), new Hsv(360f, 1f, 1f), null },
};
public static readonly TheoryData<object, object, Type> NotEqualityData =
new TheoryData<object, object, Type>()
{
@ -94,8 +149,92 @@ namespace ImageSharp.Tests.Colors
{ new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.Zero), typeof(Short4) },
};
public static readonly TheoryData<object, object, Type> NotEqualityDataColorSpaces =
new TheoryData<object, object, Type>()
{
{ new Bgra32(0, 0, 0), new Bgra32(0, 1, 0), typeof(Bgra32) },
{ new Bgra32(0, 0, 0, 0), new Bgra32(0, 1, 0, 0), typeof(Bgra32) },
{ new Bgra32(100, 100, 0, 0), new Bgra32(100, 0, 0, 0), typeof(Bgra32) },
{ new Bgra32(255, 255, 255), new Bgra32(255, 0, 255), typeof(Bgra32) },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 1f, 0f), typeof(CieLab) },
{ new CieLab(1f, 1f, 1f), new CieLab(1f, 0f, 1f), typeof(CieLab) },
{ new CieLab(0f, -100f, -100f), new CieLab(0f, 100f, -100f), typeof(CieLab) },
{ new CieLab(0f, 100f, -100f), new CieLab(0f, -100f, -100f), typeof(CieLab) },
{ new CieLab(0f, -100f, 100f), new CieLab(0f, 100f, 100f), typeof(CieLab) },
{ new CieLab(0f, -100f, 50f), new CieLab(0f, 100f, 20f), typeof(CieLab) },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 0f, 380f), typeof(CieXyz) },
{ new CieXyz(780f, 780f, 780f), new CieXyz(780f, 0f, 780f), typeof(CieXyz) },
{ new CieXyz(380f, 780f, 780f), new CieXyz(380f, 0f, 780f), typeof(CieXyz) },
{ new CieXyz(50f, 20f, 60f), new CieXyz(50f, 0f, 60f), typeof(CieXyz) },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 1f, 0f, 0f), typeof(Cmyk) },
{ new Cmyk(1f, 1f, 1f, 1f), new Cmyk(1f, 1f, 0f, 1f), typeof(Cmyk) },
{ new Cmyk(10f, 10f, 10f, 10f), new Cmyk(10f, 10f, 0f, 10f), typeof(Cmyk) },
{ new Cmyk(.4f, .5f, .1f, .2f), new Cmyk(.4f, .5f, 5f, .2f), typeof(Cmyk) },
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 5f, 0f), typeof(Hsl) },
{ new Hsl(360f, 1f, 1f), new Hsl(360f, .5f, 1f), typeof(Hsl) },
{ new Hsl(100f, .5f, .1f), new Hsl(100f, 9f, .1f), typeof(Hsl) },
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 1f, 0f), typeof(Hsv) },
{ new Hsv(360f, 1f, 1f), new Hsv(0f, 1f, 1f), typeof(Hsv) },
{ new Hsv(100f, .5f, .1f), new Hsv(2f, .5f, .1f), typeof(Hsv) },
{ new YCbCr(0, 0, 0), new YCbCr(0, 1, 0), typeof(YCbCr) },
{ new YCbCr(255, 255, 255), new YCbCr(255, 0, 255), typeof(YCbCr) },
{ new YCbCr(100, 100, 0), new YCbCr(100, 20, 0), typeof(YCbCr) },
};
public static readonly TheoryData<object, object, Type, float> AlmostEqualsData =
new TheoryData<object, object, Type, float>()
{
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), 0f },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), .001f },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), .0001f },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0f), typeof(CieLab), .0005f },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, .001f, 0f), typeof(CieLab), .001f },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, .0001f), typeof(CieLab), .0001f },
{ new CieLab(0f, 0f, 0f), new CieLab(.0005f, 0f, 0f), typeof(CieLab), .0005f },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380f), typeof(CieXyz), 0f },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380.001f, 380f, 380f), typeof(CieXyz), .01f },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380.001f, 380f), typeof(CieXyz), .01f },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380.001f), typeof(CieXyz), .01f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0f), typeof(Cmyk), 0f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0.001f, 0f, 0f, 0f), typeof(Cmyk), .01f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0.001f, 0f, 0f), typeof(Cmyk), .01f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0.001f, 0f), typeof(Cmyk), .01f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0.001f), typeof(Cmyk), .01f },
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0f), typeof(Hsl), 0f },
{ new Hsl(0f, 0f, 0f), new Hsl(0.001f, 0f, 0f), typeof(Hsl), .01f },
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0.001f, 0f), typeof(Hsl), .01f },
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0.001f), typeof(Hsl), .01f },
{ new Hsv(360f, 1f, 1f), new Hsv(360f, 1f, 1f), typeof(Hsv), 0f },
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0f), typeof(Hsv), 0f },
{ new Hsv(0f, 0f, 0f), new Hsv(0.001f, 0f, 0f), typeof(Hsv), .01f },
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0.001f, 0f), typeof(Hsv), .01f },
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0.001f), typeof(Hsv), .01f },
};
public static readonly TheoryData<object, object, Type, float> AlmostNotEqualsData =
new TheoryData<object, object, Type, float>()
{
{ new CieLab(0f, 0f, 0f), new CieLab(0.1f, 0f, 0f), typeof(CieLab), .001f },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0.1f, 0f), typeof(CieLab), .001f },
{ new CieLab(0f, 0f, 0f), new CieLab(0f, 0f, 0.1f), typeof(CieLab), .001f },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380.1f, 380f, 380f), typeof(CieXyz), .001f },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380.1f, 380f), typeof(CieXyz), .001f },
{ new CieXyz(380f, 380f, 380f), new CieXyz(380f, 380f, 380.1f), typeof(CieXyz), .001f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0.1f, 0f, 0f, 0f), typeof(Cmyk), .001f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0.1f, 0f, 0f), typeof(Cmyk), .001f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0.1f, 0f), typeof(Cmyk), .001f },
{ new Cmyk(0f, 0f, 0f, 0f), new Cmyk(0f, 0f, 0f, 0.1f), typeof(Cmyk), .001f },
{ new Hsl(0f, 0f, 0f), new Hsl(0.1f, 0f, 0f), typeof(Hsl), .001f },
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0.1f, 0f), typeof(Hsl), .001f },
{ new Hsl(0f, 0f, 0f), new Hsl(0f, 0f, 0.1f), typeof(Hsl), .001f },
{ new Hsv(0f, 0f, 0f), new Hsv(0.1f, 0f, 0f), typeof(Hsv), .001f },
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0.1f, 0f), typeof(Hsv), .001f },
{ new Hsv(0f, 0f, 0f), new Hsv(0f, 0f, 0.1f), typeof(Hsv), .001f },
};
[Theory]
[MemberData(nameof(EqualityData))]
[MemberData(nameof(EqualityDataColorSpaces))]
public void Equality(object first, object second, Type type)
{
// Act
@ -107,8 +246,11 @@ namespace ImageSharp.Tests.Colors
[Theory]
[MemberData(nameof(NotEqualityDataNulls))]
[MemberData(nameof(NotEqualityDataNullsColorSpaces))]
[MemberData(nameof(NotEqualityDataDifferentObjects))]
[MemberData(nameof(NotEqualityDataDifferentObjectsColorSpaces))]
[MemberData(nameof(NotEqualityData))]
[MemberData(nameof(NotEqualityDataColorSpaces))]
public void NotEquality(object first, object second, Type type)
{
// Act
@ -120,6 +262,7 @@ namespace ImageSharp.Tests.Colors
[Theory]
[MemberData(nameof(EqualityData))]
[MemberData(nameof(EqualityDataColorSpaces))]
public void HashCodeEqual(object first, object second, Type type)
{
// Act
@ -131,6 +274,7 @@ namespace ImageSharp.Tests.Colors
[Theory]
[MemberData(nameof(NotEqualityDataDifferentObjects))]
[MemberData(nameof(NotEqualityDataDifferentObjectsColorSpaces))]
public void HashCodeNotEqual(object first, object second, Type type)
{
// Act
@ -142,6 +286,7 @@ namespace ImageSharp.Tests.Colors
[Theory]
[MemberData(nameof(EqualityData))]
[MemberData(nameof(EqualityDataColorSpaces))]
public void EqualityObject(object first, object second, Type type)
{
// Arrange
@ -160,6 +305,7 @@ namespace ImageSharp.Tests.Colors
[Theory]
[MemberData(nameof(NotEqualityData))]
[MemberData(nameof(NotEqualityDataColorSpaces))]
public void NotEqualityObject(object first, object second, Type type)
{
// Arrange
@ -178,6 +324,7 @@ namespace ImageSharp.Tests.Colors
[Theory]
[MemberData(nameof(EqualityData))]
[MemberData(nameof(EqualityDataColorSpaces))]
public void EqualityOperator(object first, object second, Type type)
{
// Arrange
@ -196,6 +343,7 @@ namespace ImageSharp.Tests.Colors
[Theory]
[MemberData(nameof(NotEqualityData))]
[MemberData(nameof(NotEqualityDataColorSpaces))]
public void NotEqualityOperator(object first, object second, Type type)
{
// Arrange
@ -211,5 +359,41 @@ namespace ImageSharp.Tests.Colors
// Assert
Assert.True(notEqual);
}
[Theory]
[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 :)
dynamic firstObject = Convert.ChangeType(first, type);
dynamic secondObject = Convert.ChangeType(second, type);
// Act
var almostEqual = firstObject.AlmostEquals(secondObject, precision);
// Assert
Assert.True(almostEqual);
}
[Theory]
[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 :)
dynamic firstObject = Convert.ChangeType(first, type);
dynamic secondObject = Convert.ChangeType(second, type);
// Act
var almostEqual = firstObject.AlmostEquals(secondObject, precision);
// Assert
Assert.False(almostEqual);
}
}
}

Loading…
Cancel
Save