Browse Source

Flatten pixel blender hierarchy

pull/3161/head
James Jackson-South 3 weeks ago
parent
commit
3c3d523954
  1. 1512
      src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlenders.Generated.cs
  2. 14
      src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlenders.Generated.tt
  3. 216
      src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlenders.cs
  4. 49
      src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlender{TPixel,TOperator}.cs
  5. 1512
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
  6. 14
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt
  7. 5
      src/ImageSharp/PixelFormats/PixelBlenders/IPixelBlenderOperator.cs
  8. 86
      src/ImageSharp/PixelFormats/PixelBlenders/PixelBlender{TPixel,TOperator}.cs
  9. 216
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.PixelBenders.cs
  10. 278
      tests/ImageSharp.Tests/PixelFormats/PixelBlenderTests.cs
  11. 36
      tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTestsTPixel.cs

1512
src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlenders.Generated.cs

File diff suppressed because it is too large

14
src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlenders.Generated.tt

@ -61,6 +61,9 @@ foreach (var composer in composers)
/// </summary> /// </summary>
public readonly struct <#= blenderComposer #> : IPixelBlenderOperator public readonly struct <#= blenderComposer #> : IPixelBlenderOperator
{ {
/// <inheritdoc />
public static bool IsAssociatedAlpha => true;
/// <inheritdoc /> /// <inheritdoc />
public static Vector4 Invoke(Vector4 background, Vector4 source, float amount) public static Vector4 Invoke(Vector4 background, Vector4 source, float amount)
=> AssociatedAlphaPorterDuffFunctions.<#= blenderComposer #>(background, source, amount); => AssociatedAlphaPorterDuffFunctions.<#= blenderComposer #>(background, source, amount);
@ -95,16 +98,9 @@ foreach (var composer in composers)
var blenderComposer = $"{blender}{composer}"; var blenderComposer = $"{blender}{composer}";
#> #>
/// <summary> /// <summary>
/// Blends pixels with the "<#= blenderComposer #>" composition equation. /// Gets the shared blender for the "<#= blenderComposer #>" composition equation.
/// </summary> /// </summary>
public sealed class <#= blenderComposer #> : public static PixelBlender<TPixel> <#= blenderComposer #> => PixelBlender<TPixel, AssociatedAlphaPixelBlenderOperators.<#= blenderComposer #>>.Instance;
AssociatedAlphaPixelBlender<TPixel, AssociatedAlphaPixelBlenderOperators.<#= blenderComposer #>>
{
/// <summary>
/// Gets the shared blender instance.
/// </summary>
public static <#= blenderComposer #> Instance { get; } = new();
}
<# <#
} }

216
src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlenders.cs

