diff --git a/src/ImageSharp/Processing/Processors/Effects/IPixelRowDelegate.cs b/src/ImageSharp/Processing/Processors/Effects/IPixelRowDelegate.cs new file mode 100644 index 0000000000..626ffd7168 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/Effects/IPixelRowDelegate.cs @@ -0,0 +1,21 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; + +namespace SixLabors.ImageSharp.Processing.Processors.Effects +{ + /// + /// An used by the row delegates for a given instance + /// + public interface IPixelRowDelegate + { + /// + /// Applies the current pixel row delegate to a target row of preprocessed pixels. + /// + /// The target row of pixels to process. + /// The initial horizontal and vertical offset for the input pixels to process. + void Invoke(Span span, Point offset); + } +} diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor.cs index 5bdc0bc80b..9563f87187 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor.cs @@ -1,6 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; +using System.Numerics; +using System.Runtime.CompilerServices; using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Processing.Processors.Effects @@ -34,6 +37,31 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle) where TPixel : struct, IPixel - => new PixelRowDelegateProcessor(configuration, this, source, sourceRectangle); + { + return new PixelRowDelegateProcessor( + new PixelRowDelegate(this.PixelRowOperation), + configuration, + this.Modifiers, + source, + sourceRectangle); + } + + /// + /// A implementing the row processing logic for . + /// + public readonly struct PixelRowDelegate : IPixelRowDelegate + { + private readonly PixelRowOperation pixelRowOperation; + + [MethodImpl(InliningOptions.ShortMethod)] + public PixelRowDelegate(PixelRowOperation pixelRowOperation) + { + this.pixelRowOperation = pixelRowOperation; + } + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void Invoke(Span span, Point offset) => this.pixelRowOperation(span); + } } } diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessorBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel,TDelegate}.cs similarity index 75% rename from src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessorBase{TPixel}.cs rename to src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel,TDelegate}.cs index 16d8c0ed43..eea52dd71b 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessorBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel,TDelegate}.cs @@ -14,24 +14,37 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// The base class for all processors that accept a user defined row processing delegate. /// /// The pixel format. - internal abstract class PixelRowDelegateProcessorBase : ImageProcessor + /// The row processor type. + internal sealed class PixelRowDelegateProcessor : ImageProcessor where TPixel : struct, IPixel + where TDelegate : struct, IPixelRowDelegate { + private readonly TDelegate rowDelegate; + /// /// The to apply during the pixel conversions. /// private readonly PixelConversionModifiers modifiers; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// + /// The row processor to use to process each pixel row /// The configuration which allows altering default behaviour or extending the library. /// The to apply during the pixel conversions. /// The source for the current processor instance. /// The source area to process for the current processor instance. - protected PixelRowDelegateProcessorBase(Configuration configuration, PixelConversionModifiers modifiers, Image source, Rectangle sourceRectangle) + public PixelRowDelegateProcessor( + in TDelegate rowDelegate, + Configuration configuration, + PixelConversionModifiers modifiers, + Image source, + Rectangle sourceRectangle) : base(configuration, source, sourceRectangle) - => this.modifiers = modifiers; + { + this.rowDelegate = rowDelegate; + this.modifiers = modifiers; + } /// protected override void OnFrameApply(ImageFrame source) @@ -41,18 +54,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects ParallelRowIterator.IterateRows( interest, this.Configuration, - new RowIntervalAction(interest.X, source, this.Configuration, this.modifiers, this)); + new RowIntervalAction(interest.X, source, this.Configuration, this.modifiers, this.rowDelegate)); } /// - /// Applies the current pixel row delegate to a target row of preprocessed pixels. - /// - /// The target row of pixels to process. - /// The initial horizontal and vertical offset for the input pixels to process. - protected abstract void ApplyPixelRowDelegate(Span span, Point offset); - - /// - /// A implementing the convolution logic for . + /// A implementing the convolution logic for . /// private readonly struct RowIntervalAction : IRowIntervalAction { @@ -60,7 +66,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects private readonly ImageFrame source; private readonly Configuration configuration; private readonly PixelConversionModifiers modifiers; - private readonly PixelRowDelegateProcessorBase processor; + private readonly TDelegate rowProcessor; [MethodImpl(InliningOptions.ShortMethod)] public RowIntervalAction( @@ -68,13 +74,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects ImageFrame source, Configuration configuration, PixelConversionModifiers modifiers, - PixelRowDelegateProcessorBase processor) + in TDelegate rowProcessor) { this.startX = startX; this.source = source; this.configuration = configuration; this.modifiers = modifiers; - this.processor = processor; + this.rowProcessor = rowProcessor; } /// @@ -89,7 +95,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects PixelOperations.Instance.ToVector4(this.configuration, rowSpan, vectorSpan, this.modifiers); // Run the user defined pixel shader to the current row of pixels - this.processor.ApplyPixelRowDelegate(vectorSpan, new Point(this.startX, y)); + this.rowProcessor.Invoke(vectorSpan, new Point(this.startX, y)); PixelOperations.Instance.FromVector4Destructive(this.configuration, vectorSpan, rowSpan, this.modifiers); } diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel}.cs deleted file mode 100644 index da917eaf39..0000000000 --- a/src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel}.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Numerics; - -using SixLabors.ImageSharp.PixelFormats; - -namespace SixLabors.ImageSharp.Processing.Processors.Effects -{ - /// - /// Applies a user defined row processing delegate to the image. - /// - /// The pixel format. - internal sealed class PixelRowDelegateProcessor : PixelRowDelegateProcessorBase - where TPixel : struct, IPixel - { - /// - /// The user defined pixel row processing delegate. - /// - private readonly PixelRowOperation pixelRowOperation; - - /// - /// Initializes a new instance of the class. - /// - /// The configuration which allows altering default behaviour or extending the library. - /// The defining the processor parameters. - /// The source for the current processor instance. - /// The source area to process for the current processor instance. - public PixelRowDelegateProcessor(Configuration configuration, PixelRowDelegateProcessor definition, Image source, Rectangle sourceRectangle) - : base(configuration, definition.Modifiers, source, sourceRectangle) - { - this.pixelRowOperation = definition.PixelRowOperation; - } - - /// - protected override void ApplyPixelRowDelegate(Span span, Point offset) => this.pixelRowOperation(span); - } -} diff --git a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelRowDelegateProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelRowDelegateProcessor.cs index bf21f5b9b1..362b158101 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelRowDelegateProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelRowDelegateProcessor.cs @@ -1,6 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; +using System.Numerics; +using System.Runtime.CompilerServices; using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Processing.Processors.Effects @@ -34,6 +37,31 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle) where TPixel : struct, IPixel - => new PositionAwarePixelRowDelegateProcessor(configuration, this, source, sourceRectangle); + { + return new PixelRowDelegateProcessor( + new PixelRowDelegate(this.PixelRowOperation), + configuration, + this.Modifiers, + source, + sourceRectangle); + } + + /// + /// A implementing the row processing logic for . + /// + public readonly struct PixelRowDelegate : IPixelRowDelegate + { + private readonly PixelRowOperation pixelRowOperation; + + [MethodImpl(InliningOptions.ShortMethod)] + public PixelRowDelegate(PixelRowOperation pixelRowOperation) + { + this.pixelRowOperation = pixelRowOperation; + } + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void Invoke(Span span, Point offset) => this.pixelRowOperation(span, offset); + } } } diff --git a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelRowDelegateProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelRowDelegateProcessor{TPixel}.cs deleted file mode 100644 index 901a3a9856..0000000000 --- a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelRowDelegateProcessor{TPixel}.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.Numerics; - -using SixLabors.ImageSharp.PixelFormats; - -namespace SixLabors.ImageSharp.Processing.Processors.Effects -{ - /// - /// Applies a user defined, position aware, row processing delegate to the image. - /// - /// The pixel format. - internal sealed class PositionAwarePixelRowDelegateProcessor : PixelRowDelegateProcessorBase - where TPixel : struct, IPixel - { - private readonly PixelRowOperation pixelRowOperation; - - /// - /// Initializes a new instance of the class. - /// - /// The configuration which allows altering default behaviour or extending the library. - /// The defining the processor parameters. - /// The source for the current processor instance. - /// The source area to process for the current processor instance. - public PositionAwarePixelRowDelegateProcessor(Configuration configuration, PositionAwarePixelRowDelegateProcessor definition, Image source, Rectangle sourceRectangle) - : base(configuration, definition.Modifiers, source, sourceRectangle) - { - this.pixelRowOperation = definition.PixelRowOperation; - } - - /// - protected override void ApplyPixelRowDelegate(Span span, Point offset) => this.pixelRowOperation(span, offset); - } -}