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);
}