Browse Source

Update AdaptiveHistogramEqualizationProcessor and rename interfaces

af/octree-no-pixelmap
James Jackson-South 6 years ago
parent
commit
e2e47a0ecf
  1. 18
      src/ImageSharp/Advanced/IRowIntervalOperation.cs
  2. 20
      src/ImageSharp/Advanced/IRowIntervalOperation{TBuffer}.cs
  3. 52
      src/ImageSharp/Advanced/ParallelRowIterator.cs
  4. 6
      src/ImageSharp/ImageFrame{TPixel}.cs
  5. 6
      src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
  6. 26
      src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs
  7. 8
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs
  8. 12
      src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
  9. 8
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
  10. 6
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor{TPixel}.cs
  11. 6
      src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs
  12. 6
      src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs
  13. 8
      src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel,TDelegate}.cs
  14. 11
      src/ImageSharp/Processing/Processors/Effects/PixelateProcessor{TPixel}.cs
  15. 8
      src/ImageSharp/Processing/Processors/Filters/FilterProcessor{TPixel}.cs
  16. 299
      src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs
  17. 12
      src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs
  18. 6
      src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor{TPixel}.cs
  19. 8
      src/ImageSharp/Processing/Processors/Overlays/GlowProcessor{TPixel}.cs
  20. 8
      src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor{TPixel}.cs
  21. 14
      src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor{TPixel}.cs
  22. 8
      src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs
  23. 6
      src/ImageSharp/Processing/Processors/Transforms/FlipProcessor{TPixel}.cs
  24. 14
      src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor{TPixel}.cs
  25. 6
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs
  26. 18
      src/ImageSharp/Processing/Processors/Transforms/RotateProcessor{TPixel}.cs

18
src/ImageSharp/Advanced/IRowIntervalAction.cs → src/ImageSharp/Advanced/IRowIntervalOperation.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Advanced
/// <summary> /// <summary>
/// Defines the contract for an action that operates on a row interval. /// Defines the contract for an action that operates on a row interval.
/// </summary> /// </summary>
public interface IRowIntervalAction public interface IRowIntervalOperation
{ {
/// <summary> /// <summary>
/// Invokes the method passing the row interval. /// Invokes the method passing the row interval.
@ -40,13 +40,13 @@ namespace SixLabors.ImageSharp.Advanced
} }
} }
internal readonly struct WrappingRowIntervalAction internal readonly struct WrappingRowIntervalOperation
{ {
private readonly WrappingRowIntervalInfo info; private readonly WrappingRowIntervalInfo info;
private readonly Action<RowInterval> action; private readonly Action<RowInterval> action;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public WrappingRowIntervalAction(in WrappingRowIntervalInfo info, Action<RowInterval> action) public WrappingRowIntervalOperation(in WrappingRowIntervalInfo info, Action<RowInterval> action)
{ {
this.info = info; this.info = info;
this.action = action; this.action = action;
@ -69,17 +69,17 @@ namespace SixLabors.ImageSharp.Advanced
} }
} }
internal readonly struct WrappingRowIntervalAction<T> internal readonly struct WrappingRowIntervalOperation<T>
where T : struct, IRowIntervalAction where T : struct, IRowIntervalOperation
{ {
private readonly WrappingRowIntervalInfo info; private readonly WrappingRowIntervalInfo info;
private readonly T action; private readonly T operation;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public WrappingRowIntervalAction(in WrappingRowIntervalInfo info, in T action) public WrappingRowIntervalOperation(in WrappingRowIntervalInfo info, in T operation)
{ {
this.info = info; this.info = info;
this.action = action; this.operation = operation;
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Advanced
var rows = new RowInterval(yMin, yMax); var rows = new RowInterval(yMin, yMax);
// Skip the safety copy when invoking a potentially impure method on a readonly field // Skip the safety copy when invoking a potentially impure method on a readonly field
Unsafe.AsRef(this.action).Invoke(in rows); Unsafe.AsRef(this.operation).Invoke(in rows);
} }
} }
} }

20
src/ImageSharp/Advanced/IRowIntervalAction{TBuffer}.cs → src/ImageSharp/Advanced/IRowIntervalOperation{TBuffer}.cs

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Advanced
/// Defines the contract for an action that operates on a row interval with a temporary buffer. /// Defines the contract for an action that operates on a row interval with a temporary buffer.
/// </summary> /// </summary>
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam> /// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
public interface IRowIntervalAction<TBuffer> public interface IRowIntervalOperation<TBuffer>
where TBuffer : unmanaged where TBuffer : unmanaged
{ {
/// <summary> /// <summary>
@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Advanced
void Invoke(in RowInterval rows, Memory<TBuffer> memory); void Invoke(in RowInterval rows, Memory<TBuffer> memory);
} }
internal readonly struct WrappingRowIntervalBufferAction<TBuffer> internal readonly struct WrappingRowIntervalBufferOperation<TBuffer>
where TBuffer : unmanaged where TBuffer : unmanaged
{ {
private readonly WrappingRowIntervalInfo info; private readonly WrappingRowIntervalInfo info;
@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Advanced
private readonly Action<RowInterval, Memory<TBuffer>> action; private readonly Action<RowInterval, Memory<TBuffer>> action;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public WrappingRowIntervalBufferAction( public WrappingRowIntervalBufferOperation(
in WrappingRowIntervalInfo info, in WrappingRowIntervalInfo info,
MemoryAllocator allocator, MemoryAllocator allocator,
Action<RowInterval, Memory<TBuffer>> action) Action<RowInterval, Memory<TBuffer>> action)
@ -59,23 +59,23 @@ namespace SixLabors.ImageSharp.Advanced
} }
} }
internal readonly struct WrappingRowIntervalBufferAction<T, TBuffer> internal readonly struct WrappingRowIntervalBufferOperation<T, TBuffer>
where T : struct, IRowIntervalAction<TBuffer> where T : struct, IRowIntervalOperation<TBuffer>
where TBuffer : unmanaged where TBuffer : unmanaged
{ {
private readonly WrappingRowIntervalInfo info; private readonly WrappingRowIntervalInfo info;
private readonly MemoryAllocator allocator; private readonly MemoryAllocator allocator;
private readonly T action; private readonly T operation;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public WrappingRowIntervalBufferAction( public WrappingRowIntervalBufferOperation(
in WrappingRowIntervalInfo info, in WrappingRowIntervalInfo info,
MemoryAllocator allocator, MemoryAllocator allocator,
in T action) in T operation)
{ {
this.info = info; this.info = info;
this.allocator = allocator; this.allocator = allocator;
this.action = action; this.operation = operation;
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.Advanced
using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.info.MaxX); using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.info.MaxX);
Unsafe.AsRef(this.action).Invoke(in rows, buffer.Memory); Unsafe.AsRef(this.operation).Invoke(in rows, buffer.Memory);
} }
} }
} }

52
src/ImageSharp/Advanced/ParallelRowIterator.cs