@ -21,147 +21,147 @@ internal static partial class AssociatedAlphaPixelBlenders<TPixel>
{ {
PixelAlphaCompositionMode.Src => colorMode switch PixelAlphaCompositionMode.Src => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplySrc.Instance, PixelColorBlendingMode.Multiply => MultiplySrc,
PixelColorBlendingMode.Add => AddSrc.Instance, PixelColorBlendingMode.Add => AddSrc,
PixelColorBlendingMode.Subtract => SubtractSrc.Instance, PixelColorBlendingMode.Subtract => SubtractSrc,
PixelColorBlendingMode.Screen => ScreenSrc.Instance, PixelColorBlendingMode.Screen => ScreenSrc,
PixelColorBlendingMode.Darken => DarkenSrc.Instance, PixelColorBlendingMode.Darken => DarkenSrc,
PixelColorBlendingMode.Lighten => LightenSrc.Instance, PixelColorBlendingMode.Lighten => LightenSrc,
PixelColorBlendingMode.Overlay => OverlaySrc.Instance, PixelColorBlendingMode.Overlay => OverlaySrc,
PixelColorBlendingMode.HardLight => HardLightSrc.Instance, PixelColorBlendingMode.HardLight => HardLightSrc,
_ => NormalSrc.Instance, _ => NormalSrc,
}, },
PixelAlphaCompositionMode.SrcAtop => colorMode switch PixelAlphaCompositionMode.SrcAtop => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplySrcAtop.Instance, PixelColorBlendingMode.Multiply => MultiplySrcAtop,
PixelColorBlendingMode.Add => AddSrcAtop.Instance, PixelColorBlendingMode.Add => AddSrcAtop,
PixelColorBlendingMode.Subtract => SubtractSrcAtop.Instance, PixelColorBlendingMode.Subtract => SubtractSrcAtop,
PixelColorBlendingMode.Screen => ScreenSrcAtop.Instance, PixelColorBlendingMode.Screen => ScreenSrcAtop,
PixelColorBlendingMode.Darken => DarkenSrcAtop.Instance, PixelColorBlendingMode.Darken => DarkenSrcAtop,
PixelColorBlendingMode.Lighten => LightenSrcAtop.Instance, PixelColorBlendingMode.Lighten => LightenSrcAtop,
PixelColorBlendingMode.Overlay => OverlaySrcAtop.Instance, PixelColorBlendingMode.Overlay => OverlaySrcAtop,
PixelColorBlendingMode.HardLight => HardLightSrcAtop.Instance, PixelColorBlendingMode.HardLight => HardLightSrcAtop,
_ => NormalSrcAtop.Instance, _ => NormalSrcAtop,
}, },
PixelAlphaCompositionMode.SrcIn => colorMode switch PixelAlphaCompositionMode.SrcIn => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplySrcIn.Instance, PixelColorBlendingMode.Multiply => MultiplySrcIn,
PixelColorBlendingMode.Add => AddSrcIn.Instance, PixelColorBlendingMode.Add => AddSrcIn,
PixelColorBlendingMode.Subtract => SubtractSrcIn.Instance, PixelColorBlendingMode.Subtract => SubtractSrcIn,
PixelColorBlendingMode.Screen => ScreenSrcIn.Instance, PixelColorBlendingMode.Screen => ScreenSrcIn,
PixelColorBlendingMode.Darken => DarkenSrcIn.Instance, PixelColorBlendingMode.Darken => DarkenSrcIn,
PixelColorBlendingMode.Lighten => LightenSrcIn.Instance, PixelColorBlendingMode.Lighten => LightenSrcIn,
PixelColorBlendingMode.Overlay => OverlaySrcIn.Instance, PixelColorBlendingMode.Overlay => OverlaySrcIn,
PixelColorBlendingMode.HardLight => HardLightSrcIn.Instance, PixelColorBlendingMode.HardLight => HardLightSrcIn,
_ => NormalSrcIn.Instance, _ => NormalSrcIn,
}, },
PixelAlphaCompositionMode.SrcOut => colorMode switch PixelAlphaCompositionMode.SrcOut => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplySrcOut.Instance, PixelColorBlendingMode.Multiply => MultiplySrcOut,
PixelColorBlendingMode.Add => AddSrcOut.Instance, PixelColorBlendingMode.Add => AddSrcOut,
PixelColorBlendingMode.Subtract => SubtractSrcOut.Instance, PixelColorBlendingMode.Subtract => SubtractSrcOut,
PixelColorBlendingMode.Screen => ScreenSrcOut.Instance, PixelColorBlendingMode.Screen => ScreenSrcOut,
PixelColorBlendingMode.Darken => DarkenSrcOut.Instance, PixelColorBlendingMode.Darken => DarkenSrcOut,
PixelColorBlendingMode.Lighten => LightenSrcOut.Instance, PixelColorBlendingMode.Lighten => LightenSrcOut,
PixelColorBlendingMode.Overlay => OverlaySrcOut.Instance, PixelColorBlendingMode.Overlay => OverlaySrcOut,
PixelColorBlendingMode.HardLight => HardLightSrcOut.Instance, PixelColorBlendingMode.HardLight => HardLightSrcOut,
_ => NormalSrcOut.Instance, _ => NormalSrcOut,
}, },
PixelAlphaCompositionMode.Dest => colorMode switch PixelAlphaCompositionMode.Dest => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplyDest.Instance, PixelColorBlendingMode.Multiply => MultiplyDest,
PixelColorBlendingMode.Add => AddDest.Instance, PixelColorBlendingMode.Add => AddDest,
PixelColorBlendingMode.Subtract => SubtractDest.Instance, PixelColorBlendingMode.Subtract => SubtractDest,
PixelColorBlendingMode.Screen => ScreenDest.Instance, PixelColorBlendingMode.Screen => ScreenDest,
PixelColorBlendingMode.Darken => DarkenDest.Instance, PixelColorBlendingMode.Darken => DarkenDest,
PixelColorBlendingMode.Lighten => LightenDest.Instance, PixelColorBlendingMode.Lighten => LightenDest,
PixelColorBlendingMode.Overlay => OverlayDest.Instance, PixelColorBlendingMode.Overlay => OverlayDest,
PixelColorBlendingMode.HardLight => HardLightDest.Instance, PixelColorBlendingMode.HardLight => HardLightDest,
_ => NormalDest.Instance, _ => NormalDest,
}, },
PixelAlphaCompositionMode.DestAtop => colorMode switch PixelAlphaCompositionMode.DestAtop => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplyDestAtop.Instance, PixelColorBlendingMode.Multiply => MultiplyDestAtop,
PixelColorBlendingMode.Add => AddDestAtop.Instance, PixelColorBlendingMode.Add => AddDestAtop,
PixelColorBlendingMode.Subtract => SubtractDestAtop.Instance, PixelColorBlendingMode.Subtract => SubtractDestAtop,
PixelColorBlendingMode.Screen => ScreenDestAtop.Instance, PixelColorBlendingMode.Screen => ScreenDestAtop,
PixelColorBlendingMode.Darken => DarkenDestAtop.Instance, PixelColorBlendingMode.Darken => DarkenDestAtop,
PixelColorBlendingMode.Lighten => LightenDestAtop.Instance, PixelColorBlendingMode.Lighten => LightenDestAtop,
PixelColorBlendingMode.Overlay => OverlayDestAtop.Instance, PixelColorBlendingMode.Overlay => OverlayDestAtop,
PixelColorBlendingMode.HardLight => HardLightDestAtop.Instance, PixelColorBlendingMode.HardLight => HardLightDestAtop,
_ => NormalDestAtop.Instance, _ => NormalDestAtop,
}, },
PixelAlphaCompositionMode.DestOver => colorMode switch PixelAlphaCompositionMode.DestOver => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplyDestOver.Instance, PixelColorBlendingMode.Multiply => MultiplyDestOver,
PixelColorBlendingMode.Add => AddDestOver.Instance, PixelColorBlendingMode.Add => AddDestOver,
PixelColorBlendingMode.Subtract => SubtractDestOver.Instance, PixelColorBlendingMode.Subtract => SubtractDestOver,
PixelColorBlendingMode.Screen => ScreenDestOver.Instance, PixelColorBlendingMode.Screen => ScreenDestOver,
PixelColorBlendingMode.Darken => DarkenDestOver.Instance, PixelColorBlendingMode.Darken => DarkenDestOver,
PixelColorBlendingMode.Lighten => LightenDestOver.Instance, PixelColorBlendingMode.Lighten => LightenDestOver,
PixelColorBlendingMode.Overlay => OverlayDestOver.Instance, PixelColorBlendingMode.Overlay => OverlayDestOver,
PixelColorBlendingMode.HardLight => HardLightDestOver.Instance, PixelColorBlendingMode.HardLight => HardLightDestOver,
_ => NormalDestOver.Instance, _ => NormalDestOver,
}, },
PixelAlphaCompositionMode.DestIn => colorMode switch PixelAlphaCompositionMode.DestIn => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplyDestIn.Instance, PixelColorBlendingMode.Multiply => MultiplyDestIn,
PixelColorBlendingMode.Add => AddDestIn.Instance, PixelColorBlendingMode.Add => AddDestIn,
PixelColorBlendingMode.Subtract => SubtractDestIn.Instance, PixelColorBlendingMode.Subtract => SubtractDestIn,
PixelColorBlendingMode.Screen => ScreenDestIn.Instance, PixelColorBlendingMode.Screen => ScreenDestIn,
PixelColorBlendingMode.Darken => DarkenDestIn.Instance, PixelColorBlendingMode.Darken => DarkenDestIn,
PixelColorBlendingMode.Lighten => LightenDestIn.Instance, PixelColorBlendingMode.Lighten => LightenDestIn,
PixelColorBlendingMode.Overlay => OverlayDestIn.Instance, PixelColorBlendingMode.Overlay => OverlayDestIn,
PixelColorBlendingMode.HardLight => HardLightDestIn.Instance, PixelColorBlendingMode.HardLight => HardLightDestIn,
_ => NormalDestIn.Instance, _ => NormalDestIn,
}, },
PixelAlphaCompositionMode.DestOut => colorMode switch PixelAlphaCompositionMode.DestOut => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplyDestOut.Instance, PixelColorBlendingMode.Multiply => MultiplyDestOut,
PixelColorBlendingMode.Add => AddDestOut.Instance, PixelColorBlendingMode.Add => AddDestOut,
PixelColorBlendingMode.Subtract => SubtractDestOut.Instance, PixelColorBlendingMode.Subtract => SubtractDestOut,
PixelColorBlendingMode.Screen => ScreenDestOut.Instance, PixelColorBlendingMode.Screen => ScreenDestOut,
PixelColorBlendingMode.Darken => DarkenDestOut.Instance, PixelColorBlendingMode.Darken => DarkenDestOut,
PixelColorBlendingMode.Lighten => LightenDestOut.Instance, PixelColorBlendingMode.Lighten => LightenDestOut,
PixelColorBlendingMode.Overlay => OverlayDestOut.Instance, PixelColorBlendingMode.Overlay => OverlayDestOut,
PixelColorBlendingMode.HardLight => HardLightDestOut.Instance, PixelColorBlendingMode.HardLight => HardLightDestOut,
_ => NormalDestOut.Instance, _ => NormalDestOut,
}, },
PixelAlphaCompositionMode.Clear => colorMode switch PixelAlphaCompositionMode.Clear => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplyClear.Instance, PixelColorBlendingMode.Multiply => MultiplyClear,
PixelColorBlendingMode.Add => AddClear.Instance, PixelColorBlendingMode.Add => AddClear,
PixelColorBlendingMode.Subtract => SubtractClear.Instance, PixelColorBlendingMode.Subtract => SubtractClear,
PixelColorBlendingMode.Screen => ScreenClear.Instance, PixelColorBlendingMode.Screen => ScreenClear,
PixelColorBlendingMode.Darken => DarkenClear.Instance, PixelColorBlendingMode.Darken => DarkenClear,
PixelColorBlendingMode.Lighten => LightenClear.Instance, PixelColorBlendingMode.Lighten => LightenClear,
PixelColorBlendingMode.Overlay => OverlayClear.Instance, PixelColorBlendingMode.Overlay => OverlayClear,
PixelColorBlendingMode.HardLight => HardLightClear.Instance, PixelColorBlendingMode.HardLight => HardLightClear,
_ => NormalClear.Instance, _ => NormalClear,
}, },
PixelAlphaCompositionMode.Xor => colorMode switch PixelAlphaCompositionMode.Xor => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplyXor.Instance, PixelColorBlendingMode.Multiply => MultiplyXor,
PixelColorBlendingMode.Add => AddXor.Instance, PixelColorBlendingMode.Add => AddXor,
PixelColorBlendingMode.Subtract => SubtractXor.Instance, PixelColorBlendingMode.Subtract => SubtractXor,
PixelColorBlendingMode.Screen => ScreenXor.Instance, PixelColorBlendingMode.Screen => ScreenXor,
PixelColorBlendingMode.Darken => DarkenXor.Instance, PixelColorBlendingMode.Darken => DarkenXor,
PixelColorBlendingMode.Lighten => LightenXor.Instance, PixelColorBlendingMode.Lighten => LightenXor,
PixelColorBlendingMode.Overlay => OverlayXor.Instance, PixelColorBlendingMode.Overlay => OverlayXor,
PixelColorBlendingMode.HardLight => HardLightXor.Instance, PixelColorBlendingMode.HardLight => HardLightXor,
_ => NormalXor.Instance, _ => NormalXor,
}, },
_ => colorMode switch _ => colorMode switch
{ {
PixelColorBlendingMode.Multiply => MultiplySrcOver.Instance, PixelColorBlendingMode.Multiply => MultiplySrcOver,
PixelColorBlendingMode.Add => AddSrcOver.Instance, PixelColorBlendingMode.Add => AddSrcOver,
PixelColorBlendingMode.Subtract => SubtractSrcOver.Instance, PixelColorBlendingMode.Subtract => SubtractSrcOver,
PixelColorBlendingMode.Screen => ScreenSrcOver.Instance, PixelColorBlendingMode.Screen => ScreenSrcOver,
PixelColorBlendingMode.Darken => DarkenSrcOver.Instance, PixelColorBlendingMode.Darken => DarkenSrcOver,
PixelColorBlendingMode.Lighten => LightenSrcOver.Instance, PixelColorBlendingMode.Lighten => LightenSrcOver,
PixelColorBlendingMode.Overlay => OverlaySrcOver.Instance, PixelColorBlendingMode.Overlay => OverlaySrcOver,
PixelColorBlendingMode.HardLight => HardLightSrcOver.Instance, PixelColorBlendingMode.HardLight => HardLightSrcOver,
_ => NormalSrcOver.Instance, _ => NormalSrcOver,
}, },
}; };
} }

