diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index 28b3d3a4d..4606f482c 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -55,13 +55,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [MethodImpl(InliningOptions.ShortMethod)] public Vector4 Convolve(Span rowSpan) { - ref Vector4 vecPtr = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowSpan), this.StartIndex); - - return this.ConvolveCore(ref vecPtr); + return this.ConvolveCore(rowSpan.Slice(this.StartIndex)); } [MethodImpl(InliningOptions.ShortMethod)] - public Vector4 ConvolveCore(ref Vector4 rowStartRef) + public Vector4 ConvolveCore(Span offsetedRowSpan) { ref float horizontalValues = ref Unsafe.AsRef(this.bufferPtr); // Destination color components @@ -70,7 +68,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int i = 0; i < this.Length; i++) { float weight = Unsafe.Add(ref horizontalValues, i); - Vector4 v = Unsafe.Add(ref rowStartRef, i); + //Vector4 v = Unsafe.Add(ref rowStartRef, i); + Vector4 v = offsetedRowSpan[i]; result += v * weight; } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs index 73f9b4241..abbe5908e 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs @@ -272,10 +272,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int x = 0; x < width; x++) { Span firstPassColumn = resizeWindow.GetColumnSpan(x, kernel.StartIndex); - ref Vector4 rowStartReference = ref MemoryMarshal.GetReference(firstPassColumn); // Destination color components - Unsafe.Add(ref tempRowBase, x) = kernel.ConvolveCore(ref rowStartReference); + Unsafe.Add(ref tempRowBase, x) = kernel.ConvolveCore(firstPassColumn); } Span targetRowSpan = destination.GetPixelRowSpan(y); diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs index ba5f9a984..8221a9cc4 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWindow.cs @@ -38,6 +38,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms private readonly int diameter; + private readonly int windowHeight; + public ResizeWindow( Configuration configuration, BufferArea source, @@ -59,15 +61,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.diameter = verticalKernelMap.MaxDiameter; + this.windowHeight = Math.Min(this.sourceRectangle.Height, 2 * this.diameter); + this.buffer = configuration.MemoryAllocator.Allocate2D( - this.sourceRectangle.Height, + this.windowHeight, destWidth, AllocationOptions.Clean); this.tempRowBuffer = configuration.MemoryAllocator.Allocate(this.sourceRectangle.Width); - - this.Top = 0; - - this.Bottom = this.sourceRectangle.Height; } public int Bottom { get; private set; } @@ -82,21 +82,26 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span GetColumnSpan(int x, int startY) { - return this.buffer.GetRowSpan(x).Slice(startY); + return this.buffer.GetRowSpan(x).Slice(startY - this.Top); } public void Initialize() { - this.Initialize(0, this.sourceRectangle.Height); + this.Initialize(0, this.windowHeight); } public void Slide() { - throw new InvalidOperationException("Shouldn't happen yet!"); + int top = this.Top + this.diameter; + int bottom = Math.Min(this.Bottom + this.diameter, this.sourceRectangle.Height); + this.Initialize(top, bottom); } private void Initialize(int top, int bottom) { + this.Top = top; + this.Bottom = bottom; + Span tempRowSpan = this.tempRowBuffer.GetSpan(); for (int y = top; y < bottom; y++) { @@ -108,12 +113,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms tempRowSpan, this.conversionModifiers); - ref Vector4 firstPassBaseRef = ref this.buffer.Span[y]; + //ref Vector4 firstPassBaseRef = ref this.buffer.Span[y - top]; + Span firstPassSpan = this.buffer.Span.Slice(y - top); for (int x = this.destWorkingRect.Left; x < this.destWorkingRect.Right; x++) { ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - this.startX); - Unsafe.Add(ref firstPassBaseRef, x * this.sourceRectangle.Height) = kernel.Convolve(tempRowSpan); + firstPassSpan[x * this.windowHeight] = kernel.Convolve(tempRowSpan); + //Unsafe.Add(ref firstPassBaseRef, x * this.sourceRectangle.Height) = kernel.Convolve(tempRowSpan); } } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 8c59fff26..3d6f08a15 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -102,6 +102,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms // [WithBasicTestPatternImages(15, 12, PixelTypes.Rgba32, 2, 3, 1, 2)] means: // resizing: (15, 12) -> (10, 6) // kernel dimensions: (3, 4) + using (Image image = provider.GetImage()) {