@ -5,7 +5,6 @@ using System;
using System.Buffers; using System.Buffers;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Advanced namespace SixLabors.ImageSharp.Advanced
@ -21,13 +20,13 @@ namespace SixLabors.ImageSharp.Advanced
/// <summary> /// <summary>
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s. /// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s.
/// </summary> /// </summary>
/// <typeparam name="T">The type of row action to perform.</typeparam> /// <typeparam name="T">The type of row operation to perform.</typeparam>
/// <param name="rectangle">The <see cref="Rectangle"/>.</param> /// <param name="rectangle">The <see cref="Rectangle"/>.</param>
/// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param> /// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param>
/// <param name="body">The method body defining the iteration logic on a single <see cref="RowInterval"/>.</param> /// <param name="body">The method body defining the iteration logic on a single <see cref="RowInterval"/>.</param>
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public static void IterateRows<T>(Rectangle rectangle, Configuration configuration, in T body) public static void IterateRows<T>(Rectangle rectangle, Configuration configuration, in T body)
where T : struct, IRowIntervalAction where T : struct, IRowIntervalOperation
{ {
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration);
IterateRows(rectangle, in parallelSettings, in body); IterateRows(rectangle, in parallelSettings, in body);
@ -36,15 +35,15 @@ namespace SixLabors.ImageSharp.Advanced
/// <summary> /// <summary>
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s. /// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s.
/// </summary> /// </summary>
/// <typeparam name="T">The type of row action to perform.</typeparam> /// <typeparam name="T">The type of row operation to perform.</typeparam>
/// <param name="rectangle">The <see cref="Rectangle"/>.</param> /// <param name="rectangle">The <see cref="Rectangle"/>.</param>
/// <param name="parallelSettings">The <see cref="ParallelExecutionSettings"/>.</param> /// <param name="parallelSettings">The <see cref="ParallelExecutionSettings"/>.</param>
/// <param name="body">The method body defining the iteration logic on a single <see cref="RowInterval"/>.</param> /// <param name="operation">The method body defining the iteration logic on a single <see cref="RowInterval"/>.</param>
public static void IterateRows<T>( public static void IterateRows<T>(
Rectangle rectangle, Rectangle rectangle,
in ParallelExecutionSettings parallelSettings, in ParallelExecutionSettings parallelSettings,
in T body) in T operation)
where T : struct, IRowIntervalAction where T : struct, IRowIntervalOperation
{ {
ValidateRectangle(rectangle); ValidateRectangle(rectangle);
@ -60,14 +59,14 @@ namespace SixLabors.ImageSharp.Advanced
if (numOfSteps == 1) if (numOfSteps == 1)
{ {
var rows = new RowInterval(top, bottom); var rows = new RowInterval(top, bottom);
Unsafe.AsRef(body).Invoke(in rows); Unsafe.AsRef(operation).Invoke(in rows);
return; return;
} }
int verticalStep = DivideCeil(rectangle.Height, numOfSteps); int verticalStep = DivideCeil(rectangle.Height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps };
var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep); var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep);
var rowAction = new WrappingRowIntervalAction<T>(in rowInfo, in body); var rowAction = new WrappingRowIntervalOperation<T>(in rowInfo, in operation);
Parallel.For( Parallel.For(
0, 0,
@ -78,30 +77,35 @@ namespace SixLabors.ImageSharp.Advanced
/// <summary> /// <summary>
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s /// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s
/// instantiating a temporary buffer for each <paramref name="body"/> invocation. /// instantiating a temporary buffer for each <paramref name="operation"/> invocation.
/// </summary> /// </summary>
/// <typeparam name="T">The type of row action to perform.</typeparam> /// <typeparam name="T">The type of row operation to perform.</typeparam>
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam> /// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
/// <param name="rectangle">The <see cref="Rectangle"/>.</param> /// <param name="rectangle">The <see cref="Rectangle"/>.</param>
/// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param> /// <param name="configuration">The <see cref="Configuration"/> to get the parallel settings from.</param>
/// <param name="body">The method body defining the iteration logic on a single <see cref="RowInterval"/>.</param> /// <param name="operation">The method body defining the iteration logic on a single <see cref="RowInterval"/>.</param>
public static void IterateRows<T, TBuffer>(Rectangle rectangle, Configuration configuration, in T body) public static void IterateRows<T, TBuffer>(Rectangle rectangle, Configuration configuration, in T operation)
where T : struct, IRowIntervalAction<TBuffer> where T : struct, IRowIntervalOperation<TBuffer>
where TBuffer : unmanaged where TBuffer : unmanaged
{ {
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration);
IterateRows<T, TBuffer>(rectangle, in parallelSettings, in body); IterateRows<T, TBuffer>(rectangle, in parallelSettings, in operation);
} }
/// <summary> /// <summary>
/// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s /// Iterate through the rows of a rectangle in optimized batches defined by <see cref="RowInterval"/>-s
/// instantiating a temporary buffer for each <paramref name="body"/> invocation. /// instantiating a temporary buffer for each <paramref name="operation"/> invocation.
/// </summary> /// </summary>
internal static void IterateRows<T, TBuffer>( /// <typeparam name="T">The type of row operation to perform.</typeparam>
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
/// <param name="rectangle">The <see cref="Rectangle"/>.</param>
/// <param name="parallelSettings">The <see cref="ParallelExecutionSettings"/>.</param>
/// <param name="operation">The method body defining the iteration logic on a single <see cref="RowInterval"/>.</param>
public static void IterateRows<T, TBuffer>(
Rectangle rectangle, Rectangle rectangle,
in ParallelExecutionSettings parallelSettings, in ParallelExecutionSettings parallelSettings,
in T body) in T operation)
where T : struct, IRowIntervalAction<TBuffer> where T : struct, IRowIntervalOperation<TBuffer>
where TBuffer : unmanaged where TBuffer : unmanaged
{ {
ValidateRectangle(rectangle); ValidateRectangle(rectangle);
@ -121,7 +125,7 @@ namespace SixLabors.ImageSharp.Advanced
var rows = new RowInterval(top, bottom); var rows = new RowInterval(top, bottom);
using (IMemoryOwner<TBuffer> buffer = allocator.Allocate<TBuffer>(width)) using (IMemoryOwner<TBuffer> buffer = allocator.Allocate<TBuffer>(width))
{ {
Unsafe.AsRef(body).Invoke(rows, buffer.Memory); Unsafe.AsRef(operation).Invoke(rows, buffer.Memory);
} }
return; return;
@ -130,13 +134,13 @@ namespace SixLabors.ImageSharp.Advanced
int verticalStep = DivideCeil(height, numOfSteps); int verticalStep = DivideCeil(height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps };
var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep, width); var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep, width);
var rowAction = new WrappingRowIntervalBufferAction<T, TBuffer>(in rowInfo, allocator, in body); var rowOperation = new WrappingRowIntervalBufferOperation<T, TBuffer>(in rowInfo, allocator, in operation);
Parallel.For( Parallel.For(
0, 0,
numOfSteps, numOfSteps,
parallelOptions, parallelOptions,
rowAction.Invoke); rowOperation.Invoke);
} }
/// <summary> /// <summary>
@ -183,7 +187,7 @@ namespace SixLabors.ImageSharp.Advanced
int verticalStep = DivideCeil(rectangle.Height, numOfSteps); int verticalStep = DivideCeil(rectangle.Height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps };
var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep); var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep);
var rowAction = new WrappingRowIntervalAction(in rowInfo, body); var rowAction = new WrappingRowIntervalOperation(in rowInfo, body);
Parallel.For( Parallel.For(
0, 0,
@ -242,7 +246,7 @@ namespace SixLabors.ImageSharp.Advanced
int verticalStep = DivideCeil(rectangle.Height, numOfSteps); int verticalStep = DivideCeil(rectangle.Height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps };
var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep, width); var rowInfo = new WrappingRowIntervalInfo(top, bottom, verticalStep, width);
var rowAction = new WrappingRowIntervalBufferAction<TBuffer>(in rowInfo, allocator, body); var rowAction = new WrappingRowIntervalBufferOperation<TBuffer>(in rowInfo, allocator, body);
Parallel.For( Parallel.For(
0, 0,

6
src/ImageSharp/ImageFrame{TPixel}.cs

@ -263,7 +263,7 @@ namespace SixLabors.ImageSharp
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
this.Bounds(), this.Bounds(),
configuration, configuration,
new RowIntervalAction<TPixel2>(this, target, configuration)); new RowIntervalOperation<TPixel2>(this, target, configuration));
return target; return target;
} }
@ -289,7 +289,7 @@ namespace SixLabors.ImageSharp
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the clone logic for <see cref="ImageFrame{TPixel}"/>. /// A <see langword="struct"/> implementing the clone logic for <see cref="ImageFrame{TPixel}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction<TPixel2> : IRowIntervalAction private readonly struct RowIntervalOperation<TPixel2> : IRowIntervalOperation
where TPixel2 : struct, IPixel<TPixel2> where TPixel2 : struct, IPixel<TPixel2>
{ {
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
@ -297,7 +297,7 @@ namespace SixLabors.ImageSharp
private readonly Configuration configuration; private readonly Configuration configuration;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
ImageFrame<TPixel> source, ImageFrame<TPixel> source,
ImageFrame<TPixel2> target, ImageFrame<TPixel2> target,
Configuration configuration) Configuration configuration)

