diff --git a/src/ImageSharp/Processing/AffineTransformBuilder.cs b/src/ImageSharp/Processing/AffineTransformBuilder.cs index d16b2fe55a..59264698bd 100644 --- a/src/ImageSharp/Processing/AffineTransformBuilder.cs +++ b/src/ImageSharp/Processing/AffineTransformBuilder.cs @@ -11,7 +11,8 @@ namespace SixLabors.ImageSharp.Processing; /// public class AffineTransformBuilder { - private readonly List> matrixFactories = new List>(); + private readonly List> transformMatrixFactories = new(); + private readonly List> boundsMatrixFactories = new(); /// /// Prepends a rotation matrix using the given rotation angle in degrees @@ -29,7 +30,9 @@ public AffineTransformBuilder PrependRotationDegrees(float degrees) /// The amount of rotation, in radians. /// The . public AffineTransformBuilder PrependRotationRadians(float radians) - => this.Prepend(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); + => this.Prepend( + size => TransformUtils.CreateRotationTransformMatrixRadians(radians, size), + size => TransformUtils.CreateRotationBoundsMatrixRadians(radians, size)); /// /// Prepends a rotation matrix using the given rotation in degrees at the given origin. @@ -65,7 +68,9 @@ public AffineTransformBuilder AppendRotationDegrees(float degrees) /// The amount of rotation, in radians. /// The . public AffineTransformBuilder AppendRotationRadians(float radians) - => this.Append(size => TransformUtils.CreateRotationMatrixRadians(radians, size)); + => this.Append( + size => TransformUtils.CreateRotationTransformMatrixRadians(radians, size), + size => TransformUtils.CreateRotationBoundsMatrixRadians(radians, size)); /// /// Appends a rotation matrix using the given rotation in degrees at the given origin. @@ -140,7 +145,9 @@ public AffineTransformBuilder AppendScale(Vector2 scales) /// The Y angle, in degrees. /// The . public AffineTransformBuilder PrependSkewDegrees(float degreesX, float degreesY) - => this.Prepend(size => TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size)); + => this.Prepend( + size => TransformUtils.CreateSkewTransformMatrixDegrees(degreesX, degreesY, size), + size => TransformUtils.CreateSkewBoundsMatrixDegrees(degreesX, degreesY, size)); /// /// Prepends a centered skew matrix from the give angles in radians. @@ -149,7 +156,9 @@ public AffineTransformBuilder PrependSkewDegrees(float degreesX, float degreesY) /// The Y angle, in radians. /// The . public AffineTransformBuilder PrependSkewRadians(float radiansX, float radiansY) - => this.Prepend(size => TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size)); + => this.Prepend( + size => TransformUtils.CreateSkewTransformMatrixRadians(radiansX, radiansY, size), + size => TransformUtils.CreateSkewBoundsMatrixRadians(radiansX, radiansY, size)); /// /// Prepends a skew matrix using the given angles in degrees at the given origin. @@ -178,7 +187,9 @@ public AffineTransformBuilder PrependSkewRadians(float radiansX, float radiansY, /// The Y angle, in degrees. /// The . public AffineTransformBuilder AppendSkewDegrees(float degreesX, float degreesY) - => this.Append(size => TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size)); + => this.Append( + size => TransformUtils.CreateSkewTransformMatrixDegrees(degreesX, degreesY, size), + size => TransformUtils.CreateSkewBoundsMatrixDegrees(degreesX, degreesY, size)); /// /// Appends a centered skew matrix from the give angles in radians. @@ -187,7 +198,9 @@ public AffineTransformBuilder AppendSkewDegrees(float degreesX, float degreesY) /// The Y angle, in radians. /// The . public AffineTransformBuilder AppendSkewRadians(float radiansX, float radiansY) - => this.Append(size => TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size)); + => this.Append( + size => TransformUtils.CreateSkewTransformMatrixRadians(radiansX, radiansY, size), + size => TransformUtils.CreateSkewBoundsMatrixRadians(radiansX, radiansY, size)); /// /// Appends a skew matrix using the given angles in degrees at the given origin. @@ -254,7 +267,7 @@ public AffineTransformBuilder AppendTranslation(Vector2 position) public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) { CheckDegenerate(matrix); - return this.Prepend(_ => matrix); + return this.Prepend(_ => matrix, _ => matrix); } /// @@ -270,7 +283,7 @@ public AffineTransformBuilder PrependMatrix(Matrix3x2 matrix) public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) { CheckDegenerate(matrix); - return this.Append(_ => matrix); + return this.Append(_ => matrix, _ => matrix); } /// @@ -281,7 +294,7 @@ public AffineTransformBuilder AppendMatrix(Matrix3x2 matrix) public Matrix3x2 BuildMatrix(Size sourceSize) => this.BuildMatrix(new Rectangle(Point.Empty, sourceSize)); /// - /// Returns the combined matrix for a given source rectangle. + /// Returns the combined transform matrix for a given source rectangle. /// /// The rectangle in the source image. /// @@ -296,11 +309,11 @@ public Matrix3x2 BuildMatrix(Rectangle sourceRectangle) Guard.MustBeGreaterThan(sourceRectangle.Height, 0, nameof(sourceRectangle)); // Translate the origin matrix to cater for source rectangle offsets. - var matrix = Matrix3x2.CreateTranslation(-sourceRectangle.Location); + Matrix3x2 matrix = Matrix3x2.CreateTranslation(-sourceRectangle.Location); Size size = sourceRectangle.Size; - foreach (Func factory in this.matrixFactories) + foreach (Func factory in this.transformMatrixFactories) { matrix *= factory(size); } @@ -310,6 +323,32 @@ public Matrix3x2 BuildMatrix(Rectangle sourceRectangle) return matrix; } + /// + /// Returns the size of a rectangle large enough to contain the transformed source rectangle. + /// + /// The rectangle in the source image. + /// + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. + /// + /// The . + public Size GetTransformedSize(Rectangle sourceRectangle) + { + Size size = sourceRectangle.Size; + + // Translate the origin matrix to cater for source rectangle offsets. + Matrix3x2 matrix = Matrix3x2.CreateTranslation(-sourceRectangle.Location); + + foreach (Func factory in this.boundsMatrixFactories) + { + matrix *= factory(size); + CheckDegenerate(matrix); + } + + return TransformUtils.GetTransformedSize(size, matrix); + } + private static void CheckDegenerate(Matrix3x2 matrix) { if (TransformUtils.IsDegenerate(matrix)) @@ -318,15 +357,17 @@ private static void CheckDegenerate(Matrix3x2 matrix) } } - private AffineTransformBuilder Prepend(Func factory) + private AffineTransformBuilder Prepend(Func transformFactory, Func boundsFactory) { - this.matrixFactories.Insert(0, factory); + this.transformMatrixFactories.Insert(0, transformFactory); + this.boundsMatrixFactories.Insert(0, boundsFactory); return this; } - private AffineTransformBuilder Append(Func factory) + private AffineTransformBuilder Append(Func transformFactory, Func boundsFactory) { - this.matrixFactories.Add(factory); + this.transformMatrixFactories.Add(transformFactory); + this.boundsMatrixFactories.Add(boundsFactory); return this; } } diff --git a/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs index e88f000a7c..60f90b10f2 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs @@ -51,7 +51,7 @@ public static IImageProcessingContext Transform( IResampler sampler) { Matrix3x2 transform = builder.BuildMatrix(sourceRectangle); - Size targetDimensions = TransformUtils.GetTransformedSize(sourceRectangle.Size, transform); + Size targetDimensions = builder.GetTransformedSize(sourceRectangle); return source.Transform(sourceRectangle, transform, targetDimensions, sampler); } @@ -113,7 +113,7 @@ public static IImageProcessingContext Transform( IResampler sampler) { Matrix4x4 transform = builder.BuildMatrix(sourceRectangle); - Size targetDimensions = TransformUtils.GetTransformedSize(sourceRectangle.Size, transform); + Size targetDimensions = builder.GetTransformedSize(sourceRectangle); return source.Transform(sourceRectangle, transform, targetDimensions, sampler); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs index c92f424290..b5eb202c18 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtility.cs @@ -38,8 +38,8 @@ public static float GetSamplingRadius(in TResampler sampler, int sou /// /// The radius. /// The center position. - /// The min allowed amouunt. - /// The max allowed amouunt. + /// The min allowed amount. + /// The max allowed amount. /// The . [MethodImpl(InliningOptions.ShortMethod)] public static int GetRangeStart(float radius, float center, int min, int max) @@ -51,8 +51,8 @@ public static int GetRangeStart(float radius, float center, int min, int max) /// /// The radius. /// The center position. - /// The min allowed amouunt. - /// The max allowed amouunt. + /// The min allowed amount. + /// The max allowed amount. /// The . [MethodImpl(InliningOptions.ShortMethod)] public static int GetRangeEnd(float radius, float center, int min, int max) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor.cs index b8a8f424ba..6580636a24 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor.cs @@ -28,14 +28,15 @@ public RotateProcessor(float degrees, Size sourceSize) /// The source image size public RotateProcessor(float degrees, IResampler sampler, Size sourceSize) : this( - TransformUtils.CreateRotationMatrixDegrees(degrees, sourceSize), + TransformUtils.CreateRotationTransformMatrixDegrees(degrees, sourceSize), + TransformUtils.CreateRotationBoundsMatrixDegrees(degrees, sourceSize), sampler, sourceSize) => this.Degrees = degrees; // Helper constructor - private RotateProcessor(Matrix3x2 rotationMatrix, IResampler sampler, Size sourceSize) - : base(rotationMatrix, sampler, TransformUtils.GetTransformedSize(sourceSize, rotationMatrix)) + private RotateProcessor(Matrix3x2 rotationMatrix, Matrix3x2 boundsMatrix, IResampler sampler, Size sourceSize) + : base(rotationMatrix, sampler, TransformUtils.GetTransformedSize(sourceSize, boundsMatrix)) { } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/SkewProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/SkewProcessor.cs index 5f16ec530b..97b18de6c8 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/SkewProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/SkewProcessor.cs @@ -30,7 +30,8 @@ public SkewProcessor(float degreesX, float degreesY, Size sourceSize) /// The source image size public SkewProcessor(float degreesX, float degreesY, IResampler sampler, Size sourceSize) : this( - TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, sourceSize), + TransformUtils.CreateSkewTransformMatrixDegrees(degreesX, degreesY, sourceSize), + TransformUtils.CreateSkewBoundsMatrixDegrees(degreesX, degreesY, sourceSize), sampler, sourceSize) { @@ -39,8 +40,8 @@ public SkewProcessor(float degreesX, float degreesY, IResampler sampler, Size so } // Helper constructor: - private SkewProcessor(Matrix3x2 skewMatrix, IResampler sampler, Size sourceSize) - : base(skewMatrix, sampler, TransformUtils.GetTransformedSize(sourceSize, skewMatrix)) + private SkewProcessor(Matrix3x2 skewMatrix, Matrix3x2 boundsMatrix, IResampler sampler, Size sourceSize) + : base(skewMatrix, sampler, TransformUtils.GetTransformedSize(sourceSize, boundsMatrix)) { } diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs index 6ae0bbbdb0..70112ab5a8 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs @@ -29,7 +29,7 @@ public static bool IsDegenerate(Matrix3x2 matrix) public static bool IsDegenerate(Matrix4x4 matrix) => IsNaN(matrix) || IsZero(matrix.GetDeterminant()); - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool IsZero(float a) => a > -Constants.EpsilonSquared && a < Constants.EpsilonSquared; @@ -39,13 +39,11 @@ private static bool IsZero(float a) /// /// The transform matrix. /// The . - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNaN(Matrix3x2 matrix) - { - return float.IsNaN(matrix.M11) || float.IsNaN(matrix.M12) - || float.IsNaN(matrix.M21) || float.IsNaN(matrix.M22) - || float.IsNaN(matrix.M31) || float.IsNaN(matrix.M32); - } + => float.IsNaN(matrix.M11) || float.IsNaN(matrix.M12) + || float.IsNaN(matrix.M21) || float.IsNaN(matrix.M22) + || float.IsNaN(matrix.M31) || float.IsNaN(matrix.M32); /// /// Returns a value that indicates whether the specified matrix contains any values @@ -53,14 +51,12 @@ public static bool IsNaN(Matrix3x2 matrix) /// /// The transform matrix. /// The . - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsNaN(Matrix4x4 matrix) - { - return float.IsNaN(matrix.M11) || float.IsNaN(matrix.M12) || float.IsNaN(matrix.M13) || float.IsNaN(matrix.M14) - || float.IsNaN(matrix.M21) || float.IsNaN(matrix.M22) || float.IsNaN(matrix.M23) || float.IsNaN(matrix.M24) - || float.IsNaN(matrix.M31) || float.IsNaN(matrix.M32) || float.IsNaN(matrix.M33) || float.IsNaN(matrix.M34) - || float.IsNaN(matrix.M41) || float.IsNaN(matrix.M42) || float.IsNaN(matrix.M43) || float.IsNaN(matrix.M44); - } + => float.IsNaN(matrix.M11) || float.IsNaN(matrix.M12) || float.IsNaN(matrix.M13) || float.IsNaN(matrix.M14) + || float.IsNaN(matrix.M21) || float.IsNaN(matrix.M22) || float.IsNaN(matrix.M23) || float.IsNaN(matrix.M24) + || float.IsNaN(matrix.M31) || float.IsNaN(matrix.M32) || float.IsNaN(matrix.M33) || float.IsNaN(matrix.M34) + || float.IsNaN(matrix.M41) || float.IsNaN(matrix.M42) || float.IsNaN(matrix.M43) || float.IsNaN(matrix.M44); /// /// Applies the projective transform against the given coordinates flattened into the 2D space. @@ -69,71 +65,121 @@ public static bool IsNaN(Matrix4x4 matrix) /// The "y" vector coordinate. /// The transform matrix. /// The . - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 ProjectiveTransform2D(float x, float y, Matrix4x4 matrix) { - const float Epsilon = 0.0000001F; - var v4 = Vector4.Transform(new Vector4(x, y, 0, 1F), matrix); - return new Vector2(v4.X, v4.Y) / MathF.Max(v4.W, Epsilon); + const float epsilon = 0.0000001F; + Vector4 v4 = Vector4.Transform(new Vector4(x, y, 0, 1F), matrix); + return new Vector2(v4.X, v4.Y) / MathF.Max(v4.W, epsilon); } /// - /// Creates a centered rotation matrix using the given rotation in degrees and the source size. + /// Creates a centered rotation transform matrix using the given rotation in degrees and the source size. /// /// The amount of rotation, in degrees. /// The source image size. /// The . - [MethodImpl(InliningOptions.ShortMethod)] - public static Matrix3x2 CreateRotationMatrixDegrees(float degrees, Size size) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateRotationTransformMatrixDegrees(float degrees, Size size) => CreateCenteredTransformMatrix( new Rectangle(Point.Empty, size), Matrix3x2Extensions.CreateRotationDegrees(degrees, PointF.Empty)); /// - /// Creates a centered rotation matrix using the given rotation in radians and the source size. + /// Creates a centered rotation transform matrix using the given rotation in radians and the source size. /// /// The amount of rotation, in radians. /// The source image size. /// The . - [MethodImpl(InliningOptions.ShortMethod)] - public static Matrix3x2 CreateRotationMatrixRadians(float radians, Size size) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateRotationTransformMatrixRadians(float radians, Size size) => CreateCenteredTransformMatrix( new Rectangle(Point.Empty, size), Matrix3x2Extensions.CreateRotation(radians, PointF.Empty)); /// - /// Creates a centered skew matrix from the give angles in degrees and the source size. + /// Creates a centered rotation bounds matrix using the given rotation in degrees and the source size. + /// + /// The amount of rotation, in degrees. + /// The source image size. + /// The . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateRotationBoundsMatrixDegrees(float degrees, Size size) + => CreateCenteredBoundsMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateRotationDegrees(degrees, PointF.Empty)); + + /// + /// Creates a centered rotation bounds matrix using the given rotation in radians and the source size. + /// + /// The amount of rotation, in radians. + /// The source image size. + /// The . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateRotationBoundsMatrixRadians(float radians, Size size) + => CreateCenteredBoundsMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateRotation(radians, PointF.Empty)); + + /// + /// Creates a centered skew transform matrix from the give angles in degrees and the source size. /// /// The X angle, in degrees. /// The Y angle, in degrees. /// The source image size. /// The . - [MethodImpl(InliningOptions.ShortMethod)] - public static Matrix3x2 CreateSkewMatrixDegrees(float degreesX, float degreesY, Size size) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateSkewTransformMatrixDegrees(float degreesX, float degreesY, Size size) => CreateCenteredTransformMatrix( new Rectangle(Point.Empty, size), Matrix3x2Extensions.CreateSkewDegrees(degreesX, degreesY, PointF.Empty)); /// - /// Creates a centered skew matrix from the give angles in radians and the source size. + /// Creates a centered skew transform matrix from the give angles in radians and the source size. /// /// The X angle, in radians. /// The Y angle, in radians. /// The source image size. /// The . - [MethodImpl(InliningOptions.ShortMethod)] - public static Matrix3x2 CreateSkewMatrixRadians(float radiansX, float radiansY, Size size) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateSkewTransformMatrixRadians(float radiansX, float radiansY, Size size) => CreateCenteredTransformMatrix( new Rectangle(Point.Empty, size), Matrix3x2Extensions.CreateSkew(radiansX, radiansY, PointF.Empty)); /// - /// Gets the centered transform matrix based upon the source and destination rectangles. + /// Creates a centered skew bounds matrix from the give angles in degrees and the source size. + /// + /// The X angle, in degrees. + /// The Y angle, in degrees. + /// The source image size. + /// The . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateSkewBoundsMatrixDegrees(float degreesX, float degreesY, Size size) + => CreateCenteredBoundsMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateSkewDegrees(degreesX, degreesY, PointF.Empty)); + + /// + /// Creates a centered skew bounds matrix from the give angles in radians and the source size. + /// + /// The X angle, in radians. + /// The Y angle, in radians. + /// The source image size. + /// The . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateSkewBoundsMatrixRadians(float radiansX, float radiansY, Size size) + => CreateCenteredBoundsMatrix( + new Rectangle(Point.Empty, size), + Matrix3x2Extensions.CreateSkew(radiansX, radiansY, PointF.Empty)); + + /// + /// Gets the centered transform matrix based upon the source rectangle. /// /// The source image bounds. /// The transformation matrix. /// The - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Matrix3x2 CreateCenteredTransformMatrix(Rectangle sourceRectangle, Matrix3x2 matrix) { Rectangle destinationRectangle = GetTransformedBoundingRectangle(sourceRectangle, matrix); @@ -142,8 +188,33 @@ public static Matrix3x2 CreateCenteredTransformMatrix(Rectangle sourceRectangle, // This ensures scaling matrices are correct. Matrix3x2.Invert(matrix, out Matrix3x2 inverted); - var translationToTargetCenter = Matrix3x2.CreateTranslation(new Vector2(-destinationRectangle.Width, -destinationRectangle.Height) * .5F); - var translateToSourceCenter = Matrix3x2.CreateTranslation(new Vector2(sourceRectangle.Width, sourceRectangle.Height) * .5F); + // Centered transforms must be 0 based so we offset the bounds width and height. + Matrix3x2 translationToTargetCenter = Matrix3x2.CreateTranslation(new Vector2(-(destinationRectangle.Width - 1), -(destinationRectangle.Height - 1)) * .5F); + Matrix3x2 translateToSourceCenter = Matrix3x2.CreateTranslation(new Vector2(sourceRectangle.Width - 1, sourceRectangle.Height - 1) * .5F); + + // Translate back to world space. + Matrix3x2.Invert(translationToTargetCenter * inverted * translateToSourceCenter, out Matrix3x2 centered); + + return centered; + } + + /// + /// Gets the centered bounds matrix based upon the source rectangle. + /// + /// The source image bounds. + /// The transformation matrix. + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Matrix3x2 CreateCenteredBoundsMatrix(Rectangle sourceRectangle, Matrix3x2 matrix) + { + Rectangle destinationRectangle = GetTransformedBoundingRectangle(sourceRectangle, matrix); + + // We invert the matrix to handle the transformation from screen to world space. + // This ensures scaling matrices are correct. + Matrix3x2.Invert(matrix, out Matrix3x2 inverted); + + Matrix3x2 translationToTargetCenter = Matrix3x2.CreateTranslation(new Vector2(-destinationRectangle.Width, -destinationRectangle.Height) * .5F); + Matrix3x2 translateToSourceCenter = Matrix3x2.CreateTranslation(new Vector2(sourceRectangle.Width, sourceRectangle.Height) * .5F); // Translate back to world space. Matrix3x2.Invert(translationToTargetCenter * inverted * translateToSourceCenter, out Matrix3x2 centered); @@ -160,7 +231,7 @@ public static Matrix3x2 CreateCenteredTransformMatrix(Rectangle sourceRectangle, /// An enumeration that indicates on which corners to taper the rectangle. /// The amount to taper. /// The - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Matrix4x4 CreateTaperMatrix(Size size, TaperSide side, TaperCorner corner, float fraction) { Matrix4x4 matrix = Matrix4x4.Identity; @@ -281,7 +352,7 @@ public static Matrix4x4 CreateTaperMatrix(Size size, TaperSide side, TaperCorner /// /// The . /// - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Rectangle GetTransformedBoundingRectangle(Rectangle rectangle, Matrix3x2 matrix) { Rectangle transformed = GetTransformedRectangle(rectangle, matrix); @@ -303,10 +374,10 @@ public static Rectangle GetTransformedRectangle(Rectangle rectangle, Matrix3x2 m return rectangle; } - var tl = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Top), matrix); - var tr = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Top), matrix); - var bl = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Bottom), matrix); - var br = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Bottom), matrix); + Vector2 tl = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Top), matrix); + Vector2 tr = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Top), matrix); + Vector2 bl = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Bottom), matrix); + Vector2 br = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Bottom), matrix); return GetBoundingRectangle(tl, tr, bl, br); } @@ -341,7 +412,7 @@ public static Size GetTransformedSize(Size size, Matrix3x2 matrix) /// /// The . /// - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Rectangle GetTransformedRectangle(Rectangle rectangle, Matrix4x4 matrix) { if (rectangle.Equals(default) || Matrix4x4.Identity.Equals(matrix)) @@ -365,7 +436,7 @@ public static Rectangle GetTransformedRectangle(Rectangle rectangle, Matrix4x4 m /// /// The . /// - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Size GetTransformedSize(Size size, Matrix4x4 matrix) { Guard.IsTrue(size.Width > 0 && size.Height > 0, nameof(size), "Source size dimensions cannot be 0!"); @@ -380,7 +451,7 @@ public static Size GetTransformedSize(Size size, Matrix4x4 matrix) return ConstrainSize(rectangle); } - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Size ConstrainSize(Rectangle rectangle) { // We want to resize the canvas here taking into account any translations. @@ -402,7 +473,7 @@ private static Size ConstrainSize(Rectangle rectangle) return new Size(width, height); } - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Rectangle GetBoundingRectangle(Vector2 tl, Vector2 tr, Vector2 bl, Vector2 br) { // Find the minimum and maximum "corners" based on the given vectors diff --git a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs index ad0888ad77..0387adebb9 100644 --- a/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs +++ b/src/ImageSharp/Processing/ProjectiveTransformBuilder.cs @@ -11,7 +11,8 @@ namespace SixLabors.ImageSharp.Processing; /// public class ProjectiveTransformBuilder { - private readonly List> matrixFactories = new(); + private readonly List> transformMatrixFactories = new(); + private readonly List> boundsMatrixFactories = new(); /// /// Prepends a matrix that performs a tapering projective transform. @@ -21,7 +22,9 @@ public class ProjectiveTransformBuilder /// The amount to taper. /// The . public ProjectiveTransformBuilder PrependTaper(TaperSide side, TaperCorner corner, float fraction) - => this.Prepend(size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction)); + => this.Prepend( + size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction), + size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction)); /// /// Appends a matrix that performs a tapering projective transform. @@ -31,7 +34,9 @@ public ProjectiveTransformBuilder PrependTaper(TaperSide side, TaperCorner corne /// The amount to taper. /// The . public ProjectiveTransformBuilder AppendTaper(TaperSide side, TaperCorner corner, float fraction) - => this.Append(size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction)); + => this.Append( + size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction), + size => TransformUtils.CreateTaperMatrix(size, side, corner, fraction)); /// /// Prepends a centered rotation matrix using the given rotation in degrees. @@ -47,7 +52,9 @@ public ProjectiveTransformBuilder PrependRotationDegrees(float degrees) /// The amount of rotation, in radians. /// The . public ProjectiveTransformBuilder PrependRotationRadians(float radians) - => this.Prepend(size => new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, size))); + => this.Prepend( + size => new Matrix4x4(TransformUtils.CreateRotationTransformMatrixRadians(radians, size)), + size => new Matrix4x4(TransformUtils.CreateRotationBoundsMatrixRadians(radians, size))); /// /// Prepends a centered rotation matrix using the given rotation in degrees at the given origin. @@ -81,7 +88,9 @@ public ProjectiveTransformBuilder AppendRotationDegrees(float degrees) /// The amount of rotation, in radians. /// The . public ProjectiveTransformBuilder AppendRotationRadians(float radians) - => this.Append(size => new Matrix4x4(TransformUtils.CreateRotationMatrixRadians(radians, size))); + => this.Append( + size => new Matrix4x4(TransformUtils.CreateRotationTransformMatrixRadians(radians, size)), + size => new Matrix4x4(TransformUtils.CreateRotationBoundsMatrixRadians(radians, size))); /// /// Appends a centered rotation matrix using the given rotation in degrees at the given origin. @@ -165,7 +174,9 @@ internal ProjectiveTransformBuilder PrependSkewDegrees(float degreesX, float deg /// The Y angle, in radians. /// The . public ProjectiveTransformBuilder PrependSkewRadians(float radiansX, float radiansY) - => this.Prepend(size => new Matrix4x4(TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size))); + => this.Prepend( + size => new Matrix4x4(TransformUtils.CreateSkewTransformMatrixRadians(radiansX, radiansY, size)), + size => new Matrix4x4(TransformUtils.CreateSkewBoundsMatrixRadians(radiansX, radiansY, size))); /// /// Prepends a skew matrix using the given angles in degrees at the given origin. @@ -203,7 +214,9 @@ internal ProjectiveTransformBuilder AppendSkewDegrees(float degreesX, float degr /// The Y angle, in radians. /// The . public ProjectiveTransformBuilder AppendSkewRadians(float radiansX, float radiansY) - => this.Append(size => new Matrix4x4(TransformUtils.CreateSkewMatrixRadians(radiansX, radiansY, size))); + => this.Append( + size => new Matrix4x4(TransformUtils.CreateSkewTransformMatrixRadians(radiansX, radiansY, size)), + size => new Matrix4x4(TransformUtils.CreateSkewBoundsMatrixRadians(radiansX, radiansY, size))); /// /// Appends a skew matrix using the given angles in degrees at the given origin. @@ -270,7 +283,7 @@ public ProjectiveTransformBuilder AppendTranslation(Vector2 position) public ProjectiveTransformBuilder PrependMatrix(Matrix4x4 matrix) { CheckDegenerate(matrix); - return this.Prepend(_ => matrix); + return this.Prepend(_ => matrix, _ => matrix); } /// @@ -286,7 +299,7 @@ public ProjectiveTransformBuilder PrependMatrix(Matrix4x4 matrix) public ProjectiveTransformBuilder AppendMatrix(Matrix4x4 matrix) { CheckDegenerate(matrix); - return this.Append(_ => matrix); + return this.Append(_ => matrix, _ => matrix); } /// @@ -317,7 +330,7 @@ public Matrix4x4 BuildMatrix(Rectangle sourceRectangle) Size size = sourceRectangle.Size; - foreach (Func factory in this.matrixFactories) + foreach (Func factory in this.transformMatrixFactories) { matrix *= factory(size); } @@ -327,6 +340,32 @@ public Matrix4x4 BuildMatrix(Rectangle sourceRectangle) return matrix; } + /// + /// Returns the size of a rectangle large enough to contain the transformed source rectangle. + /// + /// The rectangle in the source image. + /// + /// The resultant matrix is degenerate containing one or more values equivalent + /// to or a zero determinant and therefore cannot be used + /// for linear transforms. + /// + /// The . + public Size GetTransformedSize(Rectangle sourceRectangle) + { + Size size = sourceRectangle.Size; + + // Translate the origin matrix to cater for source rectangle offsets. + Matrix4x4 matrix = Matrix4x4.CreateTranslation(new Vector3(-sourceRectangle.Location, 0)); + + foreach (Func factory in this.boundsMatrixFactories) + { + matrix *= factory(size); + CheckDegenerate(matrix); + } + + return TransformUtils.GetTransformedSize(size, matrix); + } + private static void CheckDegenerate(Matrix4x4 matrix) { if (TransformUtils.IsDegenerate(matrix)) @@ -335,15 +374,17 @@ private static void CheckDegenerate(Matrix4x4 matrix) } } - private ProjectiveTransformBuilder Prepend(Func factory) + private ProjectiveTransformBuilder Prepend(Func transformFactory, Func boundsFactory) { - this.matrixFactories.Insert(0, factory); + this.transformMatrixFactories.Insert(0, transformFactory); + this.boundsMatrixFactories.Insert(0, boundsFactory); return this; } - private ProjectiveTransformBuilder Append(Func factory) + private ProjectiveTransformBuilder Append(Func transformFactory, Func boundsFactory) { - this.matrixFactories.Add(factory); + this.transformMatrixFactories.Add(transformFactory); + this.boundsMatrixFactories.Add(boundsFactory); return this; } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs index 0fc5e286da..895cf60fd3 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs @@ -261,6 +261,34 @@ public void Transform_With_Custom_Dimensions(TestImageProvider p image.CompareToReferenceOutput(ValidatorComparer, provider, testOutputDetails: radians); } + [Fact] + public void TransformRotationDoesNotOffset() + { + Rgba32 marker = Color.Aqua; + + using Image img = new(100, 100, Color.DimGray); + img[0, 0] = marker; + + img.Mutate(c => c.Rotate(180)); + + Assert.Equal(marker, img[99, 99]); + + using Image img2 = new(100, 100, Color.DimGray); + img2[0, 0] = marker; + + img2.Mutate( + c => + c.Transform(new AffineTransformBuilder().AppendRotationDegrees(180), KnownResamplers.NearestNeighbor)); + + using Image img3 = new(100, 100, Color.DimGray); + img3[0, 0] = marker; + + img3.Mutate(c => c.Transform(new AffineTransformBuilder().AppendRotationDegrees(180))); + + ImageComparer.Exact.VerifySimilarity(img, img2); + ImageComparer.Exact.VerifySimilarity(img, img3); + } + private static IResampler GetResampler(string name) { PropertyInfo property = typeof(KnownResamplers).GetTypeInfo().GetProperty(name); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs index a744a0ecc6..21eda034ea 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs @@ -185,6 +185,34 @@ public void Transform_With_Custom_Dimensions(TestImageProvider p image.CompareToReferenceOutput(ValidatorComparer, provider, testOutputDetails: radians); } + [Fact] + public void TransformRotationDoesNotOffset() + { + Rgba32 marker = Color.Aqua; + + using Image img = new(100, 100, Color.DimGray); + img[0, 0] = marker; + + img.Mutate(c => c.Rotate(180)); + + Assert.Equal(marker, img[99, 99]); + + using Image img2 = new(100, 100, Color.DimGray); + img2[0, 0] = marker; + + img2.Mutate( + c => + c.Transform(new ProjectiveTransformBuilder().AppendRotationDegrees(180), KnownResamplers.NearestNeighbor)); + + using Image img3 = new(100, 100, Color.DimGray); + img3[0, 0] = marker; + + img3.Mutate(c => c.Transform(new AffineTransformBuilder().AppendRotationDegrees(180))); + + ImageComparer.Exact.VerifySimilarity(img, img2); + ImageComparer.Exact.VerifySimilarity(img, img3); + } + private static IResampler GetResampler(string name) { PropertyInfo property = typeof(KnownResamplers).GetTypeInfo().GetProperty(name); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs index c17fd23799..9d256efc1c 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/TransformBuilderTestBase.cs @@ -97,7 +97,7 @@ public void AppendRotationDegrees_WithoutSpecificRotationCenter_RotationIsCenter this.AppendRotationDegrees(builder, degrees); // TODO: We should also test CreateRotationMatrixDegrees() (and all TransformUtils stuff!) for correctness - Matrix3x2 matrix = TransformUtils.CreateRotationMatrixDegrees(degrees, size); + Matrix3x2 matrix = TransformUtils.CreateRotationTransformMatrixDegrees(degrees, size); var position = new Vector2(x, y); var expected = Vector2.Transform(position, matrix); @@ -151,7 +151,7 @@ public void AppendSkewDegrees_WithoutSpecificSkewCenter_SkewIsCenteredAroundImag this.AppendSkewDegrees(builder, degreesX, degreesY); - Matrix3x2 matrix = TransformUtils.CreateSkewMatrixDegrees(degreesX, degreesY, size); + Matrix3x2 matrix = TransformUtils.CreateSkewTransformMatrixDegrees(degreesX, degreesY, size); var position = new Vector2(x, y); var expected = Vector2.Transform(position, matrix); diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(-20,-10).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(-20,-10).png index d2ee69ce84..e8edb57b9b 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(-20,-10).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(-20,-10).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6b13fd15f767271628930510b9a00cc71c8dbe37158cdee7459e8184b2c254b -size 689 +oid sha256:8dc4da0a0c727f2c95bbfdcc7710ca612b008dca97dfc5101175c384c010641b +size 770 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(0,0).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(0,0).png index b3dc8be7f7..20fa4e18fc 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(0,0).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(0,0).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c186653c2431d706175ac59b06637852942d18a9177b21772d3ab511c563202 -size 723 +oid sha256:5ec2dd66678dc1a0ae3bd4bf6667fbb8ceb8a8af63ca878c490545e303c9d1ad +size 851 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(20,10).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(20,10).png index f00a63f90d..beb117e113 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(20,10).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,1)_T(20,10).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:291e1044a062943cc91840cd252e7cc4722d8f5bc59386597c6c2aac5565b5f4 -size 757 +oid sha256:febfdb0554e69f7fe363bca5aaff4b0a5347d216b29a0ba8cbebe92aa8678015 +size 892 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,2)_T(0,0).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,2)_T(0,0).png index 1b361c4674..da8e446c02 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,2)_T(0,0).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(1,2)_T(0,0).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8f2167445c7ca069b0f33b56f4e758e9929ff5753d076c987cf53c5d7cc3bc2 -size 3318 +oid sha256:b66a5f9d8a7f3f2a78b868bec6c7d1deea927b82d81aa6d1677e0461a3920dc9 +size 3800 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(2,1)_T(0,0).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(2,1)_T(0,0).png index 7a8fe20870..4c45ba8c6c 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(2,1)_T(0,0).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(0)_S(2,1)_T(0,0).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:462eaba7681f5a43f3012f8b6445180173b398c932a3cd8ec2e15cb1df9d9c4e -size 4327 +oid sha256:d5fdc46ee866e088e0ec3221145a3d2d954a0bcb6d25cbb4d538978272f34949 +size 4871 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(-20,-10).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(-20,-10).png index 49c7795fe5..2ba0560e65 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(-20,-10).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(-20,-10).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2ef489dc0837b382ad7c7ead6b7c7042dfbfba39902d4cc81b5f3805d5b03967 -size 9175 +oid sha256:1b926c8335eca5530d8704739cecae0799cc651139daedb1f88ac85b0ee1bd5d +size 9484 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(0,0).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(0,0).png index ad39ebb12c..d141a2e28c 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(0,0).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(0,0).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d1fb97a28b5f754150343a3dc3c6974ac9abbb1577a44d88db61f0169983db0 -size 11083 +oid sha256:7f79389f79d91ac6749f21c27a592edfd2cff6efbb1d46296a26ae60d4e721f8 +size 10103 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(20,10).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(20,10).png index 20d15c665d..d01fcb4a49 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(20,10).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1,1)_T(20,10).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c78c6310b6b716e9fdb1605b5b356fa7e1b0fbed9f6e6ff0d705d5152ce52665 -size 11148 +oid sha256:322c7e061f8565efdc19642e27353ec3073ee43d8c17fbef8c13be3bb60d11dc +size 10190 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.1,1.3)_T(30,-20).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.1,1.3)_T(30,-20).png index 713ce31038..171080746b 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.1,1.3)_T(30,-20).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.1,1.3)_T(30,-20).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b4b00b7801fd844035d9235f3d1163587e9847001b918b2d971ea7e917485371 -size 13683 +oid sha256:544e7bac188d0869f98ec075fa0e73ab831e4dafe40c1520dce194df6a53c9b8 +size 12737 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.5,1.5)_T(0,0).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.5,1.5)_T(0,0).png index df59e96932..07c65142a4 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.5,1.5)_T(0,0).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50_R(50)_S(1.5,1.5)_T(0,0).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0b6f27c2361cc100b6928195522e0c8e76ee3ceeda814bd036d0636957024c9f -size 22761 +oid sha256:2ccc08769974e4088702d2c95fd274af7e02095955953b424a6313d656a77735 +size 19974 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50__original.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50__original.png index a6ff73cf83..20fa4e18fc 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50__original.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScaleTranslate_Rgba32_TestPattern100x50__original.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99d6c1d6b092a2feba2aebe2e09c521c3cc9682f3d748927cdc3cbaa38448b28 -size 710 +oid sha256:5ec2dd66678dc1a0ae3bd4bf6667fbb8ceb8a8af63ca878c490545e303c9d1ad +size 851 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScale_ManuallyCentered_Rgba32_TestPattern96x96_R(50)_S(0.8).png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScale_ManuallyCentered_Rgba32_TestPattern96x96_R(50)_S(0.8).png index 27a25224d3..84fffa468f 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScale_ManuallyCentered_Rgba32_TestPattern96x96_R(50)_S(0.8).png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_RotateScale_ManuallyCentered_Rgba32_TestPattern96x96_R(50)_S(0.8).png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad5beec2c4a09ef8c4718bb39bda5b2d0bfcccfa4634b7458ac748d2fda498fe -size 11738 +oid sha256:c1179b300b35d526bab148833ab6240f1207b8ade36674b1f47cc5a2d47a084c +size 10603 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Bicubic.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Bicubic.png index a909194b0b..1f1d530517 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Bicubic.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Bicubic.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04a3b84c668758b586f4d998f080ef96b09f726b0298b28f5dd3d739b0e90744 -size 13138 +oid sha256:f666fe67ee4a1c7152fc6190affba95ea4cbd857d96bac0968e5f1fd89792d32 +size 13486 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Box.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Box.png index 5a8c0f2faa..0ce7ad5625 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Box.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Box.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21f13832d15b9491e8b73711b3081fa56c08ca69bd9b165c323dec0ba4e6f99f -size 11358 +oid sha256:5b05406a1d95f0709a7aaab7c1f57ba161b7907b76746f61788cfe527796a489 +size 4131 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_CatmullRom.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_CatmullRom.png index a909194b0b..e93934b48d 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_CatmullRom.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_CatmullRom.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04a3b84c668758b586f4d998f080ef96b09f726b0298b28f5dd3d739b0e90744 -size 13138 +oid sha256:be52d36cc8f616a781c8b1416ca0bf6207b9acd580e9c06e1ee5ad434d48ab38 +size 13481 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Hermite.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Hermite.png index 7bfe765533..2a68a381d4 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Hermite.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Hermite.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:829f7e7315a5a0cc3e88115529305ddb0c53a104863a8a66f6ad1f2efc440109 -size 12231 +oid sha256:33c99b8f0fb5d10a273a90946767f93ab6cd2dd1942f9829d695987db30dccfa +size 12488 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos2.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos2.png index e248b6d918..08f89da07e 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos2.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ea7ca66c31474c0bb9673a0d85c1c7465e387ebabf4e2d1e8f9daebfc7c8f34 -size 13956 +oid sha256:af2c0201c59065a500ae985e9b7ca164e5bcb4ce2d8d8305103398830472e07c +size 14206 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos3.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos3.png index 5c81a5f5da..85d4871036 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos3.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6dd98ac441f3c20ea999f058c7b21601d5981d46e9b77709c25f2930a64edb93 -size 17148 +oid sha256:4cef17988c4a3a667dede3dd86ed61d0507a84e5b846f52459683fd04e5a396a +size 17297 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos5.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos5.png index 1647aae60d..347cbf089f 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos5.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5c4772d9b9dc57c4b5d47450ec9d02d96e40656cf2015f171b5425945f8a598 -size 18726 +oid sha256:9699a81572c03c2bc47d8bbdd1d64df26f87df3d4ad59fb6f164f6e82786d91d +size 18853 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos8.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos8.png index 3949197248..69fe0b1355 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos8.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Lanczos8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb025c4470cec1b0d6544924e46b84cbdb90d75da5d0f879f2c7d7ec9875dee2 -size 20574 +oid sha256:4fb1f59c5393debdff9bd4b7a6c222b7a0686e6d5ef24363e3d5c94ba9b5bc27 +size 20725 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_MitchellNetravali.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_MitchellNetravali.png index da8413be52..0fa8cf0c06 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_MitchellNetravali.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_MitchellNetravali.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4abaa06827cb779026f8fbb655692bdd8adab37ae5b00c3ae18ebea456eb8d9 -size 13459 +oid sha256:8ffa8ca6a60de9fe26a191edc2127886c61c072c1aa2b91fe3125512fe40e1b3 +size 13848 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_NearestNeighbor.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_NearestNeighbor.png index 06c6bfa22e..36e409ecb9 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_NearestNeighbor.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_NearestNeighbor.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37332e56f71506663b00deacc52adaa7574167565e395217b493d235965b29b9 -size 11563 +oid sha256:abf1d0f323795c0aaff0ff8b488d9866c5b2f7c64aad83701cb1f60e22668b0e +size 4161 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Robidoux.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Robidoux.png index 5bdf261405..f8f102e4c8 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Robidoux.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Robidoux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3435ade8f7988779280820342e16881b049f717735d2218ac5a971a1bd807db1 -size 13448 +oid sha256:9b0f3c41248138bd501ae844e5b54fb9f49e5d22bab9b2ef0a0654034708b99f +size 14027 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_RobidouxSharp.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_RobidouxSharp.png index 0e2dbf2565..fc46cad7c0 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_RobidouxSharp.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_RobidouxSharp.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0098aa45e820544dd16a58396fa70860886b7d79900916ed97376a8328a5ff2 -size 13367 +oid sha256:6a3f839d64984b9fda4125c6643f4699add6f95373a2194c5726ed3740565a47 +size 13725 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Spline.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Spline.png index 27ed945dc8..58e879d4e3 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Spline.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Spline.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7729495277b80a42e24dd8f40cdd8a280443575710fb4e199e4871c28b558271 -size 14253 +oid sha256:2ac143bc73612cecfffbec049a7b68234e7bf7581e680c3f996a977c6d671cc1 +size 14865 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Triangle.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Triangle.png index 90c47e96d7..fa25146d9c 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Triangle.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Triangle.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2304c234b93bdabaa018263dec70e62090ad1bbb7005ef62643b88600a863fb -size 12157 +oid sha256:4eb9dab20d5a03c0adde05a9b741d9e1b0fb8c3d79054a8bc5788de496e5c7f8 +size 12420 diff --git a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Welch.png b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Welch.png index 581b229500..dc8ea690c2 100644 --- a/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Welch.png +++ b/tests/Images/External/ReferenceOutput/AffineTransformTests/Transform_WithSampler_Rgba32_TestPattern150x150_Welch.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:54b0da9646b7f4cf83df784d69dfbec48e0bdc1788d70a9872817543f72f57c1 -size 16829 +oid sha256:0f56ee78cc2fd698ac8ea84912648f0b49d4b4d66b439f6976447c56a44c2998 +size 16909 diff --git a/tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/DrawTransformed.png b/tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/DrawTransformed.png index c04521ebc7..17238cf2f7 100644 --- a/tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/DrawTransformed.png +++ b/tests/Images/External/ReferenceOutput/Drawing/DrawImageTests/DrawTransformed.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:233d8c6c9e101dddf5d210d47c7a20807f8f956738289068ea03b774258ef8c6 -size 182754 +oid sha256:00836a98742d177a2376af32d8d858fcf9f26a4da5a311dd5faf5cd80f233c0b +size 184397 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-170.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-170.png index e5ac34ff9d..a9289abd0d 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-170.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-170.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:964e8e5c160d7cd57e3b1fc584a39c1c8c61b835ff6af8264ec0631175286fca -size 10794 +oid sha256:801067dfb19b2a9a1fbd14b771e780b475c21f3ccdc1e709bbc20d62061ad1d1 +size 8782 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-50.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-50.png index 5b2ecebd6c..43fcd5df5e 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-50.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_-50.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2997d51c4ca534df2561f2c3bf1801f04631277b4259e25d9ef3fc164212f722 -size 11223 +oid sha256:ccbdd3dcdbc888923e85495fbd7837478cca813be6ecece63ee645bdf39d436f +size 10325 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_170.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_170.png index d620913d41..9a7f9866da 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_170.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_170.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8bd1219a9363bcc8dc088fb0a0a17c5e1914d418c89f4affc3fb9abf236f705 -size 10725 +oid sha256:60d1be2ffa6d50f97561b92efe8d0c0337f9c121582e38c9ab9af75be8eed32d +size 8539 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_50.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_50.png index ad39ebb12c..d141a2e28c 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_50.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern100x50_50.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d1fb97a28b5f754150343a3dc3c6974ac9abbb1577a44d88db61f0169983db0 -size 11083 +oid sha256:7f79389f79d91ac6749f21c27a592edfd2cff6efbb1d46296a26ae60d4e721f8 +size 10103 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-170.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-170.png index 8b15fa6c4e..1d27e23958 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-170.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-170.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e62ccc2cca36898a01445ef03361b84ff19aa1c0498e9dcbf21703dc1c009dd -size 11278 +oid sha256:75fb59ea2947efb1abf73cd824e54b6e8f6271343bd2fdadb005b29476988921 +size 9423 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-50.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-50.png index 8bb5f272bc..628d0c889c 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-50.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_-50.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f8f1f14a3c32d8d7e0406c2cf9480aa78dcef7bf223966e80f620680ef68375c -size 12064 +oid sha256:9c2d94791af40e001fc44b23eeecac7a606492c747b22ede0cdc7069ef121cb8 +size 11193 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_170.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_170.png index 6245b32266..0e927cfbd0 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_170.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_170.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7756d2402f4cf7d221d832d921fcff80fef6a36da5373cd9cb46b8e0f00e2fb1 -size 11273 +oid sha256:016de6e82b6fb03fd55168ea7fc12ab245d0e0387ca7c32d3ef1158a85a8facd +size 9330 diff --git a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_50.png b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_50.png index 28435befbc..ac4d473624 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_50.png +++ b/tests/Images/External/ReferenceOutput/Transforms/RotateTests/Rotate_WithAngle_TestPattern50x100_50.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d49ac2a6529959eb2a5d257c804ba576f9426fafe918c7fb267fc397477666dd -size 12051 +oid sha256:9219cc118fe7195b730cbe2e6407cde54e6f4c7930a71b7418bc7c273aa4120c +size 11050 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_-20_-10.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_-20_-10.png index 163cc401df..147f9c9897 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_-20_-10.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_-20_-10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d56651460aa5c942d800f2c92f0934f4c53b0f83e6fe8a2eb891a85bd9d93542 -size 10244 +oid sha256:2b243340f372220033b349a96cbd7ecd732395fa15e4d1ed62048d2031c42794 +size 8398 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_20_10.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_20_10.png index d080ba778d..d1252cb2c4 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_20_10.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Bgra32_TestPattern100x50_20_10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2912a3cd8088e9ad5e4e33b7c85825aedf9f910c32abbe78f3560510024b770 -size 10141 +oid sha256:fdd2745aba2f09bb4a09e881339fe62774ce5658902aa9d83b3a1e0718260084 +size 8694 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_-20_-10.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_-20_-10.png index 058b229a2c..235e95d8fc 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_-20_-10.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_-20_-10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58aea9e0fb398d84dc2f27e1b06ad53d195f2dd06bb1f489c6e51fae5724867d -size 7478 +oid sha256:281bd00550ab1cf9b05011750e6de330cdd42a8644ecf3b7c176bd5c6e94c59b +size 6098 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_20_10.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_20_10.png index 899864e537..3b63f58f36 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_20_10.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_IsNotBoundToSinglePixelType_Rgb24_TestPattern100x50_20_10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49b3eaeedfdd1c90b5ec48bf07e387d6cac8062ba15826971c22868b29ecb769 -size 7462 +oid sha256:e755ed61d7eab2c297f4b6592366b54ac801cbdb3d920741dfdd04dfaf73f9b9 +size 6086 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Bicubic.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Bicubic.png index 0e0106041a..340455428a 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Bicubic.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Bicubic.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e27f9c12e743d3bcc328dc7e5708c738c5a8ccba3ac99a465bb2fbc045afdc45 -size 28062 +oid sha256:8e8afa56c5abb0e4b5895f35415db1178d041120d9f8306902f554cfaaada88d +size 26540 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Box.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Box.png index 8f9dd4e74f..9ef7866924 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Box.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Box.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3dfbc7ca2c42fba08daff44f29fdc64f76cb5515ee8f0fd5798270ed64fdeb27 -size 26282 +oid sha256:a2c174ef54b68f025352e25800f655fe3b94a0d3f75cb48bd2ac0e8d6931faf8 +size 24827 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_CatmullRom.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_CatmullRom.png index 65e094dc1f..14f7748537 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_CatmullRom.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_CatmullRom.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad0e7cf115b2057fa223c45340f67b1659be6f6acefad32e0b02ca35327ffdf8 -size 28052 +oid sha256:6b56ceae2f350a1402beecc5b5e2930be1011a95fbf224cccf73b96f3931b646 +size 26531 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Hermite.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Hermite.png index 6d1eb77e19..c8204eacf3 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Hermite.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Hermite.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ca5e0729371222626d711a3f425c602198f5b51c8629e59027e37d63fadf5fa -size 25870 +oid sha256:049ee7fc2bb758609a64149c338bfae2eab44755f53e6b7c25a5e8b8725ed8ac +size 24416 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos2.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos2.png index 9098e51bee..2bc57092a2 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos2.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf1df2d5b53bc779f01e6ad32ca502cd5fb40826cb1fbf5ddc55b769f68e0d8c -size 28060 +oid sha256:72c487a2fa3d608021b26a4d6b4517f8548fdcfc62fbafdd8649015dbec8ff87 +size 26504 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos3.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos3.png index 00f4e8d925..fee364e217 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos3.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f21b8a574beb978befbb44e65def5a4d818fbca6be211cccc455fd819c278531 -size 34325 +oid sha256:099733c9d4490c86cfbb10a016e2dd073539a95f9d5ff9018cf9b5be5404fa13 +size 33435 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos5.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos5.png index 69afe9a6fd..30325ccc6f 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos5.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ced1fc39a97381af2ef369b94351a96930a58052343dcaa464b12da1747906f -size 37066 +oid sha256:27f2a2b21f8ae878e15120ea5a4a983bde7984b3468dc8426055885efc278fe6 +size 35547 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos8.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos8.png index 53e0dfa079..ff81256a70 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos8.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Lanczos8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b60fa32cf39ee70103d8498e5dc751fe2d5801fa30ff9f0948376fac64cb1021 -size 41427 +oid sha256:6b5cbe60e26e123e5a5cdf5a4e88305340f76d32a9c64a220c1fa7512f84e786 +size 39442 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_MitchellNetravali.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_MitchellNetravali.png index 9216e2f17b..263dd7426d 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_MitchellNetravali.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_MitchellNetravali.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce56cc11a369838e011a796cc380f9f06ca915a845e5b6b0425cb7366f162a5c -size 27303 +oid sha256:102cceb79acb1dfd7ec8887b4906e33456c774d48320d1624b3c73975d26f145 +size 25981 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_NearestNeighbor.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_NearestNeighbor.png index 8f9dd4e74f..9ef7866924 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_NearestNeighbor.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_NearestNeighbor.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3dfbc7ca2c42fba08daff44f29fdc64f76cb5515ee8f0fd5798270ed64fdeb27 -size 26282 +oid sha256:a2c174ef54b68f025352e25800f655fe3b94a0d3f75cb48bd2ac0e8d6931faf8 +size 24827 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Robidoux.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Robidoux.png index 79ef7ef283..85bbd5ec38 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Robidoux.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Robidoux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ce82b69d9dde2621a3d54647e7a659d440e2f9b0102831773a97abca4bcfa4c -size 27248 +oid sha256:e61629aeefac7e0a1a6b46b44ad86ed4a5ba0908bb3febc18bb5f9f3ded1c08d +size 25751 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_RobidouxSharp.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_RobidouxSharp.png index 823f471f2a..f200a5f955 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_RobidouxSharp.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_RobidouxSharp.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71d45938ec05003c5dcae0962ac6847041410123ba1dc2debbbf41e22ac2d91a -size 27519 +oid sha256:45b1b48e1df393f4c435189c71a6bd3bccfe7a055d76d414a8d0c009b59fa0a0 +size 26145 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Spline.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Spline.png index 23766e557a..434bb32a81 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Spline.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Spline.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75bd6138967d8795d0be7fe2e76c889718276924d702349105003c24f08957e2 -size 25559 +oid sha256:d6d186f9e547f658b719bc033e3b110d64cf2a02caecc510d4e2f88359e69746 +size 24176 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Triangle.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Triangle.png index 33e7b6ef1e..e3be1ffe5a 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Triangle.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Triangle.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b280a880b864a14225fd433378dede02cfad897059939cebbe0e04659de6d5a9 -size 25382 +oid sha256:339b3299984f1450f1a8200e487964c0338b511b82e459d67a3583d0bd46b805 +size 24013 diff --git a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Welch.png b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Welch.png index a170cc2cb0..7dbeeaf357 100644 --- a/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Welch.png +++ b/tests/Images/External/ReferenceOutput/Transforms/SkewTests/Skew_WorksWithAllResamplers_ducky_Welch.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c94d6ae8ad8ddab17a5ad1cfc73e711912a3f13e6bd3dfe9e5f0c8ec2c004af -size 33257 +oid sha256:5335c6184829fdc405475bd34d2fae60cf6d5ae050b4d671ac5dd25242ff1368 +size 31888