From a220b3d5b894724fb7722efae95cd75c83609edc Mon Sep 17 00:00:00 2001 From: Dmitry Pentin Date: Sat, 28 Aug 2021 19:29:30 +0300 Subject: [PATCH] Removed obsolete code, tests cleanup --- .../Formats/Jpeg/Components/Block8x8F.cs | 57 ------- .../Formats/Jpeg/Components/ZigZag.cs | 4 - .../Formats/Jpg/Block8x8Tests.cs | 155 +++++++++++++++++- .../Formats/Jpg/HuffmanScanEncoderTests.cs | 152 ----------------- 4 files changed, 154 insertions(+), 214 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index 79a35e2cd..b29c13e6e 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -768,62 +768,5 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return true; } } - - /// - /// 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. - /// - [MethodImpl(InliningOptions.ShortMethod)] - 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; - - ref Vector256 mcuStride = ref Unsafe.As>(ref this); - - for (int i = 7; i >= 0; i--) - { - int areEqual = Avx2.MoveMask(Avx2.CompareEqual(Avx.ConvertToVector256Int32WithTruncation(Unsafe.Add(ref mcuStride, i)), zero8).AsByte()); - - if (areEqual != equalityMask) - { - // Each 4 bits represents comparison operation for each 4-byte element in input vectors - // LSB represents first element in the stride - // MSB represents last element in the stride - // lzcnt operation would calculate number of zero numbers at the end - - // Given mask is not actually suitable for lzcnt as 1's represent zero elements and 0's represent non-zero elements - // So we need to invert it - int lzcnt = BitOperations.LeadingZeroCount(~(uint)areEqual); - - // As input number is represented by 4 bits in the mask, we need to divide lzcnt result by 4 - // to get the exact number of zero elements in the stride - int strideRelativeIndex = 7 - (lzcnt / 4); - return (i * 8) + strideRelativeIndex; - } - } - - return -1; - } - else -#endif - { - int index = Size - 1; - ref float elemRef = ref Unsafe.As(ref this); - - while (index >= 0 && (int)Unsafe.Add(ref elemRef, index) == 0) - { - index--; - } - - return index; - } - } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs index c2b0fc5d0..e519a8a1d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs @@ -2,10 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; namespace SixLabors.ImageSharp.Formats.Jpeg.Components { diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs index afe71ad04..6d73181cb 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs @@ -1,9 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using System; using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; - +using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; using Xunit.Abstractions; @@ -121,5 +122,157 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(15, d); } + + [Fact] + public void GetLastNonZeroIndex_AllZero() + { + static void RunTest() + { + Block8x8 data = default; + + int expected = -1; + + int actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Fact] + public void GetLastNonZeroIndex_AllNonZero() + { + static void RunTest() + { + Block8x8 data = default; + for (int i = 0; i < Block8x8.Size; i++) + { + data[i] = 10; + } + + int expected = Block8x8.Size - 1; + + int actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(1)] + [InlineData(2)] + public void GetLastNonZeroIndex_RandomFilledSingle(int seed) + { + static void RunTest(string seedSerialized) + { + int seed = FeatureTestRunner.Deserialize(seedSerialized); + var rng = new Random(seed); + + for (int i = 0; i < 1000; i++) + { + Block8x8 data = default; + + int setIndex = rng.Next(1, Block8x8.Size); + data[setIndex] = (short)rng.Next(-2000, 2000); + + int expected = setIndex; + + int actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + seed, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(1)] + [InlineData(2)] + public void GetLastNonZeroIndex_RandomFilledPartially(int seed) + { + static void RunTest(string seedSerialized) + { + int seed = FeatureTestRunner.Deserialize(seedSerialized); + var rng = new Random(seed); + + for (int i = 0; i < 1000; i++) + { + Block8x8 data = default; + + int lastIndex = rng.Next(1, Block8x8.Size); + short fillValue = (short)rng.Next(-2000, 2000); + for (int dataIndex = 0; dataIndex <= lastIndex; dataIndex++) + { + data[dataIndex] = fillValue; + } + + int expected = lastIndex; + + int actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + seed, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(1)] + [InlineData(2)] + public void GetLastNonZeroIndex_RandomFilledFragmented(int seed) + { + static void RunTest(string seedSerialized) + { + int seed = FeatureTestRunner.Deserialize(seedSerialized); + var rng = new Random(seed); + + for (int i = 0; i < 1000; i++) + { + Block8x8 data = default; + + short fillValue = (short)rng.Next(-2000, 2000); + + // first filled chunk + int lastIndex1 = rng.Next(1, Block8x8F.Size / 2); + for (int dataIndex = 0; dataIndex <= lastIndex1; dataIndex++) + { + data[dataIndex] = fillValue; + } + + // second filled chunk, there might be a spot with zero(s) between first and second chunk + int lastIndex2 = rng.Next(lastIndex1 + 1, Block8x8F.Size); + for (int dataIndex = 0; dataIndex <= lastIndex2; dataIndex++) + { + data[dataIndex] = fillValue; + } + + int expected = lastIndex2; + + int actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + seed, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs index a3aa957ee..42f2fa0d5 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs @@ -85,157 +85,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(expected, actual); } } - - [Fact] - public void GetLastNonZeroIndex_AllZero() - { - static void RunTest() - { - Block8x8F data = default; - - int expectedLessThan = 1; - - int actual = data.GetLastNonZeroIndex(); - - Assert.True(actual < expectedLessThan); - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Fact] - public void GetLastNonZeroIndex_AllNonZero() - { - static void RunTest() - { - Block8x8F data = default; - for (int i = 0; i < Block8x8F.Size; i++) - { - data[i] = 10; - } - - int expected = Block8x8F.Size - 1; - - int actual = data.GetLastNonZeroIndex(); - - Assert.Equal(expected, actual); - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void GetLastNonZeroIndex_RandomFilledSingle(int seed) - { - static void RunTest(string seedSerialized) - { - int seed = FeatureTestRunner.Deserialize(seedSerialized); - var rng = new Random(seed); - - for (int i = 0; i < 1000; i++) - { - Block8x8F data = default; - - int setIndex = rng.Next(1, Block8x8F.Size); - data[setIndex] = rng.Next(); - - int expected = setIndex; - - int actual = data.GetLastNonZeroIndex(); - - Assert.Equal(expected, actual); - } - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - seed, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void GetLastNonZeroIndex_RandomFilledPartially(int seed) - { - static void RunTest(string seedSerialized) - { - int seed = FeatureTestRunner.Deserialize(seedSerialized); - var rng = new Random(seed); - - for (int i = 0; i < 1000; i++) - { - Block8x8F data = default; - - int lastIndex = rng.Next(1, Block8x8F.Size); - int fillValue = rng.Next(); - for (int dataIndex = 0; dataIndex <= lastIndex; dataIndex++) - { - data[dataIndex] = fillValue; - } - - int expected = lastIndex; - - int actual = data.GetLastNonZeroIndex(); - - Assert.Equal(expected, actual); - } - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - seed, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void GetLastNonZeroIndex_RandomFilledFragmented(int seed) - { - static void RunTest(string seedSerialized) - { - int seed = FeatureTestRunner.Deserialize(seedSerialized); - var rng = new Random(seed); - - for (int i = 0; i < 1000; i++) - { - Block8x8F data = default; - - int fillValue = rng.Next(); - - // first filled chunk - int lastIndex1 = rng.Next(1, Block8x8F.Size / 2); - for (int dataIndex = 0; dataIndex <= lastIndex1; dataIndex++) - { - data[dataIndex] = fillValue; - } - - // second filled chunk, there might be a spot with zero(s) between first and second chunk - int lastIndex2 = rng.Next(lastIndex1 + 1, Block8x8F.Size); - for (int dataIndex = 0; dataIndex <= lastIndex2; dataIndex++) - { - data[dataIndex] = fillValue; - } - - int expected = lastIndex2; - - int actual = data.GetLastNonZeroIndex(); - - Assert.Equal(expected, actual); - } - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - seed, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } } }