using System; namespace Prism.UnitTests { public class ColorSpaceTests : UnitTestSharp.TestFixture { private const double Tolerance = 1e-9; public class SrgbToLinearTests : UnitTestSharp.TestFixture { public void ZeroStaysZero() { CheckEqual(0.0, ColorSpace.SrgbToLinear(0.0)); } public void OneStaysOne() { CheckTrue(Math.Abs(ColorSpace.SrgbToLinear(1.0) - 1.0) < Tolerance); } public void BelowTheKneeIsExactlyLinear() { CheckEqual(0.03 / 12.92, ColorSpace.SrgbToLinear(0.03)); } public void MidtonesDarkenTowardTheLinearValue() { CheckTrue(ColorSpace.SrgbToLinear(0.5) < 0.5); } } public class LinearToSrgbTests : UnitTestSharp.TestFixture { public void ZeroStaysZero() { CheckEqual(0.0, ColorSpace.LinearToSrgb(0.0)); } public void OneStaysOne() { CheckTrue(Math.Abs(ColorSpace.LinearToSrgb(1.0) - 1.0) < Tolerance); } public void BelowTheKneeIsExactlyLinear() { CheckEqual(0.002 * 12.92, ColorSpace.LinearToSrgb(0.002)); } public void MidtonesBrightenTowardTheEncodedValue() { CheckTrue(ColorSpace.LinearToSrgb(0.5) > 0.5); } public void InvertsSrgbToLinear() { foreach (double srgb in new[] { 0.02, 0.05, 0.25, 0.5, 0.75, 0.95 }) { double roundTripped = ColorSpace.LinearToSrgb(ColorSpace.SrgbToLinear(srgb)); CheckTrue(Math.Abs(roundTripped - srgb) < Tolerance); } } } public class SrgbByteToLinearTests : UnitTestSharp.TestFixture { public void Zero_IsZero() { CheckEqual(0f, ColorSpace.SrgbByteToLinear(0)); } public void FullByte_IsOne() { CheckEqual(1f, ColorSpace.SrgbByteToLinear(255)); } public void MatchesTheCurveAtMidtones() { CheckEqual((float)ColorSpace.SrgbToLinear(128 / 255.0), ColorSpace.SrgbByteToLinear(128)); } public void BelowTheKnee_IsExactlyLinear() { CheckEqual((float)(10 / 255.0 / 12.92), ColorSpace.SrgbByteToLinear(10)); } } public class LinearToSrgbByteTests : UnitTestSharp.TestFixture { public void ZeroNegativeAndNaN_EncodeToZero() { CheckEqual((byte)0, ColorSpace.LinearToSrgbByte(0f)); CheckEqual((byte)0, ColorSpace.LinearToSrgbByte(-0.5f)); CheckEqual((byte)0, ColorSpace.LinearToSrgbByte(float.NegativeInfinity)); CheckEqual((byte)0, ColorSpace.LinearToSrgbByte(float.NaN)); } public void OneAndAbove_EncodeTo255() { CheckEqual((byte)255, ColorSpace.LinearToSrgbByte(1f)); CheckEqual((byte)255, ColorSpace.LinearToSrgbByte(7f)); CheckEqual((byte)255, ColorSpace.LinearToSrgbByte(float.PositiveInfinity)); } public void TheLinearValueOfAByte_EncodesBackToThatByte() { CheckEqual((byte)1, ColorSpace.LinearToSrgbByte(0.00030353f)); CheckEqual((byte)128, ColorSpace.LinearToSrgbByte(0.2158605f)); } public void JustBelowTheFirstMidpoint_EncodesToZero() { CheckEqual((byte)0, ColorSpace.LinearToSrgbByte(0.00015f)); CheckEqual((byte)1, ColorSpace.LinearToSrgbByte(0.00016f)); } public void NearBlackSteps_FollowTheLinearSegment() { CheckEqual((byte)1, ColorSpace.LinearToSrgbByte(0.00045f)); CheckEqual((byte)2, ColorSpace.LinearToSrgbByte(0.00046f)); } public void ValuesOnEitherSideOfALookupSliceEdge_EncodeToTheirOwnBytes() { CheckEqual((byte)1, ColorSpace.LinearToSrgbByte(1f / 4096 - 1e-7f)); CheckEqual((byte)1, ColorSpace.LinearToSrgbByte(1f / 4096)); CheckEqual((byte)2, ColorSpace.LinearToSrgbByte(2f / 4096)); } public void NearWhite_EncodesToTheLastBytes() { CheckEqual((byte)254, ColorSpace.LinearToSrgbByte(0.99f)); CheckEqual((byte)255, ColorSpace.LinearToSrgbByte(0.9999f)); } public void InvertsSrgbByteToLinear_ForEveryByte() { for (int value = 0; value < 256; ++value) { CheckEqual((byte)value, ColorSpace.LinearToSrgbByte(ColorSpace.SrgbByteToLinear((byte)value))); } } } } }