Browse Source

Add CIE xyY

pull/144/head
James Jackson-South 9 years ago
parent
commit
f5a68df2ff
  1. 155
      src/ImageSharp/Colors/Spaces/CieXyy.cs
  2. 12
      src/ImageSharp/Colors/Spaces/CieXyz.cs
  3. 13
      src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.CieLab.cs
  4. 113
      src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.CieXyy.cs
  5. 13
      src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.CieXyz.cs
  6. 13
      src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.HunterLab.cs
  7. 13
      src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.LinearRgb.cs
  8. 13
      src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.Lms.cs
  9. 13
      src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.Rgb.cs
  10. 49
      src/ImageSharp/Colors/Spaces/Conversion/Implementation/CieXyy/CieXyzAndCieXyyConverter.cs
  11. 3
      src/ImageSharp/ImageSharp.csproj
  12. 61
      tests/ImageSharp.Tests/Colors/Colorspaces/CieXyzAndCieXyyConversionTest.cs
  13. 63
      tests/ImageSharp.Tests/Colors/Colorspaces/ColorSpaceEqualityTests.cs

155
src/ImageSharp/Colors/Spaces/CieXyy.cs

@ -0,0 +1,155 @@
// <copyright file="CieXyy.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Colors.Spaces
{
using System;
using System.ComponentModel;
using System.Numerics;
/// <summary>
/// Represents an CIE xyY 1931 color
/// <see href="https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space"/>
/// </summary>
public struct CieXyy : IColorVector, IEquatable<CieXyy>, IAlmostEquatable<CieXyy, float>
{
/// <summary>
/// Represents a <see cref="CieXyy"/> that has X, Y, and Y values set to zero.
/// </summary>
public static readonly CieXyy Empty = default(CieXyy);
/// <summary>
/// The backing vector for SIMD support.
/// </summary>
private readonly Vector3 backingVector;
/// <summary>
/// Initializes a new instance of the <see cref="CieXyy"/> struct.
/// </summary>
/// <param name="x">The x chroma component.</param>
/// <param name="y">The y chroma component.</param>
/// <param name="yl">The y luminance component.</param>
public CieXyy(float x, float y, float yl)
: this(new Vector3(x, y, yl))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="CieXyy"/> struct.
/// </summary>
/// <param name="vector">The vector representing the x, y, Y components.</param>
public CieXyy(Vector3 vector)
: this()
{
// Not clamping as documentation about this space seems to indicate "usual" ranges
this.backingVector = vector;
}
/// <summary>
/// Gets the X chrominance component.
/// <remarks>A value usually ranging between 0 and 1.</remarks>
/// </summary>
public float X => this.backingVector.X;
/// <summary>
/// Gets the Y chrominance component.
/// <remarks>A value usually ranging between 0 and 1.</remarks>
/// </summary>
public float Y => this.backingVector.Y;
/// <summary>
/// Gets the Y luminance component.
/// <remarks>A value usually ranging between 0 and 1.</remarks>
/// </summary>
public float Yl => this.backingVector.Z;
/// <summary>
/// Gets a value indicating whether this <see cref="CieXyy"/> is empty.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsEmpty => this.Equals(Empty);
/// <inheritdoc />
public Vector3 Vector => this.backingVector;
/// <summary>
/// Compares two <see cref="CieXyy"/> objects for equality.
/// </summary>
/// <param name="left">
/// The <see cref="CieXyy"/> on the left side of the operand.
/// </param>
/// <param name="right">
/// The <see cref="CieXyy"/> on the right side of the operand.
/// </param>
/// <returns>
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator ==(CieXyy left, CieXyy right)
{
return left.Equals(right);
}
/// <summary>
/// Compares two <see cref="CieXyy"/> objects for inequality.
/// </summary>
/// <param name="left">
/// The <see cref="CieXyy"/> on the left side of the operand.
/// </param>
/// <param name="right">
/// The <see cref="CieXyy"/> on the right side of the operand.
/// </param>
/// <returns>
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator !=(CieXyy left, CieXyy right)
{
return !left.Equals(right);
}
/// <inheritdoc/>
public override int GetHashCode()
{
return this.backingVector.GetHashCode();
}
/// <inheritdoc/>
public override string ToString()
{
if (this.IsEmpty)
{
return "CieXyy [ Empty ]";
}
return $"CieXyy [ X={this.X:#0.##}, Y={this.Y:#0.##}, Yl={this.Yl:#0.##} ]";
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj is CieXyy)
{
return this.Equals((CieXyy)obj);
}
return false;
}
/// <inheritdoc/>
public bool Equals(CieXyy other)
{
return this.backingVector.Equals(other.backingVector);
}
/// <inheritdoc/>
public bool AlmostEquals(CieXyy other, float precision)
{
Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
return result.X <= precision
&& result.Y <= precision
&& result.Z <= precision;
}
}
}

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

