diff --git a/src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs b/src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs
index 0230b7a86..075ea2d52 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs
@@ -8,11 +8,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
public interface ISwizzler
{
+ ///
+ /// Gets the size of the image after transformation.
+ ///
+ Size DestinationSize { get; }
+
///
/// Applies the swizzle transformation to a given point.
///
/// Point to transform.
- /// Transformed point.
- Point Transform(Point point);
+ /// The transformed point.
+ void Transform(Point point, out Point newPoint);
}
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs
index a42a4bf77..c9b9b4570 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs
@@ -1,31 +1,38 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
+using System;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
- internal class SwizzleProcessor : ImageProcessor
+ internal class SwizzleProcessor : TransformProcessor
where TSwizzler : struct, ISwizzler
where TPixel : unmanaged, IPixel
{
private readonly TSwizzler swizzler;
+ private readonly Size destinationSize;
public SwizzleProcessor(Configuration configuration, TSwizzler swizzler, Image source, Rectangle sourceRectangle)
: base(configuration, source, sourceRectangle)
{
this.swizzler = swizzler;
+ this.destinationSize = swizzler.DestinationSize;
}
- ///
- protected override void OnFrameApply(ImageFrame source)
+ protected override Size GetDestinationSize()
+ => this.destinationSize;
+
+ protected override void OnFrameApply(ImageFrame source, ImageFrame destination)
{
- for (int y = 0; y < source.Height; y++)
+ Point p = default;
+ Point newPoint;
+ for (p.Y = 0; p.Y < source.Height; p.Y++)
{
- var pixelRowSpan = source.GetPixelRowSpan(y);
- for (int x = 0; x < source.Width; x++)
+ for (p.X = 0; p.X < source.Width; p.X++)
{
- var newPoint = this.swizzler.Transform(new Point(x, y));
+ this.swizzler.Transform(p, out newPoint);
+ destination[newPoint.X, newPoint.Y] = source[p.X, p.Y];
}
}
}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs
index e5b95e673..d48257334 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs
@@ -17,7 +17,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
/// The swizzler operation.
public SwizzleProcessor(TSwizzler swizzler)
- => this.Swizzler = swizzler;
+ {
+ this.Swizzler = swizzler;
+ }
///
/// Gets the swizzler operation.
@@ -27,6 +29,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
///
public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle)
where TPixel : unmanaged, IPixel
- => new SwizzleProcessor(configuration, this, source, sourceRectangle);
+ => new SwizzleProcessor(configuration, this.Swizzler, source, sourceRectangle);
}
}
diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/SwizzleTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/SwizzleTests.cs
new file mode 100644
index 000000000..b951a7fb0
--- /dev/null
+++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/SwizzleTests.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing.Extensions.Transforms;
+using SixLabors.ImageSharp.Processing.Processors.Transforms;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
+{
+ [GroupOutput("Transforms")]
+ public class SwizzleTests
+ {
+ private struct InvertXAndYSwizzler : ISwizzler
+ {
+ public Size DestinationSize => new Size(10, 10);
+
+ public void Transform(Point point, out Point newPoint)
+ => newPoint = new Point(point.Y, point.X);
+ }
+
+ [Theory]
+ [WithTestPatternImages(20, 37, PixelTypes.Rgba32)]
+ [WithTestPatternImages(53, 37, PixelTypes.Byte4)]
+ [WithTestPatternImages(17, 32, PixelTypes.Rgba32)]
+ public void InvertXAndYSwizzle(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ provider.RunValidatingProcessorTest(
+ ctx => ctx.Swizzle(default(InvertXAndYSwizzler)),
+ testOutputDetails: nameof(InvertXAndYSwizzler),
+ appendPixelTypeToFileName: false);
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs
index 2862df212..c54bfa25e 100644
--- a/tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs
+++ b/tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs
@@ -11,21 +11,29 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
{
private struct InvertXAndYSwizzler : ISwizzler
{
- public Point Transform(Point point) => new Point(point.Y, point.X);
+ public Size DestinationSize => new Size(10, 10);
+
+ public void Transform(Point point, out Point newPoint)
+ => newPoint = new Point(point.Y, point.X);
}
[Fact]
- public void RotateDegreesFloatRotateProcessorWithAnglesSet()
+ public void InvertXAndYSwizzlerSetsCorrectSizes()
{
+ int width = 5;
+ int height = 10;
+
this.operations.Swizzle(default(InvertXAndYSwizzler));
SwizzleProcessor processor = this.Verify>();
- // assert that pixels have been changed
+ Assert.Equal(processor.Swizzler.DestinationSize.Width, height);
+ Assert.Equal(processor.Swizzler.DestinationSize.Height, width);
this.operations.Swizzle(default(InvertXAndYSwizzler));
- SwizzleProcessor processor2 = this.Verify>();
+ SwizzleProcessor processor2 = this.Verify>(1);
- // assert that pixels have been changed (i.e. back to original)
+ Assert.Equal(processor2.Swizzler.DestinationSize.Width, width);
+ Assert.Equal(processor2.Swizzler.DestinationSize.Height, height);
}
}
}