diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs
index 3a5f35cd14..8f1d373556 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor{TPixel}.cs
@@ -60,17 +60,32 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
protected override void OnFrameApply(ImageFrame source)
{
- using Buffer2D targetPixels = this.Configuration.MemoryAllocator.Allocate2D(source.Width, source.Height);
+ MemoryAllocator allocator = this.Configuration.MemoryAllocator;
+ using Buffer2D targetPixels = allocator.Allocate2D(source.Width, source.Height);
source.CopyTo(targetPixels);
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
- var operation = new RowOperation(interest, targetPixels, source.PixelBuffer, this.KernelY, this.KernelX, this.Configuration, this.PreserveAlpha);
+ using (var map = new KernelSamplingMap(allocator))
+ {
+ // Since the kernel sizes are identical we can use a single map.
+ map.BuildSamplingOffsetMap(this.KernelY, interest);
+
+ var operation = new RowOperation(
+ interest,
+ targetPixels,
+ source.PixelBuffer,
+ map,
+ this.KernelY,
+ this.KernelX,
+ this.Configuration,
+ this.PreserveAlpha);
- ParallelRowIterator.IterateRows(
- this.Configuration,
- interest,
- in operation);
+ ParallelRowIterator.IterateRows(
+ this.Configuration,
+ interest,
+ in operation);
+ }
Buffer2D.SwapOrCopyContent(source.PixelBuffer, targetPixels);
}
@@ -81,10 +96,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly struct RowOperation : IRowOperation
{
private readonly Rectangle bounds;
- private readonly int maxY;
- private readonly int maxX;
private readonly Buffer2D targetPixels;
private readonly Buffer2D sourcePixels;
+ private readonly KernelSamplingMap map;
private readonly DenseMatrix kernelY;
private readonly DenseMatrix kernelX;
private readonly Configuration configuration;
@@ -95,16 +109,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
Rectangle bounds,
Buffer2D targetPixels,
Buffer2D sourcePixels,
+ KernelSamplingMap map,
DenseMatrix kernelY,
DenseMatrix kernelX,
Configuration configuration,
bool preserveAlpha)
{
this.bounds = bounds;
- this.maxY = this.bounds.Bottom - 1;
- this.maxX = this.bounds.Right - 1;
this.targetPixels = targetPixels;
this.sourcePixels = sourcePixels;
+ this.map = map;
this.kernelY = kernelY;
this.kernelX = kernelX;
this.configuration = configuration;
@@ -115,42 +129,41 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y, Span span)
{
- ref Vector4 spanRef = ref MemoryMarshal.GetReference(span);
+ ref Vector4 targetRowRef = ref MemoryMarshal.GetReference(span);
Span targetRowSpan = this.targetPixels.GetRowSpan(y).Slice(this.bounds.X);
PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span);
+ Span yOffsets = this.map.GetYOffsetSpan();
+ Span xOffsets = this.map.GetXOffsetSpan();
+ int row = y - this.bounds.Y;
if (this.preserveAlpha)
{
- for (int x = 0; x < this.bounds.Width; x++)
+ for (int column = 0; column < this.bounds.Width; column++)
{
- DenseMatrixUtils.Convolve2D3(
+ Convolver.Convolve2D3(
in this.kernelY,
in this.kernelX,
+ yOffsets,
+ xOffsets,
this.sourcePixels,
- ref spanRef,
- y,
- x,
- this.bounds.Y,
- this.maxY,
- this.bounds.X,
- this.maxX);
+ ref targetRowRef,
+ row,
+ column);
}
}
else
{
- for (int x = 0; x < this.bounds.Width; x++)
+ for (int column = 0; column < this.bounds.Width; column++)
{
- DenseMatrixUtils.Convolve2D4(
+ Convolver.Convolve2D4(
in this.kernelY,
in this.kernelX,
+ yOffsets,
+ xOffsets,
this.sourcePixels,
- ref spanRef,
- y,
- x,
- this.bounds.Y,
- this.maxY,
- this.bounds.X,
- this.maxX);
+ ref targetRowRef,
+ row,
+ column);
}
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
index 63fbca98a9..2ea062e281 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
@@ -63,9 +63,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
- using (var mapX = new KernelOffsetMap(this.Configuration.MemoryAllocator))
+ using (var mapX = new KernelSamplingMap(this.Configuration.MemoryAllocator))
{
- mapX.BuildOffsetMap(this.KernelX, interest);
+ mapX.BuildSamplingOffsetMap(this.KernelX, interest);
// Horizontal convolution
var horizontalOperation = new RowOperation(
@@ -83,9 +83,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
in horizontalOperation);
}
- using (var mapY = new KernelOffsetMap(this.Configuration.MemoryAllocator))
+ using (var mapY = new KernelSamplingMap(this.Configuration.MemoryAllocator))
{
- mapY.BuildOffsetMap(this.KernelY, interest);
+ mapY.BuildSamplingOffsetMap(this.KernelY, interest);
// Vertical convolution
var verticalOperation = new RowOperation(
@@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly Rectangle bounds;
private readonly Buffer2D targetPixels;
private readonly Buffer2D sourcePixels;
- private readonly KernelOffsetMap map;
+ private readonly KernelSamplingMap map;
private readonly DenseMatrix kernel;
private readonly Configuration configuration;
private readonly bool preserveAlpha;
@@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
Rectangle bounds,
Buffer2D targetPixels,
Buffer2D sourcePixels,
- KernelOffsetMap map,
+ KernelSamplingMap map,
DenseMatrix kernel,
Configuration configuration,
bool preserveAlpha)
@@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y, Span span)
{
- ref Vector4 targetRef = ref MemoryMarshal.GetReference(span);
+ ref Vector4 targetRowRef = ref MemoryMarshal.GetReference(span);
Span targetRowSpan = this.targetPixels.GetRowSpan(y).Slice(this.bounds.X);
PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span);
Span yOffsets = this.map.GetYOffsetSpan();
@@ -151,12 +151,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
for (int column = 0; column < this.bounds.Width; column++)
{
- DenseMatrixUtils.Convolve3(
+ Convolver.Convolve3(
in this.kernel,
yOffsets,
xOffsets,
this.sourcePixels,
- ref targetRef,
+ ref targetRowRef,
row,
column);
}
@@ -165,12 +165,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
for (int column = 0; column < this.bounds.Width; column++)
{
- DenseMatrixUtils.Convolve4(
+ Convolver.Convolve4(
in this.kernel,
yOffsets,
xOffsets,
this.sourcePixels,
- ref targetRef,
+ ref targetRowRef,
row,
column);
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
index ae2e8893f7..999fba22be 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
@@ -57,9 +57,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
source.CopyTo(targetPixels);
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
- using (var map = new KernelOffsetMap(allocator))
+ using (var map = new KernelSamplingMap(allocator))
{
- map.BuildOffsetMap(this.KernelXY, interest);
+ map.BuildSamplingOffsetMap(this.KernelXY, interest);
var operation = new RowOperation(interest, targetPixels, source.PixelBuffer, map, this.KernelXY, this.Configuration, this.PreserveAlpha);
ParallelRowIterator.IterateRows(
@@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private readonly Rectangle bounds;
private readonly Buffer2D targetPixels;
private readonly Buffer2D sourcePixels;
- private readonly KernelOffsetMap map;
+ private readonly KernelSamplingMap map;
private readonly DenseMatrix kernel;
private readonly Configuration configuration;
private readonly bool preserveAlpha;
@@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
Rectangle bounds,
Buffer2D targetPixels,
Buffer2D sourcePixels,
- KernelOffsetMap map,
+ KernelSamplingMap map,
DenseMatrix kernel,
Configuration configuration,
bool preserveAlpha)
@@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y, Span span)
{
- ref Vector4 targetRef = ref MemoryMarshal.GetReference(span);
+ ref Vector4 targetRowRef = ref MemoryMarshal.GetReference(span);
Span targetRowSpan = this.targetPixels.GetRowSpan(y).Slice(this.bounds.X);
PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span);
Span yOffsets = this.map.GetYOffsetSpan();
@@ -118,12 +118,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
for (int column = 0; column < this.bounds.Width; column++)
{
- DenseMatrixUtils.Convolve3(
+ Convolver.Convolve3(
in this.kernel,
yOffsets,
xOffsets,
this.sourcePixels,
- ref targetRef,
+ ref targetRowRef,
row,
column);
}
@@ -132,12 +132,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{
for (int column = 0; column < this.bounds.Width; column++)
{
- DenseMatrixUtils.Convolve4(
+ Convolver.Convolve4(
in this.kernel,
yOffsets,
xOffsets,
this.sourcePixels,
- ref targetRef,
+ ref targetRowRef,
row,
column);
}
diff --git a/src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolver.cs
similarity index 57%
rename from src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
rename to src/ImageSharp/Processing/Processors/Convolution/Convolver.cs
index cf7eb1162a..c9e9d74148 100644
--- a/src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/Convolver.cs
@@ -6,56 +6,50 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing.Processors.Convolution;
namespace SixLabors.ImageSharp
{
///
- /// Extension methods for .
- /// TODO: One day rewrite all this to use SIMD intrinsics. There's a lot of scope for improvement.
+ /// Provides methods to perform convolution operations.
///
- internal static class DenseMatrixUtils
+ internal static class Convolver
{
///
/// Computes the sum of vectors in the span referenced by weighted by the two kernel weight values.
/// Using this method the convolution filter is not applied to alpha in addition to the color channels.
///
/// The pixel format.
- /// The vertical dense matrix.
- /// The horizontal dense matrix.
+ /// The vertical convolution kernel.
+ /// The horizontal convolution kernel.
+ /// The span containing precalculated kernel y-sampling offsets.
+ /// The span containing precalculated kernel x-sampling offsets.
/// The source frame.
/// The target row base reference.
/// The current row.
/// The current column.
- /// The minimum working area row.
- /// The maximum working area row.
- /// The minimum working area column.
- /// The maximum working area column.
[MethodImpl(InliningOptions.ShortMethod)]
public static void Convolve2D3(
- in DenseMatrix matrixY,
- in DenseMatrix matrixX,
+ in DenseMatrix kernelY,
+ in DenseMatrix kernelX,
+ Span rowSampleOffsets,
+ Span columnSampleOffsets,
Buffer2D sourcePixels,
ref Vector4 targetRowRef,
int row,
- int column,
- int minRow,
- int maxRow,
- int minColumn,
- int maxColumn)
+ int column)
where TPixel : unmanaged, IPixel
{
+ Vector4 vector = default;
+
Convolve2DImpl(
- in matrixY,
- in matrixX,
+ in kernelY,
+ in kernelX,
+ rowSampleOffsets,
+ columnSampleOffsets,
sourcePixels,
row,
column,
- minRow,
- maxRow,
- minColumn,
- maxColumn,
- out Vector4 vector);
+ ref vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
vector.W = target.W;
@@ -69,41 +63,37 @@ namespace SixLabors.ImageSharp
/// Using this method the convolution filter is applied to alpha in addition to the color channels.
///
/// The pixel format.
- /// The vertical dense matrix.
- /// The horizontal dense matrix.
+ /// The vertical convolution kernel.
+ /// The horizontal convolution kernel.
+ /// The span containing precalculated kernel y-sampling offsets.
+ /// The span containing precalculated kernel x-sampling offsets.
/// The source frame.
/// The target row base reference.
/// The current row.
/// The current column.
- /// The minimum working area row.
- /// The maximum working area row.
- /// The minimum working area column.
- /// The maximum working area column.
[MethodImpl(InliningOptions.ShortMethod)]
public static void Convolve2D4(
- in DenseMatrix matrixY,
- in DenseMatrix matrixX,
+ in DenseMatrix kernelY,
+ in DenseMatrix kernelX,
+ Span rowSampleOffsets,
+ Span columnSampleOffsets,
Buffer2D sourcePixels,
ref Vector4 targetRowRef,
int row,
- int column,
- int minRow,
- int maxRow,
- int minColumn,
- int maxColumn)
+ int column)
where TPixel : unmanaged, IPixel
{
+ Vector4 vector = default;
+
Convolve2DImpl(
- in matrixY,
- in matrixX,
+ in kernelY,
+ in kernelX,
+ rowSampleOffsets,
+ columnSampleOffsets,
sourcePixels,
row,
column,
- minRow,
- maxRow,
- minColumn,
- maxColumn,
- out Vector4 vector);
+ ref vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
Numerics.UnPremultiply(ref vector);
@@ -112,43 +102,38 @@ namespace SixLabors.ImageSharp
[MethodImpl(InliningOptions.ShortMethod)]
public static void Convolve2DImpl(
- in DenseMatrix matrixY,
- in DenseMatrix matrixX,
+ in DenseMatrix kernelY,
+ in DenseMatrix kernelX,
+ Span rowSampleOffsets,
+ Span columnSampleOffsets,
Buffer2D sourcePixels,
int row,
int column,
- int minRow,
- int maxRow,
- int minColumn,
- int maxColumn,
- out Vector4 vector)
+ ref Vector4 targetVector)
where TPixel : unmanaged, IPixel
{
Vector4 vectorY = default;
Vector4 vectorX = default;
- int matrixHeight = matrixY.Rows;
- int matrixWidth = matrixY.Columns;
- int radiusY = matrixHeight >> 1;
- int radiusX = matrixWidth >> 1;
- int sourceOffsetColumnBase = column + minColumn;
+ int kernelHeight = kernelY.Rows;
+ int kernelWidth = kernelY.Columns;
- for (int y = 0; y < matrixHeight; y++)
+ for (int y = 0; y < kernelHeight; y++)
{
- int offsetY = Numerics.Clamp(row + y - radiusY, minRow, maxRow);
+ int offsetY = rowSampleOffsets[(row * kernelHeight) + y];
Span sourceRowSpan = sourcePixels.GetRowSpan(offsetY);
- for (int x = 0; x < matrixWidth; x++)
+ for (int x = 0; x < kernelWidth; x++)
{
- int offsetX = Numerics.Clamp(sourceOffsetColumnBase + x - radiusX, minColumn, maxColumn);
- var currentColor = sourceRowSpan[offsetX].ToVector4();
- Numerics.Premultiply(ref currentColor);
+ int offsetX = columnSampleOffsets[(column * kernelWidth) + x];
+ var sample = sourceRowSpan[offsetX].ToVector4();
+ Numerics.Premultiply(ref sample);
- vectorX += matrixX[y, x] * currentColor;
- vectorY += matrixY[y, x] * currentColor;
+ vectorX += kernelX[y, x] * sample;
+ vectorY += kernelY[y, x] * sample;
}
}
- vector = Vector4.SquareRoot((vectorX * vectorX) + (vectorY * vectorY));
+ targetVector = Vector4.SquareRoot((vectorX * vectorX) + (vectorY * vectorY));
}
///
@@ -156,18 +141,18 @@ namespace SixLabors.ImageSharp
/// Using this method the convolution filter is not applied to alpha in addition to the color channels.
///
/// The pixel format.
- /// The dense matrix.
- /// The span containing precalculated kernel y-offsets.
- /// The span containing precalculated kernel x-offsets.
+ /// The convolution kernel.
+ /// The span containing precalculated kernel y-sampling offsets.
+ /// The span containing precalculated kernel x-sampling offsets.
/// The source frame.
/// The target row base reference.
/// The current row.
/// The current column.
[MethodImpl(InliningOptions.ShortMethod)]
public static void Convolve3(
- in DenseMatrix matrix,
- Span yOffsetSpan,
- Span xOffsetSpan,
+ in DenseMatrix kernel,
+ Span rowSampleOffsets,
+ Span columnSampleOffsets,
Buffer2D sourcePixels,
ref Vector4 targetRowRef,
int row,
@@ -177,9 +162,9 @@ namespace SixLabors.ImageSharp
Vector4 vector = default;
ConvolveImpl(
- in matrix,
- yOffsetSpan,
- xOffsetSpan,
+ in kernel,
+ rowSampleOffsets,
+ columnSampleOffsets,
sourcePixels,
row,
column,
@@ -197,18 +182,18 @@ namespace SixLabors.ImageSharp
/// Using this method the convolution filter is applied to alpha in addition to the color channels.
///
/// The pixel format.
- /// The dense matrix.
- /// The span containing precalculated kernel y-offsets.
- /// The span containing precalculated kernel x-offsets.
+ /// The convolution kernel.
+ /// The span containing precalculated kernel y-offsets.
+ /// The span containing precalculated kernel x-offsets.
/// The source frame.
/// The target row base reference.
/// The current row.
/// The current column.
[MethodImpl(InliningOptions.ShortMethod)]
public static void Convolve4(
- in DenseMatrix matrix,
- Span yOffsetSpan,
- Span xOffsetSpan,
+ in DenseMatrix kernel,
+ Span rowSampleOffsets,
+ Span columnSampleOffsets,
Buffer2D sourcePixels,
ref Vector4 targetRowRef,
int row,
@@ -218,9 +203,9 @@ namespace SixLabors.ImageSharp
Vector4 vector = default;
ConvolveImpl(
- in matrix,
- yOffsetSpan,
- xOffsetSpan,
+ in kernel,
+ rowSampleOffsets,
+ columnSampleOffsets,
sourcePixels,
row,
column,
@@ -233,29 +218,29 @@ namespace SixLabors.ImageSharp
[MethodImpl(InliningOptions.ShortMethod)]
private static void ConvolveImpl(
- in DenseMatrix matrix,
- Span yOffsetSpan,
- Span xOffsetSpan,
+ in DenseMatrix kernel,
+ Span rowSampleOffsets,
+ Span columnSampleOffsets,
Buffer2D sourcePixels,
int row,
int column,
ref Vector4 targetVector)
where TPixel : unmanaged, IPixel
{
- int matrixHeight = matrix.Rows;
- int matrixWidth = matrix.Columns;
+ int kernelHeight = kernel.Rows;
+ int kernelWidth = kernel.Columns;
- for (int y = 0; y < matrixHeight; y++)
+ for (int y = 0; y < kernelHeight; y++)
{
- int offsetY = yOffsetSpan[(row * matrixHeight) + y];
+ int offsetY = rowSampleOffsets[(row * kernelHeight) + y];
Span sourceRowSpan = sourcePixels.GetRowSpan(offsetY);
- for (int x = 0; x < matrixWidth; x++)
+ for (int x = 0; x < kernelWidth; x++)
{
- int offsetX = xOffsetSpan[(column * matrixWidth) + x];
- var currentColor = sourceRowSpan[offsetX].ToVector4();
- Numerics.Premultiply(ref currentColor);
- targetVector += matrix[y, x] * currentColor;
+ int offsetX = columnSampleOffsets[(column * kernelWidth) + x];
+ var sample = sourceRowSpan[offsetX].ToVector4();
+ Numerics.Premultiply(ref sample);
+ targetVector += kernel[y, x] * sample;
}
}
}
diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/KernelOffsetMap.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/KernelSamplingMap.cs
similarity index 66%
rename from src/ImageSharp/Processing/Processors/Convolution/Kernels/KernelOffsetMap.cs
rename to src/ImageSharp/Processing/Processors/Convolution/Kernels/KernelSamplingMap.cs
index c1adf357ca..493c0d0fd2 100644
--- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/KernelOffsetMap.cs
+++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/KernelSamplingMap.cs
@@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
///
/// Provides a map of the convolution kernel sampling offsets.
///
- internal sealed class KernelOffsetMap : IDisposable
+ internal sealed class KernelSamplingMap : IDisposable
{
private readonly MemoryAllocator allocator;
private bool isDisposed;
@@ -19,37 +19,42 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
private IMemoryOwner xOffsets;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The memory allocator.
- public KernelOffsetMap(MemoryAllocator allocator) => this.allocator = allocator;
+ public KernelSamplingMap(MemoryAllocator allocator) => this.allocator = allocator;
- public void BuildOffsetMap(in DenseMatrix matrix, Rectangle bounds)
+ ///
+ /// Builds a map of the sampling offsets for the kernel clamped by the given bounds.
+ ///
+ /// The convolution kernel.
+ /// The source bounds.
+ public void BuildSamplingOffsetMap(DenseMatrix kernel, Rectangle bounds)
{
- int matrixHeight = matrix.Rows;
- int matrixWidth = matrix.Columns;
- this.yOffsets = this.allocator.Allocate(bounds.Height * matrixHeight);
- this.xOffsets = this.allocator.Allocate(bounds.Width * matrixWidth);
+ int kernelHeight = kernel.Rows;
+ int kernelWidth = kernel.Columns;
+ this.yOffsets = this.allocator.Allocate(bounds.Height * kernelHeight);
+ this.xOffsets = this.allocator.Allocate(bounds.Width * kernelWidth);
int minY = bounds.Y;
int maxY = bounds.Bottom - 1;
int minX = bounds.X;
int maxX = bounds.Right - 1;
- int radiusY = matrixHeight >> 1;
- int radiusX = matrixWidth >> 1;
+ int radiusY = kernelHeight >> 1;
+ int radiusX = kernelWidth >> 1;
// Calculate the potential sampling y-offsets.
Span ySpan = this.yOffsets.GetSpan();
for (int row = 0; row < bounds.Height; row++)
{
- for (int y = 0; y < matrixHeight; y++)
+ for (int y = 0; y < kernelHeight; y++)
{
- ySpan[(row * matrixHeight) + y] = row + y + minY - radiusY;
+ ySpan[(row * kernelHeight) + y] = row + y + minY - radiusY;
}
}
- if (matrixHeight > 1)
+ if (kernelHeight > 1)
{
Numerics.Clamp(ySpan, minY, maxY);
}
@@ -58,13 +63,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
Span xSpan = this.xOffsets.GetSpan();
for (int column = 0; column < bounds.Width; column++)
{
- for (int x = 0; x < matrixWidth; x++)
+ for (int x = 0; x < kernelWidth; x++)
{
- xSpan[(column * matrixWidth) + x] = column + x + minX - radiusX;
+ xSpan[(column * kernelWidth) + x] = column + x + minX - radiusX;
}
}
- if (matrixWidth > 1)
+ if (kernelWidth > 1)
{
Numerics.Clamp(xSpan, minX, maxX);
}