49
src/ImageSharp/PixelFormats/PixelBlenders/AssociatedAlphaPixelBlender{TPixel,TOperator}.cs

@ -1,49 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Numerics;
namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders;
/// <summary>
/// Provides the vector representation used to blend pixels that store associated alpha.
/// </summary>
/// <typeparam name="TPixel">The associated-alpha pixel format.</typeparam>
/// <typeparam name="TOperator">The Porter-Duff equation.</typeparam>
internal abstract class AssociatedAlphaPixelBlender<TPixel, TOperator> : PixelBlender<TPixel, TOperator>
where TPixel : unmanaged, IPixel<TPixel>
where TOperator : struct, IPixelBlenderOperator
{
private static readonly PixelOperations<TPixel> Operations = PixelOperations<TPixel>.Instance;
/// <inheritdoc />
public sealed override TPixel Blend(TPixel background, TPixel source, float amount)
{
// Associated RGB and alpha must remain in their stored representation throughout composition.
Vector4 result = TOperator.Invoke(background.ToAssociatedScaledVector4(), source.ToAssociatedScaledVector4(), Numerics.Clamp(amount, 0, 1F));
return TPixel.FromAssociatedScaledVector4(result);
}
/// <inheritdoc />
protected override void ToBlendVector4<TPixelSource>(
Configuration configuration,
ReadOnlySpan<TPixelSource> source,
Span<Vector4> destination)
{
// Selecting the source representation once per row avoids a format check for every blended pixel.
PixelOperations<TPixelSource>.Instance.ToVector4(configuration, source, destination, PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply);
}
/// <inheritdoc />
protected override Vector4 ToBlendVector4(TPixel source) => source.ToAssociatedScaledVector4();
/// <inheritdoc />
protected override void FromBlendVector4(
Configuration configuration,
Span<Vector4> source,
Span<TPixel> destination)
{
Operations.FromVector4Destructive(configuration, source, destination, PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply);
}
}

1512
src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs

File diff suppressed because it is too large

14
src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt

