Added additional tests and some small fixes and improvements

This commit is contained in:
Darth Affe 2024-07-18 23:09:49 +02:00
parent e1738845ea
commit c6ac54a936
24 changed files with 1503 additions and 187 deletions

View File

@ -15,6 +15,18 @@ public static partial class ReferencePixelHelper
(byte)(sum.A / count));
}
public static T Average<T>(IImage<T> image)
where T : struct, IColor
{
float count = image.Width * image.Height;
ISum sum = Sum(image);
return (T)T.Create((byte)(sum.R / count),
(byte)(sum.G / count),
(byte)(sum.B / count),
(byte)(sum.A / count));
}
public static T Average<T>(RefImage<T> image)
where T : struct, IColor
{
@ -27,6 +39,18 @@ public static partial class ReferencePixelHelper
(byte)(sum.A / count));
}
public static T Average<T>(Span<T> colors)
where T : struct, IColor
{
float count = colors.Length;
ISum sum = Sum(colors);
return (T)T.Create((byte)(sum.R / count),
(byte)(sum.G / count),
(byte)(sum.B / count),
(byte)(sum.A / count));
}
public static T Average<T>(ReadOnlySpan<T> colors)
where T : struct, IColor
{

View File

@ -47,6 +47,28 @@ public static partial class ReferencePixelHelper
return new MinMaxRGBA(minR, maxR, minG, maxG, minB, maxB, minA, maxA);
}
public static IMinMax MinMax<T>(Span<T> colors)
where T : struct, IColor
{
byte minR = byte.MaxValue, minG = byte.MaxValue, minB = byte.MaxValue, minA = byte.MaxValue;
byte maxR = byte.MinValue, maxG = byte.MinValue, maxB = byte.MinValue, maxA = byte.MinValue;
foreach (T color in colors)
{
minR = Math.Min(minR, color.R);
minG = Math.Min(minG, color.G);
minB = Math.Min(minB, color.B);
minA = Math.Min(minA, color.A);
maxR = Math.Max(maxR, color.R);
maxG = Math.Max(maxG, color.G);
maxB = Math.Max(maxB, color.B);
maxA = Math.Max(maxA, color.A);
}
return new MinMaxRGBA(minR, maxR, minG, maxG, minB, maxB, minA, maxA);
}
public static IMinMax MinMax<T>(ReadOnlySpan<T> colors)
where T : struct, IColor
{

View File

@ -35,6 +35,22 @@ public static partial class ReferencePixelHelper
return new SumRGBA(sumR, sumG, sumB, sumA);
}
public static ISum Sum<T>(Span<T> colors)
where T : struct, IColor
{
long sumR = 0, sumG = 0, sumB = 0, sumA = 0;
foreach (T color in colors)
{
sumR += color.R;
sumG += color.G;
sumB += color.B;
sumA += color.A;
}
return new SumRGBA(sumR, sumG, sumB, sumA);
}
public static ISum Sum<T>(ReadOnlySpan<T> colors)
where T : struct, IColor
{

View File

@ -0,0 +1,90 @@
namespace HPPH.Test.Colors;
[TestClass]
public class ColorFormatTests
{
[TestMethod]
public void ColorFormatRGBName()
{
Assert.AreEqual("RGB", IColorFormat.RGB.Name);
Assert.AreEqual("RGB", ColorRGB.ColorFormat.Name);
}
[TestMethod]
public void ColorFormatBGRName()
{
Assert.AreEqual("BGR", IColorFormat.BGR.Name);
Assert.AreEqual("BGR", ColorBGR.ColorFormat.Name);
}
[TestMethod]
public void ColorFormatRGBAName()
{
Assert.AreEqual("RGBA", IColorFormat.RGBA.Name);
Assert.AreEqual("RGBA", ColorRGBA.ColorFormat.Name);
}
[TestMethod]
public void ColorFormatBGRAName()
{
Assert.AreEqual("BGRA", IColorFormat.BGRA.Name);
Assert.AreEqual("BGRA", ColorBGRA.ColorFormat.Name);
}
[TestMethod]
public void ColorFormatARGBName()
{
Assert.AreEqual("ARGB", IColorFormat.ARGB.Name);
Assert.AreEqual("ARGB", ColorARGB.ColorFormat.Name);
}
[TestMethod]
public void ColorFormatABGRName()
{
Assert.AreEqual("ABGR", IColorFormat.ABGR.Name);
Assert.AreEqual("ABGR", ColorABGR.ColorFormat.Name);
}
[TestMethod]
public void ColorFormatRGBBPP()
{
Assert.AreEqual(3, IColorFormat.RGB.BytesPerPixel);
Assert.AreEqual(3, ColorRGB.ColorFormat.BytesPerPixel);
}
[TestMethod]
public void ColorFormatBGRBPP()
{
Assert.AreEqual(3, IColorFormat.BGR.BytesPerPixel);
Assert.AreEqual(3, ColorBGR.ColorFormat.BytesPerPixel);
}
[TestMethod]
public void ColorFormatRGBABPP()
{
Assert.AreEqual(4, IColorFormat.RGBA.BytesPerPixel);
Assert.AreEqual(4, ColorRGBA.ColorFormat.BytesPerPixel);
}
[TestMethod]
public void ColorFormatBGRABPP()
{
Assert.AreEqual(4, IColorFormat.BGRA.BytesPerPixel);
Assert.AreEqual(4, ColorBGRA.ColorFormat.BytesPerPixel);
}
[TestMethod]
public void ColorFormatARGBBPP()
{
Assert.AreEqual(4, IColorFormat.ARGB.BytesPerPixel);
Assert.AreEqual(4, ColorARGB.ColorFormat.BytesPerPixel);
}
[TestMethod]
public void ColorFormatABGRBPP()
{
Assert.AreEqual(4, IColorFormat.ABGR.BytesPerPixel);
Assert.AreEqual(4, ColorABGR.ColorFormat.BytesPerPixel);
}
}

View File

@ -0,0 +1,183 @@
using System.Runtime.InteropServices;
namespace HPPH.Test.Colors;
[TestClass]
public class ColorTests
{
[TestMethod]
public void ColorRGBLayout()
{
Span<byte> data = [1, 2, 3, 4];
ColorRGB color = MemoryMarshal.Cast<byte, ColorRGB>(data)[0];
Assert.AreEqual(data[0], color.R);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.B);
Assert.AreEqual(byte.MaxValue, color.A);
}
[TestMethod]
public void ColorBGRLayout()
{
Span<byte> data = [1, 2, 3, 4];
ColorBGR color = MemoryMarshal.Cast<byte, ColorBGR>(data)[0];
Assert.AreEqual(data[0], color.B);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.R);
Assert.AreEqual(byte.MaxValue, color.A);
}
[TestMethod]
public void ColorRGBALayout()
{
Span<byte> data = [1, 2, 3, 4];
ColorRGBA color = MemoryMarshal.Cast<byte, ColorRGBA>(data)[0];
Assert.AreEqual(data[0], color.R);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.B);
Assert.AreEqual(data[3], color.A);
}
[TestMethod]
public void ColorBGRALayout()
{
Span<byte> data = [1, 2, 3, 4];
ColorBGRA color = MemoryMarshal.Cast<byte, ColorBGRA>(data)[0];
Assert.AreEqual(data[0], color.B);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.R);
Assert.AreEqual(data[3], color.A);
}
[TestMethod]
public void ColorARGBLayout()
{
Span<byte> data = [1, 2, 3, 4];
ColorARGB color = MemoryMarshal.Cast<byte, ColorARGB>(data)[0];
Assert.AreEqual(data[0], color.A);
Assert.AreEqual(data[1], color.R);
Assert.AreEqual(data[2], color.G);
Assert.AreEqual(data[3], color.B);
}
[TestMethod]
public void ColorABGRLayout()
{
Span<byte> data = [1, 2, 3, 4];
ColorABGR color = MemoryMarshal.Cast<byte, ColorABGR>(data)[0];
Assert.AreEqual(data[0], color.A);
Assert.AreEqual(data[1], color.B);
Assert.AreEqual(data[2], color.G);
Assert.AreEqual(data[3], color.R);
}
[TestMethod]
public void ColorRGBCreate()
{
IColor color = ColorRGB.Create(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(byte.MaxValue, color.A);
}
[TestMethod]
public void ColorBGRCreate()
{
IColor color = ColorBGR.Create(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(byte.MaxValue, color.A);
}
[TestMethod]
public void ColorRGBACreate()
{
IColor color = ColorRGBA.Create(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void ColorBGRACreate()
{
IColor color = ColorBGRA.Create(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void ColorARGBCreate()
{
IColor color = ColorARGB.Create(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void ColorABGRCreate()
{
IColor color = ColorABGR.Create(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void ColorRGBToString()
{
Assert.AreEqual("[A: 255, R: 1, G: 2, B: 3]", new ColorRGB(1, 2, 3).ToString());
}
[TestMethod]
public void ColorBGRToString()
{
Assert.AreEqual("[A: 255, R: 1, G: 2, B: 3]", new ColorBGR(3, 2, 1).ToString());
}
[TestMethod]
public void ColorRGBAToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new ColorRGBA(1, 2, 3, 4).ToString());
}
[TestMethod]
public void ColorBGRAToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new ColorBGRA(3, 2, 1, 4).ToString());
}
[TestMethod]
public void ColorARGBToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new ColorARGB(4, 1, 2, 3).ToString());
}
[TestMethod]
public void ColorABGRToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new ColorABGR(4, 3, 2, 1).ToString());
}
}

View File

@ -0,0 +1,176 @@
using System.Runtime.InteropServices;
namespace HPPH.Test.Colors;
[TestClass]
public class MinMaxStructTests
{
[TestMethod]
public void MinMaxRGBCreate()
{
IMinMax color = new MinMaxRGB(1, 3, 4, 7, 16, 31);
Assert.AreEqual(1, color.RedMin);
Assert.AreEqual(3, color.RedMax);
Assert.AreEqual(2, color.RedRange);
Assert.AreEqual(4, color.GreenMin);
Assert.AreEqual(7, color.GreenMax);
Assert.AreEqual(3, color.GreenRange);
Assert.AreEqual(16, color.BlueMin);
Assert.AreEqual(31, color.BlueMax);
Assert.AreEqual(15, color.BlueRange);
Assert.AreEqual(byte.MaxValue, color.AlphaMin);
Assert.AreEqual(byte.MaxValue, color.AlphaMax);
Assert.AreEqual(0, color.AlphaRange);
}
[TestMethod]
public void MinMaxBGRCreate()
{
IMinMax color = new MinMaxBGR(1, 3, 4, 7, 16, 31);
Assert.AreEqual(1, color.BlueMin);
Assert.AreEqual(3, color.BlueMax);
Assert.AreEqual(2, color.BlueRange);
Assert.AreEqual(4, color.GreenMin);
Assert.AreEqual(7, color.GreenMax);
Assert.AreEqual(3, color.GreenRange);
Assert.AreEqual(16, color.RedMin);
Assert.AreEqual(31, color.RedMax);
Assert.AreEqual(15, color.RedRange);
Assert.AreEqual(byte.MaxValue, color.AlphaMin);
Assert.AreEqual(byte.MaxValue, color.AlphaMax);
Assert.AreEqual(0, color.AlphaRange);
}
[TestMethod]
public void MinMaxRGBACreate()
{
IMinMax color = new MinMaxRGBA(1, 3, 4, 7, 16, 31, 64, 127);
Assert.AreEqual(1, color.RedMin);
Assert.AreEqual(3, color.RedMax);
Assert.AreEqual(2, color.RedRange);
Assert.AreEqual(4, color.GreenMin);
Assert.AreEqual(7, color.GreenMax);
Assert.AreEqual(3, color.GreenRange);
Assert.AreEqual(16, color.BlueMin);
Assert.AreEqual(31, color.BlueMax);
Assert.AreEqual(15, color.BlueRange);
Assert.AreEqual(64, color.AlphaMin);
Assert.AreEqual(127, color.AlphaMax);
Assert.AreEqual(63, color.AlphaRange);
}
[TestMethod]
public void MinMaxBGRACreate()
{
IMinMax color = new MinMaxBGRA(1, 3, 4, 7, 16, 31, 64, 127);
Assert.AreEqual(1, color.BlueMin);
Assert.AreEqual(3, color.BlueMax);
Assert.AreEqual(2, color.BlueRange);
Assert.AreEqual(4, color.GreenMin);
Assert.AreEqual(7, color.GreenMax);
Assert.AreEqual(3, color.GreenRange);
Assert.AreEqual(16, color.RedMin);
Assert.AreEqual(31, color.RedMax);
Assert.AreEqual(15, color.RedRange);
Assert.AreEqual(64, color.AlphaMin);
Assert.AreEqual(127, color.AlphaMax);
Assert.AreEqual(63, color.AlphaRange);
}
[TestMethod]
public void MinMaxARGBCreate()
{
IMinMax color = new MinMaxARGB(1, 3, 4, 7, 16, 31, 64, 127);
Assert.AreEqual(1, color.AlphaMin);
Assert.AreEqual(3, color.AlphaMax);
Assert.AreEqual(2, color.AlphaRange);
Assert.AreEqual(4, color.RedMin);
Assert.AreEqual(7, color.RedMax);
Assert.AreEqual(3, color.RedRange);
Assert.AreEqual(16, color.GreenMin);
Assert.AreEqual(31, color.GreenMax);
Assert.AreEqual(15, color.GreenRange);
Assert.AreEqual(64, color.BlueMin);
Assert.AreEqual(127, color.BlueMax);
Assert.AreEqual(63, color.BlueRange);
}
[TestMethod]
public void MinMaxABGRCreate()
{
IMinMax color = new MinMaxABGR(1, 3, 4, 7, 16, 31, 64, 127);
Assert.AreEqual(1, color.AlphaMin);
Assert.AreEqual(3, color.AlphaMax);
Assert.AreEqual(2, color.AlphaRange);
Assert.AreEqual(4, color.BlueMin);
Assert.AreEqual(7, color.BlueMax);
Assert.AreEqual(3, color.BlueRange);
Assert.AreEqual(16, color.GreenMin);
Assert.AreEqual(31, color.GreenMax);
Assert.AreEqual(15, color.GreenRange);
Assert.AreEqual(64, color.RedMin);
Assert.AreEqual(127, color.RedMax);
Assert.AreEqual(63, color.RedRange);
}
[TestMethod]
public void MinMaxRGBToString()
{
Assert.AreEqual("[A: 255-255, R: 1-3, G: 4-7, B: 16-31]", new MinMaxRGB(1, 3, 4, 7, 16, 31).ToString());
}
[TestMethod]
public void MinMaxBGRToString()
{
Assert.AreEqual("[A: 255-255, R: 16-31, G: 4-7, B: 1-3]", new MinMaxBGR(1, 3, 4, 7, 16, 31).ToString());
}
[TestMethod]
public void MinMaxRGBAToString()
{
Assert.AreEqual("[A: 64-127, R: 1-3, G: 4-7, B: 16-31]", new MinMaxRGBA(1, 3, 4, 7, 16, 31, 64, 127).ToString());
}
[TestMethod]
public void MinMaxBGRAToString()
{
Assert.AreEqual("[A: 64-127, R: 16-31, G: 4-7, B: 1-3]", new MinMaxBGRA(1, 3, 4, 7, 16, 31, 64, 127).ToString());
}
[TestMethod]
public void MinMaxARGBToString()
{
Assert.AreEqual("[A: 1-3, R: 4-7, G: 16-31, B: 64-127]", new MinMaxARGB(1, 3, 4, 7, 16, 31, 64, 127).ToString());
}
[TestMethod]
public void MinMaxABGRToString()
{
Assert.AreEqual("[A: 1-3, R: 64-127, G: 16-31, B: 4-7]", new MinMaxABGR(1, 3, 4, 7, 16, 31, 64, 127).ToString());
}
}

View File

@ -0,0 +1,183 @@
using System.Runtime.InteropServices;
namespace HPPH.Test.Colors;
[TestClass]
public class SumStructTests
{
[TestMethod]
public void SumRGBLayout()
{
Span<long> data = [1, 2, 3, 4];
SumRGB color = MemoryMarshal.Cast<long, SumRGB>(data)[0];
Assert.AreEqual(data[0], color.R);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.B);
Assert.AreEqual(data[3], color.A);
}
[TestMethod]
public void SumBGRLayout()
{
Span<long> data = [1, 2, 3, 4];
SumBGR color = MemoryMarshal.Cast<long, SumBGR>(data)[0];
Assert.AreEqual(data[0], color.B);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.R);
Assert.AreEqual(data[3], color.A);
}
[TestMethod]
public void SumRGBALayout()
{
Span<long> data = [1, 2, 3, 4];
SumRGBA color = MemoryMarshal.Cast<long, SumRGBA>(data)[0];
Assert.AreEqual(data[0], color.R);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.B);
Assert.AreEqual(data[3], color.A);
}
[TestMethod]
public void SumBGRALayout()
{
Span<long> data = [1, 2, 3, 4];
SumBGRA color = MemoryMarshal.Cast<long, SumBGRA>(data)[0];
Assert.AreEqual(data[0], color.B);
Assert.AreEqual(data[1], color.G);
Assert.AreEqual(data[2], color.R);
Assert.AreEqual(data[3], color.A);
}
[TestMethod]
public void SumARGBLayout()
{
Span<long> data = [1, 2, 3, 4];
SumARGB color = MemoryMarshal.Cast<long, SumARGB>(data)[0];
Assert.AreEqual(data[0], color.A);
Assert.AreEqual(data[1], color.R);
Assert.AreEqual(data[2], color.G);
Assert.AreEqual(data[3], color.B);
}
[TestMethod]
public void SumABGRLayout()
{
Span<long> data = [1, 2, 3, 4];
SumABGR color = MemoryMarshal.Cast<long, SumABGR>(data)[0];
Assert.AreEqual(data[0], color.A);
Assert.AreEqual(data[1], color.B);
Assert.AreEqual(data[2], color.G);
Assert.AreEqual(data[3], color.R);
}
[TestMethod]
public void SumRGBCreate()
{
ISum color = new SumRGB(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void SumBGRCreate()
{
ISum color = new SumBGR(3, 2, 1, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void SumRGBACreate()
{
ISum color = new SumRGBA(1, 2, 3, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void SumBGRACreate()
{
ISum color = new SumBGRA(3, 2, 1, 4);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void SumARGBCreate()
{
ISum color = new SumARGB(4, 1, 2, 3);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void SumABGRCreate()
{
ISum color = new SumABGR(4, 3, 2, 1);
Assert.AreEqual(1, color.R);
Assert.AreEqual(2, color.G);
Assert.AreEqual(3, color.B);
Assert.AreEqual(4, color.A);
}
[TestMethod]
public void SumRGBToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new SumRGB(1, 2, 3, 4).ToString());
}
[TestMethod]
public void SumBGRToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new SumBGR(3, 2, 1, 4).ToString());
}
[TestMethod]
public void SumRGBAToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new SumRGBA(1, 2, 3, 4).ToString());
}
[TestMethod]
public void SumBGRAToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new SumBGRA(3, 2, 1, 4).ToString());
}
[TestMethod]
public void SumARGBToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new SumARGB(4, 1, 2, 3).ToString());
}
[TestMethod]
public void SumABGRToString()
{
Assert.AreEqual("[A: 4, R: 1, G: 2, B: 3]", new SumABGR(4, 3, 2, 1).ToString());
}
}

