Browse Source

Add bulk scaled pixel operations methods

af/merge-core
James Jackson-South 8 years ago
parent
commit
1b9676aac4
  1. 42
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
  2. 84
      tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs

42
src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs

@ -63,6 +63,48 @@ namespace SixLabors.ImageSharp.PixelFormats
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.PackFromScaledVector4(Vector4)"/>
/// </summary>
/// <param name="sourceVectors">The <see cref="Span{T}"/> to the source vectors.</param>
/// <param name="destinationColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromScaledVector4(ReadOnlySpan<Vector4> sourceVectors, Span<TPixel> destinationColors, int count)
{
GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count);
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceVectors);
ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors);
for (int i = 0; i < count; i++)
{
ref Vector4 sp = ref Unsafe.Add(ref sourceRef, i);
ref TPixel dp = ref Unsafe.Add(ref destRef, i);
dp.PackFromScaledVector4(sp);
}
}
/// <summary>
/// Bulk version of <see cref="IPixel.ToScaledVector4()"/>.
/// </summary>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destinationVectors">The <see cref="Span{T}"/> to the destination vectors.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToScaledVector4(ReadOnlySpan<TPixel> sourceColors, Span<Vector4> destinationVectors, int count)
{
GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count);
ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors);
ref Vector4 destRef = ref MemoryMarshal.GetReference(destinationVectors);
for (int i = 0; i < count; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceRef, i);
ref Vector4 dp = ref Unsafe.Add(ref destRef, i);
dp = sp.ToScaledVector4();
}
}
/// <summary>
/// Verifies that the given 'source' and 'destination' spans are at least of 'minLength' size.
/// Throwing an <see cref="ArgumentException"/> if the condition is not met.

84
tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs

@ -97,7 +97,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
internal static TPixel[] CreateExpectedPixelData(Vector4[] source)
{
TPixel[] expected = new TPixel[source.Length];
var expected = new TPixel[source.Length];
for (int i = 0; i < expected.Length; i++)
{
@ -106,6 +106,17 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
return expected;
}
internal static TPixel[] CreateScaledExpectedPixelData(Vector4[] source)
{
var expected = new TPixel[source.Length];
for (int i = 0; i < expected.Length; i++)
{
expected[i].PackFromScaledVector4(source[i]);
}
return expected;
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void PackFromVector4(int count)
@ -120,9 +131,23 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void PackFromScaledVector4(int count)
{
Vector4[] source = CreateVector4TestData(count);
TPixel[] expected = CreateScaledExpectedPixelData(source);
TestOperation(
source,
expected,
(s, d) => Operations.PackFromScaledVector4(s, d.Span, count)
);
}
internal static Vector4[] CreateExpectedVector4Data(TPixel[] source)
{
Vector4[] expected = new Vector4[source.Length];
var expected = new Vector4[source.Length];
for (int i = 0; i < expected.Length; i++)
{
@ -131,6 +156,17 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
return expected;
}
internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source)
{
var expected = new Vector4[source.Length];
for (int i = 0; i < expected.Length; i++)
{
expected[i] = source[i].ToScaledVector4();
}
return expected;
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToVector4(int count)
@ -145,13 +181,26 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToScaledVector4(int count)
{
TPixel[] source = CreateScaledPixelTestData(count);
Vector4[] expected = CreateExpectedScaledVector4Data(source);
TestOperation(
source,
expected,
(s, d) => Operations.ToScaledVector4(s, d.Span, count)
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void PackFromXyzBytes(int count)
{
byte[] source = CreateByteTestData(count * 3);
TPixel[] expected = new TPixel[count];
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
@ -196,7 +245,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
public void PackFromXyzwBytes(int count)
{
byte[] source = CreateByteTestData(count * 4);
TPixel[] expected = new TPixel[count];
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
@ -242,7 +291,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
public void PackFromZyxBytes(int count)
{
byte[] source = CreateByteTestData(count * 3);
TPixel[] expected = new TPixel[count];
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
@ -287,7 +336,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
public void PackFromZyxwBytes(int count)
{
byte[] source = CreateByteTestData(count * 4);
TPixel[] expected = new TPixel[count];
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
@ -336,7 +385,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
public TSource[] SourceBuffer { get; }
public IBuffer<TDest> ActualDestBuffer { get; }
public TDest[] ExpectedDestBuffer { get; }
public TestBuffers(TSource[] source, TDest[] expectedDest)
{
this.SourceBuffer = source;
@ -357,7 +406,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
if (typeof(TDest) == typeof(Vector4))
{
Span<Vector4> expected = this.ExpectedDestBuffer.AsSpan().NonPortableCast<TDest, Vector4>();
Span<Vector4> actual = this.ActualDestBuffer.Span.NonPortableCast<TDest, Vector4>();
@ -396,7 +445,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
internal static Vector4[] CreateVector4TestData(int length)
{
Vector4[] result = new Vector4[length];
var result = new Vector4[length];
var rnd = new Random(42); // Deterministic random values
for (int i = 0; i < result.Length; i++)
@ -408,7 +457,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
internal static TPixel[] CreatePixelTestData(int length)
{
TPixel[] result = new TPixel[length];
var result = new TPixel[length];
var rnd = new Random(42); // Deterministic random values
@ -421,6 +470,21 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
return result;
}
internal static TPixel[] CreateScaledPixelTestData(int length)
{
var result = new TPixel[length];
var rnd = new Random(42); // Deterministic random values
for (int i = 0; i < result.Length; i++)
{
Vector4 v = GetVector(rnd);
result[i].PackFromScaledVector4(v);
}
return result;
}
internal static byte[] CreateByteTestData(int length)
{
byte[] result = new byte[length];

Loading…
Cancel
Save