@ -61,6 +61,9 @@ foreach (var composer in composers)
/// </summary> /// </summary>
public readonly struct <#= blenderComposer #> : IPixelBlenderOperator public readonly struct <#= blenderComposer #> : IPixelBlenderOperator
{ {
/// <inheritdoc />
public static bool IsAssociatedAlpha => false;
/// <inheritdoc /> /// <inheritdoc />
public static Vector4 Invoke(Vector4 background, Vector4 source, float amount) public static Vector4 Invoke(Vector4 background, Vector4 source, float amount)
=> PorterDuffFunctions.<#= blenderComposer #>(background, source, amount); => PorterDuffFunctions.<#= blenderComposer #>(background, source, amount);
@ -95,16 +98,9 @@ foreach (var composer in composers)
var blenderComposer = $"{blender}{composer}"; var blenderComposer = $"{blender}{composer}";
#> #>
/// <summary> /// <summary>
/// Blends pixels with the "<#= blenderComposer #>" composition equation. /// Gets the shared blender for the "<#= blenderComposer #>" composition equation.
/// </summary> /// </summary>
public sealed class <#= blenderComposer #> : public static PixelBlender<TPixel> <#= blenderComposer #> => PixelBlender<TPixel, DefaultPixelBlenderOperators.<#= blenderComposer #>>.Instance;
DefaultPixelBlender<TPixel, DefaultPixelBlenderOperators.<#= blenderComposer #>>
{
/// <summary>
/// Gets the shared blender instance.
/// </summary>
public static <#= blenderComposer #> Instance { get; } = new();
}
<# <#
} }

5
src/ImageSharp/PixelFormats/PixelBlenders/IPixelBlenderOperator.cs

@ -11,6 +11,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders;
/// </summary> /// </summary>
internal interface IPixelBlenderOperator internal interface IPixelBlenderOperator
{ {
/// <summary>
/// Gets a value indicating whether pixel conversion uses associated-alpha vectors.
/// </summary>
public static abstract bool IsAssociatedAlpha { get; }
/// <summary> /// <summary>
/// Blends one pixel represented by four RGBA lanes. /// Blends one pixel represented by four RGBA lanes.
/// </summary> /// </summary>

86
src/ImageSharp/PixelFormats/PixelBlenders/PixelBlender{TPixel,TOperator}.cs

@ -13,10 +13,75 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders;
/// </summary> /// </summary>
/// <typeparam name="TPixel">The destination pixel format.</typeparam> /// <typeparam name="TPixel">The destination pixel format.</typeparam>
/// <typeparam name="TOperator">The Porter-Duff equation.</typeparam> /// <typeparam name="TOperator">The Porter-Duff equation.</typeparam>
internal abstract class PixelBlender<TPixel, TOperator> : PixelBlender<TPixel> internal sealed class PixelBlender<TPixel, TOperator> : PixelBlender<TPixel>
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
where TOperator : struct, IPixelBlenderOperator where TOperator : struct, IPixelBlenderOperator
{ {
/// <summary>
/// Initializes a new instance of the <see cref="PixelBlender{TPixel, TOperator}"/> class.
/// </summary>
private PixelBlender()
{
}
/// <summary>
/// Gets the shared blender instance for this exact pixel and equation combination.
/// </summary>
// Keeping the singleton on the already-required closed blender type preserves per-mode lazy initialization
// without introducing another NativeAOT holder type or eagerly allocating every blender for a pixel format.
public static PixelBlender<TPixel> Instance { get; } = new PixelBlender<TPixel, TOperator>();
/// <inheritdoc />
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
// The operator type uniquely determines the alpha representation. NativeAOT therefore needs only the
// pixel/operator closure, while the JIT can remove this static choice from the generated hot path.
Vector4 backgroundVector = TOperator.IsAssociatedAlpha
? background.ToAssociatedScaledVector4()
: background.ToUnassociatedScaledVector4();
Vector4 sourceVector = TOperator.IsAssociatedAlpha
? source.ToAssociatedScaledVector4()
: source.ToUnassociatedScaledVector4();
Vector4 result = TOperator.Invoke(backgroundVector, sourceVector, Numerics.Clamp(amount, 0, 1F));
return TOperator.IsAssociatedAlpha
? TPixel.FromAssociatedScaledVector4(result)
: TPixel.FromUnassociatedScaledVector4(result);
}
/// <inheritdoc />
protected sealed override void ToBlendVector4<TPixelSource>(
Configuration configuration,
ReadOnlySpan<TPixelSource> source,
Span<Vector4> destination)
{
PixelConversionModifiers modifiers = TOperator.IsAssociatedAlpha
? PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply
: PixelConversionModifiers.Scale | PixelConversionModifiers.UnPremultiply;
PixelOperations<TPixelSource>.Instance.ToVector4(configuration, source, destination, modifiers);
}
/// <inheritdoc />
protected sealed override Vector4 ToBlendVector4(TPixel source)
=> TOperator.IsAssociatedAlpha
? source.ToAssociatedScaledVector4()
: source.ToUnassociatedScaledVector4();
/// <inheritdoc />
protected sealed override void FromBlendVector4(
Configuration configuration,
Span<Vector4> source,
Span<TPixel> destination)
{
PixelConversionModifiers modifiers = TOperator.IsAssociatedAlpha
? PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply
: PixelConversionModifiers.Scale | PixelConversionModifiers.UnPremultiply;
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, source, destination, modifiers);
}
/// <inheritdoc /> /// <inheritdoc />
protected sealed override void BlendFunction(Span<Vector4> destination, ReadOnlySpan<Vector4> background, ReadOnlySpan<Vector4> source, float amount) protected sealed override void BlendFunction(Span<Vector4> destination, ReadOnlySpan<Vector4> background, ReadOnlySpan<Vector4> source, float amount)
{ {
@ -519,22 +584,3 @@ internal abstract class PixelBlender<TPixel, TOperator> : PixelBlender<TPixel>
return Vector512.Min(Vector512.Max(Vector512<float>.Zero, result), Vector512.Create(1F)); return Vector512.Min(Vector512.Max(Vector512<float>.Zero, result), Vector512.Create(1F));
} }
} }
/// <summary>
/// Applies a statically selected Porter-Duff equation to straight-alpha pixels.
/// </summary>
/// <typeparam name="TPixel">The straight-alpha pixel format.</typeparam>
/// <typeparam name="TOperator">The Porter-Duff equation.</typeparam>
internal abstract class DefaultPixelBlender<TPixel, TOperator> : PixelBlender<TPixel, TOperator>
where TPixel : unmanaged, IPixel<TPixel>
where TOperator : struct, IPixelBlenderOperator
{
/// <inheritdoc />
public sealed override TPixel Blend(TPixel background, TPixel source, float amount)
{
// The operator consumes the same unassociated, scaled representation used by the bulk conversion path.
Vector4 result = TOperator.Invoke(background.ToUnassociatedScaledVector4(), source.ToUnassociatedScaledVector4(), Numerics.Clamp(amount, 0, 1F));
return TPixel.FromUnassociatedScaledVector4(result);
}
}

216
src/ImageSharp/PixelFormats/PixelOperations{TPixel}.PixelBenders.cs

@ -34,182 +34,182 @@ public partial class PixelOperations<TPixel>
case PixelAlphaCompositionMode.Clear: case PixelAlphaCompositionMode.Clear:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyClear.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyClear;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddClear.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddClear;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractClear.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractClear;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenClear.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenClear;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenClear.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenClear;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenClear.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenClear;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayClear.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayClear;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightClear.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightClear;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalClear.Instance; default: return DefaultPixelBlenders<TPixel>.NormalClear;
} }
case PixelAlphaCompositionMode.Xor: case PixelAlphaCompositionMode.Xor:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyXor.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyXor;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddXor.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddXor;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractXor.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractXor;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenXor.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenXor;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenXor.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenXor;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenXor.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenXor;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayXor.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayXor;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightXor.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightXor;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalXor.Instance; default: return DefaultPixelBlenders<TPixel>.NormalXor;
} }
case PixelAlphaCompositionMode.Src: case PixelAlphaCompositionMode.Src:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrc.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrc;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrc.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrc;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrc.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrc;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrc.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrc;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrc.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrc;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrc.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrc;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrc.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrc;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrc.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrc;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalSrc.Instance; default: return DefaultPixelBlenders<TPixel>.NormalSrc;
} }
case PixelAlphaCompositionMode.SrcAtop: case PixelAlphaCompositionMode.SrcAtop:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcAtop.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcAtop;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcAtop.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcAtop;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcAtop.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcAtop;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcAtop.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcAtop;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcAtop.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcAtop;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcAtop.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcAtop;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcAtop.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcAtop;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcAtop.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcAtop;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalSrcAtop.Instance; default: return DefaultPixelBlenders<TPixel>.NormalSrcAtop;
} }
case PixelAlphaCompositionMode.SrcIn: case PixelAlphaCompositionMode.SrcIn:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcIn.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcIn;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcIn.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcIn;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcIn.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcIn;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcIn.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcIn;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcIn.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcIn;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcIn.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcIn;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcIn.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcIn;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcIn.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcIn;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalSrcIn.Instance; default: return DefaultPixelBlenders<TPixel>.NormalSrcIn;
} }
case PixelAlphaCompositionMode.SrcOut: case PixelAlphaCompositionMode.SrcOut:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcOut.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcOut;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcOut.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcOut;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcOut.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcOut;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcOut.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcOut;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcOut.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcOut;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcOut.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcOut;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcOut.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcOut;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcOut.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcOut;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalSrcOut.Instance; default: return DefaultPixelBlenders<TPixel>.NormalSrcOut;
} }
case PixelAlphaCompositionMode.Dest: case PixelAlphaCompositionMode.Dest:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDest.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDest;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDest.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDest;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDest.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDest;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDest.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDest;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDest.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDest;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDest.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDest;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDest.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDest;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDest.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDest;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalDest.Instance; default: return DefaultPixelBlenders<TPixel>.NormalDest;
} }
case PixelAlphaCompositionMode.DestAtop: case PixelAlphaCompositionMode.DestAtop:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestAtop.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestAtop;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestAtop.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestAtop;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestAtop.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestAtop;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestAtop.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestAtop;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestAtop.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestAtop;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestAtop.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestAtop;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestAtop.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestAtop;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestAtop.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestAtop;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalDestAtop.Instance; default: return DefaultPixelBlenders<TPixel>.NormalDestAtop;
} }
case PixelAlphaCompositionMode.DestIn: case PixelAlphaCompositionMode.DestIn:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestIn.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestIn;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestIn.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestIn;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestIn.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestIn;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestIn.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestIn;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestIn.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestIn;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestIn.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestIn;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestIn.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestIn;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestIn.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestIn;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalDestIn.Instance; default: return DefaultPixelBlenders<TPixel>.NormalDestIn;
} }
case PixelAlphaCompositionMode.DestOut: case PixelAlphaCompositionMode.DestOut:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestOut.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestOut;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestOut.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestOut;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestOut.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestOut;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestOut.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestOut;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestOut.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestOut;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestOut.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestOut;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestOut.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestOut;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestOut.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestOut;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalDestOut.Instance; default: return DefaultPixelBlenders<TPixel>.NormalDestOut;
} }
case PixelAlphaCompositionMode.DestOver: case PixelAlphaCompositionMode.DestOver:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestOver.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplyDestOver;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestOver.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddDestOver;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestOver.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractDestOver;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestOver.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenDestOver;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestOver.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenDestOver;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestOver.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenDestOver;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestOver.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlayDestOver;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestOver.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightDestOver;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalDestOver.Instance; default: return DefaultPixelBlenders<TPixel>.NormalDestOver;
} }
case PixelAlphaCompositionMode.SrcOver: case PixelAlphaCompositionMode.SrcOver:
default: default:
switch (colorMode) switch (colorMode)
{ {
case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcOver.Instance; case PixelColorBlendingMode.Multiply: return DefaultPixelBlenders<TPixel>.MultiplySrcOver;
case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcOver.Instance; case PixelColorBlendingMode.Add: return DefaultPixelBlenders<TPixel>.AddSrcOver;
case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcOver.Instance; case PixelColorBlendingMode.Subtract: return DefaultPixelBlenders<TPixel>.SubtractSrcOver;
case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcOver.Instance; case PixelColorBlendingMode.Screen: return DefaultPixelBlenders<TPixel>.ScreenSrcOver;
case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcOver.Instance; case PixelColorBlendingMode.Darken: return DefaultPixelBlenders<TPixel>.DarkenSrcOver;
case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcOver.Instance; case PixelColorBlendingMode.Lighten: return DefaultPixelBlenders<TPixel>.LightenSrcOver;
case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcOver.Instance; case PixelColorBlendingMode.Overlay: return DefaultPixelBlenders<TPixel>.OverlaySrcOver;
case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcOver.Instance; case PixelColorBlendingMode.HardLight: return DefaultPixelBlenders<TPixel>.HardLightSrcOver;
case PixelColorBlendingMode.Normal: case PixelColorBlendingMode.Normal:
default: return DefaultPixelBlenders<TPixel>.NormalSrcOver.Instance; default: return DefaultPixelBlenders<TPixel>.NormalSrcOver;
} }
} }
} }

278
tests/ImageSharp.Tests/PixelFormats/PixelBlenderTests.cs