6
src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs

@ -54,13 +54,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
workingRect, workingRect,
configuration, configuration,
new RowIntervalAction(source, upper, lower, threshold, startX, endX, isAlphaOnly)); new RowIntervalOperation(source, upper, lower, threshold, startX, endX, isAlphaOnly));
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the clone logic for <see cref="BinaryThresholdProcessor{TPixel}"/>. /// A <see langword="struct"/> implementing the clone logic for <see cref="BinaryThresholdProcessor{TPixel}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
private readonly TPixel upper; private readonly TPixel upper;
@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
private readonly bool isAlphaOnly; private readonly bool isAlphaOnly;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
ImageFrame<TPixel> source, ImageFrame<TPixel> source,
TPixel upper, TPixel upper,
TPixel lower, TPixel lower,

26
src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs

@ -268,10 +268,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
protected override void OnFrameApply(ImageFrame<TPixel> source) protected override void OnFrameApply(ImageFrame<TPixel> source)
{ {
// Preliminary gamma highlight pass // Preliminary gamma highlight pass
ParallelRowIterator.IterateRows<ApplyGammaExposureRowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<ApplyGammaExposureRowIntervalOperation, Vector4>(
this.SourceRectangle, this.SourceRectangle,
this.Configuration, this.Configuration,
new ApplyGammaExposureRowIntervalAction(this.SourceRectangle, source.PixelBuffer, this.Configuration, this.gamma)); new ApplyGammaExposureRowIntervalOperation(this.SourceRectangle, source.PixelBuffer, this.Configuration, this.gamma));
// Create a 0-filled buffer to use to store the result of the component convolutions // Create a 0-filled buffer to use to store the result of the component convolutions
using Buffer2D<Vector4> processingBuffer = this.Configuration.MemoryAllocator.Allocate2D<Vector4>(source.Size(), AllocationOptions.Clean); using Buffer2D<Vector4> processingBuffer = this.Configuration.MemoryAllocator.Allocate2D<Vector4>(source.Size(), AllocationOptions.Clean);
@ -285,7 +285,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
this.SourceRectangle, this.SourceRectangle,
this.Configuration, this.Configuration,
new ApplyInverseGammaExposureRowIntervalAction(this.SourceRectangle, source.PixelBuffer, processingBuffer, this.Configuration, inverseGamma)); new ApplyInverseGammaExposureRowIntervalOperation(this.SourceRectangle, source.PixelBuffer, processingBuffer, this.Configuration, inverseGamma));
} }
/// <summary> /// <summary>
@ -317,20 +317,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
sourceRectangle, sourceRectangle,
configuration, configuration,
new ApplyVerticalConvolutionRowIntervalAction(ref sourceRectangle, firstPassBuffer, source.PixelBuffer, kernel)); new ApplyVerticalConvolutionRowIntervalOperation(ref sourceRectangle, firstPassBuffer, source.PixelBuffer, kernel));
// Compute the horizontal 1D convolutions and accumulate the partial results on the target buffer // Compute the horizontal 1D convolutions and accumulate the partial results on the target buffer
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
sourceRectangle, sourceRectangle,
configuration, configuration,
new ApplyHorizontalConvolutionRowIntervalAction(ref sourceRectangle, processingBuffer, firstPassBuffer, kernel, parameters.Z, parameters.W)); new ApplyHorizontalConvolutionRowIntervalOperation(ref sourceRectangle, processingBuffer, firstPassBuffer, kernel, parameters.Z, parameters.W));
} }
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the vertical convolution logic for <see cref="BokehBlurProcessor{T}"/>. /// A <see langword="struct"/> implementing the vertical convolution logic for <see cref="BokehBlurProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct ApplyVerticalConvolutionRowIntervalAction : IRowIntervalAction private readonly struct ApplyVerticalConvolutionRowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Buffer2D<ComplexVector4> targetValues; private readonly Buffer2D<ComplexVector4> targetValues;
@ -340,7 +340,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly int maxX; private readonly int maxX;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public ApplyVerticalConvolutionRowIntervalAction( public ApplyVerticalConvolutionRowIntervalOperation(
ref Rectangle bounds, ref Rectangle bounds,
Buffer2D<ComplexVector4> targetValues, Buffer2D<ComplexVector4> targetValues,
Buffer2D<TPixel> sourcePixels, Buffer2D<TPixel> sourcePixels,
@ -373,7 +373,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the horizontal convolution logic for <see cref="BokehBlurProcessor{T}"/>. /// A <see langword="struct"/> implementing the horizontal convolution logic for <see cref="BokehBlurProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct ApplyHorizontalConvolutionRowIntervalAction : IRowIntervalAction private readonly struct ApplyHorizontalConvolutionRowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Buffer2D<Vector4> targetValues; private readonly Buffer2D<Vector4> targetValues;
@ -385,7 +385,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly int maxX; private readonly int maxX;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public ApplyHorizontalConvolutionRowIntervalAction( public ApplyHorizontalConvolutionRowIntervalOperation(
ref Rectangle bounds, ref Rectangle bounds,
Buffer2D<Vector4> targetValues, Buffer2D<Vector4> targetValues,
Buffer2D<ComplexVector4> sourceValues, Buffer2D<ComplexVector4> sourceValues,
@ -422,7 +422,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>. /// A <see langword="struct"/> implementing the gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct ApplyGammaExposureRowIntervalAction : IRowIntervalAction<Vector4> private readonly struct ApplyGammaExposureRowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Buffer2D<TPixel> targetPixels; private readonly Buffer2D<TPixel> targetPixels;
@ -430,7 +430,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly float gamma; private readonly float gamma;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public ApplyGammaExposureRowIntervalAction( public ApplyGammaExposureRowIntervalOperation(
Rectangle bounds, Rectangle bounds,
Buffer2D<TPixel> targetPixels, Buffer2D<TPixel> targetPixels,
Configuration configuration, Configuration configuration,
@ -471,7 +471,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the inverse gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>. /// A <see langword="struct"/> implementing the inverse gamma exposure logic for <see cref="BokehBlurProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct ApplyInverseGammaExposureRowIntervalAction : IRowIntervalAction private readonly struct ApplyInverseGammaExposureRowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Buffer2D<TPixel> targetPixels; private readonly Buffer2D<TPixel> targetPixels;
@ -480,7 +480,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly float inverseGamma; private readonly float inverseGamma;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public ApplyInverseGammaExposureRowIntervalAction( public ApplyInverseGammaExposureRowIntervalOperation(
Rectangle bounds, Rectangle bounds,
Buffer2D<TPixel> targetPixels, Buffer2D<TPixel> targetPixels,
Buffer2D<Vector4> sourceValues, Buffer2D<Vector4> sourceValues,

8
src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs

@ -66,10 +66,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
interest, interest,
this.Configuration, this.Configuration,
new RowIntervalAction(interest, targetPixels, source.PixelBuffer, this.KernelY, this.KernelX, this.Configuration, this.PreserveAlpha)); new RowIntervalOperation(interest, targetPixels, source.PixelBuffer, this.KernelY, this.KernelX, this.Configuration, this.PreserveAlpha));
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels); Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);
} }
@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the convolution logic for <see cref="Convolution2DProcessor{T}"/>. /// A <see langword="struct"/> implementing the convolution logic for <see cref="Convolution2DProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction<Vector4> private readonly struct RowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly int maxY; private readonly int maxY;
@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly bool preserveAlpha; private readonly bool preserveAlpha;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Rectangle bounds, Rectangle bounds,
Buffer2D<TPixel> targetPixels, Buffer2D<TPixel> targetPixels,
Buffer2D<TPixel> sourcePixels, Buffer2D<TPixel> sourcePixels,

12
src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs

@ -64,22 +64,22 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
// Horizontal convolution // Horizontal convolution
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
interest, interest,
this.Configuration, this.Configuration,
new RowIntervalAction(interest, firstPassPixels, source.PixelBuffer, this.KernelX, this.Configuration, this.PreserveAlpha)); new RowIntervalOperation(interest, firstPassPixels, source.PixelBuffer, this.KernelX, this.Configuration, this.PreserveAlpha));
// Vertical convolution // Vertical convolution
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
interest, interest,
this.Configuration, this.Configuration,
new RowIntervalAction(interest, source.PixelBuffer, firstPassPixels, this.KernelY, this.Configuration, this.PreserveAlpha)); new RowIntervalOperation(interest, source.PixelBuffer, firstPassPixels, this.KernelY, this.Configuration, this.PreserveAlpha));
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the convolution logic for <see cref="Convolution2PassProcessor{T}"/>. /// A <see langword="struct"/> implementing the convolution logic for <see cref="Convolution2PassProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction<Vector4> private readonly struct RowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Buffer2D<TPixel> targetPixels; private readonly Buffer2D<TPixel> targetPixels;
@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly bool preserveAlpha; private readonly bool preserveAlpha;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Rectangle bounds, Rectangle bounds,
Buffer2D<TPixel> targetPixels, Buffer2D<TPixel> targetPixels,
Buffer2D<TPixel> sourcePixels, Buffer2D<TPixel> sourcePixels,

