diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs index 81071dd1dc..beb14ad019 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs @@ -81,7 +81,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms if (sampler is NearestNeighborResampler) { - var nnOperation = new NNAffineOperation(source.PixelBuffer, destination.PixelBuffer, matrix); + var nnOperation = new NNAffineOperation( + source.PixelBuffer, + Rectangle.Intersect(this.SourceRectangle, source.Bounds()), + destination.PixelBuffer, + matrix); + ParallelRowIterator.IterateRows( configuration, destination.Bounds(), @@ -93,6 +98,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms var operation = new AffineOperation( configuration, source.PixelBuffer, + Rectangle.Intersect(this.SourceRectangle, source.Bounds()), destination.PixelBuffer, in sampler, matrix); @@ -113,12 +119,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [MethodImpl(InliningOptions.ShortMethod)] public NNAffineOperation( Buffer2D source, + Rectangle bounds, Buffer2D destination, Matrix3x2 matrix) { this.source = source; + this.bounds = bounds; this.destination = destination; - this.bounds = source.Bounds(); this.matrix = matrix; } @@ -146,6 +153,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { private readonly Configuration configuration; private readonly Buffer2D source; + private readonly Rectangle bounds; private readonly Buffer2D destination; private readonly TResampler sampler; private readonly Matrix3x2 matrix; @@ -156,12 +164,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public AffineOperation( Configuration configuration, Buffer2D source, + Rectangle bounds, Buffer2D destination, in TResampler sampler, Matrix3x2 matrix) { this.configuration = configuration; this.source = source; + this.bounds = bounds; this.destination = destination; this.sampler = sampler; this.matrix = matrix; @@ -190,8 +200,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms TResampler sampler = this.sampler; float yRadius = this.yRadius; float xRadius = this.xRadius; - int maxY = this.source.Height - 1; - int maxX = this.source.Width - 1; + int minY = this.bounds.Y; + int maxY = this.bounds.Right - 1; + int minX = this.bounds.X; + int maxX = this.bounds.Bottom - 1; for (int y = rows.Min; y < rows.Max; y++) { @@ -208,10 +220,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float pY = point.Y; float pX = point.X; - int top = LinearTransformUtility.GetRangeStart(yRadius, pY, maxY); - int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, maxY); - int left = LinearTransformUtility.GetRangeStart(xRadius, pX, maxX); - int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, maxX); + int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY); + int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY); + int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX); + int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX); if (bottom == top || right == left) { @@ -253,8 +265,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms TResampler sampler = this.sampler; float yRadius = this.yRadius; float xRadius = this.xRadius; - int maxY = this.source.Height - 1; - int maxX = this.source.Width - 1; + int minY = this.bounds.Y; + int maxY = this.bounds.Right - 1; + int minX = this.bounds.X; + int maxX = this.bounds.Bottom - 1; for (int y = rows.Min; y < rows.Max; y++) { @@ -271,10 +285,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float pY = point.Y; float pX = point.X; - int top = LinearTransformUtility.GetRangeStart(yRadius, pY, maxY); - int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, maxY); - int left = LinearTransformUtility.GetRangeStart(xRadius, pX, maxX); - int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, maxX); + int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY); + int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY); + int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX); + int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX); if (bottom == top || right == left) { diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs index c6168b4619..fd0c7f23bd 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs @@ -39,11 +39,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The radius. /// The center position. + /// The min allowed amouunt. /// The max allowed amouunt. /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static int GetRangeStart(float radius, float center, int max) - => Numerics.Clamp((int)MathF.Ceiling(center - radius), 0, max); + public static int GetRangeStart(float radius, float center, int min, int max) + => Numerics.Clamp((int)MathF.Ceiling(center - radius), min, max); /// /// Gets the end position (inclusive) for a sampling range given @@ -51,10 +52,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The radius. /// The center position. + /// The min allowed amouunt. /// The max allowed amouunt. /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static int GetRangeEnd(float radius, float center, int max) - => Numerics.Clamp((int)MathF.Floor(center + radius), 0, max); + public static int GetRangeEnd(float radius, float center, int min, int max) + => Numerics.Clamp((int)MathF.Floor(center + radius), min, max); } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs index 96e51afa8d..00bb074001 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs @@ -80,7 +80,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms if (sampler is NearestNeighborResampler) { - var nnOperation = new NNProjectiveOperation(source.PixelBuffer, destination.PixelBuffer, matrix); + var nnOperation = new NNProjectiveOperation( + source.PixelBuffer, + Rectangle.Intersect(this.SourceRectangle, source.Bounds()), + destination.PixelBuffer, + matrix); + ParallelRowIterator.IterateRows( configuration, destination.Bounds(), @@ -92,6 +97,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms var operation = new ProjectiveOperation( configuration, source.PixelBuffer, + Rectangle.Intersect(this.SourceRectangle, source.Bounds()), destination.PixelBuffer, in sampler, matrix); @@ -112,12 +118,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [MethodImpl(InliningOptions.ShortMethod)] public NNProjectiveOperation( Buffer2D source, + Rectangle bounds, Buffer2D destination, Matrix4x4 matrix) { this.source = source; + this.bounds = bounds; this.destination = destination; - this.bounds = source.Bounds(); this.matrix = matrix; } @@ -145,6 +152,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { private readonly Configuration configuration; private readonly Buffer2D source; + private readonly Rectangle bounds; private readonly Buffer2D destination; private readonly TResampler sampler; private readonly Matrix4x4 matrix; @@ -155,18 +163,20 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public ProjectiveOperation( Configuration configuration, Buffer2D source, + Rectangle bounds, Buffer2D destination, in TResampler sampler, Matrix4x4 matrix) { this.configuration = configuration; this.source = source; + this.bounds = bounds; this.destination = destination; this.sampler = sampler; this.matrix = matrix; - this.yRadius = LinearTransformUtility.GetSamplingRadius(in sampler, source.Height, destination.Height); - this.xRadius = LinearTransformUtility.GetSamplingRadius(in sampler, source.Width, destination.Width); + this.yRadius = LinearTransformUtility.GetSamplingRadius(in sampler, bounds.Height, destination.Height); + this.xRadius = LinearTransformUtility.GetSamplingRadius(in sampler, bounds.Width, destination.Width); } [MethodImpl(InliningOptions.ShortMethod)] @@ -189,8 +199,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms TResampler sampler = this.sampler; float yRadius = this.yRadius; float xRadius = this.xRadius; - int maxY = this.source.Height - 1; - int maxX = this.source.Width - 1; + int minY = this.bounds.Y; + int maxY = this.bounds.Right - 1; + int minX = this.bounds.X; + int maxX = this.bounds.Bottom - 1; for (int y = rows.Min; y < rows.Max; y++) { @@ -207,10 +219,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float pY = point.Y; float pX = point.X; - int top = LinearTransformUtility.GetRangeStart(yRadius, pY, maxY); - int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, maxY); - int left = LinearTransformUtility.GetRangeStart(xRadius, pX, maxX); - int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, maxX); + int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY); + int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY); + int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX); + int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX); if (bottom <= top || right <= left) { @@ -252,8 +264,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms TResampler sampler = this.sampler; float yRadius = this.yRadius; float xRadius = this.xRadius; - int maxY = this.source.Height - 1; - int maxX = this.source.Width - 1; + int minY = this.bounds.Y; + int maxY = this.bounds.Right - 1; + int minX = this.bounds.X; + int maxX = this.bounds.Bottom - 1; for (int y = rows.Min; y < rows.Max; y++) { @@ -270,10 +284,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms float pY = point.Y; float pX = point.X; - int top = LinearTransformUtility.GetRangeStart(yRadius, pY, maxY); - int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, maxY); - int left = LinearTransformUtility.GetRangeStart(xRadius, pX, maxX); - int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, maxX); + int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY); + int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY); + int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX); + int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX); if (bottom <= top || right <= left) {