mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
419 lines
11 KiB
419 lines
11 KiB
// Copyright (c) Six Labors.
|
|
// Licensed under the Six Labors Split License.
|
|
|
|
using SixLabors.ImageSharp.Processing.Processors.Convolution;
|
|
|
|
namespace SixLabors.ImageSharp.Tests.Processing.Convolution;
|
|
|
|
[Trait("Category", "Processors")]
|
|
public class KernelSamplingMapTest
|
|
{
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7RepeatBorder()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Repeat;
|
|
int[] expected =
|
|
{
|
|
0, 0, 0, 1, 2,
|
|
0, 0, 1, 2, 3,
|
|
0, 1, 2, 3, 4,
|
|
1, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 6,
|
|
4, 5, 6, 6, 6,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7BounceBorder()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Bounce;
|
|
int[] expected =
|
|
{
|
|
2, 1, 0, 1, 2,
|
|
1, 0, 1, 2, 3,
|
|
0, 1, 2, 3, 4,
|
|
1, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 5,
|
|
4, 5, 6, 5, 4,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7MirrorBorder()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Mirror;
|
|
int[] expected =
|
|
{
|
|
1, 0, 0, 1, 2,
|
|
0, 0, 1, 2, 3,
|
|
0, 1, 2, 3, 4,
|
|
1, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 6,
|
|
4, 5, 6, 6, 5,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7WrapBorder()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Wrap;
|
|
int[] expected =
|
|
{
|
|
5, 6, 0, 1, 2,
|
|
6, 0, 1, 2, 3,
|
|
0, 1, 2, 3, 4,
|
|
1, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 0,
|
|
4, 5, 6, 0, 1,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image9x9BounceBorder()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(1, 1, 9, 9);
|
|
var mode = BorderWrappingMode.Bounce;
|
|
int[] expected =
|
|
{
|
|
3, 2, 1, 2, 3,
|
|
2, 1, 2, 3, 4,
|
|
1, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 7,
|
|
4, 5, 6, 7, 8,
|
|
5, 6, 7, 8, 9,
|
|
6, 7, 8, 9, 8,
|
|
7, 8, 9, 8, 7,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image9x9MirrorBorder()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(1, 1, 9, 9);
|
|
var mode = BorderWrappingMode.Mirror;
|
|
int[] expected =
|
|
{
|
|
2, 1, 1, 2, 3,
|
|
1, 1, 2, 3, 4,
|
|
1, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 7,
|
|
4, 5, 6, 7, 8,
|
|
5, 6, 7, 8, 9,
|
|
6, 7, 8, 9, 9,
|
|
7, 8, 9, 9, 8,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image9x9WrapBorder()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(1, 1, 9, 9);
|
|
var mode = BorderWrappingMode.Wrap;
|
|
int[] expected =
|
|
{
|
|
8, 9, 1, 2, 3,
|
|
9, 1, 2, 3, 4,
|
|
1, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 7,
|
|
4, 5, 6, 7, 8,
|
|
5, 6, 7, 8, 9,
|
|
6, 7, 8, 9, 1,
|
|
7, 8, 9, 1, 2,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7RepeatBorderTile()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Repeat;
|
|
int[] expected =
|
|
{
|
|
2, 2, 2, 3, 4,
|
|
2, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 7,
|
|
4, 5, 6, 7, 8,
|
|
5, 6, 7, 8, 8,
|
|
6, 7, 8, 8, 8,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7BounceBorderTile()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Bounce;
|
|
int[] expected =
|
|
{
|
|
4, 3, 2, 3, 4,
|
|
3, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 7,
|
|
4, 5, 6, 7, 8,
|
|
5, 6, 7, 8, 7,
|
|
6, 7, 8, 7, 6,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7MirrorBorderTile()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Mirror;
|
|
int[] expected =
|
|
{
|
|
3, 2, 2, 3, 4,
|
|
2, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 7,
|
|
4, 5, 6, 7, 8,
|
|
5, 6, 7, 8, 8,
|
|
6, 7, 8, 8, 7,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel5Image7x7WrapBorderTile()
|
|
{
|
|
var kernelSize = new Size(5, 5);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Wrap;
|
|
int[] expected =
|
|
{
|
|
7, 8, 2, 3, 4,
|
|
8, 2, 3, 4, 5,
|
|
2, 3, 4, 5, 6,
|
|
3, 4, 5, 6, 7,
|
|
4, 5, 6, 7, 8,
|
|
5, 6, 7, 8, 2,
|
|
6, 7, 8, 2, 3,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7x7RepeatBorder()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Repeat;
|
|
int[] expected =
|
|
{
|
|
0, 0, 1,
|
|
0, 1, 2,
|
|
1, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 6,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7x7BounceBorder()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Bounce;
|
|
int[] expected =
|
|
{
|
|
1, 0, 1,
|
|
0, 1, 2,
|
|
1, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 5,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7x7MirrorBorder()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Mirror;
|
|
int[] expected =
|
|
{
|
|
0, 0, 1,
|
|
0, 1, 2,
|
|
1, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 6,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7x7WrapBorder()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(0, 0, 7, 7);
|
|
var mode = BorderWrappingMode.Wrap;
|
|
int[] expected =
|
|
{
|
|
6, 0, 1,
|
|
0, 1, 2,
|
|
1, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 0,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7x7RepeatBorderTile()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Repeat;
|
|
int[] expected =
|
|
{
|
|
2, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 7,
|
|
6, 7, 8,
|
|
7, 8, 8,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7BounceBorderTile()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Bounce;
|
|
int[] expected =
|
|
{
|
|
3, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 7,
|
|
6, 7, 8,
|
|
7, 8, 7,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7MirrorBorderTile()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Mirror;
|
|
int[] expected =
|
|
{
|
|
2, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 7,
|
|
6, 7, 8,
|
|
7, 8, 8,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7x7WrapBorderTile()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(2, 2, 7, 7);
|
|
var mode = BorderWrappingMode.Wrap;
|
|
int[] expected =
|
|
{
|
|
8, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 7,
|
|
6, 7, 8,
|
|
7, 8, 2,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, expected, expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void KernalSamplingMap_Kernel3Image7x5WrapBorderTile()
|
|
{
|
|
var kernelSize = new Size(3, 3);
|
|
var bounds = new Rectangle(2, 2, 7, 5);
|
|
var mode = BorderWrappingMode.Wrap;
|
|
int[] xExpected =
|
|
{
|
|
8, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 7,
|
|
6, 7, 8,
|
|
7, 8, 2,
|
|
};
|
|
int[] yExpected =
|
|
{
|
|
6, 2, 3,
|
|
2, 3, 4,
|
|
3, 4, 5,
|
|
4, 5, 6,
|
|
5, 6, 2,
|
|
};
|
|
this.AssertOffsets(kernelSize, bounds, mode, mode, xExpected, yExpected);
|
|
}
|
|
|
|
private void AssertOffsets(Size kernelSize, Rectangle bounds, BorderWrappingMode xBorderMode, BorderWrappingMode yBorderMode, int[] xExpected, int[] yExpected)
|
|
{
|
|
// Arrange
|
|
var map = new KernelSamplingMap(Configuration.Default.MemoryAllocator);
|
|
|
|
// Act
|
|
map.BuildSamplingOffsetMap(kernelSize.Height, kernelSize.Width, bounds, xBorderMode, yBorderMode);
|
|
|
|
// Assert
|
|
var xOffsets = map.GetColumnOffsetSpan().ToArray();
|
|
Assert.Equal(xExpected, xOffsets);
|
|
var yOffsets = map.GetRowOffsetSpan().ToArray();
|
|
Assert.Equal(yExpected, yOffsets);
|
|
}
|
|
}
|
|
|