8
src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs

@ -57,10 +57,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
interest, interest,
this.Configuration, this.Configuration,
new RowIntervalAction(interest, targetPixels, source.PixelBuffer, this.KernelXY, this.Configuration, this.PreserveAlpha)); new RowIntervalOperation(interest, targetPixels, source.PixelBuffer, this.KernelXY, this.Configuration, this.PreserveAlpha));
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels); Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);
} }
@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the convolution logic for <see cref="ConvolutionProcessor{T}"/>. /// A <see langword="struct"/> implementing the convolution logic for <see cref="ConvolutionProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction<Vector4> private readonly struct RowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly int maxY; private readonly int maxY;
@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly bool preserveAlpha; private readonly bool preserveAlpha;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Rectangle bounds, Rectangle bounds,
Buffer2D<TPixel> targetPixels, Buffer2D<TPixel> targetPixels,
Buffer2D<TPixel> sourcePixels, Buffer2D<TPixel> sourcePixels,

6
src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor{TPixel}.cs

@ -105,14 +105,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
Rectangle.FromLTRB(minX, minY, maxX, maxY), Rectangle.FromLTRB(minX, minY, maxX, maxY),
this.Configuration, this.Configuration,
new RowIntervalAction(source.PixelBuffer, pass.PixelBuffer, minX, maxX, shiftY, shiftX)); new RowIntervalOperation(source.PixelBuffer, pass.PixelBuffer, minX, maxX, shiftY, shiftX));
} }
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the convolution logic for <see cref="EdgeDetectorCompassProcessor{T}"/>. /// A <see langword="struct"/> implementing the convolution logic for <see cref="EdgeDetectorCompassProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly Buffer2D<TPixel> targetPixels; private readonly Buffer2D<TPixel> targetPixels;
private readonly Buffer2D<TPixel> passPixels; private readonly Buffer2D<TPixel> passPixels;
@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly int shiftX; private readonly int shiftX;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Buffer2D<TPixel> targetPixels, Buffer2D<TPixel> targetPixels,
Buffer2D<TPixel> passPixels, Buffer2D<TPixel> passPixels,
int minX, int minX,

6
src/ImageSharp/Processing/Processors/Drawing/DrawImageProcessor{TPixelBg,TPixelFg}.cs

@ -102,13 +102,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
workingRect, workingRect,
configuration, configuration,
new RowIntervalAction(source, targetImage, blender, configuration, minX, width, locationY, targetX, this.Opacity)); new RowIntervalOperation(source, targetImage, blender, configuration, minX, width, locationY, targetX, this.Opacity));
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the draw logic for <see cref="DrawImageProcessor{TPixelBg,TPixelFg}"/>. /// A <see langword="struct"/> implementing the draw logic for <see cref="DrawImageProcessor{TPixelBg,TPixelFg}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly ImageFrame<TPixelBg> sourceFrame; private readonly ImageFrame<TPixelBg> sourceFrame;
private readonly Image<TPixelFg> targetImage; private readonly Image<TPixelFg> targetImage;
@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
private readonly float opacity; private readonly float opacity;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
ImageFrame<TPixelBg> sourceFrame, ImageFrame<TPixelBg> sourceFrame,
Image<TPixelFg> targetImage, Image<TPixelFg> targetImage,
PixelBlender<TPixelBg> blender, PixelBlender<TPixelBg> blender,

6
src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs

@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
this.SourceRectangle, this.SourceRectangle,
this.Configuration, this.Configuration,
new RowIntervalAction(this.SourceRectangle, targetPixels, source, this.Configuration, brushSize >> 1, this.definition.Levels)); new RowIntervalOperation(this.SourceRectangle, targetPixels, source, this.Configuration, brushSize >> 1, this.definition.Levels));
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels); Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);
} }
@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the convolution logic for <see cref="OilPaintingProcessor{T}"/>. /// A <see langword="struct"/> implementing the convolution logic for <see cref="OilPaintingProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Buffer2D<TPixel> targetPixels; private readonly Buffer2D<TPixel> targetPixels;
@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
private readonly int levels; private readonly int levels;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Rectangle bounds, Rectangle bounds,
Buffer2D<TPixel> targetPixels, Buffer2D<TPixel> targetPixels,
ImageFrame<TPixel> source, ImageFrame<TPixel> source,