View File

@ -7,6 +7,7 @@
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>

View File

@ -1,3 +1,5 @@
using System.Collections;
namespace HPPH.Test.Image;
[TestClass]
@ -204,5 +206,308 @@ public class ImageTest
}
}
[TestMethod]
public void ToArray()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
ColorARGB[] testData = image.ToArray();
for (int y = 0; y < TEST_HEIGHT; y++)
for (int x = 0; x < TEST_WIDTH; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y), testData[(y * TEST_WIDTH) + x]);
}
[TestMethod]
public void CopyTo()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
ColorARGB[] testData = new ColorARGB[TEST_WIDTH * TEST_HEIGHT];
image.CopyTo(testData);
for (int y = 0; y < TEST_HEIGHT; y++)
for (int x = 0; x < TEST_WIDTH; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y), testData[(y * TEST_WIDTH) + x]);
}
[TestMethod]
public void SubImage()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
RefImage<ColorARGB> subImage = image[10, 20, 100, 200];
for (int y = 0; y < 200; y++)
for (int x = 0; x < 100; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(10 + x, 20 + y), subImage[x, y]);
}
[TestMethod]
public void GenericRowsIterate()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int y = 0;
foreach (ImageRow<ColorARGB> row in image.Rows)
{
int x = 0;
foreach (ColorARGB color in row)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x++, y), color);
y++;
}
}
[TestMethod]
public void GenericRowsCopyTo()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int y = 0;
foreach (ImageRow<ColorARGB> row in image.Rows)
{
ColorARGB[] colors = new ColorARGB[TEST_WIDTH];
byte[] bytes = new byte[TEST_WIDTH * 4];
row.CopyTo(colors);
row.CopyTo(bytes);
int x = 0;
foreach (ColorARGB color in colors)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x++, y), color);
for (x = 0; x < TEST_WIDTH; x++)
{
ColorARGB reference = TestDataHelper.GetColorFromLocation<ColorARGB>(x, y);
Assert.AreEqual(reference.A, bytes[(x * 4) + 0]);
Assert.AreEqual(reference.R, bytes[(x * 4) + 1]);
Assert.AreEqual(reference.G, bytes[(x * 4) + 2]);
Assert.AreEqual(reference.B, bytes[(x * 4) + 3]);
}
y++;
}
}
[TestMethod]
public void GenericRowsToArray()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int y = 0;
foreach (ImageRow<ColorARGB> row in image.Rows)
{
ColorARGB[] data = row.ToArray();
for (int x = 0; x < TEST_WIDTH; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y), data[x]);
y++;
}
}
[TestMethod]
public void GenericColumnsIterate()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int x = 0;
foreach (ImageColumn<ColorARGB> column in image.Columns)
{
int y = 0;
foreach (ColorARGB color in column)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y++), color);
x++;
}
}
[TestMethod]
public void GenericColumnsCopyTo()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int x = 0;
foreach (ImageColumn<ColorARGB> column in image.Columns)
{
ColorARGB[] colors = new ColorARGB[TEST_HEIGHT];
byte[] bytes = new byte[TEST_HEIGHT * 4];
column.CopyTo(colors);
column.CopyTo(bytes);
int y = 0;
foreach (ColorARGB color in colors)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y++), color);
for (y = 0; y < TEST_HEIGHT; y++)
{
ColorARGB reference = TestDataHelper.GetColorFromLocation<ColorARGB>(x, y);
Assert.AreEqual(reference.A, bytes[(y * 4) + 0]);
Assert.AreEqual(reference.R, bytes[(y * 4) + 1]);
Assert.AreEqual(reference.G, bytes[(y * 4) + 2]);
Assert.AreEqual(reference.B, bytes[(y * 4) + 3]);
}
x++;
}
}
[TestMethod]
public void GenericColumnsToArray()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int x = 0;
foreach (ImageColumn<ColorARGB> column in image.Columns)
{
ColorARGB[] data = column.ToArray();
for (int y = 0; y < TEST_HEIGHT; y++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y), data[y]);
x++;
}
}
[TestMethod]
public void GenericEnumerate()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
ColorARGB[] reference = TestDataHelper.GetPixelData<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int i = 0;
foreach (ColorARGB color in image)
Assert.AreEqual(reference[i++], color);
IEnumerable enumerable = image;
i = 0;
foreach (ColorARGB color in enumerable)
Assert.AreEqual(reference[i++], color);
}
[TestMethod]
public unsafe void Pin()
{
Image<ColorARGB> image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
ColorARGB[] reference = TestDataHelper.GetPixelData<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
fixed (byte* ptr = image)
{
for (int i = 0; i < reference.Length; i++)
{
Assert.AreEqual(reference[i].A, ptr[(i * 4) + 0]);
Assert.AreEqual(reference[i].R, ptr[(i * 4) + 1]);
Assert.AreEqual(reference[i].G, ptr[(i * 4) + 2]);
Assert.AreEqual(reference[i].B, ptr[(i * 4) + 3]);
}
}
}
[TestMethod]
public void InterfaceRowsIterate()
{
IImage image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int y = 0;
foreach (IImageRow row in image.Rows)
{
int x = 0;
foreach (IColor color in row)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x++, y), color);
y++;
}
}
[TestMethod]
public void InterfaceColumnsIterate()
{
IImage image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int x = 0;
foreach (IImageColumn column in image.Columns)
{
int y = 0;
foreach (IColor color in column)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y++), color);
x++;
}
x = 0;
foreach (IImageColumn column in (IEnumerable)image.Columns)
{
int y = 0;
foreach (IColor color in (IEnumerable)column)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y++), color);
x++;
}
}
[TestMethod]
public void InterfaceEnumerate()
{
IImage image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
ColorARGB[] reference = TestDataHelper.GetPixelData<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int i = 0;
foreach (IColor color in image)
Assert.AreEqual(reference[i++], color);
IEnumerable enumerable = image;
i = 0;
foreach (IColor color in enumerable)
Assert.AreEqual(reference[i++], color);
}
[TestMethod]
public void InterfaceColumnsCopyTo()
{
IImage image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int x = 0;
foreach (IImageColumn column in image.Columns)
{
IColor[] colors = new IColor[TEST_HEIGHT];
byte[] bytes = new byte[TEST_HEIGHT * 4];
column.CopyTo(colors);
column.CopyTo(bytes);
int y = 0;
foreach (IColor color in colors)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y++), color);
for (y = 0; y < TEST_HEIGHT; y++)
{
IColor reference = TestDataHelper.GetColorFromLocation<ColorARGB>(x, y);
Assert.AreEqual(reference.A, bytes[(y * 4) + 0]);
Assert.AreEqual(reference.R, bytes[(y * 4) + 1]);
Assert.AreEqual(reference.G, bytes[(y * 4) + 2]);
Assert.AreEqual(reference.B, bytes[(y * 4) + 3]);
}
x++;
}
}
[TestMethod]
public void InterfaceColumnsToArray()
{
IImage image = TestDataHelper.CreateTestImage<ColorARGB>(TEST_WIDTH, TEST_HEIGHT);
int x = 0;
foreach (IImageColumn column in image.Columns)
{
IColor[] data = column.ToArray();
for (int y = 0; y < TEST_HEIGHT; y++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y), data[y]);
x++;
}
}
#endregion
}

