diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs
index 0581993014..e8ba6dde61 100644
--- a/src/ImageSharp/Common/Helpers/Numerics.cs
+++ b/src/ImageSharp/Common/Helpers/Numerics.cs
@@ -825,5 +825,17 @@ namespace SixLabors.ImageSharp
return Sse2.ConvertToInt32(vsum);
}
#endif
+
+ ///
+ /// Calculates how many minimum bits needed to store given value.
+ ///
+ /// Unsigned integer to store
+ /// Minimum number of bits needed to store given value
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int MinimumBitsToStore(uint number)
+ {
+ const int bitInUnsignedInteger = sizeof(uint) * 8;
+ return bitInUnsignedInteger - BitOperations.LeadingZeroCount(number);
+ }
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
index 8b23211d35..0c1b4dedcf 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Threading;
using SixLabors.ImageSharp.Memory;
@@ -54,29 +55,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
this.target = outputStream;
}
- ///
- /// Gets the counts the number of bits needed to hold an integer.
- ///
- // The C# compiler emits this as a compile-time constant embedded in the PE file.
- // This is effectively compiled down to: return new ReadOnlySpan(&data, length)
- // More details can be found: https://github.com/dotnet/roslyn/pull/24621
- private static ReadOnlySpan BitCountLut => new byte[]
- {
- 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8,
- };
-
///
/// Encodes the image with no subsampling.
///
@@ -394,15 +372,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
b = value - 1;
}
- uint bt;
- if (a < 0x100)
- {
- bt = BitCountLut[a];
- }
- else
- {
- bt = 8 + (uint)BitCountLut[a >> 8];
- }
+ uint bt = (uint)Numerics.MinimumBitsToStore((uint)a);
this.EmitHuff(index, (int)((uint)(runLength << 4) | bt));
if (bt > 0)