diff --git a/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations.cs b/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations.cs index c1f6001af..ffa28fc13 100644 --- a/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations.cs +++ b/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations.cs @@ -71,7 +71,6 @@ ArrayPointer destBytes, int count) { byte* sp = (byte*)sourceColors; - byte[] dest = destBytes.Array; for (int i = destBytes.Offset; i < destBytes.Offset + count*3; i+=3) @@ -81,29 +80,89 @@ sp += ColorSize; } } - - internal virtual void PackToXyzwBytes(ArrayPointer sourceColors, ArrayPointer destBytes, int count) - { - } internal virtual void PackFromXyzwBytes(ArrayPointer sourceBytes, ArrayPointer destColors, int count) { + byte* sp = (byte*)sourceBytes; + byte* dp = (byte*)destColors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = default(TColor); + c.PackFromBytes(sp[0], sp[1], sp[2], sp[3]); + Unsafe.Write(dp, c); + sp += 4; + dp += ColorSize; + } } - - internal virtual void PackToZyxBytes(ArrayPointer sourceColors, ArrayPointer destBytes, int count) + + internal virtual void PackToXyzwBytes(ArrayPointer sourceColors, ArrayPointer destBytes, int count) { + byte* sp = (byte*)sourceColors; + byte[] dest = destBytes.Array; + + for (int i = destBytes.Offset; i < destBytes.Offset + count * 4; i += 4) + { + TColor c = Unsafe.Read(sp); + c.ToXyzwBytes(dest, i); + sp += ColorSize; + } } internal virtual void PackFromZyxBytes(ArrayPointer sourceBytes, ArrayPointer destColors, int count) { + byte* sp = (byte*)sourceBytes; + byte* dp = (byte*)destColors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = default(TColor); + c.PackFromBytes(sp[2], sp[1], sp[0], 255); + Unsafe.Write(dp, c); + sp += 3; + dp += ColorSize; + } } - internal virtual void PackToZyxwBytes(ArrayPointer sourceColors, ArrayPointer destBytes, int count) + internal virtual void PackToZyxBytes(ArrayPointer sourceColors, ArrayPointer destBytes, int count) { + byte* sp = (byte*)sourceColors; + byte[] dest = destBytes.Array; + + for (int i = destBytes.Offset; i < destBytes.Offset + count * 3; i += 3) + { + TColor c = Unsafe.Read(sp); + c.ToZyxBytes(dest, i); + sp += ColorSize; + } } internal virtual void PackFromZyxwBytes(ArrayPointer sourceBytes, ArrayPointer destColors, int count) { + byte* sp = (byte*)sourceBytes; + byte* dp = (byte*)destColors.PointerAtOffset; + + for (int i = 0; i < count; i++) + { + TColor c = default(TColor); + c.PackFromBytes(sp[2], sp[1], sp[0], sp[3]); + Unsafe.Write(dp, c); + sp += 4; + dp += ColorSize; + } + } + + internal virtual void PackToZyxwBytes(ArrayPointer sourceColors, ArrayPointer destBytes, int count) + { + byte* sp = (byte*)sourceColors; + byte[] dest = destBytes.Array; + + for (int i = destBytes.Offset; i < destBytes.Offset + count * 4; i += 4) + { + TColor c = Unsafe.Read(sp); + c.ToZyxwBytes(dest, i); + sp += ColorSize; + } } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs b/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs index 472582310..3682aa78a 100644 --- a/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs @@ -21,7 +21,7 @@ public abstract class BulkPixelOperationsTests where TColor : struct, IPixel { - public static TheoryData ArraySizesData = new TheoryData { 7, 16, 1111 }; + protected static TheoryData ArraySizesData = new TheoryData { 7, 16, 1111 }; [Theory] [MemberData(nameof(ArraySizesData))] @@ -103,48 +103,129 @@ ); } - [Theory] [MemberData(nameof(ArraySizesData))] - public void PackToXyzwBytes(int count) + public void PackFromXyzwBytes(int count) { - throw new NotImplementedException(); + byte[] source = CreateByteTestData(count * 4); + TColor[] expected = new TColor[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromBytes(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3]); + } + + TestOperation( + source, + expected, + (ops, s, d) => ops.PackFromXyzwBytes(s, d, count) + ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromXyzwBytes(int count) + public void PackToXyzwBytes(int count) { - throw new NotImplementedException(); + TColor[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToXyzwBytes(expected, i4); + } + + TestOperation( + source, + expected, + (ops, s, d) => ops.PackToXyzwBytes(s, d, count) + ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackToZyxBytes(int count) + public void PackFromZyxBytes(int count) { - throw new NotImplementedException(); + byte[] source = CreateByteTestData(count * 3); + TColor[] expected = new TColor[count]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + + expected[i].PackFromBytes(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255); + } + + TestOperation( + source, + expected, + (ops, s, d) => ops.PackFromZyxBytes(s, d, count) + ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromZyxBytes(int count) + public void PackToZyxBytes(int count) { - throw new NotImplementedException(); + TColor[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 3]; + + for (int i = 0; i < count; i++) + { + int i3 = i * 3; + source[i].ToZyxBytes(expected, i3); + } + + TestOperation( + source, + expected, + (ops, s, d) => ops.PackToZyxBytes(s, d, count) + ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackToZyxwBytes(int count) + public void PackFromZyxwBytes(int count) { - throw new NotImplementedException(); + byte[] source = CreateByteTestData(count * 4); + TColor[] expected = new TColor[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromBytes(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3]); + } + + TestOperation( + source, + expected, + (ops, s, d) => ops.PackFromZyxwBytes(s, d, count) + ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromZyxwBytes(int count) + public void PackToZyxwBytes(int count) { - throw new NotImplementedException(); + TColor[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToZyxwBytes(expected, i4); + } + + TestOperation( + source, + expected, + (ops, s, d) => ops.PackToZyxwBytes(s, d, count) + ); } + private class TestBuffers : IDisposable where TSource : struct