diff --git a/src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs b/src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs
index 2c470054a2..250e7b329c 100644
--- a/src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs
+++ b/src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs
@@ -36,10 +36,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private const int EofSymbol = 256;
- // The lengths of the bit length codes are sent in order of decreasing
- // probability, to avoid transmitting the lengths for unused bit length codes.
- private static readonly int[] BitLengthOrder = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
-
private static readonly short[] StaticLCodes;
private static readonly byte[] StaticLLength;
private static readonly short[] StaticDCodes;
@@ -126,6 +122,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.pinnedLiteralBuffer = (short*)this.literalBufferHandle.Pointer;
}
+ ///
+ /// Gets the lengths of the bit length codes are sent in order of decreasing probability, to avoid transmitting the lengths for unused bit length codes.
+ ///
+ private static ReadOnlySpan BitLengthOrder => new byte[] { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
+
private static ReadOnlySpan Bit4Reverse => new byte[] { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
///
@@ -158,9 +159,14 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.Pending.WriteBits(this.literalTree.NumCodes - 257, 5);
this.Pending.WriteBits(this.distTree.NumCodes - 1, 5);
this.Pending.WriteBits(blTreeCodes - 4, 4);
+
+ ref byte bitLengthOrderRef = ref MemoryMarshal.GetReference(BitLengthOrder);
+
for (int rank = 0; rank < blTreeCodes; rank++)
{
- this.Pending.WriteBits(this.blTree.Length[BitLengthOrder[rank]], 3);
+ ref byte bitsRef = ref Unsafe.Add(ref bitLengthOrderRef, rank);
+
+ this.Pending.WriteBits(this.blTree.Length[bitsRef], 3);
}
this.literalTree.WriteTree(this.Pending, this.blTree);
@@ -249,10 +255,14 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
// Build bitlen tree
this.blTree.BuildTree();
+ ref byte bitLengthOrderRef = ref MemoryMarshal.GetReference(BitLengthOrder);
int blTreeCodes = 4;
+
for (int i = 18; i > blTreeCodes; i--)
{
- if (this.blTree.Length[BitLengthOrder[i]] > 0)
+ ref byte bits = ref Unsafe.Add(ref bitLengthOrderRef, i);
+
+ if (this.blTree.Length[bits] > 0)
{
blTreeCodes = i + 1;
}