View File

@ -6,35 +6,43 @@ internal static class ImageHelper
{
#region Methods
public static ColorRGB[] Get3ByteColorsFromImage(string file)
public static T[] GetColorsFromImage<T>(string file)
where T : struct, IColor
{
using FileStream stream = File.OpenRead(file);
using Bitmap bmp = new(stream);
ColorRGB[] colors = new ColorRGB[bmp.Width * bmp.Height];
return GetColors<T>(bmp);
}
public static Image<T> GetImage<T>(string file)
where T : struct, IColor
{
using FileStream stream = File.OpenRead(file);
using Bitmap bmp = new(stream);
T[] colors = new T[bmp.Width * bmp.Height];
int i = 0;
for (int x = 0; x < bmp.Width; x++)
for (int y = 0; y < bmp.Height; y++)
{
Color color = bmp.GetPixel(x, y);
colors[i++] = new ColorRGB(color.R, color.G, color.B);
colors[i++] = (T)T.Create(color.R, color.G, color.B, color.A);
}
return colors;
return Image<T>.Create(GetColors<T>(bmp), bmp.Width, bmp.Height);
}
public static ColorRGBA[] Get4ByteColorsFromImage(string file)
private static T[] GetColors<T>(Bitmap bmp)
where T : struct, IColor
{
using FileStream stream = File.OpenRead(file);
using Bitmap bmp = new(stream);
ColorRGBA[] colors = new ColorRGBA[bmp.Width * bmp.Height];
T[] colors = new T[bmp.Width * bmp.Height];
int i = 0;
for (int x = 0; x < bmp.Width; x++)
for (int y = 0; y < bmp.Height; y++)
{
Color color = bmp.GetPixel(x, y);
colors[i++] = new ColorRGBA(color.R, color.G, color.B, color.A);
colors[i++] = (T)T.Create(color.R, color.G, color.B, color.A);
}
return colors;

View File

@ -8,58 +8,144 @@ public class AverageTests
private static IEnumerable<string> GetTestImages() => Directory.EnumerateFiles(@"..\..\..\..\sample_data", "*.png", SearchOption.AllDirectories);
[TestMethod]
public void AverageImage3Byte()
{
}
[TestMethod]
public void AverageRefImage3Byte()
{
}
[TestMethod]
public void AverageReadOnlySpan3Byte()
public void AverageRefImage()
{
foreach (string image in GetTestImages())
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image);
ReadOnlySpan<ColorRGB> span = data;
ColorRGB reference = ReferencePixelHelper.Average(span);
ColorRGB test = span.Average();
Assert.AreEqual(reference.R, test.R, "R differs");
Assert.AreEqual(reference.G, test.G, "G differs");
Assert.AreEqual(reference.B, test.B, "B differs");
Assert.AreEqual(reference.A, test.A, "A differs");
AverageRefImage<ColorRGB>(image);
AverageRefImage<ColorBGR>(image);
AverageRefImage<ColorRGBA>(image);
AverageRefImage<ColorBGRA>(image);
AverageRefImage<ColorARGB>(image);
AverageRefImage<ColorABGR>(image);
}
}
[TestMethod]
public void AverageImage4Byte()
private static void AverageRefImage<T>(string image)
where T : struct, IColor
{
RefImage<T> data = ImageHelper.GetImage<T>(image).AsRefImage<T>();
T reference = ReferencePixelHelper.Average(data);
T test = data.Average();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void AverageRefImage4Byte()
{
}
[TestMethod]
public void AverageReadOnlySpan4Byte()
public void AverageGenericImage()
{
foreach (string image in GetTestImages())
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image);
ReadOnlySpan<ColorRGBA> span = data;
ColorRGBA reference = ReferencePixelHelper.Average(span);
ColorRGBA test = span.Average();
Assert.AreEqual(reference.R, test.R, "R differs");
Assert.AreEqual(reference.G, test.G, "G differs");
Assert.AreEqual(reference.B, test.B, "B differs");
Assert.AreEqual(reference.A, test.A, "A differs");
AverageGenericImage<ColorRGB>(image);
AverageGenericImage<ColorBGR>(image);
AverageGenericImage<ColorRGBA>(image);
AverageGenericImage<ColorBGRA>(image);
AverageGenericImage<ColorARGB>(image);
AverageGenericImage<ColorABGR>(image);
}
}
private static void AverageGenericImage<T>(string image)
where T : struct, IColor
{
Image<T> data = ImageHelper.GetImage<T>(image);
IColor reference = ReferencePixelHelper.Average(data);
T test = data.Average();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void AverageImage()
{
foreach (string image in GetTestImages())
{
AverageImage<ColorRGB>(image);
AverageImage<ColorBGR>(image);
AverageImage<ColorRGBA>(image);
AverageImage<ColorBGRA>(image);
AverageImage<ColorARGB>(image);
AverageImage<ColorABGR>(image);
}
}
private static void AverageImage<T>(string image)
where T : struct, IColor
{
IImage data = ImageHelper.GetImage<T>(image);
IColor reference = ReferencePixelHelper.Average(data);
IColor test = data.Average();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void AverageSpan()
{
foreach (string image in GetTestImages())
{
AverageSpan<ColorRGB>(image);
AverageSpan<ColorBGR>(image);
AverageSpan<ColorRGBA>(image);
AverageSpan<ColorBGRA>(image);
AverageSpan<ColorARGB>(image);
AverageSpan<ColorABGR>(image);
}
}
private static void AverageSpan<T>(string image)
where T : struct, IColor
{
T[] data = ImageHelper.GetColorsFromImage<T>(image);
Span<T> span = data;
T reference = ReferencePixelHelper.Average(span);
T test = span.Average();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void AverageReadOnlySpan()
{
foreach (string image in GetTestImages())
{
AverageReadOnlySpan<ColorRGB>(image);
AverageReadOnlySpan<ColorBGR>(image);
AverageReadOnlySpan<ColorRGBA>(image);
AverageReadOnlySpan<ColorBGRA>(image);
AverageReadOnlySpan<ColorARGB>(image);
AverageReadOnlySpan<ColorABGR>(image);
}
}
private static void AverageReadOnlySpan<T>(string image)
where T : struct, IColor
{
T[] data = ImageHelper.GetColorsFromImage<T>(image);
ReadOnlySpan<T> span = data;
T reference = ReferencePixelHelper.Average(span);
T test = span.Average();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
}

View File

@ -12,7 +12,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGB> referenceData = data;
Span<ColorRGB> sourceData = new ColorRGB[referenceData.Length];
@ -42,7 +42,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGBA[] data = ImageHelper.GetColorsFromImage<ColorRGBA>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGBA> referenceData = data;
Span<ColorRGBA> sourceData = new ColorRGBA[referenceData.Length];
@ -72,7 +72,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGBA[] data = ImageHelper.GetColorsFromImage<ColorRGBA>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGBA> referenceData = data;
Span<ColorRGBA> sourceData = new ColorRGBA[referenceData.Length];
@ -102,7 +102,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGBA[] data = ImageHelper.GetColorsFromImage<ColorRGBA>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGBA> referenceData = data;
Span<ColorRGBA> sourceData = new ColorRGBA[referenceData.Length];
@ -132,7 +132,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGBA[] data = ImageHelper.GetColorsFromImage<ColorRGBA>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGBA> referenceData = data;
Span<ColorRGBA> sourceData = new ColorRGBA[referenceData.Length];
@ -162,7 +162,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGB> referenceData = data;
Span<ColorRGB> sourceData = new ColorRGB[referenceData.Length];
@ -192,7 +192,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGB> referenceData = data;
Span<ColorRGB> sourceData = new ColorRGB[referenceData.Length];
@ -222,7 +222,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGB> referenceData = data;
Span<ColorRGB> sourceData = new ColorRGB[referenceData.Length];
@ -252,7 +252,7 @@ public class ConvertTests
{
for (int skip = 0; skip < 4; skip++)
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image).SkipLast(skip).ToArray();
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image).SkipLast(skip).ToArray();
ReadOnlySpan<ColorRGB> referenceData = data;
Span<ColorRGB> sourceData = new ColorRGB[referenceData.Length];

View File

@ -8,78 +8,194 @@ public class MinMaxTests
private static IEnumerable<string> GetTestImages() => Directory.EnumerateFiles(@"..\..\..\..\sample_data", "*.png", SearchOption.AllDirectories);
[TestMethod]
public void MinMaxImage3Byte()
{
}
[TestMethod]
public void MinMaxRefImage3Byte()
{
}
[TestMethod]
public void MinMaxReadOnlySpan3Byte()
public void MinMaxRefImage()
{
foreach (string image in GetTestImages())
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image);
ReadOnlySpan<ColorRGB> span = data;
MinMaxRefImage<ColorRGB>(image);
MinMaxRefImage<ColorBGR>(image);
MinMaxRefImage<ColorRGBA>(image);
MinMaxRefImage<ColorBGRA>(image);
MinMaxRefImage<ColorARGB>(image);
MinMaxRefImage<ColorABGR>(image);
}
}
private static void MinMaxRefImage<T>(string image)
where T : struct, IColor
{
RefImage<T> data = ImageHelper.GetImage<T>(image).AsRefImage<T>();
IMinMax reference = ReferencePixelHelper.MinMax(data);
IMinMax test = data.MinMax();
Assert.AreEqual(reference.RedMin, test.RedMin, $"RedMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMin, test.GreenMin, $"GreenMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMin, test.BlueMin, $"BlueMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMin, test.AlphaMin, $"AlphaMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedMax, test.RedMax, $"RedMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMax, test.GreenMax, $"GreenMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMax, test.BlueMax, $"BlueMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMax, test.AlphaMax, $"AlphaMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedRange, test.RedRange, $"RedRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenRange, test.GreenRange, $"GreenRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueRange, test.BlueRange, $"BlueRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaRange, test.AlphaRange, $"AlphaRange differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void MinMaxGenericImage()
{
foreach (string image in GetTestImages())
{
MinMaxGenericImage<ColorRGB>(image);
MinMaxGenericImage<ColorBGR>(image);
MinMaxGenericImage<ColorRGBA>(image);
MinMaxGenericImage<ColorBGRA>(image);
MinMaxGenericImage<ColorARGB>(image);
MinMaxGenericImage<ColorABGR>(image);
}
}
private static void MinMaxGenericImage<T>(string image)
where T : struct, IColor
{
Image<T> data = ImageHelper.GetImage<T>(image);
IMinMax reference = ReferencePixelHelper.MinMax(data);
IMinMax test = data.MinMax();
Assert.AreEqual(reference.RedMin, test.RedMin, $"RedMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMin, test.GreenMin, $"GreenMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMin, test.BlueMin, $"BlueMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMin, test.AlphaMin, $"AlphaMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedMax, test.RedMax, $"RedMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMax, test.GreenMax, $"GreenMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMax, test.BlueMax, $"BlueMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMax, test.AlphaMax, $"AlphaMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedRange, test.RedRange, $"RedRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenRange, test.GreenRange, $"GreenRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueRange, test.BlueRange, $"BlueRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaRange, test.AlphaRange, $"AlphaRange differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void MinMaxImage()
{
foreach (string image in GetTestImages())
{
MinMaxImage<ColorRGB>(image);
MinMaxImage<ColorBGR>(image);
MinMaxImage<ColorRGBA>(image);
MinMaxImage<ColorBGRA>(image);
MinMaxImage<ColorARGB>(image);
MinMaxImage<ColorABGR>(image);
}
}
private static void MinMaxImage<T>(string image)
where T : struct, IColor
{
IImage data = ImageHelper.GetImage<T>(image);
IMinMax reference = ReferencePixelHelper.MinMax(data);
IMinMax test = data.MinMax();
Assert.AreEqual(reference.RedMin, test.RedMin, $"RedMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMin, test.GreenMin, $"GreenMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMin, test.BlueMin, $"BlueMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMin, test.AlphaMin, $"AlphaMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedMax, test.RedMax, $"RedMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMax, test.GreenMax, $"GreenMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMax, test.BlueMax, $"BlueMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMax, test.AlphaMax, $"AlphaMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedRange, test.RedRange, $"RedRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenRange, test.GreenRange, $"GreenRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueRange, test.BlueRange, $"BlueRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaRange, test.AlphaRange, $"AlphaRange differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void MinMaxSpan()
{
foreach (string image in GetTestImages())
{
MinMaxSpan<ColorRGB>(image);
MinMaxSpan<ColorBGR>(image);
MinMaxSpan<ColorRGBA>(image);
MinMaxSpan<ColorBGRA>(image);
MinMaxSpan<ColorARGB>(image);
MinMaxSpan<ColorABGR>(image);
}
}
private static void MinMaxSpan<T>(string image)
where T : struct, IColor
{
T[] data = ImageHelper.GetColorsFromImage<T>(image);
Span<T> span = data;
IMinMax reference = ReferencePixelHelper.MinMax(span);
IMinMax test = span.MinMax();
Assert.AreEqual(reference.RedMin, test.RedMin, "RedMin differs");
Assert.AreEqual(reference.GreenMin, test.GreenMin, "GreenMin differs");
Assert.AreEqual(reference.BlueMin, test.BlueMin, "BlueMin differs");
Assert.AreEqual(reference.AlphaMin, test.AlphaMin, "AlphaMin differs");
Assert.AreEqual(reference.RedMin, test.RedMin, $"RedMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMin, test.GreenMin, $"GreenMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMin, test.BlueMin, $"BlueMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMin, test.AlphaMin, $"AlphaMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedMax, test.RedMax, "RedMax differs");
Assert.AreEqual(reference.GreenMax, test.GreenMax, "GreenMax differs");
Assert.AreEqual(reference.BlueMax, test.BlueMax, "BlueMax differs");
Assert.AreEqual(reference.AlphaMax, test.AlphaMax, "AlphaMax differs");
Assert.AreEqual(reference.RedMax, test.RedMax, $"RedMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMax, test.GreenMax, $"GreenMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMax, test.BlueMax, $"BlueMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMax, test.AlphaMax, $"AlphaMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedRange, test.RedRange, "RedRange differs");
Assert.AreEqual(reference.GreenRange, test.GreenRange, "GreenRange differs");
Assert.AreEqual(reference.BlueRange, test.BlueRange, "BlueRange differs");
Assert.AreEqual(reference.AlphaRange, test.AlphaRange, "AlphaRange differs");
}
Assert.AreEqual(reference.RedRange, test.RedRange, $"RedRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenRange, test.GreenRange, $"GreenRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueRange, test.BlueRange, $"BlueRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaRange, test.AlphaRange, $"AlphaRange differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void MinMaxImage4Byte()
{
}
[TestMethod]
public void MinMaxRefImage4Byte()
{
}
[TestMethod]
public void MinMaxReadOnlySpan4Byte()
public void MinMaxReadOnlySpan()
{
foreach (string image in GetTestImages())
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image);
ReadOnlySpan<ColorRGBA> span = data;
MinMaxReadOnlySpan<ColorRGB>(image);
MinMaxReadOnlySpan<ColorBGR>(image);
MinMaxReadOnlySpan<ColorRGBA>(image);
MinMaxReadOnlySpan<ColorBGRA>(image);
MinMaxReadOnlySpan<ColorARGB>(image);
MinMaxReadOnlySpan<ColorABGR>(image);
}
}
private static void MinMaxReadOnlySpan<T>(string image)
where T : struct, IColor
{
T[] data = ImageHelper.GetColorsFromImage<T>(image);
ReadOnlySpan<T> span = data;
IMinMax reference = ReferencePixelHelper.MinMax(span);
IMinMax test = span.MinMax();
Assert.AreEqual(reference.RedMin, test.RedMin, "RedMin differs");
Assert.AreEqual(reference.GreenMin, test.GreenMin, "GreenMin differs");
Assert.AreEqual(reference.BlueMin, test.BlueMin, "BlueMin differs");
Assert.AreEqual(reference.AlphaMin, test.AlphaMin, "AlphaMin differs");
Assert.AreEqual(reference.RedMin, test.RedMin, $"RedMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMin, test.GreenMin, $"GreenMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMin, test.BlueMin, $"BlueMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMin, test.AlphaMin, $"AlphaMin differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedMax, test.RedMax, "RedMax differs");
Assert.AreEqual(reference.GreenMax, test.GreenMax, "GreenMax differs");
Assert.AreEqual(reference.BlueMax, test.BlueMax, "BlueMax differs");
Assert.AreEqual(reference.AlphaMax, test.AlphaMax, "AlphaMax differs");
Assert.AreEqual(reference.RedMax, test.RedMax, $"RedMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenMax, test.GreenMax, $"GreenMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueMax, test.BlueMax, $"BlueMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaMax, test.AlphaMax, $"AlphaMax differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.RedRange, test.RedRange, "RedRange differs");
Assert.AreEqual(reference.GreenRange, test.GreenRange, "GreenRange differs");
Assert.AreEqual(reference.BlueRange, test.BlueRange, "BlueRange differs");
Assert.AreEqual(reference.AlphaRange, test.AlphaRange, "AlphaRange differs");
}
Assert.AreEqual(reference.RedRange, test.RedRange, $"RedRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.GreenRange, test.GreenRange, $"GreenRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.BlueRange, test.BlueRange, $"BlueRange differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.AlphaRange, test.AlphaRange, $"AlphaRange differs in type '{T.ColorFormat.Name}'");
}
}

View File

@ -12,7 +12,7 @@ public class CreateColorPaletteTests
{
foreach (string image in GetTestImages())
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image);
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image);
Span<ColorRGB> span = data;
ColorRGB[] reference = [.. ReferencePixelHelper.CreateColorPalette(span, 1).OrderBy(x => x.R).ThenBy(x => x.G).ThenBy(x => x.B).ThenBy(x => x.A)];
@ -30,7 +30,7 @@ public class CreateColorPaletteTests
{
foreach (string image in GetTestImages())
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image);
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image);
Span<ColorRGB> span = data;
ColorRGB[] reference = [.. ReferencePixelHelper.CreateColorPalette(span, 2).OrderBy(x => x.R).ThenBy(x => x.G).ThenBy(x => x.B).ThenBy(x => x.A)];
@ -48,7 +48,7 @@ public class CreateColorPaletteTests
{
foreach (string image in GetTestImages())
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image);
ColorRGB[] data = ImageHelper.GetColorsFromImage<ColorRGB>(image);
Span<ColorRGB> span = data;
ColorRGB[] reference = [.. ReferencePixelHelper.CreateColorPalette(span, 16).OrderBy(x => x.R).ThenBy(x => x.G).ThenBy(x => x.B).ThenBy(x => x.A)];
@ -66,7 +66,7 @@ public class CreateColorPaletteTests
{
foreach (string image in GetTestImages())
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image);
ColorRGBA[] data = ImageHelper.GetColorsFromImage<ColorRGBA>(image);
Span<ColorRGBA> span = data;
ColorRGBA[] reference = [.. ReferencePixelHelper.CreateColorPalette(span, 1).OrderBy(x => x.R).ThenBy(x => x.G).ThenBy(x => x.B).ThenBy(x => x.A)];
@ -84,7 +84,7 @@ public class CreateColorPaletteTests
{
foreach (string image in GetTestImages())
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image);
ColorRGBA[] data = ImageHelper.GetColorsFromImage<ColorRGBA>(image);
Span<ColorRGBA> span = data;
ColorRGBA[] reference = [.. ReferencePixelHelper.CreateColorPalette(span, 2).OrderBy(x => x.R).ThenBy(x => x.G).ThenBy(x => x.B).ThenBy(x => x.A)];
@ -102,7 +102,7 @@ public class CreateColorPaletteTests
{
foreach (string image in GetTestImages())
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image);
ColorRGBA[] data = ImageHelper.GetColorsFromImage<ColorRGBA>(image);
Span<ColorRGBA> span = data;
ColorRGBA[] reference = [.. ReferencePixelHelper.CreateColorPalette(span, 16).OrderBy(x => x.R).ThenBy(x => x.G).ThenBy(x => x.B).ThenBy(x => x.A)];

View File

@ -13,7 +13,7 @@ public class SortTests
{
foreach (string image in GetTestImages())
{
ColorRGB[] referenceData = ImageHelper.Get3ByteColorsFromImage(image);
ColorRGB[] referenceData = ImageHelper.GetColorsFromImage<ColorRGB>(image);
ColorRGB[] testData = new ColorRGB[referenceData.Length];
Span<ColorRGB> referenceSpan = referenceData;
Span<ColorRGB> testSpan = testData;
@ -32,7 +32,7 @@ public class SortTests
{
foreach (string image in GetTestImages())
{
ColorRGB[] referenceData = ImageHelper.Get3ByteColorsFromImage(image);
ColorRGB[] referenceData = ImageHelper.GetColorsFromImage<ColorRGB>(image);
ColorRGB[] testData = new ColorRGB[referenceData.Length];
Span<ColorRGB> referenceSpan = referenceData;
Span<ColorRGB> testSpan = testData;
@ -51,7 +51,7 @@ public class SortTests
{
foreach (string image in GetTestImages())
{
ColorRGB[] referenceData = ImageHelper.Get3ByteColorsFromImage(image);
ColorRGB[] referenceData = ImageHelper.GetColorsFromImage<ColorRGB>(image);
ColorRGB[] testData = new ColorRGB[referenceData.Length];
Span<ColorRGB> referenceSpan = referenceData;
Span<ColorRGB> testSpan = testData;
@ -70,7 +70,7 @@ public class SortTests
{
foreach (string image in GetTestImages())
{
ColorRGBA[] referenceData = ImageHelper.Get4ByteColorsFromImage(image);
ColorRGBA[] referenceData = ImageHelper.GetColorsFromImage<ColorRGBA>(image);
ColorRGBA[] testData = new ColorRGBA[referenceData.Length];
Span<ColorRGBA> referenceSpan = referenceData;
Span<ColorRGBA> testSpan = testData;
@ -89,7 +89,7 @@ public class SortTests
{
foreach (string image in GetTestImages())
{
ColorRGBA[] referenceData = ImageHelper.Get4ByteColorsFromImage(image);
ColorRGBA[] referenceData = ImageHelper.GetColorsFromImage<ColorRGBA>(image);
ColorRGBA[] testData = new ColorRGBA[referenceData.Length];
Span<ColorRGBA> referenceSpan = referenceData;
Span<ColorRGBA> testSpan = testData;
@ -108,7 +108,7 @@ public class SortTests
{
foreach (string image in GetTestImages())
{
ColorRGBA[] referenceData = ImageHelper.Get4ByteColorsFromImage(image);
ColorRGBA[] referenceData = ImageHelper.GetColorsFromImage<ColorRGBA>(image);
ColorRGBA[] testData = new ColorRGBA[referenceData.Length];
Span<ColorRGBA> referenceSpan = referenceData;
Span<ColorRGBA> testSpan = testData;
@ -127,7 +127,7 @@ public class SortTests
{
foreach (string image in GetTestImages())
{
ColorRGBA[] referenceData = ImageHelper.Get4ByteColorsFromImage(image);
ColorRGBA[] referenceData = ImageHelper.GetColorsFromImage<ColorRGBA>(image);
ColorRGBA[] testData = new ColorRGBA[referenceData.Length];
Span<ColorRGBA> referenceSpan = referenceData;
Span<ColorRGBA> testSpan = testData;

View File

@ -8,58 +8,144 @@ public class SumTests
private static IEnumerable<string> GetTestImages() => Directory.EnumerateFiles(@"..\..\..\..\sample_data", "*.png", SearchOption.AllDirectories);
[TestMethod]
public void SumImage3Byte()
{
}
[TestMethod]
public void SumRefImage3Byte()
{
}
[TestMethod]
public void SumReadOnlySpan3Byte()
public void SumRefImage()
{
foreach (string image in GetTestImages())
{
ColorRGB[] data = ImageHelper.Get3ByteColorsFromImage(image);
ReadOnlySpan<ColorRGB> span = data;
SumRefImage<ColorRGB>(image);
SumRefImage<ColorBGR>(image);
SumRefImage<ColorRGBA>(image);
SumRefImage<ColorBGRA>(image);
SumRefImage<ColorARGB>(image);
SumRefImage<ColorABGR>(image);
}
}
private static void SumRefImage<T>(string image)
where T : struct, IColor
{
RefImage<T> data = ImageHelper.GetImage<T>(image).AsRefImage<T>();
ISum reference = ReferencePixelHelper.Sum(data);
ISum test = data.Sum();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void SumGenericImage()
{
foreach (string image in GetTestImages())
{
SumGenericImage<ColorRGB>(image);
SumGenericImage<ColorBGR>(image);
SumGenericImage<ColorRGBA>(image);
SumGenericImage<ColorBGRA>(image);
SumGenericImage<ColorARGB>(image);
SumGenericImage<ColorABGR>(image);
}
}
private static void SumGenericImage<T>(string image)
where T : struct, IColor
{
Image<T> data = ImageHelper.GetImage<T>(image);
ISum reference = ReferencePixelHelper.Sum(data);
ISum test = data.Sum();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void SumImage()
{
foreach (string image in GetTestImages())
{
SumImage<ColorRGB>(image);
SumImage<ColorBGR>(image);
SumImage<ColorRGBA>(image);
SumImage<ColorBGRA>(image);
SumImage<ColorARGB>(image);
SumImage<ColorABGR>(image);
}
}
private static void SumImage<T>(string image)
where T : struct, IColor
{
IImage data = ImageHelper.GetImage<T>(image);
ISum reference = ReferencePixelHelper.Sum(data);
ISum test = data.Sum();
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void SumSpan()
{
foreach (string image in GetTestImages())
{
SumSpan<ColorRGB>(image);
SumSpan<ColorBGR>(image);
SumSpan<ColorRGBA>(image);
SumSpan<ColorBGRA>(image);
SumSpan<ColorARGB>(image);
SumSpan<ColorABGR>(image);
}
}
private static void SumSpan<T>(string image)
where T : struct, IColor
{
T[] data = ImageHelper.GetColorsFromImage<T>(image);
Span<T> span = data;
ISum reference = ReferencePixelHelper.Sum(span);
ISum test = span.Sum();
Assert.AreEqual(reference.R, test.R, "R differs");
Assert.AreEqual(reference.G, test.G, "G differs");
Assert.AreEqual(reference.B, test.B, "B differs");
Assert.AreEqual(reference.A, test.A, "A differs");
}
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
[TestMethod]
public void SumImage4Byte()
{
}
[TestMethod]
public void SumRefImage4Byte()
{
}
[TestMethod]
public void SumReadOnlySpan4Byte()
public void SumReadOnlySpan()
{
foreach (string image in GetTestImages())
{
ColorRGBA[] data = ImageHelper.Get4ByteColorsFromImage(image);
ReadOnlySpan<ColorRGBA> span = data;
SumReadOnlySpan<ColorRGB>(image);
SumReadOnlySpan<ColorBGR>(image);
SumReadOnlySpan<ColorRGBA>(image);
SumReadOnlySpan<ColorBGRA>(image);
SumReadOnlySpan<ColorARGB>(image);
SumReadOnlySpan<ColorABGR>(image);
}
}
private static void SumReadOnlySpan<T>(string image)
where T : struct, IColor
{
T[] data = ImageHelper.GetColorsFromImage<T>(image);
ReadOnlySpan<T> span = data;
ISum reference = ReferencePixelHelper.Sum(span);
ISum test = span.Sum();
Assert.AreEqual(reference.R, test.R, "R differs");
Assert.AreEqual(reference.G, test.G, "G differs");
Assert.AreEqual(reference.B, test.B, "B differs");
Assert.AreEqual(reference.A, test.A, "A differs");
}
Assert.AreEqual(reference.R, test.R, $"R differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.G, test.G, $"G differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.B, test.B, $"B differs in type '{T.ColorFormat.Name}'");
Assert.AreEqual(reference.A, test.A, $"A differs in type '{T.ColorFormat.Name}'");
}
}

View File

@ -10,7 +10,7 @@ internal static class TestDataHelper
return (T)T.Create(xBytes[0], xBytes[1], yBytes[0], yBytes[1]);
}
public static Image<T> CreateTestImage<T>(int width, int height)
public static T[] GetPixelData<T>(int width, int height)
where T : struct, IColor
{
T[] buffer = new T[width * height];
@ -19,6 +19,10 @@ internal static class TestDataHelper
for (int x = 0; x < width; x++)
buffer[(y * width) + x] = GetColorFromLocation<T>(x, y);
return Image<T>.Create(buffer, width, height);
return buffer;
}
public static Image<T> CreateTestImage<T>(int width, int height)
where T : struct, IColor
=> Image<T>.Create(GetPixelData<T>(width, height), width, height);
}

View File

@ -205,7 +205,7 @@ public sealed class Image<T> : IImage<T>
if (_buffer.Length == 0)
return ref Unsafe.NullRef<byte>();
return ref MemoryMarshal.GetReference(new ReadOnlySpan<byte>(_buffer)[((_y * _stride) + (_x * ColorFormat.BytesPerPixel))..]);
return ref Unsafe.Add(ref MemoryMarshal.GetReference(_buffer.AsSpan()), (_y * _stride) + (_x * ColorFormat.BytesPerPixel));
}
public IEnumerator<T> GetEnumerator()

View File

@ -60,10 +60,10 @@ public readonly ref struct ImageColumn<T>
_buffer.Slice(_start, SizeInBytes).CopyTo(destination);
else
{
ReadOnlySpan<T> data = MemoryMarshal.Cast<byte, T>(_buffer[_start..]);
ref byte dataRef = ref Unsafe.Add(ref MemoryMarshal.GetReference(_buffer), _start);
Span<T> target = MemoryMarshal.Cast<byte, T>(destination);
for (int i = 0; i < Length; i++)
target[i] = data[i * _step];
target[i] = Unsafe.As<byte, T>(ref Unsafe.Add(ref dataRef, i * _step));
}
}
@ -143,7 +143,7 @@ internal class IColorImageColumn<T> : IImageColumn
{
if ((y < 0) || (y >= _length)) throw new IndexOutOfRangeException();
return MemoryMarshal.Cast<byte, T>(_buffer.AsSpan()[(_start + (y * _step))..])[0];
return Unsafe.As<byte, T>(ref Unsafe.Add(ref MemoryMarshal.GetReference(_buffer.AsSpan()), _start + (y * _step)));
}
}
@ -181,10 +181,10 @@ internal class IColorImageColumn<T> : IImageColumn
_buffer.AsSpan().Slice(_start, SizeInBytes).CopyTo(destination);
else
{
ReadOnlySpan<T> data = MemoryMarshal.Cast<byte, T>(_buffer.AsSpan()[_start..]);
ref byte dataRef = ref Unsafe.Add(ref MemoryMarshal.GetReference(_buffer.AsSpan()), _start);
Span<T> target = MemoryMarshal.Cast<byte, T>(destination);
for (int i = 0; i < Length; i++)
target[i] = data[i * _step];
target[i] = Unsafe.As<byte, T>(ref Unsafe.Add(ref dataRef, i * _step));
}
}

View File

@ -131,7 +131,7 @@ internal class IColorImageRow<T> : IImageRow
{
if ((x < 0) || (x >= _length)) throw new IndexOutOfRangeException();
return MemoryMarshal.Cast<byte, T>(_buffer.AsSpan()[_start..])[x];
return Unsafe.Add(ref Unsafe.As<byte, T>(ref Unsafe.Add(ref MemoryMarshal.GetReference(_buffer.AsSpan()), (nint)(uint)_start)), (nint)(uint)x);
}
}

View File

@ -126,8 +126,7 @@ public readonly ref struct RefImage<T>
if (_data.Length == 0)
return ref Unsafe.NullRef<byte>();
int offset = (_y * RawStride) + (_x * T.ColorFormat.BytesPerPixel);
return ref MemoryMarshal.GetReference(_data[offset..]);
return ref Unsafe.Add(ref MemoryMarshal.GetReference(_data), (_y * RawStride) + (_x * T.ColorFormat.BytesPerPixel));
}
/// <inheritdoc cref="System.Collections.IEnumerable.GetEnumerator"/>

View File

@ -39,7 +39,7 @@ public static partial class PixelHelper
try
{
image.CopyTo(buffer);
return Average<T>(buffer);
return Average(buffer);
}
finally
{
@ -47,6 +47,19 @@ public static partial class PixelHelper
}
}
public static T Average<T>(this Span<T> colors)
where T : struct, IColor
{
if (colors == null) throw new ArgumentNullException(nameof(colors));
return T.ColorFormat.BytesPerPixel switch
{
3 => Unsafe.BitCast<Generic3ByteData, T>(Average(MemoryMarshal.Cast<T, Generic3ByteData>(colors))),
4 => Unsafe.BitCast<Generic4ByteData, T>(Average(MemoryMarshal.Cast<T, Generic4ByteData>(colors))),
_ => throw new NotSupportedException("Data is not of a supported valid color-type.")
};
}
public static T Average<T>(this ReadOnlySpan<T> colors)
where T : struct, IColor
{

View File

@ -86,7 +86,7 @@ public static partial class PixelHelper
T[] result = new T[cubes.Length];
for (int i = 0; i < cubes.Length; i++)
result[i] = Average<T>(cubes[i].Slice(colors));
result[i] = Average(cubes[i].Slice(colors));
return result;
}

View File

@ -41,7 +41,7 @@ public static unsafe partial class PixelHelper
try
{
image.CopyTo(buffer);
return Sum<T>(buffer);
return Sum(buffer);
}
finally
{
@ -53,6 +53,10 @@ public static unsafe partial class PixelHelper
where T : struct, IColor
=> T.ColorFormat.Sum(MemoryMarshal.AsBytes(colors));
public static ISum Sum<T>(this Span<T> colors)
where T : struct, IColor
=> T.ColorFormat.Sum(MemoryMarshal.AsBytes(colors));
internal static ISum Sum<T, TSum>(ReadOnlySpan<T> colors)
where T : struct, IColor
where TSum : struct, ISum