@ -10,13 +10,13 @@ namespace ImageSharp.Colors.Spaces
using System.Numerics;
/// <summary>
/// Represents an CIE 1931 color
/// <see href="https://en.wikipedia.org/wiki/CIE_1931_color_space"/>
/// Represents an CIE XYZ 1931 color
/// <see href="https://en.wikipedia.org/wiki/CIE_1931_color_space#Definition_of_the_CIE_XYZ_color_space"/>
/// </summary>
public struct CieXyz : IColorVector, IEquatable<CieXyz>, IAlmostEquatable<CieXyz, float>
{
/// <summary>
/// Represents a <see cref="CieXyz"/> that has Y, Cb, and Cr values set to zero.
/// Represents a <see cref="CieXyz"/> that has X, Y, and Z values set to zero.
/// </summary>
public static readonly CieXyz Empty = default(CieXyz);
@ -48,19 +48,19 @@ namespace ImageSharp.Colors.Spaces
}
/// <summary>
/// Gets the Y luminance component.
/// Gets the X component. A mix (a linear combination) of cone response curves chosen to be nonnegative.
/// <remarks>A value usually ranging between 0 and 1.</remarks>
/// </summary>
public float X => this.backingVector.X;
/// <summary>
/// Gets the Cb chroma component.
/// Gets the Y luminance component.
/// <remarks>A value usually ranging between 0 and 1.</remarks>
/// </summary>
public float Y => this.backingVector.Y;
/// <summary>
/// Gets the Cr chroma component.
/// Gets the Z component. Quasi-equal to blue stimulation, or the S cone response
/// <remarks>A value usually ranging between 0 and 1.</remarks>
/// </summary>
public float Z => this.backingVector.Z;

13
src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.CieLab.cs

@ -90,6 +90,19 @@ namespace ImageSharp.Colors.Spaces.Conversion
return this.ToCieLab(xyzColor);
}
/// <summary>
/// Converts a <see cref="CieXyy"/> into a <see cref="CieLab"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieLab"/></returns>
public CieLab ToCieLab(CieXyy color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToCieLab(xyzColor);
}
/// <summary>
/// Converts a <see cref="CieLch"/> into a <see cref="CieLab"/>
/// </summary>

113
src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.CieXyy.cs

@ -0,0 +1,113 @@
// <copyright file="ColorSpaceConverter.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Colors.Spaces.Conversion
{
using ImageSharp.Colors.Spaces.Conversion.Implementation.CieXyy;
/// <summary>
/// Converts between color spaces ensuring that the color is adapted using chromatic adaptation.
/// </summary>
public partial class ColorSpaceConverter
{
private static readonly CieXyzAndCieXyyConverter CieXyzAndCieXyyConverter = new CieXyzAndCieXyyConverter();
/// <summary>
/// Converts a <see cref="CieXyz"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyy"/></returns>
public CieXyy ToCieXyy(CieXyz color)
{
Guard.NotNull(color, nameof(color));
return CieXyzAndCieXyyConverter.Convert(color);
}
/// <summary>
/// Converts a <see cref="CieLab"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyy"/></returns>
public CieXyy ToCieXyy(CieLab color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToCieXyy(xyzColor);
}
/// <summary>
/// Converts a <see cref="CieLch"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyy"/></returns>
public CieXyy ToCieXyy(CieLch color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToCieXyy(xyzColor);
}
/// <summary>
/// Converts a <see cref="HunterLab"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyy"/></returns>
public CieXyy ToCieXyy(HunterLab color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToCieXyy(xyzColor);
}
/// <summary>
/// Converts a <see cref="LinearRgb"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyy"/></returns>
public CieXyy ToCieXyy(LinearRgb color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToCieXyy(xyzColor);
}
/// <summary>
/// Converts a <see cref="Rgb"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyy"/></returns>
public CieXyy ToCieXyy(Rgb color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToCieXyy(xyzColor);
}
/// <summary>
/// Converts a <see cref="Lms"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyy"/></returns>
public CieXyy ToCieXyy(Lms color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToCieXyy(xyzColor);
}
}
}

