Browse Source

Add AVX2 version of CollectHistogram

pull/1882/head
Brian Popow 4 years ago
parent
commit
2a48c941af
  1. 44
      src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs

44
src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs

@ -3,6 +3,11 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
@ -19,6 +24,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
/// </summary>
private const int MaxCoeffThresh = 31;
#if SUPPORTS_RUNTIME_INTRINSICS
private static readonly Vector256<short> MaxCoeffThreshVec = Vector256.Create((short)MaxCoeffThresh);
#endif
private int maxValue;
private int lastNonZero;
@ -52,11 +61,38 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
Vp8Encoding.FTransform(reference.Slice(WebpLookupTables.Vp8DspScan[j]), pred.Slice(WebpLookupTables.Vp8DspScan[j]), this.output, this.scratch);
// Convert coefficients to bin.
for (int k = 0; k < 16; ++k)
#if SUPPORTS_RUNTIME_INTRINSICS
if (Avx2.IsSupported)
{
int v = Math.Abs(this.output[k]) >> 3;
int clippedValue = ClipMax(v, MaxCoeffThresh);
++this.distribution[clippedValue];
// Load.
ref short outputRef = ref MemoryMarshal.GetReference<short>(this.output);
Vector256<byte> out0 = Unsafe.As<short, Vector256<byte>>(ref outputRef);
// v = abs(out) >> 3
Vector256<ushort> abs0 = Avx2.Abs(out0.AsInt16());
Vector256<short> v0 = Avx2.ShiftRightArithmetic(abs0.AsInt16(), 3);
// bin = min(v, MAX_COEFF_THRESH)
Vector256<short> min0 = Avx2.Min(v0, MaxCoeffThreshVec);
// Store.
Unsafe.As<short, Vector256<short>>(ref outputRef) = min0;
// Convert coefficients to bin.
for (int k = 0; k < 16; ++k)
{
++this.distribution[this.output[k]];
}
}
else
#endif
{
for (int k = 0; k < 16; ++k)
{
int v = Math.Abs(this.output[k]) >> 3;
int clippedValue = ClipMax(v, MaxCoeffThresh);
++this.distribution[clippedValue];
}
}
}

Loading…
Cancel
Save