@ -13,24 +13,24 @@ public class PixelBlenderTests
{ {
public static TheoryData<object, Type, PixelColorBlendingMode> BlenderMappings = new() public static TheoryData<object, Type, PixelColorBlendingMode> BlenderMappings = new()
{ {
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.NormalSrcOver), PixelColorBlendingMode.Normal }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.NormalSrcOver.GetType(), PixelColorBlendingMode.Normal },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.ScreenSrcOver), PixelColorBlendingMode.Screen }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.ScreenSrcOver.GetType(), PixelColorBlendingMode.Screen },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.HardLightSrcOver), PixelColorBlendingMode.HardLight }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.HardLightSrcOver.GetType(), PixelColorBlendingMode.HardLight },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.OverlaySrcOver), PixelColorBlendingMode.Overlay }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.OverlaySrcOver.GetType(), PixelColorBlendingMode.Overlay },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DarkenSrcOver), PixelColorBlendingMode.Darken }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.DarkenSrcOver.GetType(), PixelColorBlendingMode.Darken },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.LightenSrcOver), PixelColorBlendingMode.Lighten }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.LightenSrcOver.GetType(), PixelColorBlendingMode.Lighten },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.AddSrcOver), PixelColorBlendingMode.Add }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.AddSrcOver.GetType(), PixelColorBlendingMode.Add },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.SubtractSrcOver), PixelColorBlendingMode.Subtract }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.SubtractSrcOver.GetType(), PixelColorBlendingMode.Subtract },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.MultiplySrcOver), PixelColorBlendingMode.Multiply }, { new TestPixel<Rgba32>(), DefaultPixelBlenders<Rgba32>.MultiplySrcOver.GetType(), PixelColorBlendingMode.Multiply },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.NormalSrcOver), PixelColorBlendingMode.Normal }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.NormalSrcOver.GetType(), PixelColorBlendingMode.Normal },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.ScreenSrcOver), PixelColorBlendingMode.Screen }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.ScreenSrcOver.GetType(), PixelColorBlendingMode.Screen },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.HardLightSrcOver), PixelColorBlendingMode.HardLight }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.HardLightSrcOver.GetType(), PixelColorBlendingMode.HardLight },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.OverlaySrcOver), PixelColorBlendingMode.Overlay }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.OverlaySrcOver.GetType(), PixelColorBlendingMode.Overlay },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DarkenSrcOver), PixelColorBlendingMode.Darken }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.DarkenSrcOver.GetType(), PixelColorBlendingMode.Darken },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.LightenSrcOver), PixelColorBlendingMode.Lighten }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.LightenSrcOver.GetType(), PixelColorBlendingMode.Lighten },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.AddSrcOver), PixelColorBlendingMode.Add }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.AddSrcOver.GetType(), PixelColorBlendingMode.Add },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.SubtractSrcOver), PixelColorBlendingMode.Subtract }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.SubtractSrcOver.GetType(), PixelColorBlendingMode.Subtract },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.MultiplySrcOver), PixelColorBlendingMode.Multiply }, { new TestPixel<RgbaVector>(), DefaultPixelBlenders<RgbaVector>.MultiplySrcOver.GetType(), PixelColorBlendingMode.Multiply },
}; };
public static TheoryData<PixelColorBlendingMode, PixelAlphaCompositionMode, Type> BlenderModeMappings public static TheoryData<PixelColorBlendingMode, PixelAlphaCompositionMode, Type> BlenderModeMappings
@ -42,158 +42,158 @@ public class PixelBlenderTests
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.Clear, PixelAlphaCompositionMode.Clear,
typeof(DefaultPixelBlenders<Rgba32>.NormalClear), DefaultPixelBlenders<Rgba32>.NormalClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplyClear), DefaultPixelBlenders<Rgba32>.MultiplyClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddClear), DefaultPixelBlenders<Rgba32>.AddClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractClear), DefaultPixelBlenders<Rgba32>.SubtractClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenClear), DefaultPixelBlenders<Rgba32>.ScreenClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenClear), DefaultPixelBlenders<Rgba32>.DarkenClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenClear), DefaultPixelBlenders<Rgba32>.LightenClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlayClear), DefaultPixelBlenders<Rgba32>.OverlayClear.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightClear)); DefaultPixelBlenders<Rgba32>.HardLightClear.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.Xor, PixelAlphaCompositionMode.Xor,
typeof(DefaultPixelBlenders<Rgba32>.NormalXor), DefaultPixelBlenders<Rgba32>.NormalXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplyXor), DefaultPixelBlenders<Rgba32>.MultiplyXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddXor), DefaultPixelBlenders<Rgba32>.AddXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractXor), DefaultPixelBlenders<Rgba32>.SubtractXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenXor), DefaultPixelBlenders<Rgba32>.ScreenXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenXor), DefaultPixelBlenders<Rgba32>.DarkenXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenXor), DefaultPixelBlenders<Rgba32>.LightenXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlayXor), DefaultPixelBlenders<Rgba32>.OverlayXor.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightXor)); DefaultPixelBlenders<Rgba32>.HardLightXor.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.Src, PixelAlphaCompositionMode.Src,
typeof(DefaultPixelBlenders<Rgba32>.NormalSrc), DefaultPixelBlenders<Rgba32>.NormalSrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplySrc), DefaultPixelBlenders<Rgba32>.MultiplySrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddSrc), DefaultPixelBlenders<Rgba32>.AddSrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractSrc), DefaultPixelBlenders<Rgba32>.SubtractSrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenSrc), DefaultPixelBlenders<Rgba32>.ScreenSrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenSrc), DefaultPixelBlenders<Rgba32>.DarkenSrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenSrc), DefaultPixelBlenders<Rgba32>.LightenSrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlaySrc), DefaultPixelBlenders<Rgba32>.OverlaySrc.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightSrc)); DefaultPixelBlenders<Rgba32>.HardLightSrc.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.SrcAtop, PixelAlphaCompositionMode.SrcAtop,
typeof(DefaultPixelBlenders<Rgba32>.NormalSrcAtop), DefaultPixelBlenders<Rgba32>.NormalSrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplySrcAtop), DefaultPixelBlenders<Rgba32>.MultiplySrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddSrcAtop), DefaultPixelBlenders<Rgba32>.AddSrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractSrcAtop), DefaultPixelBlenders<Rgba32>.SubtractSrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenSrcAtop), DefaultPixelBlenders<Rgba32>.ScreenSrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenSrcAtop), DefaultPixelBlenders<Rgba32>.DarkenSrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenSrcAtop), DefaultPixelBlenders<Rgba32>.LightenSrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlaySrcAtop), DefaultPixelBlenders<Rgba32>.OverlaySrcAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightSrcAtop)); DefaultPixelBlenders<Rgba32>.HardLightSrcAtop.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.SrcIn, PixelAlphaCompositionMode.SrcIn,
typeof(DefaultPixelBlenders<Rgba32>.NormalSrcIn), DefaultPixelBlenders<Rgba32>.NormalSrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplySrcIn), DefaultPixelBlenders<Rgba32>.MultiplySrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddSrcIn), DefaultPixelBlenders<Rgba32>.AddSrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractSrcIn), DefaultPixelBlenders<Rgba32>.SubtractSrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenSrcIn), DefaultPixelBlenders<Rgba32>.ScreenSrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenSrcIn), DefaultPixelBlenders<Rgba32>.DarkenSrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenSrcIn), DefaultPixelBlenders<Rgba32>.LightenSrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlaySrcIn), DefaultPixelBlenders<Rgba32>.OverlaySrcIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightSrcIn)); DefaultPixelBlenders<Rgba32>.HardLightSrcIn.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.SrcOut, PixelAlphaCompositionMode.SrcOut,
typeof(DefaultPixelBlenders<Rgba32>.NormalSrcOut), DefaultPixelBlenders<Rgba32>.NormalSrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplySrcOut), DefaultPixelBlenders<Rgba32>.MultiplySrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddSrcOut), DefaultPixelBlenders<Rgba32>.AddSrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractSrcOut), DefaultPixelBlenders<Rgba32>.SubtractSrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenSrcOut), DefaultPixelBlenders<Rgba32>.ScreenSrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenSrcOut), DefaultPixelBlenders<Rgba32>.DarkenSrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenSrcOut), DefaultPixelBlenders<Rgba32>.LightenSrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlaySrcOut), DefaultPixelBlenders<Rgba32>.OverlaySrcOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightSrcOut)); DefaultPixelBlenders<Rgba32>.HardLightSrcOut.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.Dest, PixelAlphaCompositionMode.Dest,
typeof(DefaultPixelBlenders<Rgba32>.NormalDest), DefaultPixelBlenders<Rgba32>.NormalDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplyDest), DefaultPixelBlenders<Rgba32>.MultiplyDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddDest), DefaultPixelBlenders<Rgba32>.AddDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractDest), DefaultPixelBlenders<Rgba32>.SubtractDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenDest), DefaultPixelBlenders<Rgba32>.ScreenDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenDest), DefaultPixelBlenders<Rgba32>.DarkenDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenDest), DefaultPixelBlenders<Rgba32>.LightenDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlayDest), DefaultPixelBlenders<Rgba32>.OverlayDest.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightDest)); DefaultPixelBlenders<Rgba32>.HardLightDest.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.DestAtop, PixelAlphaCompositionMode.DestAtop,
typeof(DefaultPixelBlenders<Rgba32>.NormalDestAtop), DefaultPixelBlenders<Rgba32>.NormalDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplyDestAtop), DefaultPixelBlenders<Rgba32>.MultiplyDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddDestAtop), DefaultPixelBlenders<Rgba32>.AddDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractDestAtop), DefaultPixelBlenders<Rgba32>.SubtractDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenDestAtop), DefaultPixelBlenders<Rgba32>.ScreenDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenDestAtop), DefaultPixelBlenders<Rgba32>.DarkenDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenDestAtop), DefaultPixelBlenders<Rgba32>.LightenDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlayDestAtop), DefaultPixelBlenders<Rgba32>.OverlayDestAtop.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightDestAtop)); DefaultPixelBlenders<Rgba32>.HardLightDestAtop.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.DestIn, PixelAlphaCompositionMode.DestIn,
typeof(DefaultPixelBlenders<Rgba32>.NormalDestIn), DefaultPixelBlenders<Rgba32>.NormalDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplyDestIn), DefaultPixelBlenders<Rgba32>.MultiplyDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddDestIn), DefaultPixelBlenders<Rgba32>.AddDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractDestIn), DefaultPixelBlenders<Rgba32>.SubtractDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenDestIn), DefaultPixelBlenders<Rgba32>.ScreenDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenDestIn), DefaultPixelBlenders<Rgba32>.DarkenDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenDestIn), DefaultPixelBlenders<Rgba32>.LightenDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlayDestIn), DefaultPixelBlenders<Rgba32>.OverlayDestIn.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightDestIn)); DefaultPixelBlenders<Rgba32>.HardLightDestIn.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.DestOut, PixelAlphaCompositionMode.DestOut,
typeof(DefaultPixelBlenders<Rgba32>.NormalDestOut), DefaultPixelBlenders<Rgba32>.NormalDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplyDestOut), DefaultPixelBlenders<Rgba32>.MultiplyDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddDestOut), DefaultPixelBlenders<Rgba32>.AddDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractDestOut), DefaultPixelBlenders<Rgba32>.SubtractDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenDestOut), DefaultPixelBlenders<Rgba32>.ScreenDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenDestOut), DefaultPixelBlenders<Rgba32>.DarkenDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenDestOut), DefaultPixelBlenders<Rgba32>.LightenDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlayDestOut), DefaultPixelBlenders<Rgba32>.OverlayDestOut.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightDestOut)); DefaultPixelBlenders<Rgba32>.HardLightDestOut.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.DestOver, PixelAlphaCompositionMode.DestOver,
typeof(DefaultPixelBlenders<Rgba32>.NormalDestOver), DefaultPixelBlenders<Rgba32>.NormalDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplyDestOver), DefaultPixelBlenders<Rgba32>.MultiplyDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddDestOver), DefaultPixelBlenders<Rgba32>.AddDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractDestOver), DefaultPixelBlenders<Rgba32>.SubtractDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenDestOver), DefaultPixelBlenders<Rgba32>.ScreenDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenDestOver), DefaultPixelBlenders<Rgba32>.DarkenDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenDestOver), DefaultPixelBlenders<Rgba32>.LightenDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlayDestOver), DefaultPixelBlenders<Rgba32>.OverlayDestOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightDestOver)); DefaultPixelBlenders<Rgba32>.HardLightDestOver.GetType());
AddBlenderModeMappings( AddBlenderModeMappings(
data, data,
PixelAlphaCompositionMode.SrcOver, PixelAlphaCompositionMode.SrcOver,
typeof(DefaultPixelBlenders<Rgba32>.NormalSrcOver), DefaultPixelBlenders<Rgba32>.NormalSrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.MultiplySrcOver), DefaultPixelBlenders<Rgba32>.MultiplySrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.AddSrcOver), DefaultPixelBlenders<Rgba32>.AddSrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.SubtractSrcOver), DefaultPixelBlenders<Rgba32>.SubtractSrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.ScreenSrcOver), DefaultPixelBlenders<Rgba32>.ScreenSrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.DarkenSrcOver), DefaultPixelBlenders<Rgba32>.DarkenSrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.LightenSrcOver), DefaultPixelBlenders<Rgba32>.LightenSrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.OverlaySrcOver), DefaultPixelBlenders<Rgba32>.OverlaySrcOver.GetType(),
typeof(DefaultPixelBlenders<Rgba32>.HardLightSrcOver)); DefaultPixelBlenders<Rgba32>.HardLightSrcOver.GetType());
return data; return data;
} }
@ -246,7 +246,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void Blend_WithConstantSourceAndSingleAmount() public void Blend_WithConstantSourceAndSingleAmount()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrcOver(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrcOver;
Rgba32[] destination = new Rgba32[2]; Rgba32[] destination = new Rgba32[2];
Rgba32[] background = Rgba32[] background =
[ [
@ -265,7 +265,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void Blend_WithConstantSourceSingleAmountAndWorkingBuffer() public void Blend_WithConstantSourceSingleAmountAndWorkingBuffer()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrcOver(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrcOver;
Rgba32[] destination = new Rgba32[2]; Rgba32[] destination = new Rgba32[2];
Rgba32[] background = Rgba32[] background =
[ [
@ -285,7 +285,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void Blend_WithConstantSourceAndAmountSpan() public void Blend_WithConstantSourceAndAmountSpan()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrcOver(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrcOver;
Rgba32[] destination = new Rgba32[2]; Rgba32[] destination = new Rgba32[2];
Rgba32[] background = Rgba32[] background =
[ [
@ -305,7 +305,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void Blend_WithConstantSourceAmountSpanAndWorkingBuffer() public void Blend_WithConstantSourceAmountSpanAndWorkingBuffer()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrcOver(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrcOver;
Rgba32[] destination = new Rgba32[2]; Rgba32[] destination = new Rgba32[2];
Rgba32[] background = Rgba32[] background =
[ [
@ -326,7 +326,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void Blend_WithSourceSpanAmountSpanAndWorkingBuffer() public void Blend_WithSourceSpanAmountSpanAndWorkingBuffer()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrcOver(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrcOver;
Rgba32[] destination = new Rgba32[2]; Rgba32[] destination = new Rgba32[2];
Rgba32[] background = Rgba32[] background =
[ [
@ -352,7 +352,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithConstantSourceAndSingleAmount() public void BlendWithCoverage_WithConstantSourceAndSingleAmount()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [
@ -374,7 +374,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithConstantSourceSingleAmountAndWorkingBuffer() public void BlendWithCoverage_WithConstantSourceSingleAmountAndWorkingBuffer()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [
@ -397,7 +397,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithSourceSpanAndSingleAmount() public void BlendWithCoverage_WithSourceSpanAndSingleAmount()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [
@ -425,7 +425,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithSourceSpanSingleAmountAndWorkingBuffer() public void BlendWithCoverage_WithSourceSpanSingleAmountAndWorkingBuffer()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [
@ -454,7 +454,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithConstantSourceAndAmountSpan() public void BlendWithCoverage_WithConstantSourceAndAmountSpan()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [
@ -477,7 +477,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithConstantSourceAmountSpanAndWorkingBuffer() public void BlendWithCoverage_WithConstantSourceAmountSpanAndWorkingBuffer()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [
@ -501,7 +501,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithSourceSpanAndAmountSpan() public void BlendWithCoverage_WithSourceSpanAndAmountSpan()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [
@ -530,7 +530,7 @@ public class PixelBlenderTests
[Fact] [Fact]
public void BlendWithCoverage_WithSourceSpanAmountSpanAndWorkingBuffer() public void BlendWithCoverage_WithSourceSpanAmountSpanAndWorkingBuffer()
{ {
PixelBlender<Rgba32> blender = new DefaultPixelBlenders<Rgba32>.NormalSrc(); PixelBlender<Rgba32> blender = DefaultPixelBlenders<Rgba32>.NormalSrc;
Rgba32[] destination = new Rgba32[3]; Rgba32[] destination = new Rgba32[3];
Rgba32[] background = Rgba32[] background =
[ [

36
tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTestsTPixel.cs

@ -46,7 +46,7 @@ public class PorterDuffFunctionsTestsTPixel
public void NormalBlendFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void NormalBlendFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.NormalSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.NormalSrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -56,7 +56,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.NormalSrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.NormalSrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -91,7 +91,7 @@ public class PorterDuffFunctionsTestsTPixel
public void MultiplyFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void MultiplyFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.MultiplySrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.MultiplySrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -101,7 +101,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.MultiplySrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.MultiplySrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -146,7 +146,7 @@ public class PorterDuffFunctionsTestsTPixel
public void AddFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void AddFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.AddSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.AddSrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -156,7 +156,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.AddSrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.AddSrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -191,7 +191,7 @@ public class PorterDuffFunctionsTestsTPixel
public void SubtractFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void SubtractFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.SubtractSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.SubtractSrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -201,7 +201,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.SubtractSrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.SubtractSrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -236,7 +236,7 @@ public class PorterDuffFunctionsTestsTPixel
public void ScreenFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void ScreenFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.ScreenSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.ScreenSrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -246,7 +246,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.ScreenSrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.ScreenSrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -281,7 +281,7 @@ public class PorterDuffFunctionsTestsTPixel
public void DarkenFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void DarkenFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.DarkenSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.DarkenSrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -291,7 +291,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.DarkenSrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.DarkenSrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -326,7 +326,7 @@ public class PorterDuffFunctionsTestsTPixel
public void LightenFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void LightenFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.LightenSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.LightenSrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -336,7 +336,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.LightenSrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.LightenSrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -371,7 +371,7 @@ public class PorterDuffFunctionsTestsTPixel
public void OverlayFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void OverlayFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.OverlaySrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.OverlaySrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -381,7 +381,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.OverlaySrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.OverlaySrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)
@ -416,7 +416,7 @@ public class PorterDuffFunctionsTestsTPixel
public void HardLightFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected) public void HardLightFunctionBlender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel actual = new DefaultPixelBlenders<TPixel>.HardLightSrcOver().Blend(back.AsPixel(), source.AsPixel(), amount); TPixel actual = DefaultPixelBlenders<TPixel>.HardLightSrcOver.Blend(back.AsPixel(), source.AsPixel(), amount);
VectorAssert.Equal(expected.AsPixel(), actual, 2); VectorAssert.Equal(expected.AsPixel(), actual, 2);
} }
@ -426,7 +426,7 @@ public class PorterDuffFunctionsTestsTPixel
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
TPixel[] dest = new TPixel[BulkBlendCount]; TPixel[] dest = new TPixel[BulkBlendCount];
new DefaultPixelBlenders<TPixel>.HardLightSrcOver().Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount)); DefaultPixelBlenders<TPixel>.HardLightSrcOver.Blend(this.Configuration, dest, CreateFilledArray(back.AsPixel()), CreateFilledArray(source.AsPixel()), CreateFilledArray(amount));
TPixel expectedPixel = expected.AsPixel(); TPixel expectedPixel = expected.AsPixel();
foreach (TPixel pixel in dest) foreach (TPixel pixel in dest)

Loading…
Cancel
Save