13
src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.CieXyz.cs

@ -41,6 +41,19 @@ namespace ImageSharp.Colors.Spaces.Conversion
return adapted;
}
/// <summary>
/// Converts a <see cref="CieXyy"/> into a <see cref="CieXyz"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="CieXyz"/></returns>
public CieXyz ToCieXyz(CieXyy color)
{
Guard.NotNull(color, nameof(color));
// Conversion
return CieXyzAndCieXyyConverter.Convert(color);
}
/// <summary>
/// Converts a <see cref="Lms"/> into a <see cref="CieXyz"/>
/// </summary>

13
src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.HunterLab.cs

@ -94,5 +94,18 @@ namespace ImageSharp.Colors.Spaces.Conversion
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToHunterLab(xyzColor);
}
/// <summary>
/// Converts a <see cref="CieLab"/> into a <see cref="CieXyy"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="HunterLab"/></returns>
public HunterLab ToHunterLab(CieXyy color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToHunterLab(xyzColor);
}
}
}

13
src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.LinearRgb.cs

@ -100,6 +100,19 @@ namespace ImageSharp.Colors.Spaces.Conversion
return this.ToLinearRgb(xyzColor);
}
/// <summary>
/// Converts a <see cref="CieXyy"/> into a <see cref="LinearRgb"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="LinearRgb"/></returns>
public LinearRgb ToLinearRgb(CieXyy color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToLinearRgb(xyzColor);
}
/// <summary>
/// Gets the correct converter for the given rgb working space.
/// </summary>

13
src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.Lms.cs

@ -89,5 +89,18 @@ namespace ImageSharp.Colors.Spaces.Conversion
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToLms(xyzColor);
}
/// <summary>
/// Converts a <see cref="CieXyy"/> into a <see cref="Lms"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="Lms"/></returns>
public Lms ToLms(CieXyy color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToLms(xyzColor);
}
}
}

13
src/ImageSharp/Colors/Spaces/Conversion/ColorSpaceConverter.Rgb.cs

@ -94,5 +94,18 @@ namespace ImageSharp.Colors.Spaces.Conversion
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToRgb(xyzColor);
}
/// <summary>
/// Converts a <see cref="CieXyy"/> into a <see cref="Rgb"/>
/// </summary>
/// <param name="color">The color to convert.</param>
/// <returns>The <see cref="Rgb"/></returns>
public Rgb ToRgb(CieXyy color)
{
Guard.NotNull(color, nameof(color));
CieXyz xyzColor = this.ToCieXyz(color);
return this.ToRgb(xyzColor);
}
}
}

49
src/ImageSharp/Colors/Spaces/Conversion/Implementation/CieXyy/CieXyzAndCieXyyConverter.cs

@ -0,0 +1,49 @@
// <copyright file="CieXyy.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Colors.Spaces.Conversion.Implementation.CieXyy
{
using ImageSharp.Colors.Spaces;
/// <summary>
/// Color converter between CIE XYZ and CIE xyY
/// <see href="http://www.brucelindbloom.com/"/> for formulas.
/// </summary>
internal class CieXyzAndCieXyyConverter : IColorConversion<CieXyz, CieXyy>, IColorConversion<CieXyy, CieXyz>
{
/// <inheritdoc/>
public CieXyy Convert(CieXyz input)
{
DebugGuard.NotNull(input, nameof(input));
float x = input.X / (input.X + input.Y + input.Z);
float y = input.Y / (input.X + input.Y + input.Z);
if (float.IsNaN(x) || float.IsNaN(y))
{
return new CieXyy(0, 0, input.Y);
}
return new CieXyy(x, y, input.Y);
}
/// <inheritdoc/>
public CieXyz Convert(CieXyy input)
{
DebugGuard.NotNull(input, nameof(input));
if (MathF.Abs(input.Y) < Constants.Epsilon)
{
return new CieXyz(0, 0, input.Yl);
}
float x = (input.X * input.Yl) / input.Y;
float y = input.Yl;
float z = ((1 - input.X - input.Y) * y) / input.Y;
return new CieXyz(x, y, z);
}
}
}

