Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -167,18 +167,6 @@ private void ParseBaselineDataInterleaved()
int mcusPerLine = this.frame.McusPerLine;
ref HuffmanScanBuffer buffer = ref this.scanBuffer;

// Pre-derive the huffman table to avoid in-loop checks.
for (int i = 0; i < this.componentsCount; i++)
{
int order = this.frame.ComponentOrder[i];
JpegComponent component = this.components[order];

ref HuffmanTable dcHuffmanTable = ref this.dcHuffmanTables[component.DCHuffmanTableId];
ref HuffmanTable acHuffmanTable = ref this.acHuffmanTables[component.ACHuffmanTableId];
dcHuffmanTable.Configure();
acHuffmanTable.Configure();
}

for (int j = 0; j < mcusPerColumn; j++)
{
this.cancellationToken.ThrowIfCancellationRequested();
Expand Down Expand Up @@ -248,8 +236,6 @@ private void ParseBaselineDataNonInterleaved()

ref HuffmanTable dcHuffmanTable = ref this.dcHuffmanTables[component.DCHuffmanTableId];
ref HuffmanTable acHuffmanTable = ref this.acHuffmanTables[component.ACHuffmanTableId];
dcHuffmanTable.Configure();
acHuffmanTable.Configure();

for (int j = 0; j < h; j++)
{
Expand Down Expand Up @@ -347,15 +333,6 @@ private void ParseProgressiveDataInterleaved()
int mcusPerLine = this.frame.McusPerLine;
ref HuffmanScanBuffer buffer = ref this.scanBuffer;

// Pre-derive the huffman table to avoid in-loop checks.
for (int k = 0; k < this.componentsCount; k++)
{
int order = this.frame.ComponentOrder[k];
JpegComponent component = this.components[order];
ref HuffmanTable dcHuffmanTable = ref this.dcHuffmanTables[component.DCHuffmanTableId];
dcHuffmanTable.Configure();
}

for (int j = 0; j < mcusPerColumn; j++)
{
for (int i = 0; i < mcusPerLine; i++)
Expand Down Expand Up @@ -416,7 +393,6 @@ private void ParseProgressiveDataNonInterleaved()
if (this.SpectralStart == 0)
{
ref HuffmanTable dcHuffmanTable = ref this.dcHuffmanTables[component.DCHuffmanTableId];
dcHuffmanTable.Configure();

for (int j = 0; j < h; j++)
{
Expand Down Expand Up @@ -444,7 +420,6 @@ ref Unsafe.Add(ref blockRef, i),
else
{
ref HuffmanTable acHuffmanTable = ref this.acHuffmanTables[component.ACHuffmanTableId];
acHuffmanTable.Configure();

for (int j = 0; j < h; j++)
{
Expand Down
30 changes: 4 additions & 26 deletions src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct HuffmanTable
{
private bool isConfigured;

/// <summary>
/// Derived from the DHT marker. Sizes[k] = # of symbols with codes of length k bits; Sizes[0] is unused.
/// </summary>
public fixed byte Sizes[17];

/// <summary>
/// Derived from the DHT marker. Contains the symbols, in order of incremental code length.
/// </summary>
Expand Down Expand Up @@ -62,20 +55,7 @@ internal unsafe struct HuffmanTable
/// <param name="values">The huffman values</param>
public HuffmanTable(ReadOnlySpan<byte> codeLengths, ReadOnlySpan<byte> values)
{
this.isConfigured = false;
Unsafe.CopyBlockUnaligned(ref this.Sizes[0], ref MemoryMarshal.GetReference(codeLengths), (uint)codeLengths.Length);
Unsafe.CopyBlockUnaligned(ref this.Values[0], ref MemoryMarshal.GetReference(values), (uint)values.Length);
}

/// <summary>
/// Expands the HuffmanTable into its readable form.
/// </summary>
public void Configure()
{
if (this.isConfigured)
{
return;
}

Span<char> huffSize = stackalloc char[257];
Span<uint> huffCode = stackalloc uint[257];
Expand All @@ -84,7 +64,7 @@ public void Configure()
int p = 0;
for (int j = 1; j <= 16; j++)
{
int i = this.Sizes[j];
int i = codeLengths[j];
while (i-- != 0)
{
huffSize[p++] = (char)j;
Expand Down Expand Up @@ -113,10 +93,10 @@ public void Configure()
p = 0;
for (int j = 1; j <= 16; j++)
{
if (this.Sizes[j] != 0)
if (codeLengths[j] != 0)
{
this.ValOffset[j] = p - (int)huffCode[p];
p += this.Sizes[j];
p += codeLengths[j];
this.MaxCode[j] = huffCode[p - 1]; // Maximum code of length l
this.MaxCode[j] <<= JpegConstants.Huffman.RegisterSize - j; // Left justify
this.MaxCode[j] |= (1ul << (JpegConstants.Huffman.RegisterSize - j)) - 1;
Expand All @@ -142,7 +122,7 @@ public void Configure()
for (int length = 1; length <= JpegConstants.Huffman.LookupBits; length++)
{
int jShift = JpegConstants.Huffman.LookupBits - length;
for (int i = 1; i <= this.Sizes[length]; i++, p++)
for (int i = 1; i <= codeLengths[length]; i++, p++)
{
// length = current code's length, p = its index in huffCode[] & Values[].
// Generate left-justified code followed by all possible bit sequences
Expand All @@ -155,8 +135,6 @@ public void Configure()
}
}
}

this.isConfigured = true;
}
}
}