From e5fec9784451a24fd36efc49d04f5637811019e1 Mon Sep 17 00:00:00 2001 From: Dmitry Pentin Date: Wed, 25 Aug 2021 01:50:59 +0300 Subject: [PATCH] Fixed lvi --- .../Formats/Jpeg/Components/Block8x8.cs | 23 +++++++++---------- .../Formats/Jpeg/Components/Block8x8F.cs | 6 +++-- .../Components/Encoder/HuffmanScanEncoder.cs | 2 +- .../Formats/Jpg/HuffmanScanEncoderTests.cs | 20 ++++++++-------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs index adfabc13c7..3e5277c063 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs @@ -281,25 +281,24 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Returns index of the last non-zero element in given matrix. /// - /// - /// Returns 0 for all-zero matrix by convention. - /// - /// Index of the last non-zero element. + /// + /// Index of the last non-zero element. Returns -1 if all elements are equal to zero. + /// [MethodImpl(InliningOptions.ShortMethod)] - public int GetLastValuableElementIndex() + public int GetLastNonZeroIndex() { #if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { const int equalityMask = unchecked((int)0b1111_1111_1111_1111_1111_1111_1111_1111); - Vector256 zero8 = Vector256.Zero; + Vector256 zero16 = Vector256.Zero; ref Vector256 mcuStride = ref Unsafe.As>(ref this); - for (int i = 7; i >= 0; i--) + for (int i = 3; i >= 0; i--) { - int areEqual = Avx2.MoveMask(Avx2.CompareEqual(Unsafe.Add(ref mcuStride, i).AsInt32(), zero8).AsByte()); + int areEqual = Avx2.MoveMask(Avx2.CompareEqual(Unsafe.Add(ref mcuStride, i), zero16).AsByte()); if (areEqual != equalityMask) { @@ -314,12 +313,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // As input number is represented by 2 bits in the mask, we need to divide lzcnt result by 2 // to get the exact number of zero elements in the stride - int strideRelativeIndex = 7 - (lzcnt / 2); - return (i * 8) + strideRelativeIndex; + int strideRelativeIndex = 15 - (lzcnt / 2); + return (i * 16) + strideRelativeIndex; } } - return 0; + return -1; } else #endif @@ -327,7 +326,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components int index = Size - 1; ref short elemRef = ref Unsafe.As(ref this); - while (index > 0 && Unsafe.Add(ref elemRef, index) == 0) + while (index >= 0 && Unsafe.Add(ref elemRef, index) == 0) { index--; } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index b0d7b08764..8479cdc970 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -868,9 +868,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Returns index of the last non-zero element in this matrix. /// - /// Index of the last non-zero element. Returns -1 if all elements are equal to zero. + /// + /// Index of the last non-zero element. Returns -1 if all elements are equal to zero. + /// [MethodImpl(InliningOptions.ShortMethod)] - public int GetLastValuableElementIndex() + public int GetLastNonZeroIndex() { #if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs index 08fe486a90..fc11465444 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs @@ -272,7 +272,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder int[] acHuffTable = this.huffmanTables[(2 * (int)index) + 1].Values; int runLength = 0; - int lastValuableIndex = refTemp2.GetLastValuableElementIndex(); + int lastValuableIndex = refTemp2.GetLastNonZeroIndex(); for (int zig = 1; zig <= lastValuableIndex; zig++) { int ac = (int)refTemp2[zig]; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs index f75b0a0b8f..a3aa957ee5 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Fact] - public void GetLastValuableElementIndex_AllZero() + public void GetLastNonZeroIndex_AllZero() { static void RunTest() { @@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg int expectedLessThan = 1; - int actual = data.GetLastValuableElementIndex(); + int actual = data.GetLastNonZeroIndex(); Assert.True(actual < expectedLessThan); } @@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Fact] - public void GetLastValuableElementIndex_AllNonZero() + public void GetLastNonZeroIndex_AllNonZero() { static void RunTest() { @@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg int expected = Block8x8F.Size - 1; - int actual = data.GetLastValuableElementIndex(); + int actual = data.GetLastNonZeroIndex(); Assert.Equal(expected, actual); } @@ -131,7 +131,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Theory] [InlineData(1)] [InlineData(2)] - public void GetLastValuableElementIndex_RandomFilledSingle(int seed) + public void GetLastNonZeroIndex_RandomFilledSingle(int seed) { static void RunTest(string seedSerialized) { @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg int expected = setIndex; - int actual = data.GetLastValuableElementIndex(); + int actual = data.GetLastNonZeroIndex(); Assert.Equal(expected, actual); } @@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Theory] [InlineData(1)] [InlineData(2)] - public void GetLastValuableElementIndex_RandomFilledPartially(int seed) + public void GetLastNonZeroIndex_RandomFilledPartially(int seed) { static void RunTest(string seedSerialized) { @@ -182,7 +182,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg int expected = lastIndex; - int actual = data.GetLastValuableElementIndex(); + int actual = data.GetLastNonZeroIndex(); Assert.Equal(expected, actual); } @@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Theory] [InlineData(1)] [InlineData(2)] - public void GetLastValuableElementIndex_RandomFilledFragmented(int seed) + public void GetLastNonZeroIndex_RandomFilledFragmented(int seed) { static void RunTest(string seedSerialized) { @@ -226,7 +226,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg int expected = lastIndex2; - int actual = data.GetLastValuableElementIndex(); + int actual = data.GetLastNonZeroIndex(); Assert.Equal(expected, actual); }