3
src/ImageSharp/ImageSharp.csproj

@ -33,6 +33,9 @@
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
<AdditionalFiles Include="..\Shared\stylecop.json" />
</ItemGroup>
<ItemGroup>
<None Include="Colors\Spaces\Conversion\ColorSpaceConverter.CieXyy.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta001">
<PrivateAssets>All</PrivateAssets>

61
tests/ImageSharp.Tests/Colors/Colorspaces/CieXyzAndCieXyyConversionTest.cs

@ -0,0 +1,61 @@
namespace ImageSharp.Tests.Colors.Colorspaces
{
using System.Collections.Generic;
using ImageSharp.Colors.Spaces;
using ImageSharp.Colors.Spaces.Conversion;
using Xunit;
/// <summary>
/// Tests <see cref="CieXyz"/>-<see cref="CieXyy"/> conversions.
/// </summary>
/// <remarks>
/// Test data generated using:
/// <see href="http://www.brucelindbloom.com/index.html?ColorCalculator.html"/>
/// </remarks>
public class CieXyzAndCieXyyConversionTest
{
private static readonly IEqualityComparer<float> FloatRoundingComparer = new FloatRoundingComparer(4);
private static readonly ColorSpaceConverter Converter = new ColorSpaceConverter();
[Theory]
[InlineData(0.436075, 0.222504, 0.013932, 0.648427, 0.330856, 0.222504)]
[InlineData(0.964220, 1.000000, 0.825210, 0.345669, 0.358496, 1.000000)]
[InlineData(0.434119, 0.356820, 0.369447, 0.374116, 0.307501, 0.356820)]
[InlineData(0, 0, 0, 0.538842, 0.000000, 0.000000)]
public void Convert_xyY_to_XYZ(float xyzX, float xyzY, float xyzZ, float x, float y, float yl)
{
// Arrange
CieXyy input = new CieXyy(x, y, yl);
// Act
CieXyz output = Converter.ToCieXyz(input);
// Assert
Assert.Equal(xyzX, output.X, FloatRoundingComparer);
Assert.Equal(xyzY, output.Y, FloatRoundingComparer);
Assert.Equal(xyzZ, output.Z, FloatRoundingComparer);
}
[Theory]
[InlineData(0.436075, 0.222504, 0.013932, 0.648427, 0.330856, 0.222504)]
[InlineData(0.964220, 1.000000, 0.825210, 0.345669, 0.358496, 1.000000)]
[InlineData(0.434119, 0.356820, 0.369447, 0.374116, 0.307501, 0.356820)]
[InlineData(0.231809, 0, 0.077528, 0.749374, 0.000000, 0.000000)]
public void Convert_XYZ_to_xyY(float xyzX, float xyzY, float xyzZ, float x, float y, float yl)
{
// Arrange
CieXyz input = new CieXyz(xyzX, xyzY, xyzZ);
// Act
CieXyy output = Converter.ToCieXyy(input);
// Assert
Assert.Equal(x, output.X, FloatRoundingComparer);
Assert.Equal(y, output.Y, FloatRoundingComparer);
Assert.Equal(yl, output.Yl, FloatRoundingComparer);
}
}
}

63
tests/ImageSharp.Tests/Colors/Colorspaces/ColorSpaceEqualityTests.cs

