Browse Source

gfoidl fixes

pull/1761/head
Dmitry Pentin 5 years ago
parent
commit
6b3f0f7bd9
  1. 10
      src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
  2. 6
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs
  3. 4
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
  4. 9
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
  5. 4
      src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs
  6. 14
      src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs
  7. 16
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs

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

@ -172,7 +172,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
public static Block8x8 Load(Span<short> data)
{
Block8x8 result = default;
Unsafe.SkipInit(out Block8x8 result);
result.LoadFrom(data);
return result;
}
@ -204,7 +204,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
ref byte selfRef = ref Unsafe.As<Block8x8, byte>(ref this);
ref byte destRef = ref MemoryMarshal.GetReference(MemoryMarshal.Cast<short, byte>(destination));
Unsafe.CopyBlock(ref destRef, ref selfRef, Size * sizeof(short));
Unsafe.CopyBlockUnaligned(ref destRef, ref selfRef, Size * sizeof(short));
}
/// <summary>
@ -287,7 +287,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
/// Index of the last non-zero element. Returns -1 if all elements are equal to zero.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
public int GetLastNonZeroIndex()
public nint GetLastNonZeroIndex()
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Avx2.IsSupported)
@ -298,7 +298,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
ref Vector256<short> mcuStride = ref Unsafe.As<Block8x8, Vector256<short>>(ref this);
for (int i = 3; i >= 0; i--)
for (nint i = 3; i >= 0; i--)
{
int areEqual = Avx2.MoveMask(Avx2.CompareEqual(Unsafe.Add(ref mcuStride, i), zero16).AsByte());
@ -325,7 +325,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
else
#endif
{
int index = Size - 1;
nint index = Size - 1;
ref short elemRef = ref Unsafe.As<Block8x8, short>(ref this);
while (index >= 0 && Unsafe.Add(ref elemRef, index) == 0)

6
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs

@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
ref Vector256<short> destRef = ref dest.V01;
for (int i = 0; i < 8; i += 2)
for (nint i = 0; i < 8; i += 2)
{
Vector256<int> row0 = Avx.ConvertToVector256Int32(Avx.Multiply(Unsafe.Add(ref aBase, i + 0), Unsafe.Add(ref bBase, i + 0)));
Vector256<int> row1 = Avx.ConvertToVector256Int32(Avx.Multiply(Unsafe.Add(ref aBase, i + 1), Unsafe.Add(ref bBase, i + 1)));
@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
Vector256<short> row = Avx2.PackSignedSaturate(row0, row1);
row = Avx2.PermuteVar8x32(row.AsInt32(), MultiplyIntoInt16ShuffleMask).AsInt16();
Unsafe.Add(ref destRef, i / 2) = row;
Unsafe.Add(ref destRef, (IntPtr)((uint)i / 2)) = row;
}
}
@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
Vector128<int> right = Sse2.ConvertToVector128Int32(Sse.Multiply(Unsafe.Add(ref aBase, i + 1), Unsafe.Add(ref bBase, i + 1)));
Vector128<short> row = Sse2.PackSignedSaturate(left, right);
Unsafe.Add(ref destBase, i / 2) = row;
Unsafe.Add(ref destBase, (IntPtr)((uint)i / 2)) = row;
}
}

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

@ -414,12 +414,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
if (Avx2.IsSupported)
{
MultiplyIntoInt16_Avx2(ref block, ref qt, ref dest);
ZigZag.ApplyZigZagOrderingAvx(ref dest);
ZigZag.ApplyZigZagOrderingAvx2(ref dest);
}
else if (Ssse3.IsSupported)
{
MultiplyIntoInt16_Sse2(ref block, ref qt, ref dest);
ZigZag.ApplyZigZagOrderingSse(ref dest);
ZigZag.ApplyZigZagOrderingSsse3(ref dest);
}
else
#endif

9
src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs

@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
private bool IsFlushNeeded
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => this.emitWriteIndex < this.emitBuffer.Length / 2;
get => this.emitWriteIndex < (uint)this.emitBuffer.Length / 2;
}
/// <summary>
@ -408,15 +408,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
// Emit the AC components.
int[] acHuffTable = this.huffmanTables[(2 * (int)index) + 1].Values;
int lastValuableIndex = spectralBlock.GetLastNonZeroIndex();
nint lastValuableIndex = spectralBlock.GetLastNonZeroIndex();
int runLength = 0;
for (int zig = 1; zig <= lastValuableIndex; zig++)
ref short blockRef = ref Unsafe.As<Block8x8, short>(ref spectralBlock);
for (nint zig = 1; zig <= lastValuableIndex; zig++)
{
const int zeroRun1 = 1 << 4;
const int zeroRun16 = 16 << 4;
int ac = spectralBlock[zig];
int ac = Unsafe.Add(ref blockRef, zig);
if (ac == 0)
{
runLength += zeroRun1;

4
src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs

@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
/// Values are also scaled by 8 so DCT code won't do unnecessary division.
/// </para>
/// </remarks>
public static ReadOnlySpan<float> DctReciprocalAdjustmentCoefficients => new float[]
public static readonly float[] DctReciprocalAdjustmentCoefficients = new float[]
{
0.125f, 0.09011998f, 0.09567086f, 0.10630376f, 0.125f, 0.15909483f, 0.23096988f, 0.45306373f,
0.09011998f, 0.064972885f, 0.068974845f, 0.07664074f, 0.09011998f, 0.11470097f, 0.16652f, 0.32664075f,
@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
public static void TransformFDCT(ref Block8x8F block)
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Avx.IsSupported || Sse.IsSupported)
if (Sse.IsSupported)
{
ForwardTransformSimd(ref block);
}

14
src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs

@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
#pragma warning restore SA1309
/// <summary>
/// Gets shuffle vectors for <see cref="ApplyZigZagOrderingSse"/>
/// Gets shuffle vectors for <see cref="ApplyZigZagOrderingSsse3"/>
/// zig zag implementation.
/// </summary>
private static ReadOnlySpan<byte> SseShuffleMasks => new byte[]
@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
};
/// <summary>
/// Gets shuffle vectors for <see cref="ApplyZigZagOrderingAvx"/>
/// Gets shuffle vectors for <see cref="ApplyZigZagOrderingAvx2"/>
/// zig zag implementation.
/// </summary>
private static ReadOnlySpan<byte> AvxShuffleMasks => new byte[]
@ -126,11 +126,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
/// <summary>
/// Applies zig zag ordering for given 8x8 matrix using SSE cpu intrinsics.
/// </summary>
/// <remarks>
/// Requires Ssse3 support.
/// </remarks>
/// <param name="block">Input matrix.</param>
public static unsafe void ApplyZigZagOrderingSse(ref Block8x8 block)
public static unsafe void ApplyZigZagOrderingSsse3(ref Block8x8 block)
{
DebugGuard.IsTrue(Ssse3.IsSupported, "Ssse3 support is required to run this operation!");
@ -227,11 +224,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
/// <summary>
/// Applies zig zag ordering for given 8x8 matrix using AVX cpu intrinsics.
/// </summary>
/// <remarks>
/// Requires Avx2 support.
/// </remarks>
/// <param name="block">Input matrix.</param>
public static unsafe void ApplyZigZagOrderingAvx(ref Block8x8 block)
public static unsafe void ApplyZigZagOrderingAvx2(ref Block8x8 block)
{
DebugGuard.IsTrue(Avx2.IsSupported, "Avx2 support is required to run this operation!");

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

@ -130,9 +130,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{
Block8x8 data = default;
int expected = -1;
nint expected = -1;
int actual = data.GetLastNonZeroIndex();
nint actual = data.GetLastNonZeroIndex();
Assert.Equal(expected, actual);
}
@ -153,9 +153,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
data[i] = 10;
}
int expected = Block8x8.Size - 1;
nint expected = Block8x8.Size - 1;
int actual = data.GetLastNonZeroIndex();
nint actual = data.GetLastNonZeroIndex();
Assert.Equal(expected, actual);
}
@ -182,9 +182,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
int setIndex = rng.Next(1, Block8x8.Size);
data[setIndex] = (short)rng.Next(-2000, 2000);
int expected = setIndex;
nint expected = setIndex;
int actual = data.GetLastNonZeroIndex();
nint actual = data.GetLastNonZeroIndex();
Assert.Equal(expected, actual);
}
@ -219,7 +219,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
int expected = lastIndex;
int actual = data.GetLastNonZeroIndex();
nint actual = data.GetLastNonZeroIndex();
Assert.Equal(expected, actual);
}
@ -265,7 +265,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
int expected = secondChunkEnd;
int actual = data.GetLastNonZeroIndex();
nint actual = data.GetLastNonZeroIndex();
Assert.True(expected == actual, $"Expected: {expected}\nActual: {actual}\nInput matrix: {data}");
}

Loading…
Cancel
Save