Browse Source

More unsafe in huffman table generation

af/merge-core
James Jackson-South 8 years ago
parent
commit
f5aa1bc0a0
  1. 50
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs

50
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs

@ -1,7 +1,8 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
@ -39,12 +40,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
/// <param name="values">The huffman values</param> /// <param name="values">The huffman values</param>
public PdfJsHuffmanTable(MemoryManager memoryManager, byte[] lengths, byte[] values) public PdfJsHuffmanTable(MemoryManager memoryManager, byte[] lengths, byte[] values)
{ {
using (IBuffer<short> huffsize = memoryManager.Allocate<short>(257)) const int length = 257;
using (IBuffer<short> huffcode = memoryManager.Allocate<short>(257)) using (IBuffer<short> huffsize = memoryManager.Allocate<short>(length))
using (IBuffer<short> huffcode = memoryManager.Allocate<short>(length))
{ {
GenerateSizeTable(lengths, huffsize.Span); ref short huffsizeRef = ref MemoryMarshal.GetReference(huffsize.Span);
GenerateCodeTable(huffsize.Span, huffcode.Span); ref short huffcodeRef = ref MemoryMarshal.GetReference(huffcode.Span);
this.GenerateDecoderTables(lengths, huffcode.Span);
GenerateSizeTable(lengths, ref huffsizeRef);
GenerateCodeTable(ref huffsizeRef, ref huffcodeRef, length);
this.GenerateDecoderTables(lengths, ref huffcodeRef);
this.GenerateLookaheadTables(lengths, values); this.GenerateLookaheadTables(lengths, values);
} }
@ -61,8 +66,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
/// Figure C.1: make table of Huffman code length for each symbol /// Figure C.1: make table of Huffman code length for each symbol
/// </summary> /// </summary>
/// <param name="lengths">The code lengths</param> /// <param name="lengths">The code lengths</param>
/// <param name="huffsize">The huffman size span</param> /// <param name="huffsizeRef">The huffman size span ref</param>
private static void GenerateSizeTable(byte[] lengths, Span<short> huffsize) private static void GenerateSizeTable(byte[] lengths, ref short huffsizeRef)
{ {
short index = 0; short index = 0;
for (short l = 1; l <= 16; l++) for (short l = 1; l <= 16; l++)
@ -70,29 +75,30 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
byte i = lengths[l]; byte i = lengths[l];
for (short j = 0; j < i; j++) for (short j = 0; j < i; j++)
{ {
huffsize[index] = l; Unsafe.Add(ref huffsizeRef, index) = l;
index++; index++;
} }
} }
huffsize[index] = 0; Unsafe.Add(ref huffsizeRef, index) = 0;
} }
/// <summary> /// <summary>
/// Figure C.2: generate the codes themselves /// Figure C.2: generate the codes themselves
/// </summary> /// </summary>
/// <param name="huffsize">The huffman size span</param> /// <param name="huffsizeRef">The huffman size span ref</param>
/// <param name="huffcode">The huffman code span</param> /// <param name="huffcodeRef">The huffman code span ref</param>
private static void GenerateCodeTable(Span<short> huffsize, Span<short> huffcode) /// <param name="length">The length of the huffsize span</param>
private static void GenerateCodeTable(ref short huffsizeRef, ref short huffcodeRef, int length)
{ {
short k = 0; short k = 0;
short si = huffsize[0]; short si = huffsizeRef;
short code = 0; short code = 0;
for (short i = 0; i < huffsize.Length; i++) for (short i = 0; i < length; i++)
{ {
while (huffsize[k] == si) while (Unsafe.Add(ref huffsizeRef, k) == si)
{ {
huffcode[k] = code; Unsafe.Add(ref huffcodeRef, k) = code;
code++; code++;
k++; k++;
} }
@ -106,8 +112,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
/// Figure F.15: generate decoding tables for bit-sequential decoding /// Figure F.15: generate decoding tables for bit-sequential decoding
/// </summary> /// </summary>
/// <param name="lengths">The code lengths</param> /// <param name="lengths">The code lengths</param>
/// <param name="huffcode">The huffman code span</param> /// <param name="huffcodeRef">The huffman code span ref</param>
private void GenerateDecoderTables(byte[] lengths, Span<short> huffcode) private void GenerateDecoderTables(byte[] lengths, ref short huffcodeRef)
{ {
fixed (short* valOffsetRef = this.ValOffset.Data) fixed (short* valOffsetRef = this.ValOffset.Data)
fixed (long* maxcodeRef = this.MaxCode.Data) fixed (long* maxcodeRef = this.MaxCode.Data)
@ -117,10 +123,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{ {
if (lengths[i] != 0) if (lengths[i] != 0)
{ {
// valOffsetRef[l] = huffval[] index of 1st symbol of code length i, minus the minimum code of length i // valOffsetRef[l] = huffcodeRef[] index of 1st symbol of code length i, minus the minimum code of length i
valOffsetRef[i] = (short)(bitcount - huffcode[bitcount]); valOffsetRef[i] = (short)(bitcount - Unsafe.Add(ref huffcodeRef, bitcount));
bitcount += lengths[i]; bitcount += lengths[i];
maxcodeRef[i] = huffcode[bitcount - 1]; // maximum code of length i maxcodeRef[i] = Unsafe.Add(ref huffcodeRef, bitcount - 1); // maximum code of length i
} }
else else
{ {

Loading…
Cancel
Save