8
src/ImageSharp/Processing/Processors/Effects/PixelRowDelegateProcessor{TPixel,TDelegate}.cs

@ -51,16 +51,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
{ {
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
interest, interest,
this.Configuration, this.Configuration,
new RowIntervalAction(interest.X, source, this.Configuration, this.modifiers, this.rowDelegate)); new RowIntervalOperation(interest.X, source, this.Configuration, this.modifiers, this.rowDelegate));
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the convolution logic for <see cref="PixelRowDelegateProcessor{TPixel,TDelegate}"/>. /// A <see langword="struct"/> implementing the convolution logic for <see cref="PixelRowDelegateProcessor{TPixel,TDelegate}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction<Vector4> private readonly struct RowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly int startX; private readonly int startX;
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
private readonly TDelegate rowProcessor; private readonly TDelegate rowProcessor;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
int startX, int startX,
ImageFrame<TPixel> source, ImageFrame<TPixel> source,
Configuration configuration, Configuration configuration,

11
src/ImageSharp/Processing/Processors/Effects/PixelateProcessor{TPixel}.cs

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -29,9 +28,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
/// <param name="sourceRectangle">The source area to process for the current processor instance.</param> /// <param name="sourceRectangle">The source area to process for the current processor instance.</param>
public PixelateProcessor(Configuration configuration, PixelateProcessor definition, Image<TPixel> source, Rectangle sourceRectangle) public PixelateProcessor(Configuration configuration, PixelateProcessor definition, Image<TPixel> source, Rectangle sourceRectangle)
: base(configuration, source, sourceRectangle) : base(configuration, source, sourceRectangle)
{ => this.definition = definition;
this.definition = definition;
}
private int Size => this.definition.Size; private int Size => this.definition.Size;
@ -51,10 +48,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
Parallel.ForEach( Parallel.ForEach(
range, range,
this.Configuration.GetParallelOptions(), this.Configuration.GetParallelOptions(),
new RowAction(interest, size, source).Invoke); new RowOperation(interest, size, source).Invoke);
} }
private readonly struct RowAction private readonly struct RowOperation
{ {
private readonly int minX; private readonly int minX;
private readonly int maxX; private readonly int maxX;
@ -66,7 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowAction( public RowOperation(
Rectangle bounds, Rectangle bounds,
int size, int size,
ImageFrame<TPixel> source) ImageFrame<TPixel> source)

8
src/ImageSharp/Processing/Processors/Filters/FilterProcessor{TPixel}.cs

@ -37,16 +37,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
{ {
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
interest, interest,
this.Configuration, this.Configuration,
new RowIntervalAction(interest.X, source, this.definition.Matrix, this.Configuration)); new RowIntervalOperation(interest.X, source, this.definition.Matrix, this.Configuration));
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the convolution logic for <see cref="FilterProcessor{TPixel}"/>. /// A <see langword="struct"/> implementing the convolution logic for <see cref="FilterProcessor{TPixel}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction<Vector4> private readonly struct RowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly int startX; private readonly int startX;
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
private readonly Configuration configuration; private readonly Configuration configuration;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
int startX, int startX,
ImageFrame<TPixel> source, ImageFrame<TPixel> source,
ColorMatrix matrix, ColorMatrix matrix,

299
src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs

@ -7,8 +7,7 @@ using System.Collections.Generic;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -81,56 +80,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
yStart += tileHeight; yStart += tileHeight;
} }
Parallel.For( ParallelRowIterator.IterateRows(
0, new Rectangle(0, 0, sourceWidth, tileYStartPositions.Count),
tileYStartPositions.Count, this.Configuration,
new ParallelOptions { MaxDegreeOfParallelism = this.Configuration.MaxDegreeOfParallelism }, new RowIntervalOperation(cdfData, tileYStartPositions, tileWidth, tileHeight, tileCount, halfTileWidth, luminanceLevels, source));
index =>
{
int y = tileYStartPositions[index].y;
int cdfYY = tileYStartPositions[index].cdfY;
// It's unfortunate that we have to do this per iteration.
ref TPixel sourceBase = ref source.GetPixelReference(0, 0);
int cdfX = 0;
int x = halfTileWidth;
for (int tile = 0; tile < tileCount - 1; tile++)
{
int tileY = 0;
int yEnd = Math.Min(y + tileHeight, sourceHeight);
int xEnd = Math.Min(x + tileWidth, sourceWidth);
for (int dy = y; dy < yEnd; dy++)
{
int dyOffSet = dy * sourceWidth;
int tileX = 0;
for (int dx = x; dx < xEnd; dx++)
{
ref TPixel pixel = ref Unsafe.Add(ref sourceBase, dyOffSet + dx);
float luminanceEqualized = InterpolateBetweenFourTiles(
pixel,
cdfData,
tileCount,
tileCount,
tileX,
tileY,
cdfX,
cdfYY,
tileWidth,
tileHeight,
luminanceLevels);
pixel.FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, pixel.ToVector4().W));
tileX++;
}
tileY++;
}
cdfX++;
x += tileWidth;
}
});
ref TPixel pixelsBase = ref source.GetPixelReference(0, 0); ref TPixel pixelsBase = ref source.GetPixelReference(0, 0);
@ -416,6 +369,95 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
private static float LinearInterpolation(float left, float right, float t) private static float LinearInterpolation(float left, float right, float t)
=> left + ((right - left) * t); => left + ((right - left) * t);
private readonly struct RowIntervalOperation : IRowIntervalOperation
{
private readonly CdfTileData cdfData;
private readonly List<(int y, int cdfY)> tileYStartPositions;
private readonly int tileWidth;
private readonly int tileHeight;
private readonly int tileCount;
private readonly int halfTileWidth;
private readonly int luminanceLevels;
private readonly ImageFrame<TPixel> source;
private readonly int sourceWidth;
private readonly int sourceHeight;
[MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalOperation(
CdfTileData cdfData,
List<(int y, int cdfY)> tileYStartPositions,
int tileWidth,
int tileHeight,
int tileCount,
int halfTileWidth,
int luminanceLevels,
ImageFrame<TPixel> source)
{
this.cdfData = cdfData;
this.tileYStartPositions = tileYStartPositions;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.tileCount = tileCount;
this.halfTileWidth = halfTileWidth;
this.luminanceLevels = luminanceLevels;
this.source = source;
this.sourceWidth = source.Width;
this.sourceHeight = source.Height;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(in RowInterval rows)
{
ref TPixel sourceBase = ref this.source.GetPixelReference(0, 0);
for (int index = rows.Min; index < rows.Max; index++)
{
(int y, int cdfY) tileYStartPosition = this.tileYStartPositions[index];
int y = tileYStartPosition.y;
int cdfYY = tileYStartPosition.cdfY;
int cdfX = 0;
int x = this.halfTileWidth;
for (int tile = 0; tile < this.tileCount - 1; tile++)
{
int tileY = 0;
int yEnd = Math.Min(y + this.tileHeight, this.sourceHeight);
int xEnd = Math.Min(x + this.tileWidth, this.sourceWidth);
for (int dy = y; dy < yEnd; dy++)
{
int dyOffSet = dy * this.sourceWidth;
int tileX = 0;
for (int dx = x; dx < xEnd; dx++)
{
ref TPixel pixel = ref Unsafe.Add(ref sourceBase, dyOffSet + dx);
float luminanceEqualized = InterpolateBetweenFourTiles(
pixel,
this.cdfData,
this.tileCount,
this.tileCount,
tileX,
tileY,
cdfX,
cdfYY,
this.tileWidth,
this.tileHeight,
this.luminanceLevels);
pixel.FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, pixel.ToVector4().W));
tileX++;
}
tileY++;
}
cdfX++;
x += this.tileWidth;
}
}
}
}
/// <summary> /// <summary>
/// Contains the results of the cumulative distribution function for all tiles. /// Contains the results of the cumulative distribution function for all tiles.
/// </summary> /// </summary>
@ -470,57 +512,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
public void CalculateLookupTables(ImageFrame<TPixel> source, HistogramEqualizationProcessor<TPixel> processor) public void CalculateLookupTables(ImageFrame<TPixel> source, HistogramEqualizationProcessor<TPixel> processor)
{ {
int sourceWidth = this.sourceWidth; var rowOperation = new RowIntervalOperation(
int sourceHeight = this.sourceHeight; processor,
int tileWidth = this.tileWidth; this.memoryAllocator,
int tileHeight = this.tileHeight; this.cdfMinBuffer2D,
int luminanceLevels = this.luminanceLevels; this.cdfLutBuffer2D,
this.tileYStartPositions,
Parallel.For( this.tileWidth,
0, this.tileHeight,
this.tileYStartPositions.Count, this.luminanceLevels,
new ParallelOptions { MaxDegreeOfParallelism = this.configuration.MaxDegreeOfParallelism }, source);
index =>
{ ParallelRowIterator.IterateRows(
int cdfX = 0; new Rectangle(0, 0, this.sourceWidth, this.tileYStartPositions.Count),
int cdfY = this.tileYStartPositions[index].cdfY; this.configuration,
int y = this.tileYStartPositions[index].y; in rowOperation);
int endY = Math.Min(y + tileHeight, sourceHeight);
ref TPixel sourceBase = ref source.GetPixelReference(0, 0);
ref int cdfMinBase = ref MemoryMarshal.GetReference(this.cdfMinBuffer2D.GetRowSpan(cdfY));
using (IMemoryOwner<int> histogramBuffer = this.memoryAllocator.Allocate<int>(luminanceLevels))
{
Span<int> histogram = histogramBuffer.GetSpan();
ref int histogramBase = ref MemoryMarshal.GetReference(histogram);
for (int x = 0; x < sourceWidth; x += tileWidth)
{
histogram.Clear();
ref int cdfBase = ref MemoryMarshal.GetReference(this.GetCdfLutSpan(cdfX, index));
int xlimit = Math.Min(x + tileWidth, sourceWidth);
for (int dy = y; dy < endY; dy++)
{
int dyOffset = dy * sourceWidth;
for (int dx = x; dx < xlimit; dx++)
{
int luminance = GetLuminance(Unsafe.Add(ref sourceBase, dyOffset + dx), luminanceLevels);
histogram[luminance]++;
}
}
if (processor.ClipHistogramEnabled)
{
processor.ClipHistogram(histogram, processor.ClipLimit);
}
Unsafe.Add(ref cdfMinBase, cdfX) = processor.CalculateCdf(ref cdfBase, ref histogramBase, histogram.Length - 1);
cdfX++;
}
}
});
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
@ -548,6 +554,93 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
this.cdfMinBuffer2D.Dispose(); this.cdfMinBuffer2D.Dispose();
this.cdfLutBuffer2D.Dispose(); this.cdfLutBuffer2D.Dispose();
} }
private readonly struct RowIntervalOperation : IRowIntervalOperation
{
private readonly HistogramEqualizationProcessor<TPixel> processor;
private readonly MemoryAllocator allocator;
private readonly Buffer2D<int> cdfMinBuffer2D;
private readonly Buffer2D<int> cdfLutBuffer2D;
private readonly List<(int y, int cdfY)> tileYStartPositions;
private readonly int tileWidth;
private readonly int tileHeight;
private readonly int luminanceLevels;
private readonly ImageFrame<TPixel> source;
private readonly int sourceWidth;
private readonly int sourceHeight;
[MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalOperation(
HistogramEqualizationProcessor<TPixel> processor,
MemoryAllocator allocator,
Buffer2D<int> cdfMinBuffer2D,
Buffer2D<int> cdfLutBuffer2D,
List<(int y, int cdfY)> tileYStartPositions,
int tileWidth,
int tileHeight,
int luminanceLevels,
ImageFrame<TPixel> source)
{
this.processor = processor;
this.allocator = allocator;
this.cdfMinBuffer2D = cdfMinBuffer2D;
this.cdfLutBuffer2D = cdfLutBuffer2D;
this.tileYStartPositions = tileYStartPositions;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.luminanceLevels = luminanceLevels;
this.source = source;
this.sourceWidth = source.Width;
this.sourceHeight = source.Height;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(in RowInterval rows)
{
ref TPixel sourceBase = ref this.source.GetPixelReference(0, 0);
for (int index = rows.Min; index < rows.Max; index++)
{
int cdfX = 0;
int cdfY = this.tileYStartPositions[index].cdfY;
int y = this.tileYStartPositions[index].y;
int endY = Math.Min(y + this.tileHeight, this.sourceHeight);
ref int cdfMinBase = ref MemoryMarshal.GetReference(this.cdfMinBuffer2D.GetRowSpan(cdfY));
using IMemoryOwner<int> histogramBuffer = this.allocator.Allocate<int>(this.luminanceLevels);
Span<int> histogram = histogramBuffer.GetSpan();
ref int histogramBase = ref MemoryMarshal.GetReference(histogram);
for (int x = 0; x < this.sourceWidth; x += this.tileWidth)
{
histogram.Clear();
Span<int> cdfLutSpan = this.cdfLutBuffer2D.GetRowSpan(index).Slice(cdfX * this.luminanceLevels, this.luminanceLevels);
ref int cdfBase = ref MemoryMarshal.GetReference(cdfLutSpan);
int xlimit = Math.Min(x + this.tileWidth, this.sourceWidth);
for (int dy = y; dy < endY; dy++)
{
int dyOffset = dy * this.sourceWidth;
for (int dx = x; dx < xlimit; dx++)
{
int luminance = GetLuminance(Unsafe.Add(ref sourceBase, dyOffset + dx), this.luminanceLevels);
histogram[luminance]++;
}
}
if (this.processor.ClipHistogramEnabled)
{
this.processor.ClipHistogram(histogram, this.processor.ClipLimit);
}
Unsafe.Add(ref cdfMinBase, cdfX) = this.processor.CalculateCdf(ref cdfBase, ref histogramBase, histogram.Length - 1);
cdfX++;
}
}
}
}
} }
} }
} }

