diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor{TPixel}.cs
deleted file mode 100644
index 78310707c8..0000000000
--- a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor{TPixel}.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System.Numerics;
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp.Processing.Processors.Transforms
-{
- ///
- /// Provides the base methods to perform affine transforms on an image.
- ///
- /// The pixel format.
- internal partial class AffineTransformProcessor : TransformProcessor, IResamplingImageProcessor
- where TPixel : struct, IPixel
- {
- private readonly Size destinationSize;
- private readonly Matrix3x2 transformMatrix;
- private readonly IResampler resampler;
- private ImageFrame source;
- private ImageFrame destination;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The configuration which allows altering default behaviour or extending the library.
- /// The defining the processor parameters.
- /// The source for the current processor instance.
- /// The source area to process for the current processor instance.
- public AffineTransformProcessor(Configuration configuration, AffineTransformProcessor definition, Image source, Rectangle sourceRectangle)
- : base(configuration, source, sourceRectangle)
- {
- this.destinationSize = definition.DestinationSize;
- this.transformMatrix = definition.TransformMatrix;
- this.resampler = definition.Sampler;
- }
-
- protected override Size GetDestinationSize() => this.destinationSize;
-
- ///
- protected override void OnFrameApply(ImageFrame source, ImageFrame destination)
- {
- this.source = source;
- this.destination = destination;
- this.resampler.ApplyTransform(this);
- }
-
- ///
- public void ApplyTransform(in TResampler sampler)
- where TResampler : struct, IResampler
- => ApplyAffineTransform(
- this.Configuration,
- in sampler,
- this.source,
- this.destination,
- this.transformMatrix);
- }
-}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor{TPixel}.cs
deleted file mode 100644
index 8954d826f5..0000000000
--- a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor{TPixel}.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System.Numerics;
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp.Processing.Processors.Transforms
-{
- ///
- /// Provides the base methods to perform non-affine transforms on an image.
- ///
- /// The pixel format.
- internal partial class ProjectiveTransformProcessor : TransformProcessor, IResamplingImageProcessor
- where TPixel : struct, IPixel
- {
- private readonly Size destinationSize;
- private readonly IResampler resampler;
- private readonly Matrix4x4 transformMatrix;
- private ImageFrame source;
- private ImageFrame destination;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The configuration which allows altering default behaviour or extending the library.
- /// The defining the processor parameters.
- /// The source for the current processor instance.
- /// The source area to process for the current processor instance.
- public ProjectiveTransformProcessor(Configuration configuration, ProjectiveTransformProcessor definition, Image source, Rectangle sourceRectangle)
- : base(configuration, source, sourceRectangle)
- {
- this.destinationSize = definition.DestinationSize;
- this.transformMatrix = definition.TransformMatrix;
- this.resampler = definition.Sampler;
- }
-
- protected override Size GetDestinationSize() => this.destinationSize;
-
- ///
- protected override void OnFrameApply(ImageFrame source, ImageFrame destination)
- {
- this.source = source;
- this.destination = destination;
- this.resampler.ApplyTransform(this);
- }
-
- ///
- public void ApplyTransform(in TResampler sampler)
- where TResampler : struct, IResampler
- => ApplyProjectiveTransform(
- this.Configuration,
- in sampler,
- this.source,
- this.destination,
- this.transformMatrix);
- }
-}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/IResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/IResampler.cs
index 616872f2ab..c0c3be869b 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/IResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/IResampler.cs
@@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
/// The pixel format.
/// The transforming image processor.
- void ApplyTransform(IResamplingImageProcessor processor)
+ void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel;
}
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/IResamplingImageProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/IResamplingTransformImageProcessor{TPixel}.cs
similarity index 87%
rename from src/ImageSharp/Processing/Processors/Transforms/IResamplingImageProcessor{TPixel}.cs
rename to src/ImageSharp/Processing/Processors/Transforms/IResamplingTransformImageProcessor{TPixel}.cs
index cfa2df641d..ab750f7fb3 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/IResamplingImageProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/IResamplingTransformImageProcessor{TPixel}.cs
@@ -6,10 +6,10 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
///
- /// Implements an algorithm to alter the pixels of an image via a resampling transforms.
+ /// Implements an algorithm to alter the pixels of an image via resampling transforms.
///
/// The pixel format.
- public interface IResamplingImageProcessor : IImageProcessor
+ public interface IResamplingTransformImageProcessor : IImageProcessor
where TPixel : struct, IPixel
{
///
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor{TPixel}.Transforms.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs
similarity index 75%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor{TPixel}.Transforms.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs
index 3190857dd0..72bfa4c0be 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AffineTransformProcessor{TPixel}.Transforms.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs
@@ -11,28 +11,53 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
- ///
- /// Contains the application code for performing an affine transform.
- ///
- internal partial class AffineTransformProcessor
+ ///
+ /// Provides the base methods to perform affine transforms on an image.
+ ///
+ /// The pixel format.
+ internal class AffineTransformProcessor : TransformProcessor, IResamplingTransformImageProcessor
+ where TPixel : struct, IPixel
{
+ private readonly Size destinationSize;
+ private readonly Matrix3x2 transformMatrix;
+ private readonly IResampler resampler;
+ private ImageFrame source;
+ private ImageFrame destination;
+
///
- /// Applies an affine transformation upon an image.
+ /// Initializes a new instance of the class.
///
- /// The type of sampler.
- /// The configuration.
- /// The pixel sampler.
- /// The source image frame.
- /// The destination image frame.
- /// The transform matrix.
- public static void ApplyAffineTransform(
- Configuration configuration,
- in TResampler sampler,
- ImageFrame source,
- ImageFrame destination,
- Matrix3x2 matrix)
+ /// The configuration which allows altering default behaviour or extending the library.
+ /// The defining the processor parameters.
+ /// The source for the current processor instance.
+ /// The source area to process for the current processor instance.
+ public AffineTransformProcessor(Configuration configuration, AffineTransformProcessor definition, Image source, Rectangle sourceRectangle)
+ : base(configuration, source, sourceRectangle)
+ {
+ this.destinationSize = definition.DestinationSize;
+ this.transformMatrix = definition.TransformMatrix;
+ this.resampler = definition.Sampler;
+ }
+
+ protected override Size GetDestinationSize() => this.destinationSize;
+
+ ///
+ protected override void OnFrameApply(ImageFrame source, ImageFrame destination)
+ {
+ this.source = source;
+ this.destination = destination;
+ this.resampler.ApplyTransform(this);
+ }
+
+ ///
+ public void ApplyTransform(in TResampler sampler)
where TResampler : struct, IResampler
{
+ Configuration configuration = this.Configuration;
+ ImageFrame source = this.source;
+ ImageFrame destination = this.destination;
+ Matrix3x2 matrix = this.transformMatrix;
+
// Handle transforms that result in output identical to the original.
if (matrix.Equals(default) || matrix.Equals(Matrix3x2.Identity))
{
@@ -55,8 +80,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
return;
}
- int yRadius = AutomorphicTransformUtilities.GetSamplingRadius(in sampler, source.Height, destination.Height);
- int xRadius = AutomorphicTransformUtilities.GetSamplingRadius(in sampler, source.Width, destination.Width);
+ int yRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Height, destination.Height);
+ int xRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Width, destination.Width);
var radialExtents = new Vector2(xRadius, yRadius);
int yLength = (yRadius * 2) + 1;
int xLength = (xRadius * 2) + 1;
@@ -186,7 +211,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Use the single precision position to calculate correct bounding pixels
// otherwise we get rogue pixels outside of the bounds.
var point = Vector2.Transform(new Vector2(x, y), this.matrix);
- AutomorphicTransformUtilities.Convolve(
+ LinearTransformUtilities.Convolve(
in this.sampler,
point,
sourceBuffer,
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AutoOrientProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/AutoOrientProcessor.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AutoOrientProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/AutoOrientProcessor{TPixel}.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/FlipProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/FlipProcessor.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/FlipProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/FlipProcessor{TPixel}.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AutomorphicTransformUtilities.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtilities.cs
similarity index 98%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/AutomorphicTransformUtilities.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtilities.cs
index b2283af010..4fb1e27e09 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/AutomorphicTransformUtilities.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtilities.cs
@@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
/// Utility methods for affine and projective transforms.
///
- internal static class AutomorphicTransformUtilities
+ internal static class LinearTransformUtilities
{
[MethodImpl(InliningOptions.ShortMethod)]
internal static int GetSamplingRadius(in TResampler sampler, int sourceSize, int destinationSize)
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor{TPixel}.Transforms.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs
similarity index 75%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor{TPixel}.Transforms.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs
index c824bebaec..b3315fa554 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/ProjectiveTransformProcessor{TPixel}.Transforms.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs
@@ -11,28 +11,53 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
- ///
- /// Contains the application code for performing a projective transform.
- ///
- internal partial class ProjectiveTransformProcessor
+ ///
+ /// Provides the base methods to perform non-affine transforms on an image.
+ ///
+ /// The pixel format.
+ internal class ProjectiveTransformProcessor : TransformProcessor, IResamplingTransformImageProcessor
+ where TPixel : struct, IPixel
{
+ private readonly Size destinationSize;
+ private readonly IResampler resampler;
+ private readonly Matrix4x4 transformMatrix;
+ private ImageFrame source;
+ private ImageFrame destination;
+
///
- /// Applies a projective transformation upon an image.
+ /// Initializes a new instance of the class.
///
- /// The type of sampler.
- /// The configuration.
- /// The pixel sampler.
- /// The source image frame.
- /// The destination image frame.
- /// The transform matrix.
- public static void ApplyProjectiveTransform(
- Configuration configuration,
- in TResampler sampler,
- ImageFrame source,
- ImageFrame destination,
- Matrix4x4 matrix)
+ /// The configuration which allows altering default behaviour or extending the library.
+ /// The defining the processor parameters.
+ /// The source for the current processor instance.
+ /// The source area to process for the current processor instance.
+ public ProjectiveTransformProcessor(Configuration configuration, ProjectiveTransformProcessor definition, Image source, Rectangle sourceRectangle)
+ : base(configuration, source, sourceRectangle)
+ {
+ this.destinationSize = definition.DestinationSize;
+ this.transformMatrix = definition.TransformMatrix;
+ this.resampler = definition.Sampler;
+ }
+
+ protected override Size GetDestinationSize() => this.destinationSize;
+
+ ///
+ protected override void OnFrameApply(ImageFrame source, ImageFrame destination)
+ {
+ this.source = source;
+ this.destination = destination;
+ this.resampler.ApplyTransform(this);
+ }
+
+ ///
+ public void ApplyTransform(in TResampler sampler)
where TResampler : struct, IResampler
{
+ Configuration configuration = this.Configuration;
+ ImageFrame source = this.source;
+ ImageFrame destination = this.destination;
+ Matrix4x4 matrix = this.transformMatrix;
+
// Handle transforms that result in output identical to the original.
if (matrix.Equals(default) || matrix.Equals(Matrix4x4.Identity))
{
@@ -55,8 +80,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
return;
}
- int yRadius = AutomorphicTransformUtilities.GetSamplingRadius(in sampler, source.Height, destination.Height);
- int xRadius = AutomorphicTransformUtilities.GetSamplingRadius(in sampler, source.Width, destination.Width);
+ int yRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Height, destination.Height);
+ int xRadius = LinearTransformUtilities.GetSamplingRadius(in sampler, source.Width, destination.Width);
var radialExtents = new Vector2(xRadius, yRadius);
int yLength = (yRadius * 2) + 1;
int xLength = (xRadius * 2) + 1;
@@ -186,7 +211,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Use the single precision position to calculate correct bounding pixels
// otherwise we get rogue pixels outside of the bounds.
Vector2 point = TransformUtilities.ProjectiveTransform2D(x, y, this.matrix);
- AutomorphicTransformUtilities.Convolve(
+ LinearTransformUtilities.Convolve(
in this.sampler,
point,
sourceBuffer,
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/RotateProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/RotateProcessor.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/RotateProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/RotateProcessor{TPixel}.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Automorphic/SkewProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/SkewProcessor.cs
similarity index 100%
rename from src/ImageSharp/Processing/Processors/Transforms/Automorphic/SkewProcessor.cs
rename to src/ImageSharp/Processing/Processors/Transforms/Linear/SkewProcessor.cs
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BicubicResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BicubicResampler.cs
index 2992bbf5ac..085c81aad8 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BicubicResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BicubicResampler.cs
@@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
[MethodImpl(InliningOptions.ShortMethod)]
- public void ApplyTransform(IResamplingImageProcessor processor)
+ public void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel
=> processor.ApplyTransform(in this);
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BoxResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BoxResampler.cs
index 98a789e342..af2abb5f47 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BoxResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/BoxResampler.cs
@@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
[MethodImpl(InliningOptions.ShortMethod)]
- public void ApplyTransform(IResamplingImageProcessor processor)
+ public void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel
=> processor.ApplyTransform(in this);
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs
index a6fba1b33d..b399326741 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs
@@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
[MethodImpl(InliningOptions.ShortMethod)]
- public void ApplyTransform(IResamplingImageProcessor processor)
+ public void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel
=> processor.ApplyTransform(in this);
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs
index 90d60e1b08..202edcd363 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs
@@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
[MethodImpl(InliningOptions.ShortMethod)]
- public void ApplyTransform(IResamplingImageProcessor processor)
+ public void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel
=> processor.ApplyTransform(in this);
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/NearestNeighborResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/NearestNeighborResampler.cs
index 20f0a9fb85..0bce3d1297 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/NearestNeighborResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/NearestNeighborResampler.cs
@@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
[MethodImpl(InliningOptions.ShortMethod)]
- public void ApplyTransform(IResamplingImageProcessor processor)
+ public void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel
=> processor.ApplyTransform(in this);
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/TriangleResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/TriangleResampler.cs
index 9cf9ae66af..42459d4a3c 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/TriangleResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/TriangleResampler.cs
@@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
[MethodImpl(InliningOptions.ShortMethod)]
- public void ApplyTransform(IResamplingImageProcessor processor)
+ public void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel
=> processor.ApplyTransform(in this);
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs
index a162c7411f..6142dbe062 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
[MethodImpl(InliningOptions.ShortMethod)]
- public void ApplyTransform(IResamplingImageProcessor processor)
+ public void ApplyTransform(IResamplingTransformImageProcessor processor)
where TPixel : struct, IPixel
=> processor.ApplyTransform(in this);
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.Transforms.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.Transforms.cs
deleted file mode 100644
index 78f63ee0d3..0000000000
--- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.Transforms.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// 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;
-
-namespace SixLabors.ImageSharp.Processing.Processors.Transforms
-{
- ///
- /// Contains the application code for resizing.
- ///
- internal partial class ResizeProcessor
- where TPixel : struct, IPixel
- {
- ///
- /// Applies an resizing transformation upon an image.
- ///
- /// The type of sampler.
- /// The configuration.
- /// The pixel sampler.
- /// The source image.
- /// The destination image.
- /// The source bounds.
- /// The destination location.
- /// Whether to compress or expand individual pixel color values on processing.
- public static void ApplyResizeTransform(
- Configuration configuration,
- in TResampler sampler,
- Image source,
- Image destination,
- Rectangle sourceRectangle,
- Rectangle destinationRectangle,
- bool compand)
- where TResampler : struct, IResampler
- {
- // Handle resize dimensions identical to the original
- if (source.Width == destination.Width
- && source.Height == destination.Height
- && sourceRectangle == destinationRectangle)
- {
- for (int i = 0; i < source.Frames.Count; i++)
- {
- ImageFrame sourceFrame = source.Frames[i];
- ImageFrame destinationFrame = destination.Frames[i];
-
- // The cloned will be blank here copy all the pixel data over
- sourceFrame.GetPixelMemoryGroup().CopyTo(destinationFrame.GetPixelMemoryGroup());
- }
-
- return;
- }
-
- var interest = Rectangle.Intersect(destinationRectangle, destination.Bounds());
-
- if (sampler is NearestNeighborResampler)
- {
- for (int i = 0; i < source.Frames.Count; i++)
- {
- ImageFrame sourceFrame = source.Frames[i];
- ImageFrame destinationFrame = destination.Frames[i];
-
- ApplyNNResizeFrameTransform(
- configuration,
- sourceFrame,
- destinationFrame,
- sourceRectangle,
- destinationRectangle,
- interest);
- }
-
- return;
- }
-
- // Since all image frame dimensions have to be the same we can calculate
- // the kernel maps and reuse for all frames.
- MemoryAllocator allocator = configuration.MemoryAllocator;
- using var horizontalKernelMap = ResizeKernelMap.Calculate(
- in sampler,
- destinationRectangle.Width,
- sourceRectangle.Width,
- allocator);
-
- using var verticalKernelMap = ResizeKernelMap.Calculate(
- in sampler,
- destinationRectangle.Height,
- sourceRectangle.Height,
- allocator);
-
- for (int i = 0; i < source.Frames.Count; i++)
- {
- ImageFrame sourceFrame = source.Frames[i];
- ImageFrame destinationFrame = destination.Frames[i];
-
- ApplyResizeFrameTransform(
- configuration,
- sourceFrame,
- destinationFrame,
- horizontalKernelMap,
- verticalKernelMap,
- sourceRectangle,
- destinationRectangle,
- interest,
- compand);
- }
- }
-
- private static void ApplyNNResizeFrameTransform(
- Configuration configuration,
- ImageFrame source,
- ImageFrame destination,
- Rectangle sourceRectangle,
- Rectangle destinationRectangle,
- Rectangle interest)
- {
- // Scaling factors
- float widthFactor = sourceRectangle.Width / (float)destinationRectangle.Width;
- float heightFactor = sourceRectangle.Height / (float)destinationRectangle.Height;
-
- var operation = new NNRowIntervalOperation(
- sourceRectangle,
- destinationRectangle,
- widthFactor,
- heightFactor,
- source,
- destination);
-
- ParallelRowIterator.IterateRows(
- configuration,
- interest,
- in operation);
- }
-
- private static void ApplyResizeFrameTransform(
- Configuration configuration,
- ImageFrame source,
- ImageFrame destination,
- ResizeKernelMap horizontalKernelMap,
- ResizeKernelMap verticalKernelMap,
- Rectangle sourceRectangle,
- Rectangle destinationRectangle,
- Rectangle interest,
- bool compand)
- {
- PixelConversionModifiers conversionModifiers =
- PixelConversionModifiers.Premultiply.ApplyCompanding(compand);
-
- BufferArea sourceArea = source.PixelBuffer.GetArea(sourceRectangle);
-
- // To reintroduce parallel processing, we would launch multiple workers
- // for different row intervals of the image.
- using (var worker = new ResizeWorker(
- configuration,
- sourceArea,
- conversionModifiers,
- horizontalKernelMap,
- verticalKernelMap,
- destination.Width,
- interest,
- destinationRectangle.Location))
- {
- worker.Initialize();
-
- var workingInterval = new RowInterval(interest.Top, interest.Bottom);
- worker.FillDestinationPixels(workingInterval, destination.PixelBuffer);
- }
- }
-
- private readonly struct NNRowIntervalOperation : IRowIntervalOperation
- {
- 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 NNRowIntervalOperation(
- 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)];
- }
- }
- }
- }
- }
-}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs
index 5b69184d7c..1a6b8030db 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs
@@ -1,6 +1,10 @@
// Copyright (c) Six Labors and contributors.
// 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;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms
@@ -9,7 +13,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// Implements resizing of images using various resamplers.
///
/// The pixel format.
- internal partial class ResizeProcessor : TransformProcessor, IResamplingImageProcessor
+ internal partial class ResizeProcessor : TransformProcessor, IResamplingTransformImageProcessor
where TPixel : struct, IPixel
{
private readonly int destinationWidth;
@@ -48,14 +52,196 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
}
public void ApplyTransform(in TResampler sampler)
- where TResampler : struct, IResampler =>
- ApplyResizeTransform(
- this.Configuration,
+ where TResampler : struct, IResampler
+ {
+ Configuration configuration = this.Configuration;
+ Image source = this.Source;
+ Image destination = this.destination;
+ Rectangle sourceRectangle = this.SourceRectangle;
+ Rectangle destinationRectangle = this.destinationRectangle;
+ bool compand = this.compand;
+
+ // Handle resize dimensions identical to the original
+ if (source.Width == destination.Width
+ && source.Height == destination.Height
+ && sourceRectangle == destinationRectangle)
+ {
+ for (int i = 0; i < source.Frames.Count; i++)
+ {
+ ImageFrame sourceFrame = source.Frames[i];
+ ImageFrame destinationFrame = destination.Frames[i];
+
+ // The cloned will be blank here copy all the pixel data over
+ sourceFrame.GetPixelMemoryGroup().CopyTo(destinationFrame.GetPixelMemoryGroup());
+ }
+
+ return;
+ }
+
+ var interest = Rectangle.Intersect(destinationRectangle, destination.Bounds());
+
+ if (sampler is NearestNeighborResampler)
+ {
+ for (int i = 0; i < source.Frames.Count; i++)
+ {
+ ImageFrame sourceFrame = source.Frames[i];
+ ImageFrame destinationFrame = destination.Frames[i];
+
+ ApplyNNResizeFrameTransform(
+ configuration,
+ sourceFrame,
+ destinationFrame,
+ sourceRectangle,
+ destinationRectangle,
+ interest);
+ }
+
+ return;
+ }
+
+ // Since all image frame dimensions have to be the same we can calculate
+ // the kernel maps and reuse for all frames.
+ MemoryAllocator allocator = configuration.MemoryAllocator;
+ using var horizontalKernelMap = ResizeKernelMap.Calculate(
+ in sampler,
+ destinationRectangle.Width,
+ sourceRectangle.Width,
+ allocator);
+
+ using var verticalKernelMap = ResizeKernelMap.Calculate(
in sampler,
- this.Source,
- this.destination,
- this.SourceRectangle,
- this.destinationRectangle,
- this.compand);
+ destinationRectangle.Height,
+ sourceRectangle.Height,
+ allocator);
+
+ for (int i = 0; i < source.Frames.Count; i++)
+ {
+ ImageFrame sourceFrame = source.Frames[i];
+ ImageFrame destinationFrame = destination.Frames[i];
+
+ ApplyResizeFrameTransform(
+ configuration,
+ sourceFrame,
+ destinationFrame,
+ horizontalKernelMap,
+ verticalKernelMap,
+ sourceRectangle,
+ destinationRectangle,
+ interest,
+ compand);
+ }
+ }
+
+ private static void ApplyNNResizeFrameTransform(
+ Configuration configuration,
+ ImageFrame source,
+ ImageFrame destination,
+ Rectangle sourceRectangle,
+ Rectangle destinationRectangle,
+ Rectangle interest)
+ {
+ // Scaling factors
+ float widthFactor = sourceRectangle.Width / (float)destinationRectangle.Width;
+ float heightFactor = sourceRectangle.Height / (float)destinationRectangle.Height;
+
+ var operation = new NNRowIntervalOperation(
+ sourceRectangle,
+ destinationRectangle,
+ widthFactor,
+ heightFactor,
+ source,
+ destination);
+
+ ParallelRowIterator.IterateRows(
+ configuration,
+ interest,
+ in operation);
+ }
+
+ private static void ApplyResizeFrameTransform(
+ Configuration configuration,
+ ImageFrame source,
+ ImageFrame destination,
+ ResizeKernelMap horizontalKernelMap,
+ ResizeKernelMap verticalKernelMap,
+ Rectangle sourceRectangle,
+ Rectangle destinationRectangle,
+ Rectangle interest,
+ bool compand)
+ {
+ PixelConversionModifiers conversionModifiers =
+ PixelConversionModifiers.Premultiply.ApplyCompanding(compand);
+
+ BufferArea sourceArea = source.PixelBuffer.GetArea(sourceRectangle);
+
+ // To reintroduce parallel processing, we would launch multiple workers
+ // for different row intervals of the image.
+ using (var worker = new ResizeWorker(
+ configuration,
+ sourceArea,
+ conversionModifiers,
+ horizontalKernelMap,
+ verticalKernelMap,
+ destination.Width,
+ interest,
+ destinationRectangle.Location))
+ {
+ worker.Initialize();
+
+ var workingInterval = new RowInterval(interest.Top, interest.Bottom);
+ worker.FillDestinationPixels(workingInterval, destination.PixelBuffer);
+ }
+ }
+
+ private readonly struct NNRowIntervalOperation : IRowIntervalOperation
+ {
+ 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 NNRowIntervalOperation(
+ 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)];
+ }
+ }
+ }
+ }
}
}