diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs
index a69ceea5c..eeb4aef19 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeKernel.cs
@@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// The source row position.
/// The weighted sum
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector4 ConvolveRows(Span rowSpan, int sourceX)
+ public Vector4 Convolve(Span rowSpan, int sourceX)
{
ref float horizontalValues = ref this.GetStartReference();
int left = this.Left;
@@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// The source row position.
/// The weighted sum
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector4 ConvolveExpandRows(Span rowSpan, int sourceX)
+ public Vector4 ConvolveExpand(Span rowSpan, int sourceX)
{
ref float horizontalValues = ref this.GetStartReference();
int left = this.Left;
@@ -123,32 +123,5 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
return result;
}
-
- ///
- /// Computes the sum of vectors in 'firstPassPixels' at a row pointed by 'x',
- /// weighted by weight values, pointed by this instance.
- ///
- /// The buffer of input vectors in row first order
- /// The row position
- /// The source column position.
- /// The weighted sum
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector4 ConvolveColumnsAndUnPremultiply(Buffer2D firstPassPixels, int x, int sourceY)
- {
- ref float verticalValues = ref this.GetStartReference();
- int left = this.Left;
-
- // Destination color components
- Vector4 result = Vector4.Zero;
-
- for (int i = 0; i < this.Length; i++)
- {
- float yw = Unsafe.Add(ref verticalValues, i);
- int index = left + i + sourceY;
- result += firstPassPixels[x, index] * yw;
- }
-
- return result.UnPremultiply();
- }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
index 2643206b4..3c13d781e 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
@@ -233,10 +233,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle.
- // TODO: Using a transposed variant of 'firstPassPixels' could eliminate the need for the WeightsWindow.ComputeWeightedColumnSum() method, and improve speed!
- using (Buffer2D firstPassPixels = source.MemoryAllocator.Allocate2D(width, source.Height))
+ using (Buffer2D firstPassPixelsTransposed = source.MemoryAllocator.Allocate2D(source.Height, width))
{
- firstPassPixels.MemorySource.Clear();
+ firstPassPixelsTransposed.MemorySource.Clear();
var processColsRect = new Rectangle(0, 0, source.Width, sourceRectangle.Bottom);
@@ -247,8 +246,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
for (int y = rows.Min; y < rows.Max; y++)
{
- ref Vector4 firstPassRow =
- ref MemoryMarshal.GetReference(firstPassPixels.GetRowSpan(y));
Span sourceRow = source.GetPixelRowSpan(y);
Span tempRowSpan = tempRowBuffer.Span;
@@ -260,8 +257,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
for (int x = minX; x < maxX; x++)
{
ResizeKernel window = this.horizontalKernelMap.Kernels[x - startX];
- Unsafe.Add(ref firstPassRow, x) =
- window.ConvolveExpandRows(tempRowSpan, sourceX).UnPremultiply();
+ firstPassPixelsTransposed[y, x] = window.ConvolveExpand(tempRowSpan, sourceX).UnPremultiply();
}
}
else
@@ -269,8 +265,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
for (int x = minX; x < maxX; x++)
{
ResizeKernel window = this.horizontalKernelMap.Kernels[x - startX];
- Unsafe.Add(ref firstPassRow, x) =
- window.ConvolveRows(tempRowSpan, sourceX);
+ firstPassPixelsTransposed[y, x] =
+ window.Convolve(tempRowSpan, sourceX);
}
}
}
@@ -294,12 +290,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
for (int x = 0; x < width; x++)
{
+ Span firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x);
+
// Destination color components
- Vector4 destinationVector = window.ConvolveColumnsAndUnPremultiply(
- firstPassPixels,
- x,
- sourceY);
- destinationVector = destinationVector.Compress();
+ Vector4 destinationVector = window.Convolve(firstPassColumn, sourceY);
+ destinationVector = destinationVector.UnPremultiply().Compress();
ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
@@ -309,12 +304,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
for (int x = 0; x < width; x++)
{
- // Destination color components
- Vector4 destinationVector = window.ConvolveColumnsAndUnPremultiply(
- firstPassPixels,
- x,
- sourceY);
+ Span firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x);
+ // Destination color components
+ Vector4 destinationVector = window.Convolve(firstPassColumn, sourceY).UnPremultiply();
ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
}