12
src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs

@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
workingRect, workingRect,
this.Configuration, this.Configuration,
new GrayscaleLevelsRowIntervalAction(workingRect, histogramBuffer, source, this.LuminanceLevels)); new GrayscaleLevelsRowIntervalOperation(workingRect, histogramBuffer, source, this.LuminanceLevels));
Span<int> histogram = histogramBuffer.GetSpan(); Span<int> histogram = histogramBuffer.GetSpan();
if (this.ClipHistogramEnabled) if (this.ClipHistogramEnabled)
@ -77,13 +77,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
workingRect, workingRect,
this.Configuration, this.Configuration,
new CdfApplicationRowIntervalAction(workingRect, cdfBuffer, source, this.LuminanceLevels, numberOfPixelsMinusCdfMin)); new CdfApplicationRowIntervalOperation(workingRect, cdfBuffer, source, this.LuminanceLevels, numberOfPixelsMinusCdfMin));
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the grayscale levels logic for <see cref="GlobalHistogramEqualizationProcessor{TPixel}"/>. /// A <see langword="struct"/> implementing the grayscale levels logic for <see cref="GlobalHistogramEqualizationProcessor{TPixel}"/>.
/// </summary> /// </summary>
private readonly struct GrayscaleLevelsRowIntervalAction : IRowIntervalAction private readonly struct GrayscaleLevelsRowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly IMemoryOwner<int> histogramBuffer; private readonly IMemoryOwner<int> histogramBuffer;
@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
private readonly int luminanceLevels; private readonly int luminanceLevels;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public GrayscaleLevelsRowIntervalAction( public GrayscaleLevelsRowIntervalOperation(
in Rectangle bounds, in Rectangle bounds,
IMemoryOwner<int> histogramBuffer, IMemoryOwner<int> histogramBuffer,
ImageFrame<TPixel> source, ImageFrame<TPixel> source,
@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the cdf application levels logic for <see cref="GlobalHistogramEqualizationProcessor{TPixel}"/>. /// A <see langword="struct"/> implementing the cdf application levels logic for <see cref="GlobalHistogramEqualizationProcessor{TPixel}"/>.
/// </summary> /// </summary>
private readonly struct CdfApplicationRowIntervalAction : IRowIntervalAction private readonly struct CdfApplicationRowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly IMemoryOwner<int> cdfBuffer; private readonly IMemoryOwner<int> cdfBuffer;
@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
private readonly float numberOfPixelsMinusCdfMin; private readonly float numberOfPixelsMinusCdfMin;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public CdfApplicationRowIntervalAction( public CdfApplicationRowIntervalOperation(
in Rectangle bounds, in Rectangle bounds,
IMemoryOwner<int> cdfBuffer, IMemoryOwner<int> cdfBuffer,
ImageFrame<TPixel> source, ImageFrame<TPixel> source,

6
src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor{TPixel}.cs

@ -52,10 +52,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
interest, interest,
configuration, configuration,
new RowIntervalAction(configuration, interest, blender, amount, colors, source)); new RowIntervalOperation(configuration, interest, blender, amount, colors, source));
} }
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly Configuration configuration; private readonly Configuration configuration;
private readonly Rectangle bounds; private readonly Rectangle bounds;
@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Configuration configuration, Configuration configuration,
Rectangle bounds, Rectangle bounds,
PixelBlender<TPixel> blender, PixelBlender<TPixel> blender,

