Browse Source

Add pixeloperations tests for new pixel formats

af/merge-core
James Jackson-South 6 years ago
parent
commit
60fed0c244
  1. 6
      src/ImageSharp/Common/Helpers/ImageMaths.cs
  2. 3
      src/ImageSharp/PixelFormats/PixelImplementations/La32.cs
  3. 0
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.L16OperationsTests.cs
  4. 0
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.L8OperationsTests.cs
  5. 25
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.La16OperationsTests.cs
  6. 25
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.La32OperationsTests.cs
  7. 279
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

6
src/ImageSharp/Common/Helpers/ImageMaths.cs

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp
/// <returns>The <see cref="byte"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static byte Get8BitBT709Luminance(byte r, byte g, byte b) =>
(byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5f);
(byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp
/// <returns>The <see cref="ushort"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b) =>
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F));
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp
/// <returns>The <see cref="ushort"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static ushort Get16BitBT709Luminance(float r, float g, float b) =>
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F));
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Scales a value from a 16 bit <see cref="ushort"/> to it's 8 bit <see cref="byte"/> equivalent.

3
src/ImageSharp/PixelFormats/PixelImplementations/La32.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -236,7 +237,7 @@ namespace SixLabors.ImageSharp.PixelFormats
vector.Y,
vector.Z);
this.A = (ushort)vector.W;
this.A = (ushort)MathF.Round(vector.W);
}
}
}

0
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray16OperationsTests.cs → tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.L16OperationsTests.cs

0
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Gray8OperationsTests.cs → tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.L8OperationsTests.cs

25
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.La16OperationsTests.cs

@ -0,0 +1,25 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
public partial class PixelOperationsTests
{
public class La16OperationsTests : PixelOperationsTests<La16>
{
public La16OperationsTests(ITestOutputHelper output)
: base(output)
{
}
[Fact]
public void IsSpecialImplementation() => Assert.IsType<La16.PixelOperations>(PixelOperations<La16>.Instance);
}
}
}

25
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.La32OperationsTests.cs

@ -0,0 +1,25 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
public partial class PixelOperationsTests
{
public class La32OperationsTests : PixelOperationsTests<La32>
{
public La32OperationsTests(ITestOutputHelper output)
: base(output)
{
}
[Fact]
public void IsSpecialImplementation() => Assert.IsType<La32.PixelOperations>(PixelOperations<La32>.Instance);
}
}
}

279
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

