From 9d46c158923f8cf89f767db5939ac04552e37e4c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 13:46:19 +0100 Subject: [PATCH 01/18] Added initial version of the pixel shader delegate and processors --- .../Processing/Delegates/PixelShader.cs | 12 ++++ .../DelegatePixelShaderProcessor.cs | 38 +++++++++++ .../DelegatePixelShaderProcessor{TPixel}.cs | 66 +++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 src/ImageSharp/Processing/Delegates/PixelShader.cs create mode 100644 src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs create mode 100644 src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs diff --git a/src/ImageSharp/Processing/Delegates/PixelShader.cs b/src/ImageSharp/Processing/Delegates/PixelShader.cs new file mode 100644 index 0000000000..fd051c0e6a --- /dev/null +++ b/src/ImageSharp/Processing/Delegates/PixelShader.cs @@ -0,0 +1,12 @@ +using System; +using System.Numerics; + +namespace SixLabors.ImageSharp.Processing.Delegates +{ + /// + /// A representing a user defined pixel shader. + /// + /// The target row of pixels to process. + /// The , , , and fields map the RGBA channels respectively. + public delegate void PixelShader(Span span); +} diff --git a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs new file mode 100644 index 0000000000..13ac957ec2 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs @@ -0,0 +1,38 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Delegates; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors +{ + /// + /// Applies a user defined pixel shader effect through a given delegate. + /// + public sealed class DelegatePixelShaderProcessor : IImageProcessor + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The user defined pixel shader to use to modify images. + /// + public DelegatePixelShaderProcessor(PixelShader pixelShader) + { + this.PixelShader = pixelShader; + } + + /// + /// Gets the user defined pixel shader. + /// + public PixelShader PixelShader { get; } + + /// + public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle) + where TPixel : struct, IPixel + { + return new DelegatePixelShaderProcessor(this, source, sourceRectangle); + } + } +} diff --git a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs new file mode 100644 index 0000000000..e6119f2c85 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs @@ -0,0 +1,66 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; + +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Advanced.ParallelUtils; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Delegates; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors +{ + /// + /// Performs simple binary threshold filtering against an image. + /// + /// The pixel format. + internal class DelegatePixelShaderProcessor : ImageProcessor + where TPixel : struct, IPixel + { + /// + /// The user defined pixel shader. + /// + private readonly PixelShader pixelShader; + + /// + /// Initializes a new instance of the class. + /// + /// The defining the processor parameters. + /// The source for the current processor instance. + /// The source area to process for the current processor instance. + public DelegatePixelShaderProcessor(DelegatePixelShaderProcessor definition, Image source, Rectangle sourceRectangle) + : base(source, sourceRectangle) + { + this.pixelShader = definition.PixelShader; + } + + /// + protected override void OnFrameApply(ImageFrame source) + { + var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); + int startX = interest.X; + PixelShader pixelShader = this.pixelShader; + + ParallelHelper.IterateRowsWithTempBuffer( + interest, + this.Configuration, + (rows, vectorBuffer) => + { + for (int y = rows.Min; y < rows.Max; y++) + { + Span vectorSpan = vectorBuffer.Span; + int length = vectorSpan.Length; + Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); + PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan); + + // Run the user defined pixel shader on the current row of pixels + pixelShader(vectorSpan); + + PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan); + } + }); + } + } +} From 9e03619e2dc4b52cc040aa25fbc67e98a1f01a35 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 13:49:15 +0100 Subject: [PATCH 02/18] Added PixelShaderExtensions class --- .../Extensions/PixelShaderExtensions.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs new file mode 100644 index 0000000000..96783ba6ee --- /dev/null +++ b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs @@ -0,0 +1,36 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.Processing.Delegates; +using SixLabors.ImageSharp.Processing.Processors; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing +{ + /// + /// Defines extension methods that allow the application of user defined pixel shaders to an . + /// + public static class PixelShaderExtensions + { + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// The to allow chaining of operations. + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader) + => source.ApplyProcessor(new DelegatePixelShaderProcessor(pixelShader)); + + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The to allow chaining of operations. + public static IImageProcessingContext BlackWhite(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle) + => source.ApplyProcessor(new DelegatePixelShaderProcessor(pixelShader), rectangle); + } +} From bde0790eab04bc90479f39489be34d0d23a9126f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 14:16:34 +0100 Subject: [PATCH 03/18] Minor code refactoring --- src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs | 1 + .../{ => PixelShading}/DelegatePixelShaderProcessor.cs | 2 +- .../{ => PixelShading}/DelegatePixelShaderProcessor{TPixel}.cs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) rename src/ImageSharp/Processing/Processors/{ => PixelShading}/DelegatePixelShaderProcessor.cs (95%) rename src/ImageSharp/Processing/Processors/{ => PixelShading}/DelegatePixelShaderProcessor{TPixel}.cs (97%) diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs index 96783ba6ee..bad705a4d8 100644 --- a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs @@ -3,6 +3,7 @@ using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.ImageSharp.Processing.Processors; +using SixLabors.ImageSharp.Processing.Processors.PixelShading; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing diff --git a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor.cs similarity index 95% rename from src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs rename to src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor.cs index 13ac957ec2..b09385ff3a 100644 --- a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor.cs @@ -5,7 +5,7 @@ using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.Primitives; -namespace SixLabors.ImageSharp.Processing.Processors +namespace SixLabors.ImageSharp.Processing.Processors.PixelShading { /// /// Applies a user defined pixel shader effect through a given delegate. diff --git a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs similarity index 97% rename from src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs rename to src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs index e6119f2c85..c773e8b808 100644 --- a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs @@ -10,7 +10,7 @@ using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.Primitives; -namespace SixLabors.ImageSharp.Processing.Processors +namespace SixLabors.ImageSharp.Processing.Processors.PixelShading { /// /// Performs simple binary threshold filtering against an image. From 4a193aa5ea2e0ca3fe19ca43218f2831864a817d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 14:20:23 +0100 Subject: [PATCH 04/18] Added PositionAwarePixelShader types --- .../Delegates/PositionAwarePixelShader.cs | 14 ++++ .../DelegatePixelShaderProcessor{TPixel}.cs | 2 +- .../PositionAwarePixelShaderProcessor.cs | 38 +++++++++++ ...sitionAwarePixelShaderProcessor{TPixel}.cs | 65 +++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs create mode 100644 src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs create mode 100644 src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs diff --git a/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs b/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs new file mode 100644 index 0000000000..08314600a2 --- /dev/null +++ b/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs @@ -0,0 +1,14 @@ +using System; +using System.Numerics; + +namespace SixLabors.ImageSharp.Processing.Delegates +{ + /// + /// A representing a user defined pixel shader. + /// + /// The target row of pixels to process. + /// The initial vertical offset for the input pixels to process. + /// The initial horizontal offset for the input pixels to process. + /// The , , , and fields map the RGBA channels respectively. + public delegate void PositionAwarePixelShader(Span span, int offsetY, int offsetX); +} diff --git a/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs index c773e8b808..d15614cc4c 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs @@ -13,7 +13,7 @@ using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.PixelShading { /// - /// Performs simple binary threshold filtering against an image. + /// Applies a user defined pixel shader effect through a given delegate. /// /// The pixel format. internal class DelegatePixelShaderProcessor : ImageProcessor diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs new file mode 100644 index 0000000000..60125b2e27 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs @@ -0,0 +1,38 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Delegates; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors.PixelShading +{ + /// + /// Applies a user defined pixel shader effect through a given delegate. + /// + public sealed class PositionAwarePixelShaderProcessor : IImageProcessor + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The user defined pixel shader to use to modify images. + /// + public PositionAwarePixelShaderProcessor(PositionAwarePixelShader pixelShader) + { + this.PixelShader = pixelShader; + } + + /// + /// Gets the user defined pixel shader. + /// + public PositionAwarePixelShader PixelShader { get; } + + /// + public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle) + where TPixel : struct, IPixel + { + return new PositionAwarePixelShader(this, source, sourceRectangle); + } + } +} diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs new file mode 100644 index 0000000000..55ad325ad7 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs @@ -0,0 +1,65 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; + +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Advanced.ParallelUtils; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Delegates; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors.PixelShading +{ + /// + /// Applies a user defined pixel shader effect through a given delegate. + /// + /// The pixel format. + internal class PositionAwarePixelShaderProcessor : ImageProcessor + where TPixel : struct, IPixel + { + /// + /// The user defined pixel shader. + /// + private readonly PositionAwarePixelShader pixelShader; + + /// + /// Initializes a new instance of the class. + /// + /// The defining the processor parameters. + /// The source for the current processor instance. + /// The source area to process for the current processor instance. + public PositionAwarePixelShaderProcessor(PositionAwarePixelShaderProcessor definition, Image source, Rectangle sourceRectangle) + : base(source, sourceRectangle) + { + this.pixelShader = definition.PixelShader; + } + + /// + protected override void OnFrameApply(ImageFrame source) + { + var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); + int startX = interest.X; + PositionAwarePixelShader pixelShader = this.pixelShader; + + ParallelHelper.IterateRowsWithTempBuffer( + interest, + this.Configuration, + (rows, vectorBuffer) => + { + for (int y = rows.Min; y < rows.Max; y++) + { + Span vectorSpan = vectorBuffer.Span; + int length = vectorSpan.Length; + Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); + PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan); + + pixelShader(vectorSpan, y, startX); + + PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan); + } + }); + } + } +} From 21729331f22fd0dd4688243939be2773c426283d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 14:21:11 +0100 Subject: [PATCH 05/18] Minor code refactoring --- .../Processing/Extensions/PixelShaderExtensions.cs | 5 ++--- ...atePixelShaderProcessor.cs => PixelShaderProcessor.cs} | 8 ++++---- ...ocessor{TPixel}.cs => PixelShaderProcessor{TPixel}.cs} | 8 ++++---- 3 files changed, 10 insertions(+), 11 deletions(-) rename src/ImageSharp/Processing/Processors/PixelShading/{DelegatePixelShaderProcessor.cs => PixelShaderProcessor.cs} (75%) rename src/ImageSharp/Processing/Processors/PixelShading/{DelegatePixelShaderProcessor{TPixel}.cs => PixelShaderProcessor{TPixel}.cs} (84%) diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs index bad705a4d8..26b6de3db1 100644 --- a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.Processing.Delegates; -using SixLabors.ImageSharp.Processing.Processors; using SixLabors.ImageSharp.Processing.Processors.PixelShading; using SixLabors.Primitives; @@ -20,7 +19,7 @@ namespace SixLabors.ImageSharp.Processing /// The user defined pixel shader to use to modify images. /// The to allow chaining of operations. public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader) - => source.ApplyProcessor(new DelegatePixelShaderProcessor(pixelShader)); + => source.ApplyProcessor(new PixelShaderProcessor(pixelShader)); /// /// Applies a user defined pixel shader to the image. @@ -32,6 +31,6 @@ namespace SixLabors.ImageSharp.Processing /// /// The to allow chaining of operations. public static IImageProcessingContext BlackWhite(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle) - => source.ApplyProcessor(new DelegatePixelShaderProcessor(pixelShader), rectangle); + => source.ApplyProcessor(new PixelShaderProcessor(pixelShader), rectangle); } } diff --git a/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs similarity index 75% rename from src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor.cs rename to src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs index b09385ff3a..30ba4222ea 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs @@ -10,15 +10,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading /// /// Applies a user defined pixel shader effect through a given delegate. /// - public sealed class DelegatePixelShaderProcessor : IImageProcessor + public sealed class PixelShaderProcessor : IImageProcessor { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The user defined pixel shader to use to modify images. /// - public DelegatePixelShaderProcessor(PixelShader pixelShader) + public PixelShaderProcessor(PixelShader pixelShader) { this.PixelShader = pixelShader; } @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle) where TPixel : struct, IPixel { - return new DelegatePixelShaderProcessor(this, source, sourceRectangle); + return new PixelShaderProcessor(this, source, sourceRectangle); } } } diff --git a/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs similarity index 84% rename from src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs rename to src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs index d15614cc4c..b856355aed 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/DelegatePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading /// Applies a user defined pixel shader effect through a given delegate. /// /// The pixel format. - internal class DelegatePixelShaderProcessor : ImageProcessor + internal class PixelShaderProcessor : ImageProcessor where TPixel : struct, IPixel { /// @@ -25,12 +25,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading private readonly PixelShader pixelShader; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The defining the processor parameters. + /// The defining the processor parameters. /// The source for the current processor instance. /// The source area to process for the current processor instance. - public DelegatePixelShaderProcessor(DelegatePixelShaderProcessor definition, Image source, Rectangle sourceRectangle) + public PixelShaderProcessor(PixelShaderProcessor definition, Image source, Rectangle sourceRectangle) : base(source, sourceRectangle) { this.pixelShader = definition.PixelShader; From 429d9a540669e2008b9af462bdadfd06a3aa9a75 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 14:21:50 +0100 Subject: [PATCH 06/18] Added new pixel shader extension methods --- .../Extensions/PixelShaderExtensions.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs index 26b6de3db1..51d37caad4 100644 --- a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs @@ -30,7 +30,28 @@ namespace SixLabors.ImageSharp.Processing /// The structure that specifies the portion of the image object to alter. /// /// The to allow chaining of operations. - public static IImageProcessingContext BlackWhite(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle) + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle) => source.ApplyProcessor(new PixelShaderProcessor(pixelShader), rectangle); + + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// The to allow chaining of operations. + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader) + => source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader)); + + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The to allow chaining of operations. + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader, Rectangle rectangle) + => source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader), rectangle); } } From d91694d9ff695c553592252b70173bb1590348f8 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 14:38:55 +0100 Subject: [PATCH 07/18] Minor code refactoring --- .../Abstract/PixelShaderProcessorBase.cs | 64 +++++++++++++++++++ .../PixelShaderProcessor{TPixel}.cs | 31 +-------- ...sitionAwarePixelShaderProcessor{TPixel}.cs | 30 +-------- 3 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs diff --git a/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs b/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs new file mode 100644 index 0000000000..4d2cb233b0 --- /dev/null +++ b/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs @@ -0,0 +1,64 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; + +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Advanced.ParallelUtils; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.Primitives; + +namespace SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract +{ + /// + /// Applies a user defined pixel shader effect through a given delegate. + /// + /// The pixel format. + internal abstract class PixelShaderProcessorBase : ImageProcessor + where TPixel : struct, IPixel + { + /// + /// Initializes a new instance of the class. + /// + /// The source for the current processor instance. + /// The source area to process for the current processor instance. + protected PixelShaderProcessorBase(Image source, Rectangle sourceRectangle) + : base(source, sourceRectangle) + { } + + /// + protected override void OnFrameApply(ImageFrame source) + { + var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); + int startX = interest.X; + + ParallelHelper.IterateRowsWithTempBuffer( + interest, + this.Configuration, + (rows, vectorBuffer) => + { + for (int y = rows.Min; y < rows.Max; y++) + { + Span vectorSpan = vectorBuffer.Span; + int length = vectorSpan.Length; + Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); + PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan); + + // Run the user defined pixel shader on the current row of pixels + this.ApplyPixelShader(vectorSpan, y, startX); + + PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan); + } + }); + } + + /// + /// Applies the current pixel shader effect on a target row of preprocessed pixels. + /// + /// The target row of pixels to process. + /// The initial vertical offset for the input pixels to process. + /// The initial horizontal offset for the input pixels to process. + protected abstract void ApplyPixelShader(Span span, int offsetY, int offsetX); + } +} diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs index b856355aed..70728a4ecb 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs @@ -4,10 +4,9 @@ using System; using System.Numerics; -using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.Advanced.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Delegates; +using SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.PixelShading @@ -16,7 +15,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading /// Applies a user defined pixel shader effect through a given delegate. /// /// The pixel format. - internal class PixelShaderProcessor : ImageProcessor + internal class PixelShaderProcessor : PixelShaderProcessorBase where TPixel : struct, IPixel { /// @@ -37,30 +36,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading } /// - protected override void OnFrameApply(ImageFrame source) - { - var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); - int startX = interest.X; - PixelShader pixelShader = this.pixelShader; - - ParallelHelper.IterateRowsWithTempBuffer( - interest, - this.Configuration, - (rows, vectorBuffer) => - { - for (int y = rows.Min; y < rows.Max; y++) - { - Span vectorSpan = vectorBuffer.Span; - int length = vectorSpan.Length; - Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); - PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan); - - // Run the user defined pixel shader on the current row of pixels - pixelShader(vectorSpan); - - PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan); - } - }); - } + protected override void ApplyPixelShader(Span span, int offsetY, int offsetX) => this.pixelShader(span); } } diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs index 55ad325ad7..7c5eff5979 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs @@ -4,10 +4,9 @@ using System; using System.Numerics; -using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.Advanced.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Delegates; +using SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.PixelShading @@ -16,7 +15,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading /// Applies a user defined pixel shader effect through a given delegate. /// /// The pixel format. - internal class PositionAwarePixelShaderProcessor : ImageProcessor + internal class PositionAwarePixelShaderProcessor : PixelShaderProcessorBase where TPixel : struct, IPixel { /// @@ -37,29 +36,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading } /// - protected override void OnFrameApply(ImageFrame source) - { - var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); - int startX = interest.X; - PositionAwarePixelShader pixelShader = this.pixelShader; - - ParallelHelper.IterateRowsWithTempBuffer( - interest, - this.Configuration, - (rows, vectorBuffer) => - { - for (int y = rows.Min; y < rows.Max; y++) - { - Span vectorSpan = vectorBuffer.Span; - int length = vectorSpan.Length; - Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); - PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan); - - pixelShader(vectorSpan, y, startX); - - PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan); - } - }); - } + protected override void ApplyPixelShader(Span span, int offsetY, int offsetX) => this.pixelShader(span, offsetY, offsetX); } } From 8c2662448769e75770297c831b09141146421eb7 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 18:19:16 +0100 Subject: [PATCH 08/18] Fixed a typo --- .../PixelShading/PositionAwarePixelShaderProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs index 60125b2e27..a1fdc60821 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle) where TPixel : struct, IPixel { - return new PositionAwarePixelShader(this, source, sourceRectangle); + return new PositionAwarePixelShaderProcessor(this, source, sourceRectangle); } } } From ca3c284e6aa8deca4e2d380b72d225a64c81923c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 20 Dec 2019 19:04:31 +0100 Subject: [PATCH 09/18] Made StyleCode happy --- src/ImageSharp/Processing/Delegates/PixelShader.cs | 3 +++ .../Processing/Delegates/PositionAwarePixelShader.cs | 3 +++ .../PixelShading/Abstract/PixelShaderProcessorBase.cs | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Processing/Delegates/PixelShader.cs b/src/ImageSharp/Processing/Delegates/PixelShader.cs index fd051c0e6a..72895f14b0 100644 --- a/src/ImageSharp/Processing/Delegates/PixelShader.cs +++ b/src/ImageSharp/Processing/Delegates/PixelShader.cs @@ -1,3 +1,6 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + using System; using System.Numerics; diff --git a/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs b/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs index 08314600a2..8455b9b058 100644 --- a/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs +++ b/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs @@ -1,3 +1,6 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + using System; using System.Numerics; diff --git a/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs b/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs index 4d2cb233b0..1af50197aa 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs @@ -25,7 +25,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract /// The source area to process for the current processor instance. protected PixelShaderProcessorBase(Image source, Rectangle sourceRectangle) : base(source, sourceRectangle) - { } + { + } /// protected override void OnFrameApply(ImageFrame source) From 62272a32831f4d67df876a74e6351e076863a4aa Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 26 Dec 2019 11:17:12 +0100 Subject: [PATCH 10/18] Moved delegate types --- src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs | 1 - src/ImageSharp/Processing/{Delegates => }/PixelShader.cs | 2 +- .../Processing/{Delegates => }/PositionAwarePixelShader.cs | 2 +- .../Processing/Processors/PixelShading/PixelShaderProcessor.cs | 1 - .../Processors/PixelShading/PixelShaderProcessor{TPixel}.cs | 1 - .../PixelShading/PositionAwarePixelShaderProcessor.cs | 1 - .../PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs | 1 - 7 files changed, 2 insertions(+), 7 deletions(-) rename src/ImageSharp/Processing/{Delegates => }/PixelShader.cs (91%) rename src/ImageSharp/Processing/{Delegates => }/PositionAwarePixelShader.cs (94%) diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs index 51d37caad4..36529eb70c 100644 --- a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.ImageSharp.Processing.Processors.PixelShading; using SixLabors.Primitives; diff --git a/src/ImageSharp/Processing/Delegates/PixelShader.cs b/src/ImageSharp/Processing/PixelShader.cs similarity index 91% rename from src/ImageSharp/Processing/Delegates/PixelShader.cs rename to src/ImageSharp/Processing/PixelShader.cs index 72895f14b0..0245931fb5 100644 --- a/src/ImageSharp/Processing/Delegates/PixelShader.cs +++ b/src/ImageSharp/Processing/PixelShader.cs @@ -4,7 +4,7 @@ using System; using System.Numerics; -namespace SixLabors.ImageSharp.Processing.Delegates +namespace SixLabors.ImageSharp.Processing { /// /// A representing a user defined pixel shader. diff --git a/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs b/src/ImageSharp/Processing/PositionAwarePixelShader.cs similarity index 94% rename from src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs rename to src/ImageSharp/Processing/PositionAwarePixelShader.cs index 8455b9b058..63e9246b41 100644 --- a/src/ImageSharp/Processing/Delegates/PositionAwarePixelShader.cs +++ b/src/ImageSharp/Processing/PositionAwarePixelShader.cs @@ -4,7 +4,7 @@ using System; using System.Numerics; -namespace SixLabors.ImageSharp.Processing.Delegates +namespace SixLabors.ImageSharp.Processing { /// /// A representing a user defined pixel shader. diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs index 30ba4222ea..c0b333a691 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.PixelShading diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs index 70728a4ecb..f3f8f25983 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract; using SixLabors.Primitives; diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs index a1fdc60821..c06d460486 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.PixelShading diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs index 7c5eff5979..bca3286eb2 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Delegates; using SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract; using SixLabors.Primitives; From 8d2672c0b33880cdcce115493878e555ab564f6d Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 26 Dec 2019 11:20:12 +0100 Subject: [PATCH 11/18] Moved pixel shader processor types --- src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs | 2 +- .../{PixelShading => Effects}/PixelShaderProcessor.cs | 2 +- .../Abstract => Effects}/PixelShaderProcessorBase.cs | 2 +- .../{PixelShading => Effects}/PixelShaderProcessor{TPixel}.cs | 3 +-- .../PositionAwarePixelShaderProcessor.cs | 2 +- .../PositionAwarePixelShaderProcessor{TPixel}.cs | 3 +-- 6 files changed, 6 insertions(+), 8 deletions(-) rename src/ImageSharp/Processing/Processors/{PixelShading => Effects}/PixelShaderProcessor.cs (94%) rename src/ImageSharp/Processing/Processors/{PixelShading/Abstract => Effects}/PixelShaderProcessorBase.cs (97%) rename src/ImageSharp/Processing/Processors/{PixelShading => Effects}/PixelShaderProcessor{TPixel}.cs (91%) rename src/ImageSharp/Processing/Processors/{PixelShading => Effects}/PositionAwarePixelShaderProcessor.cs (95%) rename src/ImageSharp/Processing/Processors/{PixelShading => Effects}/PositionAwarePixelShaderProcessor{TPixel}.cs (92%) diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs index 36529eb70c..30848e346c 100644 --- a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using SixLabors.ImageSharp.Processing.Processors.PixelShading; +using SixLabors.ImageSharp.Processing.Processors.Effects; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor.cs similarity index 94% rename from src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor.cs index c0b333a691..6c44199da0 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor.cs @@ -4,7 +4,7 @@ using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; -namespace SixLabors.ImageSharp.Processing.Processors.PixelShading +namespace SixLabors.ImageSharp.Processing.Processors.Effects { /// /// Applies a user defined pixel shader effect through a given delegate. diff --git a/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs similarity index 97% rename from src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs rename to src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs index 1af50197aa..a8e032ee17 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/Abstract/PixelShaderProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs @@ -9,7 +9,7 @@ using SixLabors.ImageSharp.Advanced.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; -namespace SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract +namespace SixLabors.ImageSharp.Processing.Processors.Effects { /// /// Applies a user defined pixel shader effect through a given delegate. diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs similarity index 91% rename from src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs rename to src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs index f3f8f25983..29e3ab5a9b 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs @@ -5,10 +5,9 @@ using System; using System.Numerics; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract; using SixLabors.Primitives; -namespace SixLabors.ImageSharp.Processing.Processors.PixelShading +namespace SixLabors.ImageSharp.Processing.Processors.Effects { /// /// Applies a user defined pixel shader effect through a given delegate. diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor.cs similarity index 95% rename from src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs rename to src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor.cs index c06d460486..a83e8b5a42 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor.cs @@ -4,7 +4,7 @@ using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; -namespace SixLabors.ImageSharp.Processing.Processors.PixelShading +namespace SixLabors.ImageSharp.Processing.Processors.Effects { /// /// Applies a user defined pixel shader effect through a given delegate. diff --git a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs similarity index 92% rename from src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs rename to src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs index bca3286eb2..6c4eee35f5 100644 --- a/src/ImageSharp/Processing/Processors/PixelShading/PositionAwarePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs @@ -5,10 +5,9 @@ using System; using System.Numerics; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.PixelShading.Abstract; using SixLabors.Primitives; -namespace SixLabors.ImageSharp.Processing.Processors.PixelShading +namespace SixLabors.ImageSharp.Processing.Processors.Effects { /// /// Applies a user defined pixel shader effect through a given delegate. From 14ecd52c9bd3089389e158c17146fe326cbf78ca Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 26 Dec 2019 11:27:21 +0100 Subject: [PATCH 12/18] Added support for custom pixel modifiers --- .../Effects/PixelShaderProcessor.cs | 24 +++++++++++++++++++ .../Effects/PixelShaderProcessorBase.cs | 13 +++++++--- .../Effects/PixelShaderProcessor{TPixel}.cs | 2 +- .../PositionAwarePixelShaderProcessor.cs | 24 +++++++++++++++++++ ...sitionAwarePixelShaderProcessor{TPixel}.cs | 2 +- 5 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor.cs index 6c44199da0..2a271bef3c 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor.cs @@ -11,6 +11,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// public sealed class PixelShaderProcessor : IImageProcessor { + /// + /// The default to apply during the pixel conversions. + /// + public const PixelConversionModifiers DefaultModifiers = PixelConversionModifiers.None; + /// /// Initializes a new instance of the class. /// @@ -20,6 +25,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects public PixelShaderProcessor(PixelShader pixelShader) { this.PixelShader = pixelShader; + this.Modifiers = DefaultModifiers; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The user defined pixel shader to use to modify images. + /// + /// The to apply during the pixel conversions. + public PixelShaderProcessor(PixelShader pixelShader, PixelConversionModifiers modifiers) + { + this.PixelShader = pixelShader; + this.Modifiers = modifiers; } /// @@ -27,6 +46,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// public PixelShader PixelShader { get; } + /// + /// Gets the to apply during the pixel conversions. + /// + public PixelConversionModifiers Modifiers { get; } + /// public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle) where TPixel : struct, IPixel diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs index a8e032ee17..f1245ca510 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs @@ -18,14 +18,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects internal abstract class PixelShaderProcessorBase : ImageProcessor where TPixel : struct, IPixel { + /// + /// The to apply during the pixel conversions. + /// + private readonly PixelConversionModifiers modifiers; + /// /// Initializes a new instance of the class. /// + /// 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 PixelShaderProcessorBase(Image source, Rectangle sourceRectangle) + protected PixelShaderProcessorBase(PixelConversionModifiers modifiers, Image source, Rectangle sourceRectangle) : base(source, sourceRectangle) { + this.modifiers = modifiers; } /// @@ -44,12 +51,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects Span vectorSpan = vectorBuffer.Span; int length = vectorSpan.Length; Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); - PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan); + PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan, this.modifiers); // Run the user defined pixel shader on the current row of pixels this.ApplyPixelShader(vectorSpan, y, startX); - PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan); + PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan, this.modifiers); } }); } diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs index 29e3ab5a9b..4abd698386 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// The source for the current processor instance. /// The source area to process for the current processor instance. public PixelShaderProcessor(PixelShaderProcessor definition, Image source, Rectangle sourceRectangle) - : base(source, sourceRectangle) + : base(definition.Modifiers, source, sourceRectangle) { this.pixelShader = definition.PixelShader; } diff --git a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor.cs index a83e8b5a42..908f7472b7 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor.cs @@ -11,6 +11,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// public sealed class PositionAwarePixelShaderProcessor : IImageProcessor { + /// + /// The default to apply during the pixel conversions. + /// + public const PixelConversionModifiers DefaultModifiers = PixelConversionModifiers.None; + /// /// Initializes a new instance of the class. /// @@ -20,6 +25,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects public PositionAwarePixelShaderProcessor(PositionAwarePixelShader pixelShader) { this.PixelShader = pixelShader; + this.Modifiers = DefaultModifiers; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The user defined pixel shader to use to modify images. + /// + /// The to apply during the pixel conversions. + public PositionAwarePixelShaderProcessor(PositionAwarePixelShader pixelShader, PixelConversionModifiers modifiers) + { + this.PixelShader = pixelShader; + this.Modifiers = modifiers; } /// @@ -27,6 +46,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// public PositionAwarePixelShader PixelShader { get; } + /// + /// Gets the to apply during the pixel conversions. + /// + public PixelConversionModifiers Modifiers { get; } + /// public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle) where TPixel : struct, IPixel diff --git a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs index 6c4eee35f5..3b9f37b485 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// The source for the current processor instance. /// The source area to process for the current processor instance. public PositionAwarePixelShaderProcessor(PositionAwarePixelShaderProcessor definition, Image source, Rectangle sourceRectangle) - : base(source, sourceRectangle) + : base(definition.Modifiers, source, sourceRectangle) { this.pixelShader = definition.PixelShader; } From ed02d3525a7f667871dcf0c20c8e5e165289eebb Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 26 Dec 2019 11:29:21 +0100 Subject: [PATCH 13/18] Added overloads with custom pixel modifiers in pixel shading extensions --- .../Extensions/PixelShaderExtensions.cs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs index 30848e346c..b866e7fb14 100644 --- a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors.Effects; using SixLabors.Primitives; @@ -20,6 +21,16 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader) => source.ApplyProcessor(new PixelShaderProcessor(pixelShader)); + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// The to apply during the pixel conversions. + /// The to allow chaining of operations. + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader, PixelConversionModifiers modifiers) + => source.ApplyProcessor(new PixelShaderProcessor(pixelShader, modifiers)); + /// /// Applies a user defined pixel shader to the image. /// @@ -32,6 +43,19 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle) => source.ApplyProcessor(new PixelShaderProcessor(pixelShader), rectangle); + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The to apply during the pixel conversions. + /// The to allow chaining of operations. + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle, PixelConversionModifiers modifiers) + => source.ApplyProcessor(new PixelShaderProcessor(pixelShader, modifiers), rectangle); + /// /// Applies a user defined pixel shader to the image. /// @@ -41,6 +65,16 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader) => source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader)); + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// The to apply during the pixel conversions. + /// The to allow chaining of operations. + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader, PixelConversionModifiers modifiers) + => source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader, modifiers)); + /// /// Applies a user defined pixel shader to the image. /// @@ -52,5 +86,18 @@ namespace SixLabors.ImageSharp.Processing /// The to allow chaining of operations. public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader, Rectangle rectangle) => source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader), rectangle); + + /// + /// Applies a user defined pixel shader to the image. + /// + /// The image this method extends. + /// The user defined pixel shader to use to modify images. + /// + /// The structure that specifies the portion of the image object to alter. + /// + /// The to apply during the pixel conversions. + /// The to allow chaining of operations. + public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader, Rectangle rectangle, PixelConversionModifiers modifiers) + => source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader, modifiers), rectangle); } } From e0cbe2fa0bcf702217a0c321374007f23b67c283 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 3 Jan 2020 16:32:56 +0100 Subject: [PATCH 14/18] Added pixel shader tests --- .../Processors/Effects/PixelShaderTest.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs diff --git a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs new file mode 100644 index 0000000000..5da1e96a96 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs @@ -0,0 +1,53 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Numerics; + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects +{ + [GroupOutput("Effects")] + public class PixelShaderTest + { + [Theory] + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] + public void FullImage(TestImageProvider provider) + where TPixel : struct, IPixel + { + provider.RunValidatingProcessorTest( + x => x.ApplyPixelShaderProcessor( + span => + { + for (int i = 0; i < span.Length; i++) + { + Vector4 v4 = span[i]; + float avg = (v4.X + v4.Y + v4.Z) / 3f; + span[i] = new Vector4(avg); + } + }), + appendPixelTypeToFileName: false); + } + + [Theory] + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] + public void InBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + provider.RunRectangleConstrainedValidatingProcessorTest( + (x, rect) => x.ApplyPixelShaderProcessor( + span => + { + for (int i = 0; i < span.Length; i++) + { + Vector4 v4 = span[i]; + float avg = (v4.X + v4.Y + v4.Z) / 3f; + span[i] = new Vector4(avg); + } + }, rect)); + } + } +} From 9dc1927697695d1f427a7015519a6e7fe4188f50 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 3 Jan 2020 16:54:19 +0100 Subject: [PATCH 15/18] Added tests for convolution aware pixel shader --- .../Processors/Effects/PixelShaderTest.cs | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs index 5da1e96a96..d9af215b97 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using SixLabors.ImageSharp.PixelFormats; @@ -49,5 +50,60 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects } }, rect)); } + + [Theory] + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] + public void PositionAwareFullImage(TestImageProvider provider) + where TPixel : struct, IPixel + { + provider.RunValidatingProcessorTest( + c => c.ApplyPixelShaderProcessor( + (span, y, x) => + { + for (int i = 0; i < span.Length; i++) + { + float + sine = MathF.Sin(y), + cosine = MathF.Cos(x + i), + sum = sine + cosine, + abs = MathF.Abs(sum), + a = 0.5f + abs / 2; // Max value for sin(y) + cos(x) is 2 + + Vector4 v4 = span[i]; + float avg = (v4.X + v4.Y + v4.Z) / 3f; + var gray = new Vector4(avg, avg, avg, a); + + span[i] = Vector4.Clamp(gray, Vector4.Zero, Vector4.One); + } + }), + appendPixelTypeToFileName: false); + } + + [Theory] + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] + public void PositionAwareInBox(TestImageProvider provider) + where TPixel : struct, IPixel + { + provider.RunRectangleConstrainedValidatingProcessorTest( + (c, rect) => c.ApplyPixelShaderProcessor( + (span, y, x) => + { + for (int i = 0; i < span.Length; i++) + { + float + sine = MathF.Sin(y), + cosine = MathF.Cos(x + i), + sum = sine + cosine, + abs = MathF.Abs(sum), + a = 0.5f + abs / 2; + + Vector4 v4 = span[i]; + float avg = (v4.X + v4.Y + v4.Z) / 3f; + var gray = new Vector4(avg, avg, avg, a); + + span[i] = Vector4.Clamp(gray, Vector4.Zero, Vector4.One); + } + }, rect)); + } } } From 0c0d2bba6d93d7802aaa86fdac27f01037eaafc1 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 6 Jan 2020 02:55:28 +0100 Subject: [PATCH 16/18] Fixed lambda capturing this --- .../Processors/Effects/PixelShaderProcessorBase.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs index f1245ca510..d75d23a51f 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs @@ -40,6 +40,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects { var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); int startX = interest.X; + Configuration configuration = this.Configuration; + PixelConversionModifiers modifiers = this.modifiers; ParallelHelper.IterateRowsWithTempBuffer( interest, @@ -51,12 +53,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects Span vectorSpan = vectorBuffer.Span; int length = vectorSpan.Length; Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); - PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan, this.modifiers); + PixelOperations.Instance.ToVector4(configuration, rowSpan, vectorSpan, modifiers); // Run the user defined pixel shader on the current row of pixels this.ApplyPixelShader(vectorSpan, y, startX); - PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan, this.modifiers); + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, rowSpan, modifiers); } }); } From b12924e79016824076dd39b738089c14297e93a7 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 6 Jan 2020 15:42:59 +1100 Subject: [PATCH 17/18] Use Point for offset --- .../{ => Effects}/PixelShaderExtensions.cs | 0 .../Processing/PositionAwarePixelShader.cs | 6 +++--- .../Processors/Effects/PixelShaderProcessorBase.cs | 7 +++---- .../Effects/PixelShaderProcessor{TPixel}.cs | 4 ++-- .../PositionAwarePixelShaderProcessor{TPixel}.cs | 4 ++-- .../Processors/Effects/PixelShaderTest.cs | 14 +++++++++----- 6 files changed, 19 insertions(+), 16 deletions(-) rename src/ImageSharp/Processing/Extensions/{ => Effects}/PixelShaderExtensions.cs (100%) diff --git a/src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs b/src/ImageSharp/Processing/Extensions/Effects/PixelShaderExtensions.cs similarity index 100% rename from src/ImageSharp/Processing/Extensions/PixelShaderExtensions.cs rename to src/ImageSharp/Processing/Extensions/Effects/PixelShaderExtensions.cs diff --git a/src/ImageSharp/Processing/PositionAwarePixelShader.cs b/src/ImageSharp/Processing/PositionAwarePixelShader.cs index 63e9246b41..1ae3ba295a 100644 --- a/src/ImageSharp/Processing/PositionAwarePixelShader.cs +++ b/src/ImageSharp/Processing/PositionAwarePixelShader.cs @@ -3,6 +3,7 @@ using System; using System.Numerics; +using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing { @@ -10,8 +11,7 @@ namespace SixLabors.ImageSharp.Processing /// A representing a user defined pixel shader. /// /// The target row of pixels to process. - /// The initial vertical offset for the input pixels to process. - /// The initial horizontal offset for the input pixels to process. + /// The initial horizontal and vertical offset for the input pixels to process. /// The , , , and fields map the RGBA channels respectively. - public delegate void PositionAwarePixelShader(Span span, int offsetY, int offsetX); + public delegate void PositionAwarePixelShader(Span span, Point offset); } diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs index d75d23a51f..d46a4cf320 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessorBase.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects PixelOperations.Instance.ToVector4(configuration, rowSpan, vectorSpan, modifiers); // Run the user defined pixel shader on the current row of pixels - this.ApplyPixelShader(vectorSpan, y, startX); + this.ApplyPixelShader(vectorSpan, new Point(startX, y)); PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, rowSpan, modifiers); } @@ -67,8 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// Applies the current pixel shader effect on a target row of preprocessed pixels. /// /// The target row of pixels to process. - /// The initial vertical offset for the input pixels to process. - /// The initial horizontal offset for the input pixels to process. - protected abstract void ApplyPixelShader(Span span, int offsetY, int offsetX); + /// The initial horizontal and vertical offset for the input pixels to process. + protected abstract void ApplyPixelShader(Span span, Point offset); } } diff --git a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs index 4abd698386..ce7b858a3e 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PixelShaderProcessor{TPixel}.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// Applies a user defined pixel shader effect through a given delegate. /// /// The pixel format. - internal class PixelShaderProcessor : PixelShaderProcessorBase + internal sealed class PixelShaderProcessor : PixelShaderProcessorBase where TPixel : struct, IPixel { /// @@ -34,6 +34,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects } /// - protected override void ApplyPixelShader(Span span, int offsetY, int offsetX) => this.pixelShader(span); + protected override void ApplyPixelShader(Span span, Point offset) => this.pixelShader(span); } } diff --git a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs index 3b9f37b485..549dedac15 100644 --- a/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/PositionAwarePixelShaderProcessor{TPixel}.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// Applies a user defined pixel shader effect through a given delegate. /// /// The pixel format. - internal class PositionAwarePixelShaderProcessor : PixelShaderProcessorBase + internal sealed class PositionAwarePixelShaderProcessor : PixelShaderProcessorBase where TPixel : struct, IPixel { /// @@ -34,6 +34,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects } /// - protected override void ApplyPixelShader(Span span, int offsetY, int offsetX) => this.pixelShader(span, offsetY, offsetX); + protected override void ApplyPixelShader(Span span, Point offset) => this.pixelShader(span, offset); } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs index d9af215b97..c18f043852 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs @@ -58,8 +58,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects { provider.RunValidatingProcessorTest( c => c.ApplyPixelShaderProcessor( - (span, y, x) => + (span, offset) => { + int y = offset.Y; + int x = offset.X; for (int i = 0; i < span.Length; i++) { float @@ -67,8 +69,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects cosine = MathF.Cos(x + i), sum = sine + cosine, abs = MathF.Abs(sum), - a = 0.5f + abs / 2; // Max value for sin(y) + cos(x) is 2 - + a = 0.5f + (abs / 2); // Max value for sin(y) + cos(x) is 2 + Vector4 v4 = span[i]; float avg = (v4.X + v4.Y + v4.Z) / 3f; var gray = new Vector4(avg, avg, avg, a); @@ -86,8 +88,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects { provider.RunRectangleConstrainedValidatingProcessorTest( (c, rect) => c.ApplyPixelShaderProcessor( - (span, y, x) => + (span, offset) => { + int y = offset.Y; + int x = offset.X; for (int i = 0; i < span.Length; i++) { float @@ -95,7 +99,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects cosine = MathF.Cos(x + i), sum = sine + cosine, abs = MathF.Abs(sum), - a = 0.5f + abs / 2; + a = 0.5f + (abs / 2); Vector4 v4 = span[i]; float avg = (v4.X + v4.Y + v4.Z) / 3f; From 620cf0edcd9b8f6486c90757df824a881a9e2677 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 6 Jan 2020 15:45:03 +1100 Subject: [PATCH 18/18] Update reference images --- tests/Images/External | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Images/External b/tests/Images/External index d7c099cebd..d8ea82085a 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit d7c099cebd58f1d3ff997383351d52d28a29df3d +Subproject commit d8ea82085ac39a6aa6ca8e0806a9518d3a7d3337