8
src/ImageSharp/Processing/Processors/Overlays/GlowProcessor{TPixel}.cs

@ -55,13 +55,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
using IMemoryOwner<TPixel> rowColors = allocator.Allocate<TPixel>(interest.Width); using IMemoryOwner<TPixel> rowColors = allocator.Allocate<TPixel>(interest.Width);
rowColors.GetSpan().Fill(glowColor); rowColors.GetSpan().Fill(glowColor);
ParallelRowIterator.IterateRows<RowIntervalAction, float>( ParallelRowIterator.IterateRows<RowIntervalOperation, float>(
interest, interest,
configuration, configuration,
new RowIntervalAction(configuration, interest, rowColors, this.blender, center, maxDistance, blendPercent, source)); new RowIntervalOperation(configuration, interest, rowColors, this.blender, center, maxDistance, blendPercent, source));
} }
private readonly struct RowIntervalAction : IRowIntervalAction<float> private readonly struct RowIntervalOperation : IRowIntervalOperation<float>
{ {
private readonly Configuration configuration; private readonly Configuration configuration;
private readonly Rectangle bounds; private readonly Rectangle bounds;
@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Configuration configuration, Configuration configuration,
Rectangle bounds, Rectangle bounds,
IMemoryOwner<TPixel> colors, IMemoryOwner<TPixel> colors,

8
src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor{TPixel}.cs

@ -63,13 +63,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
using IMemoryOwner<TPixel> rowColors = allocator.Allocate<TPixel>(interest.Width); using IMemoryOwner<TPixel> rowColors = allocator.Allocate<TPixel>(interest.Width);
rowColors.GetSpan().Fill(vignetteColor); rowColors.GetSpan().Fill(vignetteColor);
ParallelRowIterator.IterateRows<RowIntervalAction, float>( ParallelRowIterator.IterateRows<RowIntervalOperation, float>(
interest, interest,
configuration, configuration,
new RowIntervalAction(configuration, interest, rowColors, this.blender, center, maxDistance, blendPercent, source)); new RowIntervalOperation(configuration, interest, rowColors, this.blender, center, maxDistance, blendPercent, source));
} }
private readonly struct RowIntervalAction : IRowIntervalAction<float> private readonly struct RowIntervalOperation : IRowIntervalOperation<float>
{ {
private readonly Configuration configuration; private readonly Configuration configuration;
private readonly Rectangle bounds; private readonly Rectangle bounds;
@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Configuration configuration, Configuration configuration,
Rectangle bounds, Rectangle bounds,
IMemoryOwner<TPixel> colors, IMemoryOwner<TPixel> colors,

14
src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor{TPixel}.cs

@ -61,23 +61,23 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
targetBounds, targetBounds,
configuration, configuration,
new NearestNeighborRowIntervalAction(this.SourceRectangle, ref matrix, width, source, destination)); new NearestNeighborRowIntervalOperation(this.SourceRectangle, ref matrix, width, source, destination));
return; return;
} }
using var kernelMap = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.resampler); using var kernelMap = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.resampler);
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
targetBounds, targetBounds,
configuration, configuration,
new RowIntervalAction(configuration, kernelMap, ref matrix, width, source, destination)); new RowIntervalOperation(configuration, kernelMap, ref matrix, width, source, destination));
} }
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the nearest neighbor resampler logic for <see cref="AffineTransformProcessor{T}"/>. /// A <see langword="struct"/> implementing the nearest neighbor resampler logic for <see cref="AffineTransformProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct NearestNeighborRowIntervalAction : IRowIntervalAction private readonly struct NearestNeighborRowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Matrix3x2 matrix; private readonly Matrix3x2 matrix;
@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public NearestNeighborRowIntervalAction( public NearestNeighborRowIntervalOperation(
Rectangle bounds, Rectangle bounds,
ref Matrix3x2 matrix, ref Matrix3x2 matrix,
int maxX, int maxX,
@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the transformation logic for <see cref="AffineTransformProcessor{T}"/>. /// A <see langword="struct"/> implementing the transformation logic for <see cref="AffineTransformProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction<Vector4> private readonly struct RowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly Configuration configuration; private readonly Configuration configuration;
private readonly TransformKernelMap kernelMap; private readonly TransformKernelMap kernelMap;
@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Configuration configuration, Configuration configuration,
TransformKernelMap kernelMap, TransformKernelMap kernelMap,
ref Matrix3x2 matrix, ref Matrix3x2 matrix,

8
src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs

@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelExecutionSettings parallelSettings = ParallelExecutionSettings parallelSettings =
ParallelExecutionSettings.FromConfiguration(this.Configuration).MultiplyMinimumPixelsPerTask(4); ParallelExecutionSettings.FromConfiguration(this.Configuration).MultiplyMinimumPixelsPerTask(4);
var rowAction = new RowIntervalAction(ref bounds, source, destination); var rowAction = new RowIntervalOperation(ref bounds, source, destination);
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
bounds, bounds,
@ -62,20 +62,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// <summary> /// <summary>
/// A <see langword="struct"/> implementing the processor logic for <see cref="CropProcessor{T}"/>. /// A <see langword="struct"/> implementing the processor logic for <see cref="CropProcessor{T}"/>.
/// </summary> /// </summary>
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RowIntervalAction"/> struct. /// Initializes a new instance of the <see cref="RowIntervalOperation"/> struct.
/// </summary> /// </summary>
/// <param name="bounds">The target processing bounds for the current instance.</param> /// <param name="bounds">The target processing bounds for the current instance.</param>
/// <param name="source">The source <see cref="Image{TPixel}"/> for the current instance.</param> /// <param name="source">The source <see cref="Image{TPixel}"/> for the current instance.</param>
/// <param name="destination">The destination <see cref="Image{TPixel}"/> for the current instance.</param> /// <param name="destination">The destination <see cref="Image{TPixel}"/> for the current instance.</param>
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction(ref Rectangle bounds, ImageFrame<TPixel> source, ImageFrame<TPixel> destination) public RowIntervalOperation(ref Rectangle bounds, ImageFrame<TPixel> source, ImageFrame<TPixel> destination)
{ {
this.bounds = bounds; this.bounds = bounds;
this.source = source; this.source = source;

6
src/ImageSharp/Processing/Processors/Transforms/FlipProcessor{TPixel}.cs

@ -79,15 +79,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
source.Bounds(), source.Bounds(),
configuration, configuration,
new RowIntervalAction(source)); new RowIntervalOperation(source));
} }
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly ImageFrame<TPixel> source; private readonly ImageFrame<TPixel> source;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction(ImageFrame<TPixel> source) => this.source = source; public RowIntervalOperation(ImageFrame<TPixel> source) => this.source = source;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(in RowInterval rows) public void Invoke(in RowInterval rows)