@ -617,6 +617,188 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void FromL8(int count)
{
byte[] sourceBytes = CreateByteTestData(count);
L8[] source = sourceBytes.Select(b => new L8(b)).ToArray();
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
expected[i].FromL8(source[i]);
}
TestOperation(
source,
expected,
(s, d) => Operations.FromL8(this.Configuration, s, d.GetSpan())
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToL8(int count)
{
TPixel[] source = CreatePixelTestData(count);
var expected = new L8[count];
for (int i = 0; i < count; i++)
{
expected[i].FromScaledVector4(source[i].ToScaledVector4());
}
TestOperation(
source,
expected,
(s, d) => Operations.ToL8(this.Configuration, s, d.GetSpan())
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void FromL16(int count)
{
L16[] source = CreateVector4TestData(count).Select(v =>
{
L16 g = default;
g.FromVector4(v);
return g;
}).ToArray();
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
expected[i].FromL16(source[i]);
}
TestOperation(
source,
expected,
(s, d) => Operations.FromL16(this.Configuration, s, d.GetSpan())
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToL16(int count)
{
TPixel[] source = CreatePixelTestData(count);
var expected = new L16[count];
for (int i = 0; i < count; i++)
{
expected[i].FromScaledVector4(source[i].ToScaledVector4());
}
TestOperation(
source,
expected,
(s, d) => Operations.ToL16(this.Configuration, s, d.GetSpan())
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void FromLa16Bytes(int count)
{
int size = Unsafe.SizeOf<La16>();
byte[] source = CreateByteTestData(count * size);
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
int offset = i * size;
La16 la = MemoryMarshal.Cast<byte, La16>(source.AsSpan().Slice(offset, size))[0];
expected[i].FromLa16(la);
}
TestOperation(
source,
expected,
(s, d) => Operations.FromLa16Bytes(this.Configuration, s, d.GetSpan(), count)
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToLa16Bytes(int count)
{
int size = Unsafe.SizeOf<La16>();
TPixel[] source = CreatePixelTestData(count);
var expected = new byte[count * size];
La16 la = default;
for (int i = 0; i < count; i++)
{
int offset = i * size;
la.FromScaledVector4(source[i].ToScaledVector4());
OctetBytes bytes = Unsafe.As<La16, OctetBytes>(ref la);
expected[offset] = bytes[0];
expected[offset + 1] = bytes[1];
}
TestOperation(
source,
expected,
(s, d) => Operations.ToLa16Bytes(this.Configuration, s, d.GetSpan(), count)
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void FromLa32Bytes(int count)
{
int size = Unsafe.SizeOf<La32>();
byte[] source = CreateByteTestData(count * size);
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
int offset = i * size;
La32 la = MemoryMarshal.Cast<byte, La32>(source.AsSpan().Slice(offset, size))[0];
expected[i].FromLa32(la);
}
TestOperation(
source,
expected,
(s, d) => Operations.FromLa32Bytes(this.Configuration, s, d.GetSpan(), count)
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToLa32Bytes(int count)
{
var size = Unsafe.SizeOf<La32>();
TPixel[] source = CreatePixelTestData(count);
var expected = new byte[count * size];
La32 la = default;
for (int i = 0; i < count; i++)
{
int offset = i * size;
la.FromScaledVector4(source[i].ToScaledVector4());
OctetBytes bytes = Unsafe.As<La32, OctetBytes>(ref la);
expected[offset] = bytes[0];
expected[offset + 1] = bytes[1];
expected[offset + 2] = bytes[2];
expected[offset + 3] = bytes[3];
}
TestOperation(
source,
expected,
(s, d) => Operations.ToLa32Bytes(this.Configuration, s, d.GetSpan(), count)
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void FromRgb24Bytes(int count)
@ -808,91 +990,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void FromL8(int count)
{
byte[] sourceBytes = CreateByteTestData(count);
L8[] source = sourceBytes.Select(b => new L8(b)).ToArray();
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
expected[i].FromL8(source[i]);
}
TestOperation(
source,
expected,
(s, d) => Operations.FromL8(this.Configuration, s, d.GetSpan())
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToL8(int count)
{
TPixel[] source = CreatePixelTestData(count);
var expected = new L8[count];
for (int i = 0; i < count; i++)
{
expected[i].FromScaledVector4(source[i].ToScaledVector4());
}
TestOperation(
source,
expected,
(s, d) => Operations.ToL8(this.Configuration, s, d.GetSpan())
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void FromL16(int count)
{
L16[] source = CreateVector4TestData(count).Select(v =>
{
L16 g = default;
g.FromVector4(v);
return g;
}).ToArray();
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
expected[i].FromL16(source[i]);
}
TestOperation(
source,
expected,
(s, d) => Operations.FromL16(this.Configuration, s, d.GetSpan())
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToL16(int count)
{
TPixel[] source = CreatePixelTestData(count);
var expected = new L16[count];
for (int i = 0; i < count; i++)
{
expected[i].FromScaledVector4(source[i].ToScaledVector4());
}
TestOperation(
source,
expected,
(s, d) => Operations.ToL16(this.Configuration, s, d.GetSpan())
);
}
public delegate void RefAction<T1>(ref T1 arg1);
internal static Vector4[] CreateExpectedVector4Data(TPixel[] source, RefAction<Vector4> vectorModifier = null)
@ -1064,18 +1161,6 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
// ReSharper restore PossibleNullReferenceException
}
}
else if (typeof(TDest) == typeof(L16))
{
// Minor difference is tolerated for 16 bit pixel values
Span<L16> expected = MemoryMarshal.Cast<TDest, L16>(this.ExpectedDestBuffer.AsSpan());
Span<L16> actual = MemoryMarshal.Cast<TDest, L16>(this.ActualDestBuffer.GetSpan());
for (int i = 0; i < count; i++)
{
int difference = expected[i].PackedValue - actual[i].PackedValue;
Assert.True(Math.Abs(difference) < 2);
}
}
else
{
Span<TDest> expected = this.ExpectedDestBuffer.AsSpan();

Loading…
Cancel
Save