Fixed potential error in in-place conversion and improved tests to cover this case

This commit is contained in:
Darth Affe 2024-08-11 21:13:27 +02:00
parent ca4e7e7af5
commit 2c2250d9d7
3 changed files with 142 additions and 22 deletions

View File

@ -33,6 +33,12 @@ public class ConvertTests
}
}
}
IImage<ColorBGR> converted = TestDataHelper.CreateTestImage<ColorRGB>(1920, 1080).ConvertTo<ColorBGR>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorBGR>(x, y), converted[x, y], $"Wrong color at x: {x}, y: {y}");
}
[TestMethod]
@ -63,6 +69,12 @@ public class ConvertTests
}
}
}
IImage<ColorARGB> converted = TestDataHelper.CreateTestImage<ColorRGBA>(1920, 1080).ConvertTo<ColorARGB>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorARGB>(x, y), converted[x, y], $"Wrong color at x: {x}, y: {y}");
}
[TestMethod]
@ -93,6 +105,12 @@ public class ConvertTests
}
}
}
IImage<ColorBGRA> converted = TestDataHelper.CreateTestImage<ColorRGBA>(1920, 1080).ConvertTo<ColorBGRA>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorBGRA>(x, y), converted[x, y], $"Wrong color at x: {x}, y: {y}");
}
[TestMethod]
@ -123,6 +141,12 @@ public class ConvertTests
}
}
}
IImage<ColorRGB> converted = TestDataHelper.CreateTestImage<ColorRGBA>(1920, 1080).ConvertTo<ColorRGB>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorRGB>(x, y), converted[x, y], $"Wrong color at x: {x}, y: {y}");
}
[TestMethod]
@ -153,6 +177,12 @@ public class ConvertTests
}
}
}
IImage<ColorBGR> converted = TestDataHelper.CreateTestImage<ColorRGBA>(1920, 1080).ConvertTo<ColorBGR>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorBGR>(x, y), converted[x, y], $"Wrong color at x: {x}, y: {y}");
}
[TestMethod]
@ -183,6 +213,20 @@ public class ConvertTests
}
}
}
IImage<ColorRGBA> converted = TestDataHelper.CreateTestImage<ColorRGB>(1920, 1080).ConvertTo<ColorRGBA>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
{
ColorABGR refColor = TestDataHelper.GetColorFromLocation<ColorABGR>(x, y);
ColorRGBA color = converted[x, y];
Assert.AreEqual(255, color.A, $"Wrong A at x: {x}, y: {y}");
Assert.AreEqual(refColor.R, color.R, $"Wrong R at x: {x}, y: {y}");
Assert.AreEqual(refColor.G, color.G, $"Wrong G at x: {x}, y: {y}");
Assert.AreEqual(refColor.B, color.B, $"Wrong B at x: {x}, y: {y}");
}
}
[TestMethod]
@ -213,6 +257,20 @@ public class ConvertTests
}
}
}
IImage<ColorARGB> converted = TestDataHelper.CreateTestImage<ColorRGB>(1920, 1080).ConvertTo<ColorARGB>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
{
ColorABGR refColor = TestDataHelper.GetColorFromLocation<ColorABGR>(x, y);
ColorARGB color = converted[x, y];
Assert.AreEqual(255, color.A, $"Wrong A at x: {x}, y: {y}");
Assert.AreEqual(refColor.R, color.R, $"Wrong R at x: {x}, y: {y}");
Assert.AreEqual(refColor.G, color.G, $"Wrong G at x: {x}, y: {y}");
Assert.AreEqual(refColor.B, color.B, $"Wrong B at x: {x}, y: {y}");
}
}
[TestMethod]
@ -243,6 +301,20 @@ public class ConvertTests
}
}
}
IImage<ColorBGRA> converted = TestDataHelper.CreateTestImage<ColorRGB>(1920, 1080).ConvertTo<ColorBGRA>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
{
ColorABGR refColor = TestDataHelper.GetColorFromLocation<ColorABGR>(x, y);
ColorBGRA color = converted[x, y];
Assert.AreEqual(255, color.A, $"Wrong A at x: {x}, y: {y}");
Assert.AreEqual(refColor.R, color.R, $"Wrong R at x: {x}, y: {y}");
Assert.AreEqual(refColor.G, color.G, $"Wrong G at x: {x}, y: {y}");
Assert.AreEqual(refColor.B, color.B, $"Wrong B at x: {x}, y: {y}");
}
}
[TestMethod]
@ -273,6 +345,20 @@ public class ConvertTests
}
}
}
IImage<ColorABGR> converted = TestDataHelper.CreateTestImage<ColorRGB>(1920, 1080).ConvertTo<ColorABGR>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
{
ColorABGR refColor = TestDataHelper.GetColorFromLocation<ColorABGR>(x, y);
ColorABGR color = converted[x, y];
Assert.AreEqual(255, color.A, $"Wrong A at x: {x}, y: {y}");
Assert.AreEqual(refColor.R, color.R, $"Wrong R at x: {x}, y: {y}");
Assert.AreEqual(refColor.G, color.G, $"Wrong G at x: {x}, y: {y}");
Assert.AreEqual(refColor.B, color.B, $"Wrong B at x: {x}, y: {y}");
}
}
[TestMethod]
@ -303,5 +389,11 @@ public class ConvertTests
}
}
}
IImage<ColorBGR> converted = TestDataHelper.CreateTestImage<ColorRGB>(1920, 1080).ConvertTo<ColorBGR>();
for (int y = 0; y < converted.Height; y++)
for (int x = 0; x < converted.Width; x++)
Assert.AreEqual(TestDataHelper.GetColorFromLocation<ColorBGR>(x, y), converted[x, y], $"Wrong color at x: {x}, y: {y}");
}
}