14
src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor{TPixel}.cs

@ -63,20 +63,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
targetBounds, targetBounds,
configuration, configuration,
new NearestNeighborRowIntervalAction(ref sourceBounds, ref matrix, width, source, destination)); new NearestNeighborRowIntervalOperation(ref sourceBounds, ref matrix, width, source, destination));
return; return;
} }
using var kernelMap = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.resampler); using var kernelMap = new TransformKernelMap(configuration, source.Size(), destination.Size(), this.resampler);
ParallelRowIterator.IterateRows<RowIntervalAction, Vector4>( ParallelRowIterator.IterateRows<RowIntervalOperation, Vector4>(
targetBounds, targetBounds,
configuration, configuration,
new RowIntervalAction(configuration, kernelMap, ref matrix, width, source, destination)); new RowIntervalOperation(configuration, kernelMap, ref matrix, width, source, destination));
} }
private readonly struct NearestNeighborRowIntervalAction : IRowIntervalAction private readonly struct NearestNeighborRowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly Matrix4x4 matrix; private readonly Matrix4x4 matrix;
@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public NearestNeighborRowIntervalAction( public NearestNeighborRowIntervalOperation(
ref Rectangle bounds, ref Rectangle bounds,
ref Matrix4x4 matrix, ref Matrix4x4 matrix,
int maxX, int maxX,
@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
} }
} }
private readonly struct RowIntervalAction : IRowIntervalAction<Vector4> private readonly struct RowIntervalOperation : IRowIntervalOperation<Vector4>
{ {
private readonly Configuration configuration; private readonly Configuration configuration;
private readonly TransformKernelMap kernelMap; private readonly TransformKernelMap kernelMap;
@ -131,7 +131,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Configuration configuration, Configuration configuration,
TransformKernelMap kernelMap, TransformKernelMap kernelMap,
ref Matrix4x4 matrix, ref Matrix4x4 matrix,

6
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs

@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
interest, interest,
configuration, configuration,
new RowIntervalAction(sourceRectangle, this.targetRectangle, widthFactor, heightFactor, source, destination)); new RowIntervalOperation(sourceRectangle, this.targetRectangle, widthFactor, heightFactor, source, destination));
return; return;
} }
@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
base.Dispose(disposing); base.Dispose(disposing);
} }
private readonly struct RowIntervalAction : IRowIntervalAction private readonly struct RowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle sourceBounds; private readonly Rectangle sourceBounds;
private readonly Rectangle destinationBounds; private readonly Rectangle destinationBounds;
@ -157,7 +157,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction( public RowIntervalOperation(
Rectangle sourceBounds, Rectangle sourceBounds,
Rectangle destinationBounds, Rectangle destinationBounds,
float widthFactor, float widthFactor,

18
src/ImageSharp/Processing/Processors/Transforms/RotateProcessor{TPixel}.cs

@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
source.Bounds(), source.Bounds(),
configuration, configuration,
new Rotate180RowIntervalAction(source.Width, source.Height, source, destination)); new Rotate180RowIntervalOperation(source.Width, source.Height, source, destination));
} }
/// <summary> /// <summary>
@ -148,7 +148,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
source.Bounds(), source.Bounds(),
configuration, configuration,
new Rotate270RowIntervalAction(destination.Bounds(), source.Width, source.Height, source, destination)); new Rotate270RowIntervalOperation(destination.Bounds(), source.Width, source.Height, source, destination));
} }
/// <summary> /// <summary>
@ -162,10 +162,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
source.Bounds(), source.Bounds(),
configuration, configuration,
new Rotate90RowIntervalAction(destination.Bounds(), source.Width, source.Height, source, destination)); new Rotate90RowIntervalOperation(destination.Bounds(), source.Width, source.Height, source, destination));
} }
private readonly struct Rotate180RowIntervalAction : IRowIntervalAction private readonly struct Rotate180RowIntervalOperation : IRowIntervalOperation
{ {
private readonly int width; private readonly int width;
private readonly int height; private readonly int height;
@ -173,7 +173,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public Rotate180RowIntervalAction( public Rotate180RowIntervalOperation(
int width, int width,
int height, int height,
ImageFrame<TPixel> source, ImageFrame<TPixel> source,
@ -201,7 +201,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
} }
} }
private readonly struct Rotate270RowIntervalAction : IRowIntervalAction private readonly struct Rotate270RowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly int width; private readonly int width;
@ -210,7 +210,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public Rotate270RowIntervalAction( public Rotate270RowIntervalOperation(
Rectangle bounds, Rectangle bounds,
int width, int width,
int height, int height,
@ -245,7 +245,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
} }
} }
private readonly struct Rotate90RowIntervalAction : IRowIntervalAction private readonly struct Rotate90RowIntervalOperation : IRowIntervalOperation
{ {
private readonly Rectangle bounds; private readonly Rectangle bounds;
private readonly int width; private readonly int width;
@ -254,7 +254,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
private readonly ImageFrame<TPixel> destination; private readonly ImageFrame<TPixel> destination;
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public Rotate90RowIntervalAction( public Rotate90RowIntervalOperation(
Rectangle bounds, Rectangle bounds,
int width, int width,
int height, int height,

Loading…
Cancel
Save