Browse Source

Reduced memory pressure, removed unnecessary buffer

pull/1926/head
Dmitry Pentin 4 years ago
parent
commit
46226bfe79
  1. 57
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

57
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -1095,12 +1095,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <param name="remaining">The remaining bytes in the segment block.</param> /// <param name="remaining">The remaining bytes in the segment block.</param>
private void ProcessDefineHuffmanTablesMarker(BufferedReadStream stream, int remaining) private void ProcessDefineHuffmanTablesMarker(BufferedReadStream stream, int remaining)
{ {
int length = remaining; const int codeLengthsByteSize = 16;
const int codeValuesMaxByteSize = 256;
const int tableWorkspaceByteSize = 257 * sizeof(uint);
const int totalBufferSize = codeLengthsByteSize + codeValuesMaxByteSize + tableWorkspaceByteSize;
using (IMemoryOwner<byte> huffmanData = this.Configuration.MemoryAllocator.Allocate<byte>(256, AllocationOptions.Clean)) int length = remaining;
using (IMemoryOwner<byte> huffmanData = this.Configuration.MemoryAllocator.Allocate<byte>(17))
{ {
Span<byte> huffmanDataSpan = huffmanData.GetSpan(); Span<byte> huffmanDataSpan = huffmanData.GetSpan();
ref byte huffmanDataRef = ref MemoryMarshal.GetReference(huffmanDataSpan);
for (int i = 2; i < remaining;) for (int i = 2; i < remaining;)
{ {
byte huffmanTableSpec = (byte)stream.ReadByte(); byte huffmanTableSpec = (byte)stream.ReadByte();
@ -1119,40 +1122,34 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
JpegThrowHelper.ThrowInvalidImageContentException($"Bad huffman table index: {tableIndex}."); JpegThrowHelper.ThrowInvalidImageContentException($"Bad huffman table index: {tableIndex}.");
} }
stream.Read(huffmanDataSpan, 0, 16); stream.Read(huffmanDataSpan, 1, 16);
using (IMemoryOwner<byte> codeLengths = this.Configuration.MemoryAllocator.Allocate<byte>(17, AllocationOptions.Clean)) int codeLengthSum = 0;
for (int j = 1; j < 17; j++)
{ {
Span<byte> codeLengthsSpan = codeLengths.GetSpan(); codeLengthSum += huffmanDataSpan[j];
ref byte codeLengthsRef = ref MemoryMarshal.GetReference(codeLengthsSpan); }
int codeLengthSum = 0;
for (int j = 1; j < 17; j++)
{
codeLengthSum += Unsafe.Add(ref codeLengthsRef, j) = Unsafe.Add(ref huffmanDataRef, j - 1);
}
length -= 17; length -= 17;
if (codeLengthSum > 256 || codeLengthSum > length) if (codeLengthSum > 256 || codeLengthSum > length)
{ {
JpegThrowHelper.ThrowInvalidImageContentException("Huffman table has excessive length."); JpegThrowHelper.ThrowInvalidImageContentException("Huffman table has excessive length.");
} }
using (IMemoryOwner<byte> huffmanValues = this.Configuration.MemoryAllocator.Allocate<byte>(256, AllocationOptions.Clean)) using (IMemoryOwner<byte> huffmanValues = this.Configuration.MemoryAllocator.Allocate<byte>(256, AllocationOptions.Clean))
{ {
Span<byte> huffmanValuesSpan = huffmanValues.GetSpan(); Span<byte> huffmanValuesSpan = huffmanValues.GetSpan();
stream.Read(huffmanValuesSpan, 0, codeLengthSum); stream.Read(huffmanValuesSpan, 0, codeLengthSum);
i += 17 + codeLengthSum; i += 17 + codeLengthSum;
this.scanDecoder.BuildHuffmanTable( this.scanDecoder.BuildHuffmanTable(
tableType, tableType,
tableIndex, tableIndex,
codeLengthsSpan, huffmanDataSpan,
huffmanValuesSpan, huffmanValuesSpan,
stackalloc uint[257]); stackalloc uint[257]);
}
} }
} }
} }

Loading…
Cancel
Save