From 5db408098aa96b07e53775b19c6ac3f38dba36e4 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 7 Feb 2020 22:44:32 +1100 Subject: [PATCH] Update ResizeProcessor{TPixel}.cs --- .../Resize/ResizeProcessor{TPixel}.cs | 88 +++++++++++++------ 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs index 5cfbbcb481..4a986adb05 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; - +using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -76,7 +76,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Configuration configuration = this.Configuration; // Handle resize dimensions identical to the original - if (source.Width == destination.Width && source.Height == destination.Height && sourceRectangle == this.targetRectangle) + if (source.Width == destination.Width + && source.Height == destination.Height + && sourceRectangle == this.targetRectangle) { // The cloned will be blank here copy all the pixel data over source.GetPixelSpan().CopyTo(destination.GetPixelSpan()); @@ -85,14 +87,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms int width = this.targetWidth; int height = this.targetHeight; - int sourceX = sourceRectangle.X; - int sourceY = sourceRectangle.Y; - int startY = this.targetRectangle.Y; - int startX = this.targetRectangle.X; - - var targetWorkingRect = Rectangle.Intersect( - this.targetRectangle, - new Rectangle(0, 0, width, height)); + var interest = Rectangle.Intersect(this.targetRectangle, new Rectangle(0, 0, width, height)); if (this.resampler is NearestNeighborResampler) { @@ -101,23 +96,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float heightFactor = sourceRectangle.Height / (float)this.targetRectangle.Height; ParallelRowIterator.IterateRows( - targetWorkingRect, + interest, configuration, - rows => - { - for (int y = rows.Min; y < rows.Max; y++) - { - // Y coordinates of source points - Span sourceRow = source.GetPixelRowSpan((int)(((y - startY) * heightFactor) + sourceY)); - Span targetRow = destination.GetPixelRowSpan(y); - - for (int x = targetWorkingRect.Left; x < targetWorkingRect.Right; x++) - { - // X coordinates of source points - targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)]; - } - } - }); + new RowIntervalAction(sourceRectangle, this.targetRectangle, widthFactor, heightFactor, source, destination)); return; } @@ -136,12 +117,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.horizontalKernelMap, this.verticalKernelMap, width, - targetWorkingRect, + interest, this.targetRectangle.Location)) { worker.Initialize(); - var workingInterval = new RowInterval(targetWorkingRect.Top, targetWorkingRect.Bottom); + var workingInterval = new RowInterval(interest.Top, interest.Bottom); worker.FillDestinationPixels(workingInterval, destination.PixelBuffer); } } @@ -165,5 +146,56 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.isDisposed = true; base.Dispose(disposing); } + + private readonly struct RowIntervalAction : IRowIntervalAction + { + private readonly Rectangle sourceBounds; + private readonly Rectangle destinationBounds; + private readonly float widthFactor; + private readonly float heightFactor; + private readonly ImageFrame source; + private readonly ImageFrame destination; + + [MethodImpl(InliningOptions.ShortMethod)] + public RowIntervalAction( + Rectangle sourceBounds, + Rectangle destinationBounds, + float widthFactor, + float heightFactor, + ImageFrame source, + ImageFrame destination) + { + this.sourceBounds = sourceBounds; + this.destinationBounds = destinationBounds; + this.widthFactor = widthFactor; + this.heightFactor = heightFactor; + this.source = source; + this.destination = destination; + } + + [MethodImpl(InliningOptions.ShortMethod)] + public void Invoke(in RowInterval rows) + { + int sourceX = this.sourceBounds.X; + int sourceY = this.sourceBounds.Y; + int destX = this.destinationBounds.X; + int destY = this.destinationBounds.Y; + int destLeft = this.destinationBounds.Left; + int destRight = this.destinationBounds.Right; + + for (int y = rows.Min; y < rows.Max; y++) + { + // Y coordinates of source points + Span sourceRow = this.source.GetPixelRowSpan((int)(((y - destY) * this.heightFactor) + sourceY)); + Span targetRow = this.destination.GetPixelRowSpan(y); + + for (int x = destLeft; x < destRight; x++) + { + // X coordinates of source points + targetRow[x] = sourceRow[(int)(((x - destX) * this.widthFactor) + sourceX)]; + } + } + } + } } }