@ -16,26 +16,49 @@ namespace ImageSharp.Tests.Colors
/// </summary>
public class ColorSpaceEqualityTests
{
public static readonly TheoryData<IColorVector> EmptyData =
new TheoryData<IColorVector>
{
CieLab.Empty,
CieLch.Empty,
CieXyz.Empty,
CieXyy.Empty,
HunterLab.Empty,
Lms.Empty,
LinearRgb.Empty,
Rgb.Empty,
};
public static readonly TheoryData<object, object, Type> EqualityData =
new TheoryData<object, object, Type>()
{
new TheoryData<object, object, Type>
{
{ new CieLab(Vector3.One), new CieLab(Vector3.One), typeof(CieLab) },
{ new CieLch(Vector3.One), new CieLch(Vector3.One), typeof(CieLch) },
{ new CieXyz(Vector3.One), new CieXyz(Vector3.One), typeof(CieXyz) },
{ new CieXyy(Vector3.One), new CieXyy(Vector3.One), typeof(CieXyy) },
{ new HunterLab(Vector3.One), new HunterLab(Vector3.One), typeof(HunterLab) },
{ new Lms(Vector3.One), new Lms(Vector3.One), typeof(Lms) },
{ new LinearRgb(Vector3.One), new LinearRgb(Vector3.One), typeof(LinearRgb) },
{ new Rgb(Vector3.One), new Rgb(Vector3.One), typeof(Rgb) },
};
public static readonly TheoryData<object, object, Type> NotEqualityDataNulls =
new TheoryData<object, object, Type>()
{
new TheoryData<object, object, Type>
{
// Valid object against null
{ new CieLab(Vector3.One), null, typeof(CieLab) },
{ new CieLch(Vector3.One), null, typeof(CieLch) },
{ new CieXyz(Vector3.One), null, typeof(CieXyz) },
{ new CieXyy(Vector3.One), null, typeof(CieXyy) },
{ new HunterLab(Vector3.One), null, typeof(HunterLab) },
{ new Lms(Vector3.One), null, typeof(Lms) },
{ new LinearRgb(Vector3.One), null, typeof(LinearRgb) },
{ new Rgb(Vector3.One), null, typeof(Rgb) },
};
public static readonly TheoryData<object, object, Type> NotEqualityDataDifferentObjects =
new TheoryData<object, object, Type>()
{
new TheoryData<object, object, Type>
{
// Valid objects of different types but not equal
{ new CieLab(Vector3.One), new CieLch(Vector3.Zero), null },
{ new CieXyz(Vector3.One), new HunterLab(Vector3.Zero), null },
@ -44,17 +67,22 @@ namespace ImageSharp.Tests.Colors
};
public static readonly TheoryData<object, object, Type> NotEqualityData =
new TheoryData<object, object, Type>()
{
new TheoryData<object, object, Type>
{
// Valid objects of the same type but not equal
{ new CieLab(Vector3.One), new CieLab(Vector3.Zero), typeof(CieLab) },
{ new CieLch(Vector3.One), new CieLch(Vector3.Zero), typeof(CieLch) },
{ new CieXyz(Vector3.One), new CieXyz(Vector3.Zero), typeof(CieXyz) },
{ new CieXyy(Vector3.One), new CieXyy(Vector3.Zero), typeof(CieXyy) },
{ new HunterLab(Vector3.One), new HunterLab(Vector3.Zero), typeof(HunterLab) },
{ new Lms(Vector3.One), new Lms(Vector3.Zero), typeof(Lms) },
{ new LinearRgb(Vector3.One), new LinearRgb(Vector3.Zero), typeof(LinearRgb) },
{ new Rgb(Vector3.One), new Rgb(Vector3.Zero), typeof(Rgb) },
};
public static readonly TheoryData<object, object, Type, float> AlmostEqualsData =
new TheoryData<object, object, Type, float>()
{
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 },
@ -69,8 +97,8 @@ namespace ImageSharp.Tests.Colors
};
public static readonly TheoryData<object, object, Type, float> AlmostNotEqualsData =
new TheoryData<object, object, Type, float>()
{
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 },
@ -79,6 +107,17 @@ namespace ImageSharp.Tests.Colors
{ new CieXyz(380F, 380F, 380F), new CieXyz(380F, 380F, 380.1F), typeof(CieXyz), .001F },
};
[Theory]
[MemberData(nameof(EmptyData))]
public void Equality(IColorVector color)
{
// Act
bool equal = color.Vector.Equals(Vector3.Zero);
// Assert
Assert.True(equal);
}
[Theory]
[MemberData(nameof(EqualityData))]
public void Equality(object first, object second, Type type)

Loading…
Cancel
Save