Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions src/ImageSharp/Formats/Jpeg/Components/Decoder/FastACTable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System.Runtime.CompilerServices;

namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
internal unsafe struct FastACTable
{
/// <summary>
/// Gets the lookahead array
/// </summary>
public fixed short Lookahead[512];

/// <summary>
/// Derives a lookup table for fast AC entropy scan decoding.
/// This can happen multiple times during progressive decoding but always outside mcu loops.
/// </summary>
/// <param name="huffmanTable">The AC Huffman table.</param>
public void Derive(ref HuffmanTable huffmanTable)
{
const int FastBits = ScanDecoder.FastBits;
ref short fastACRef = ref this.Lookahead[0];
ref byte huffmanLookaheadRef = ref huffmanTable.Lookahead[0];
ref byte huffmanValuesRef = ref huffmanTable.Values[0];
ref short huffmanSizesRef = ref huffmanTable.Sizes[0];

int i;
for (i = 0; i < (1 << FastBits); i++)
{
byte fast = Unsafe.Add(ref huffmanLookaheadRef, i);
Unsafe.Add(ref fastACRef, i) = 0;

if (fast < byte.MaxValue)
{
int rs = Unsafe.Add(ref huffmanValuesRef, fast);
int run = (rs >> 4) & 15;
int magbits = rs & 15;
int len = Unsafe.Add(ref huffmanSizesRef, fast);

if (magbits != 0 && len + magbits <= FastBits)
{
// Magnitude code followed by receive_extend code
int k = ((i << len) & ((1 << FastBits) - 1)) >> (FastBits - magbits);
int m = 1 << (magbits - 1);
if (k < m)
{
k += (int)((~0U << magbits) + 1);
}

// If the result is small enough, we can fit it in fastAC table
if (k >= -128 && k <= 127)
{
Unsafe.Add(ref fastACRef, i) = (short)((k << 8) + (run << 4) + (len + magbits));
}
}
}
}
}
}
}
90 changes: 0 additions & 90 deletions src/ImageSharp/Formats/Jpeg/Components/Decoder/FastACTables.cs

This file was deleted.

31 changes: 27 additions & 4 deletions src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct HuffmanTable
{
private bool isDerived;

private readonly MemoryAllocator memoryAllocator;

#pragma warning disable IDE0044 // Add readonly modifier
private fixed byte codeLengths[17];
#pragma warning restore IDE0044 // Add readonly modifier

/// <summary>
/// Gets the max code array
/// </summary>
Expand Down Expand Up @@ -50,16 +58,31 @@ internal unsafe struct HuffmanTable
/// <param name="values">The huffman values</param>
public HuffmanTable(MemoryAllocator memoryAllocator, ReadOnlySpan<byte> codeLengths, ReadOnlySpan<byte> values)
{
this.isDerived = false;
this.memoryAllocator = memoryAllocator;
Unsafe.CopyBlockUnaligned(ref this.codeLengths[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 derived form.
/// </summary>
public void Derive()
{
if (this.isDerived)
{
return;
}

const int Length = 257;
using (IMemoryOwner<short> huffcode = memoryAllocator.Allocate<short>(Length))
using (IMemoryOwner<short> huffcode = this.memoryAllocator.Allocate<short>(Length))
{
ref short huffcodeRef = ref MemoryMarshal.GetReference(huffcode.GetSpan());
ref byte codeLengthsRef = ref MemoryMarshal.GetReference(codeLengths);
ref byte codeLengthsRef = ref this.codeLengths[0];

// Figure C.1: make table of Huffman code length for each symbol
ref short sizesRef = ref this.Sizes[0];
short x = 0;

for (short i = 1; i < 17; i++)
{
byte length = Unsafe.Add(ref codeLengthsRef, i);
Expand Down Expand Up @@ -119,7 +142,7 @@ public HuffmanTable(MemoryAllocator memoryAllocator, ReadOnlySpan<byte> codeLeng
}
}

Unsafe.CopyBlockUnaligned(ref this.Values[0], ref MemoryMarshal.GetReference(values), 256);
this.isDerived = true;
}
}
}
26 changes: 0 additions & 26 deletions src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanTables.cs

This file was deleted.

Loading