View File

@ -16,6 +16,14 @@ public class SystemDrawingTests
IImage image2 = bitmap.ToImage();
Assert.AreEqual(IColorFormat.BGR, image2.ColorFormat);
for (int y = 0; y < image.Height; y++)
for (int x = 0; x < image.Width; x++)
{
Assert.AreEqual(image[x, y].A, image2[x, y].A, $"{x}-{y}");
Assert.AreEqual(image[x, y].R, image2[x, y].R, $"{x}-{y}");
Assert.AreEqual(image[x, y].G, image2[x, y].G, $"{x}-{y}");
Assert.AreEqual(image[x, y].B, image2[x, y].B, $"{x}-{y}");
}
image2 = image2.ConvertTo<ColorRGB>();
@ -30,6 +38,14 @@ public class SystemDrawingTests
IImage image2 = bitmap.ToImage();
Assert.AreEqual(IColorFormat.BGRA, image2.ColorFormat);
for (int y = 0; y < image.Height; y++)
for (int x = 0; x < image.Width; x++)
{
Assert.AreEqual(image[x, y].A, image2[x, y].A);
Assert.AreEqual(image[x, y].R, image2[x, y].R);
Assert.AreEqual(image[x, y].G, image2[x, y].G);
Assert.AreEqual(image[x, y].B, image2[x, y].B);
}
image2 = image2.ConvertTo<ColorRGBA>();

View File

