// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // namespace ImageSharp.Tests.PixelFormats.PixelBlenders { using System; using System.Collections.Generic; using System.Numerics; using System.Text; using ImageSharp.PixelFormats; using ImageSharp.PixelFormats.PixelBlenders; using ImageSharp.Tests.TestUtilities; using Xunit; public class PorterDuffFunctionsTests_TPixel { private static Span AsSpan(T value) where T : struct { return new Span(new[] { value }); } public static TheoryData NormalBlendFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(0.6f, 0.6f, 0.6f, 1) }, }; [Theory] [MemberData(nameof(NormalBlendFunctionData))] public void NormalBlendFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.NormalBlendFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(NormalBlendFunctionData))] public void NormalBlendFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultNormalPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(NormalBlendFunctionData))] public void NormalBlendFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultNormalPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData MultiplyFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(0.6f, 0.6f, 0.6f, 1) }, { new TestPixel(0.9f,0.9f,0.9f,0.9f), new TestPixel(0.4f,0.4f,0.4f,0.4f), .5f, new TestPixel(0.7834783f, 0.7834783f, 0.7834783f, 0.92f) }, }; [Theory] [MemberData(nameof(MultiplyFunctionData))] public void MultiplyFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.MultiplyFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(MultiplyFunctionData))] public void MultiplyFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultMultiplyPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(MultiplyFunctionData))] public void MultiplyFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultMultiplyPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData AddFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(1f, 1f, 1f, 1f) }, { new TestPixel(0.2f,0.2f,0.2f,0.3f), new TestPixel(0.3f,0.3f,0.3f,0.2f), .5f, new TestPixel(.2431373f, .2431373f, .2431373f, .372549f) }, }; [Theory] [MemberData(nameof(AddFunctionData))] public void AddFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.AddFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(AddFunctionData))] public void AddFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultAddPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(AddFunctionData))] public void AddFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultAddPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData SubstractFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(0,0,0,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(1,1,1, 1f) }, { new TestPixel(0.2f,0.2f,0.2f,0.3f), new TestPixel(0.3f,0.3f,0.3f,0.2f), .5f, new TestPixel(.2027027f, .2027027f, .2027027f, .37f) }, }; [Theory] [MemberData(nameof(SubstractFunctionData))] public void SubstractFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.SubstractFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(SubstractFunctionData))] public void SubstractFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultSubstractPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(SubstractFunctionData))] public void SubstractFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultSubstractPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData ScreenFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(1,1,1, 1f) }, { new TestPixel(0.2f,0.2f,0.2f,0.3f), new TestPixel(0.3f,0.3f,0.3f,0.2f), .5f, new TestPixel(.2383784f, .2383784f, .2383784f, .37f) }, }; [Theory] [MemberData(nameof(ScreenFunctionData))] public void ScreenFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.ScreenFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(ScreenFunctionData))] public void ScreenFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultScreenPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(ScreenFunctionData))] public void ScreenFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultScreenPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData DarkenFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(.6f,.6f,.6f, 1f) }, { new TestPixel(0.2f,0.2f,0.2f,0.3f), new TestPixel(0.3f,0.3f,0.3f,0.2f), .5f, new TestPixel(.2189189f, .2189189f, .2189189f, .37f) }, }; [Theory] [MemberData(nameof(DarkenFunctionData))] public void DarkenFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.DarkenFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(DarkenFunctionData))] public void DarkenFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultDarkenPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(DarkenFunctionData))] public void DarkenFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultDarkenPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData LightenFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(1,1,1,1f) }, { new TestPixel(0.2f,0.2f,0.2f,0.3f), new TestPixel(0.3f,0.3f,0.3f,0.2f), .5f, new TestPixel(.227027f, .227027f, .227027f, .37f) }, }; [Theory] [MemberData(nameof(LightenFunctionData))] public void LightenFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.LightenFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(LightenFunctionData))] public void LightenFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultLightenPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(LightenFunctionData))] public void LightenFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultLightenPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData OverlayFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(1,1,1,1f) }, { new TestPixel(0.2f,0.2f,0.2f,0.3f), new TestPixel(0.3f,0.3f,0.3f,0.2f), .5f, new TestPixel(.2124324f, .2124324f, .2124324f, .37f) }, }; [Theory] [MemberData(nameof(OverlayFunctionData))] public void OverlayFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.OverlayFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(OverlayFunctionData))] public void OverlayFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultOverlayPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(OverlayFunctionData))] public void OverlayFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultOverlayPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } public static TheoryData HardLightFunctionData = new TheoryData() { { new TestPixel(1,1,1,1), new TestPixel(1,1,1,1), 1, new TestPixel(1,1,1,1) }, { new TestPixel(1,1,1,1), new TestPixel(0,0,0,.8f), .5f, new TestPixel(0.6f,0.6f,0.6f,1f) }, { new TestPixel(0.2f,0.2f,0.2f,0.3f), new TestPixel(0.3f,0.3f,0.3f,0.2f), .5f, new TestPixel(.2124324f, .2124324f, .2124324f, .37f) }, }; [Theory] [MemberData(nameof(HardLightFunctionData))] public void HardLightFunction(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = PorterDuffFunctions.HardLightFunction(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(HardLightFunctionData))] public void HardLightFunction_Blender(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { TPixel actual = new DefaultHardLightPixelBlender().Blend(back, source, amount); VectorAssert.Equal(expected, actual, 2); } [Theory] [MemberData(nameof(HardLightFunctionData))] public void HardLightFunction_Blender_Bulk(TestPixel back, TestPixel source, float amount, TestPixel expected) where TPixel : struct, IPixel { Span dest = new Span(new TPixel[1]); new DefaultHardLightPixelBlender().Blend(dest, back.AsSpan(), source.AsSpan(), AsSpan(amount)); VectorAssert.Equal(expected, dest[0], 2); } } }