Browse Source

More progress toward a working swizzler

js/color-alpha-handling
Evangelink 5 years ago
parent
commit
a5e9694667
  1. 9
      src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs
  2. 21
      src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs
  3. 6
      src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs
  4. 35
      tests/ImageSharp.Tests/Processing/Processors/Transforms/SwizzleTests.cs
  5. 18
      tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs

9
src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs

@ -8,11 +8,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// </summary>
public interface ISwizzler
{
/// <summary>
/// Gets the size of the image after transformation.
/// </summary>
Size DestinationSize { get; }
/// <summary>
/// Applies the swizzle transformation to a given point.
/// </summary>
/// <param name="point">Point to transform.</param>
/// <returns>Transformed point.</returns>
Point Transform(Point point);
/// <param name="newPoint">The transformed point.</param>
void Transform(Point point, out Point newPoint);
}
}

21
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<TSwizzler, TPixel> : ImageProcessor<TPixel>
internal class SwizzleProcessor<TSwizzler, TPixel> : TransformProcessor<TPixel>
where TSwizzler : struct, ISwizzler
where TPixel : unmanaged, IPixel<TPixel>
{
private readonly TSwizzler swizzler;
private readonly Size destinationSize;
public SwizzleProcessor(Configuration configuration, TSwizzler swizzler, Image<TPixel> source, Rectangle sourceRectangle)
: base(configuration, source, sourceRectangle)
{
this.swizzler = swizzler;
this.destinationSize = swizzler.DestinationSize;
}
/// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source)
protected override Size GetDestinationSize()
=> this.destinationSize;
protected override void OnFrameApply(ImageFrame<TPixel> source, ImageFrame<TPixel> 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];
}
}
}

6
src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs

@ -17,7 +17,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// </summary>
/// <param name="swizzler">The swizzler operation.</param>
public SwizzleProcessor(TSwizzler swizzler)
=> this.Swizzler = swizzler;
{
this.Swizzler = swizzler;
}
/// <summary>
/// Gets the swizzler operation.
@ -27,6 +29,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// <inheritdoc />
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>(Configuration configuration, Image<TPixel> source, Rectangle sourceRectangle)
where TPixel : unmanaged, IPixel<TPixel>
=> new SwizzleProcessor<TSwizzler, TPixel>(configuration, this, source, sourceRectangle);
=> new SwizzleProcessor<TSwizzler, TPixel>(configuration, this.Swizzler, source, sourceRectangle);
}
}

35
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<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.RunValidatingProcessorTest(
ctx => ctx.Swizzle(default(InvertXAndYSwizzler)),
testOutputDetails: nameof(InvertXAndYSwizzler),
appendPixelTypeToFileName: false);
}
}
}

18
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<InvertXAndYSwizzler> processor = this.Verify<SwizzleProcessor<InvertXAndYSwizzler>>();
// 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<InvertXAndYSwizzler> processor2 = this.Verify<SwizzleProcessor<InvertXAndYSwizzler>>();
SwizzleProcessor<InvertXAndYSwizzler> processor2 = this.Verify<SwizzleProcessor<InvertXAndYSwizzler>>(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);
}
}
}

Loading…
Cancel
Save