@ -174,12 +174,14 @@ public static unsafe partial class PixelHelper
tar += bytesPerVector;
}
Span<byte> buffer = stackalloc byte[missingElements * BPP];
for (int i = 0; i < missingElements; i++)
{
tar[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
tar[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
tar[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
buffer[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
buffer[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
buffer[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
}
buffer.CopyTo(new Span<byte>(tar, buffer.Length));
}
else
{
@ -191,12 +193,14 @@ public static unsafe partial class PixelHelper
byte* missingSrc = sourcePtr + (batches * batchSize * BPP);
byte* missingTar = targetPtr + (batches * batchSize * BPP);
Span<byte> buffer = stackalloc byte[missing * BPP];
for (int i = 0; i < missing; i++)
{
missingTar[(i * BPP) + 0] = missingSrc[(i * BPP) + maskVector[0]];
missingTar[(i * BPP) + 1] = missingSrc[(i * BPP) + maskVector[1]];
missingTar[(i * BPP) + 2] = missingSrc[(i * BPP) + maskVector[2]];
buffer[(i * BPP) + 0] = missingSrc[(i * BPP) + maskVector[0]];
buffer[(i * BPP) + 1] = missingSrc[(i * BPP) + maskVector[1]];
buffer[(i * BPP) + 2] = missingSrc[(i * BPP) + maskVector[2]];
}
buffer.CopyTo(new Span<byte>(missingTar, buffer.Length));
}
void Process(int index)
@ -217,12 +221,14 @@ public static unsafe partial class PixelHelper
tar += bytesPerVector;
}
Span<byte> buffer = stackalloc byte[missingElements * BPP];
for (int i = 0; i < missingElements; i++)
{
tar[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
tar[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
tar[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
buffer[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
buffer[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
buffer[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
}
buffer.CopyTo(new Span<byte>(tar, buffer.Length));
}
}
}
@ -292,13 +298,15 @@ public static unsafe partial class PixelHelper
tar += bytesPerVector;
}
Span<byte> buffer = stackalloc byte[missingElements * BPP];
for (int i = 0; i < missingElements; i++)
{
tar[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
tar[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
tar[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
tar[(i * BPP) + 3] = src[(i * BPP) + maskVector[3]];
buffer[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
buffer[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
buffer[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
buffer[(i * BPP) + 3] = src[(i * BPP) + maskVector[3]];
}
buffer.CopyTo(new Span<byte>(tar, buffer.Length));
}
else
{
@ -310,13 +318,15 @@ public static unsafe partial class PixelHelper
byte* missingSrc = sourcePtr + (batches * batchSize * BPP);
byte* missingTar = targetPtr + (batches * batchSize * BPP);
Span<byte> buffer = stackalloc byte[missing * BPP];
for (int i = 0; i < missing; i++)
{
missingTar[(i * BPP) + 0] = missingSrc[(i * BPP) + maskVector[0]];
missingTar[(i * BPP) + 1] = missingSrc[(i * BPP) + maskVector[1]];
missingTar[(i * BPP) + 2] = missingSrc[(i * BPP) + maskVector[2]];
missingTar[(i * BPP) + 3] = missingSrc[(i * BPP) + maskVector[3]];
buffer[(i * BPP) + 0] = missingSrc[(i * BPP) + maskVector[0]];
buffer[(i * BPP) + 1] = missingSrc[(i * BPP) + maskVector[1]];
buffer[(i * BPP) + 2] = missingSrc[(i * BPP) + maskVector[2]];
buffer[(i * BPP) + 3] = missingSrc[(i * BPP) + maskVector[3]];
}
buffer.CopyTo(new Span<byte>(missingTar, buffer.Length));
}
void Process(int index)
@ -337,13 +347,15 @@ public static unsafe partial class PixelHelper
tar += bytesPerVector;
}
Span<byte> buffer = stackalloc byte[missingElements * BPP];
for (int i = 0; i < missingElements; i++)
{
tar[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
tar[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
tar[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
tar[(i * BPP) + 3] = src[(i * BPP) + maskVector[3]];
buffer[(i * BPP) + 0] = src[(i * BPP) + maskVector[0]];
buffer[(i * BPP) + 1] = src[(i * BPP) + maskVector[1]];
buffer[(i * BPP) + 2] = src[(i * BPP) + maskVector[2]];
buffer[(i * BPP) + 3] = src[(i * BPP) + maskVector[3]];
}
buffer.CopyTo(new Span<byte>(tar, buffer.Length));
}
}
}