Browse Source

Merge branch 'main' into bp/morewebptests

pull/2424/head
James Jackson-South 3 years ago
committed by GitHub
parent
commit
cfe2c454f4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs
  2. 111
      src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
  3. 42
      src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
  4. 25
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
  5. 7
      src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
  6. 4
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_MultiplyInPlaceBlock.cs
  7. 3
      tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs
  8. 12
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
  9. 3
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
  10. 15
      tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs
  11. 3
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs
  12. 3
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs
  13. 6
      tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs

4
src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs

@ -167,7 +167,7 @@ public static class SRgbCompanding
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void CompandAvx2(Span<Vector4> vectors, float[] table)
{
fixed (float* tablePointer = &table[0])
fixed (float* tablePointer = &MemoryMarshal.GetArrayDataReference(table))
{
var scale = Vector256.Create((float)Scale);
Vector256<float> zero = Vector256<float>.Zero;
@ -199,7 +199,7 @@ public static class SRgbCompanding
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void CompandScalar(Span<Vector4> vectors, float[] table)
{
fixed (float* tablePointer = &table[0])
fixed (float* tablePointer = &MemoryMarshal.GetArrayDataReference(table))
{
Vector4 zero = Vector4.Zero;
var scale = new Vector4(Scale);

111
src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs

@ -14,33 +14,38 @@ internal static partial class SimdUtils
{
public static class HwIntrinsics
{
public static ReadOnlySpan<byte> PermuteMaskDeinterleave8x32 => new byte[] { 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0 };
[MethodImpl(MethodImplOptions.AggressiveInlining)] // too much IL for JIT to inline, so give a hint
public static Vector256<int> PermuteMaskDeinterleave8x32() => Vector256.Create(0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0).AsInt32();
public static ReadOnlySpan<byte> PermuteMaskEvenOdd8x32 => new byte[] { 0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0 };
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<uint> PermuteMaskEvenOdd8x32() => Vector256.Create(0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0).AsUInt32();
public static ReadOnlySpan<byte> PermuteMaskSwitchInnerDWords8x32 => new byte[] { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0 };
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<uint> PermuteMaskSwitchInnerDWords8x32() => Vector256.Create(0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0).AsUInt32();
private static ReadOnlySpan<byte> MoveFirst24BytesToSeparateLanes => new byte[] { 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0 };
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector256<uint> MoveFirst24BytesToSeparateLanes() => Vector256.Create(0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0).AsUInt32();
internal static ReadOnlySpan<byte> ExtractRgb => new byte[] { 0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11, 0xFF, 0xFF, 0xFF, 0xFF };
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Vector256<byte> ExtractRgb() => Vector256.Create(0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11, 0xFF, 0xFF, 0xFF, 0xFF);
private static ReadOnlySpan<byte> ShuffleMaskPad4Nx16 => new byte[] { 0, 1, 2, 0x80, 3, 4, 5, 0x80, 6, 7, 8, 0x80, 9, 10, 11, 0x80 };
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<byte> ShuffleMaskPad4Nx16() => Vector128.Create(0, 1, 2, 0x80, 3, 4, 5, 0x80, 6, 7, 8, 0x80, 9, 10, 11, 0x80);
private static ReadOnlySpan<byte> ShuffleMaskSlice4Nx16 => new byte[] { 0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0x80, 0x80, 0x80, 0x80 };
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<byte> ShuffleMaskSlice4Nx16() => Vector128.Create(0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0x80, 0x80, 0x80, 0x80);
private static ReadOnlySpan<byte> ShuffleMaskShiftAlpha =>
new byte[]
{
0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 3, 7, 11, 15,
0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 3, 7, 11, 15
};
#pragma warning disable SA1003, SA1116, SA1117 // Parameters should be on same line or separate lines
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector256<byte> ShuffleMaskShiftAlpha() => Vector256.Create((byte)
0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 3, 7, 11, 15,
0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 3, 7, 11, 15);
public static ReadOnlySpan<byte> PermuteMaskShiftAlpha8x32 =>
new byte[]
{
0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0,
5, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<uint> PermuteMaskShiftAlpha8x32() => Vector256.Create(
0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0,
5, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0).AsUInt32();
#pragma warning restore SA1003, SA1116, SA1117 // Parameters should be on same line or separate lines
/// <summary>
/// Shuffle single-precision (32-bit) floating-point elements in <paramref name="source"/>
@ -190,7 +195,7 @@ internal static partial class SimdUtils
{
if (Ssse3.IsSupported)
{
int remainder = source.Length % (Vector128<byte>.Count * 4);
int remainder = source.Length & ((Vector128<byte>.Count * 4) - 1); // bit-hack for modulo
int sourceCount = source.Length - remainder;
int destCount = (int)((uint)sourceCount * 3 / 4);
@ -254,7 +259,7 @@ internal static partial class SimdUtils
ref Vector128<float> destBase =
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(dest));
nint n = (nint)(uint)dest.Length / Vector128<float>.Count;
nint n = (nint)((uint)dest.Length / (uint)Vector128<float>.Count);
nint m = Numerics.Modulo4(n);
nint u = n - m;
@ -307,7 +312,7 @@ internal static partial class SimdUtils
ref Vector256<byte> destBase =
ref Unsafe.As<byte, Vector256<byte>>(ref MemoryMarshal.GetReference(dest));
nint n = (nint)(uint)dest.Length / Vector256<byte>.Count;
nint n = (nint)((uint)dest.Length / (uint)Vector256<byte>.Count);
nint m = Numerics.Modulo4(n);
nint u = n - m;
@ -343,7 +348,7 @@ internal static partial class SimdUtils
ref Vector128<byte> destBase =
ref Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(dest));
nint n = (nint)(uint)dest.Length / Vector128<byte>.Count;
nint n = (nint)((uint)dest.Length / (uint)Vector128<byte>.Count);
nint m = Numerics.Modulo4(n);
nint u = n - m;
@ -376,10 +381,8 @@ internal static partial class SimdUtils
{
if (Ssse3.IsSupported)
{
ref byte vmaskBase = ref MemoryMarshal.GetReference(ShuffleMaskPad4Nx16);
Vector128<byte> vmask = Unsafe.As<byte, Vector128<byte>>(ref vmaskBase);
ref byte vmaskoBase = ref MemoryMarshal.GetReference(ShuffleMaskSlice4Nx16);
Vector128<byte> vmasko = Unsafe.As<byte, Vector128<byte>>(ref vmaskoBase);
Vector128<byte> vmask = ShuffleMaskPad4Nx16();
Vector128<byte> vmasko = ShuffleMaskSlice4Nx16();
Vector128<byte> vmaske = Ssse3.AlignRight(vmasko, vmasko, 12);
Span<byte> bytes = stackalloc byte[Vector128<byte>.Count];
@ -441,8 +444,7 @@ internal static partial class SimdUtils
{
if (Ssse3.IsSupported)
{
ref byte vmaskBase = ref MemoryMarshal.GetReference(ShuffleMaskPad4Nx16);
Vector128<byte> vmask = Unsafe.As<byte, Vector128<byte>>(ref vmaskBase);
Vector128<byte> vmask = ShuffleMaskPad4Nx16();
Vector128<byte> vfill = Vector128.Create(0xff000000ff000000ul).AsByte();
Span<byte> bytes = stackalloc byte[Vector128<byte>.Count];
@ -485,8 +487,7 @@ internal static partial class SimdUtils
{
if (Ssse3.IsSupported)
{
ref byte vmaskoBase = ref MemoryMarshal.GetReference(ShuffleMaskSlice4Nx16);
Vector128<byte> vmasko = Unsafe.As<byte, Vector128<byte>>(ref vmaskoBase);
Vector128<byte> vmasko = ShuffleMaskSlice4Nx16();
Vector128<byte> vmaske = Ssse3.AlignRight(vmasko, vmasko, 12);
Span<byte> bytes = stackalloc byte[Vector128<byte>.Count];
@ -543,9 +544,9 @@ internal static partial class SimdUtils
/// <returns>The <see cref="Vector256{T}"/>.</returns>
[MethodImpl(InliningOptions.AlwaysInline)]
public static Vector256<float> MultiplyAdd(
in Vector256<float> va,
in Vector256<float> vm0,
in Vector256<float> vm1)
Vector256<float> va,
Vector256<float> vm0,
Vector256<float> vm1)
{
if (Fma.IsSupported)
{
@ -594,9 +595,9 @@ internal static partial class SimdUtils
/// <returns>The <see cref="Vector256{T}"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static Vector256<float> MultiplySubtract(
in Vector256<float> vs,
in Vector256<float> vm0,
in Vector256<float> vm1)
Vector256<float> vs,
Vector256<float> vm0,
Vector256<float> vm1)
{
if (Fma.IsSupported)
{
@ -616,9 +617,9 @@ internal static partial class SimdUtils
/// <returns>The <see cref="Vector256{T}"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static Vector256<float> MultiplyAddNegated(
in Vector256<float> a,
in Vector256<float> b,
in Vector256<float> c)
Vector256<float> a,
Vector256<float> b,
Vector256<float> c)
{
if (Fma.IsSupported)
{
@ -684,7 +685,7 @@ internal static partial class SimdUtils
ref Vector256<float> destBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(dest));
var scale = Vector256.Create(1 / (float)byte.MaxValue);
Vector256<float> scale = Vector256.Create(1 / (float)byte.MaxValue);
for (nuint i = 0; i < n; i++)
{
@ -717,7 +718,7 @@ internal static partial class SimdUtils
ref Vector128<float> destBase =
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(dest));
var scale = Vector128.Create(1 / (float)byte.MaxValue);
Vector128<float> scale = Vector128.Create(1 / (float)byte.MaxValue);
Vector128<byte> zero = Vector128<byte>.Zero;
for (nuint i = 0; i < n; i++)
@ -819,9 +820,8 @@ internal static partial class SimdUtils
ref Vector256<byte> destBase =
ref Unsafe.As<byte, Vector256<byte>>(ref MemoryMarshal.GetReference(dest));
var scale = Vector256.Create((float)byte.MaxValue);
ref byte maskBase = ref MemoryMarshal.GetReference(PermuteMaskDeinterleave8x32);
Vector256<int> mask = Unsafe.As<byte, Vector256<int>>(ref maskBase);
Vector256<float> scale = Vector256.Create((float)byte.MaxValue);
Vector256<int> mask = PermuteMaskDeinterleave8x32();
for (nuint i = 0; i < n; i++)
{
@ -858,7 +858,7 @@ internal static partial class SimdUtils
ref Vector128<byte> destBase =
ref Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(dest));
var scale = Vector128.Create((float)byte.MaxValue);
Vector128<float> scale = Vector128.Create((float)byte.MaxValue);
for (nuint i = 0; i < n; i++)
{
@ -895,14 +895,12 @@ internal static partial class SimdUtils
nuint count = redChannel.Vector256Count<byte>();
ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32);
Vector256<uint> control1 = Unsafe.As<byte, Vector256<uint>>(ref control1Bytes);
Vector256<uint> control1 = PermuteMaskEvenOdd8x32();
ref byte control2Bytes = ref MemoryMarshal.GetReference(PermuteMaskShiftAlpha8x32);
Vector256<uint> control2 = Unsafe.As<byte, Vector256<uint>>(ref control2Bytes);
var a = Vector256.Create((byte)255);
Vector256<uint> control2 = PermuteMaskShiftAlpha8x32();
Vector256<byte> a = Vector256.Create((byte)255);
Vector256<byte> shuffleAlpha = Unsafe.As<byte, Vector256<byte>>(ref MemoryMarshal.GetReference(ShuffleMaskShiftAlpha));
Vector256<byte> shuffleAlpha = ShuffleMaskShiftAlpha();
for (nuint i = 0; i < count; i++)
{
@ -966,9 +964,8 @@ internal static partial class SimdUtils
ref Vector256<byte> dBase = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(destination));
nuint count = redChannel.Vector256Count<byte>();
ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32);
Vector256<uint> control1 = Unsafe.As<byte, Vector256<uint>>(ref control1Bytes);
var a = Vector256.Create((byte)255);
Vector256<uint> control1 = PermuteMaskEvenOdd8x32();
Vector256<byte> a = Vector256.Create((byte)255);
for (nuint i = 0; i < count; i++)
{
@ -1017,8 +1014,8 @@ internal static partial class SimdUtils
ref Vector256<float> destGRef = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(greenChannel));
ref Vector256<float> destBRef = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(blueChannel));
Vector256<uint> extractToLanesMask = Unsafe.As<byte, Vector256<uint>>(ref MemoryMarshal.GetReference(MoveFirst24BytesToSeparateLanes));
Vector256<byte> extractRgbMask = Unsafe.As<byte, Vector256<byte>>(ref MemoryMarshal.GetReference(ExtractRgb));
Vector256<uint> extractToLanesMask = MoveFirst24BytesToSeparateLanes();
Vector256<byte> extractRgbMask = ExtractRgb();
Vector256<byte> rgb, rg, bx;
Vector256<float> r, g, b;

42
src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs

@ -15,25 +15,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components;
/// 8x8 matrix of <see cref="short"/> coefficients.
/// </summary>
// ReSharper disable once InconsistentNaming
[StructLayout(LayoutKind.Explicit)]
internal unsafe partial struct Block8x8
[StructLayout(LayoutKind.Explicit, Size = 2 * Size)]
internal partial struct Block8x8
{
/// <summary>
/// A number of scalar coefficients in a <see cref="Block8x8F"/>
/// </summary>
public const int Size = 64;
#pragma warning disable IDE0051 // Remove unused private member
/// <summary>
/// A placeholder buffer so the actual struct occupies exactly 64 * 2 bytes.
/// </summary>
/// <remarks>
/// This is not used directly in the code.
/// </remarks>
[FieldOffset(0)]
private fixed short data[Size];
#pragma warning restore IDE0051
/// <summary>
/// Gets or sets a <see cref="short"/> value at the given index
/// </summary>
@ -74,9 +63,10 @@ internal unsafe partial struct Block8x8
public static Block8x8 Load(Span<short> data)
{
Unsafe.SkipInit(out Block8x8 result);
result.LoadFrom(data);
return result;
DebugGuard.MustBeGreaterThanOrEqualTo(data.Length, Size, "data is too small");
ref byte src = ref Unsafe.As<short, byte>(ref MemoryMarshal.GetReference(data));
return Unsafe.ReadUnaligned<Block8x8>(ref src);
}
/// <summary>
@ -104,9 +94,10 @@ internal unsafe partial struct Block8x8
/// </summary>
public void CopyTo(Span<short> destination)
{
ref byte selfRef = ref Unsafe.As<Block8x8, byte>(ref this);
ref byte destRef = ref MemoryMarshal.GetReference(MemoryMarshal.Cast<short, byte>(destination));
Unsafe.CopyBlockUnaligned(ref destRef, ref selfRef, Size * sizeof(short));
DebugGuard.MustBeGreaterThanOrEqualTo(destination.Length, Size, "destination is too small");
ref byte destRef = ref Unsafe.As<short, byte>(ref MemoryMarshal.GetReference(destination));
Unsafe.WriteUnaligned(ref destRef, this);
}
/// <summary>
@ -135,19 +126,6 @@ internal unsafe partial struct Block8x8
}
}
/// <summary>
/// Load raw 16bit integers from source.
/// </summary>
/// <param name="source">Source</param>
[MethodImpl(InliningOptions.ShortMethod)]
public void LoadFrom(Span<short> source)
{
ref byte sourceRef = ref Unsafe.As<short, byte>(ref MemoryMarshal.GetReference(source));
ref byte destRef = ref Unsafe.As<Block8x8, byte>(ref this);
Unsafe.CopyBlockUnaligned(ref destRef, ref sourceRef, Size * sizeof(short));
}
/// <summary>
/// Cast and copy <see cref="Size"/> <see cref="int"/>-s from the beginning of 'source' span.
/// </summary>

25
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

@ -101,24 +101,17 @@ internal partial struct Block8x8F : IEquatable<Block8x8F>
set => this[((uint)y * 8) + (uint)x] = value;
}
public static Block8x8F Load(Span<float> data)
{
Block8x8F result = default;
result.LoadFrom(data);
return result;
}
/// <summary>
/// Load raw 32bit floating point data from source.
/// </summary>
/// <param name="source">Source</param>
/// <param name="data">Source</param>
[MethodImpl(InliningOptions.ShortMethod)]
public void LoadFrom(Span<float> source)
public static Block8x8F Load(Span<float> data)
{
ref byte s = ref Unsafe.As<float, byte>(ref MemoryMarshal.GetReference(source));
ref byte d = ref Unsafe.As<Block8x8F, byte>(ref this);
DebugGuard.MustBeGreaterThanOrEqualTo(data.Length, Size, "data is too small");
Unsafe.CopyBlock(ref d, ref s, Size * sizeof(float));
ref byte src = ref Unsafe.As<float, byte>(ref MemoryMarshal.GetReference(data));
return Unsafe.ReadUnaligned<Block8x8F>(ref src);
}
/// <summary>
@ -144,10 +137,10 @@ internal partial struct Block8x8F : IEquatable<Block8x8F>
[MethodImpl(InliningOptions.ShortMethod)]
public unsafe void ScaledCopyTo(float[] dest)
{
fixed (void* ptr = &this.V0L)
{
Marshal.Copy((IntPtr)ptr, dest, 0, Size);
}
DebugGuard.MustBeGreaterThanOrEqualTo(dest.Length, Size, "dest is too small");
ref byte destRef = ref Unsafe.As<float, byte>(ref MemoryMarshal.GetArrayDataReference(dest));
Unsafe.WriteUnaligned(ref destRef, this);
}
public float[] ToArray()

7
src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs

@ -1474,8 +1474,7 @@ internal static unsafe class LosslessUtils
{
if (Sse2.IsSupported)
{
Span<short> output = scratch;
fixed (short* p = output)
fixed (short* ptr = &MemoryMarshal.GetReference(scratch))
{
Vector128<byte> a0 = Sse2.ConvertScalarToVector128UInt32(a).AsByte();
Vector128<byte> b0 = Sse2.ConvertScalarToVector128UInt32(b).AsByte();
@ -1489,8 +1488,8 @@ internal static unsafe class LosslessUtils
Vector128<byte> pa = Sse2.UnpackLow(ac, Vector128<byte>.Zero); // |a - c|
Vector128<byte> pb = Sse2.UnpackLow(bc, Vector128<byte>.Zero); // |b - c|
Vector128<ushort> diff = Sse2.Subtract(pb.AsUInt16(), pa.AsUInt16());
Sse2.Store((ushort*)p, diff);
int paMinusPb = output[3] + output[2] + output[1] + output[0];
Sse2.Store((ushort*)ptr, diff);
int paMinusPb = ptr[3] + ptr[2] + ptr[1] + ptr[0];
return (paMinusPb <= 0) ? a : b;
}
}

4
tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_MultiplyInPlaceBlock.cs

@ -29,8 +29,6 @@ public class Block8x8F_MultiplyInPlaceBlock
}
}
var source = default(Block8x8F);
source.LoadFrom(result);
return source;
return Block8x8F.Load(result);
}
}

3
tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs

@ -207,8 +207,7 @@ public unsafe class PixelConversion_PackFromRgbPlanes
nuint count = (uint)this.Count / (uint)Vector256<float>.Count;
ref byte control = ref MemoryMarshal.GetReference(SimdUtils.HwIntrinsics.PermuteMaskEvenOdd8x32);
Vector256<int> vcontrol = Unsafe.As<byte, Vector256<int>>(ref control);
Vector256<int> vcontrol = SimdUtils.HwIntrinsics.PermuteMaskEvenOdd8x32().AsInt32();
var va = Vector256.Create(1F);

12
tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs

@ -99,8 +99,7 @@ public partial class Block8x8FTests : JpegFixture
Times,
() =>
{
var b = default(Block8x8F);
b.LoadFrom(data);
Block8x8F b = Block8x8F.Load(data);
b.ScaledCopyTo(mirror);
});
@ -117,8 +116,7 @@ public partial class Block8x8FTests : JpegFixture
float[] expected = Create8x8FloatData();
ReferenceImplementations.Transpose8x8(expected);
var block8x8 = default(Block8x8F);
block8x8.LoadFrom(Create8x8FloatData());
Block8x8F block8x8 = Block8x8F.Load(Create8x8FloatData());
block8x8.TransposeInplace();
@ -153,9 +151,8 @@ public partial class Block8x8FTests : JpegFixture
[Fact]
public void NormalizeColors()
{
var block = default(Block8x8F);
float[] input = Create8x8ColorCropTestData();
block.LoadFrom(input);
Block8x8F block = Block8x8F.Load(input);
this.Output.WriteLine("Input:");
this.PrintLinearData(input);
@ -242,8 +239,7 @@ public partial class Block8x8FTests : JpegFixture
{
float[] data = Create8x8RandomFloatData(-1000, 1000);
var source = default(Block8x8F);
source.LoadFrom(data);
Block8x8F source = Block8x8F.Load(data);
var dest = default(Block8x8);
source.RoundInto(ref dest);

3
tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs

@ -269,8 +269,7 @@ public class Block8x8Tests : JpegFixture
short[] expected = Create8x8ShortData();
ReferenceImplementations.Transpose8x8(expected);
var block8x8 = default(Block8x8);
block8x8.LoadFrom(Create8x8ShortData());
Block8x8 block8x8 = Block8x8.Load(Create8x8ShortData());
block8x8.TransposeInplace();

15
tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs

@ -114,8 +114,7 @@ public static class DCTTests
int seed = FeatureTestRunner.Deserialize<int>(serialized);
Span<float> src = Create8x8RandomFloatData(MinInputValue, MaxInputValue, seed);
var srcBlock = default(Block8x8F);
srcBlock.LoadFrom(src);
Block8x8F srcBlock = Block8x8F.Load(src);
float[] expectedDest = new float[64];
float[] temp = new float[64];
@ -162,8 +161,7 @@ public static class DCTTests
public void TranformIDCT_4x4(int seed)
{
Span<float> src = Create8x8RandomFloatData(MinInputValue, MaxInputValue, seed, 4, 4);
var srcBlock = default(Block8x8F);
srcBlock.LoadFrom(src);
Block8x8F srcBlock = Block8x8F.Load(src);
float[] expectedDest = new float[64];
float[] temp = new float[64];
@ -224,8 +222,7 @@ public static class DCTTests
public void TranformIDCT_2x2(int seed)
{
Span<float> src = Create8x8RandomFloatData(MinInputValue, MaxInputValue, seed, 2, 2);
var srcBlock = default(Block8x8F);
srcBlock.LoadFrom(src);
Block8x8F srcBlock = Block8x8F.Load(src);
float[] expectedDest = new float[64];
float[] temp = new float[64];
@ -286,8 +283,7 @@ public static class DCTTests
public void TranformIDCT_1x1(int seed)
{
Span<float> src = Create8x8RandomFloatData(MinInputValue, MaxInputValue, seed, 1, 1);
var srcBlock = default(Block8x8F);
srcBlock.LoadFrom(src);
Block8x8F srcBlock = Block8x8F.Load(src);
float[] expectedDest = new float[64];
float[] temp = new float[64];
@ -330,8 +326,7 @@ public static class DCTTests
int seed = FeatureTestRunner.Deserialize<int>(serialized);
Span<float> src = Create8x8RandomFloatData(MinInputValue, MaxInputValue, seed);
var block = default(Block8x8F);
block.LoadFrom(src);
Block8x8F block = Block8x8F.Load(src);
float[] expectedDest = new float[64];
float[] temp1 = new float[64];

3
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs

@ -25,8 +25,7 @@ public partial class ReferenceImplementationsTests
{
float[] data = Create8x8RandomFloatData(-1000, 1000, seed);
var b0 = default(Block8x8F);
b0.LoadFrom(data);
Block8x8F b0 = Block8x8F.Load(data);
Block8x8F b1 = ReferenceImplementations.AccurateDCT.TransformFDCT(ref b0);
Block8x8F b2 = ReferenceImplementations.AccurateDCT.TransformIDCT(ref b1);

3
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs

@ -70,8 +70,7 @@ public partial class ReferenceImplementationsTests
{
float[] floatData = Create8x8RandomFloatData(-1000, 1000);
Block8x8F source = default;
source.LoadFrom(floatData);
Block8x8F source = Block8x8F.Load(floatData);
Block8x8F expected = ReferenceImplementations.AccurateDCT.TransformFDCT(ref source);
Block8x8F actual = ReferenceImplementations.LLM_FloatingPoint_DCT.TransformFDCT_UpscaleBy8(ref source);

6
tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs

@ -36,8 +36,7 @@ internal static partial class ReferenceImplementations
float[] temp = new float[64];
IDCT2D_llm(s, d, temp);
Block8x8F result = default;
result.LoadFrom(d);
Block8x8F result = Block8x8F.Load(d);
return result;
}
@ -49,8 +48,7 @@ internal static partial class ReferenceImplementations
float[] temp = new float[64];
FDCT2D_llm(s, d, temp);
Block8x8F result = default;
result.LoadFrom(d);
Block8x8F result = Block8x8F.Load(d);
return result;
}

Loading…
Cancel
Save