diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/Component.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/Component.cs
index db31706135..120bfb58d3 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/Component.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/Component.cs
@@ -43,6 +43,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
public void Dispose()
{
this.Output?.Dispose();
+ this.Output = null;
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/FrameComponent.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/FrameComponent.cs
index 0cb9bbb1cb..b386a86f3c 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/FrameComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/FrameComponent.cs
@@ -68,6 +68,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
public void Dispose()
{
this.BlockData?.Dispose();
+ this.BlockData = null;
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanBranch.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanBranch.cs
deleted file mode 100644
index d716355ad3..0000000000
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanBranch.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageSharp.Formats.Jpeg.Port.Components
-{
- using System.Runtime.CompilerServices;
-
- ///
- /// Represents a branch in the huffman tree
- ///
- internal struct HuffmanBranch
- {
- ///
- /// The index
- ///
- public int Index;
-
- ///
- /// The value
- ///
- public short Value;
-
- ///
- /// The children.
- ///
- public HuffmanBranch[] Children;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The value
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public HuffmanBranch(short value)
- {
- this.Index = 0;
- this.Value = value;
- this.Children = new HuffmanBranch[2];
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The branch children
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public HuffmanBranch(HuffmanBranch[] children)
- {
- this.Index = 0;
- this.Value = -1;
- this.Children = children;
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTable.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTable.cs
index 995fd550c9..bc31629785 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTable.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTable.cs
@@ -1,32 +1,45 @@
-namespace ImageSharp.Formats.Jpeg.Port.Components
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Formats.Jpeg.Port.Components
{
using System;
using System.Runtime.CompilerServices;
+ using ImageSharp.Memory;
+
///
- /// Represents a HUffman Table
+ /// Represents a Huffman Table
///
- internal sealed class HuffmanTable
+ internal struct HuffmanTable : IDisposable
{
- private short[] huffcode = new short[257];
- private short[] huffsize = new short[257];
- private short[] valOffset = new short[18];
- private long[] maxcode = new long[18];
+ private Buffer huffcode;
+ private Buffer huffsize;
+ private Buffer valOffset;
+ private Buffer maxcode;
- private byte[] huffval;
- private byte[] bits;
+ private Buffer huffval;
+ private Buffer bits;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the struct.
///
/// The code lengths
/// The huffman values
public HuffmanTable(byte[] lengths, byte[] values)
{
- this.huffval = new byte[values.Length];
- Buffer.BlockCopy(values, 0, this.huffval, 0, values.Length);
- this.bits = new byte[lengths.Length];
- Buffer.BlockCopy(lengths, 0, this.bits, 0, lengths.Length);
+ this.huffcode = Buffer.CreateClean(257);
+ this.huffsize = Buffer.CreateClean(257);
+ this.valOffset = Buffer.CreateClean(18);
+ this.maxcode = Buffer.CreateClean(18);
+
+ this.huffval = Buffer.CreateClean(values.Length);
+ Buffer.BlockCopy(values, 0, this.huffval.Array, 0, values.Length);
+
+ this.bits = Buffer.CreateClean(lengths.Length);
+ Buffer.BlockCopy(lengths, 0, this.bits.Array, 0, lengths.Length);
this.GenerateSizeTable();
this.GenerateCodeTable();
@@ -66,6 +79,24 @@
return this.valOffset[i];
}
+ ///
+ public void Dispose()
+ {
+ this.huffcode?.Dispose();
+ this.huffsize?.Dispose();
+ this.valOffset?.Dispose();
+ this.maxcode?.Dispose();
+ this.huffval?.Dispose();
+ this.bits?.Dispose();
+
+ this.huffcode = null;
+ this.huffsize = null;
+ this.valOffset = null;
+ this.maxcode = null;
+ this.huffval = null;
+ this.bits = null;
+ }
+
///
/// Figure C.1: make table of Huffman code length for each symbol
///
diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTables.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTables.cs
index 8aeafd7db8..6de8c441db 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTables.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/HuffmanTables.cs
@@ -5,13 +5,14 @@
namespace ImageSharp.Formats.Jpeg.Port.Components
{
+ using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
///
/// Defines a pair of huffman tables
///
- internal class HuffmanTables
+ internal sealed class HuffmanTables : IDisposable
{
private readonly HuffmanTable[] tables = new HuffmanTable[4];
@@ -34,5 +35,14 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
this.tables[index] = value;
}
}
+
+ ///
+ public void Dispose()
+ {
+ for (int i = 0; i < this.tables.Length; i++)
+ {
+ this.tables[i].Dispose();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs
index 1d588301fe..62b0a82e4c 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs
@@ -734,7 +734,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
return;
}
- var componentBlockDataSpan = component.BlockData.Span;
+ Span componentBlockDataSpan = component.BlockData.Span;
int k = this.specStart;
int e = this.specEnd;
while (k <= e)
@@ -773,7 +773,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
int k = this.specStart;
int e = this.specEnd;
int r = 0;
- var componentBlockDataSpan = component.BlockData.Span;
+ Span componentBlockDataSpan = component.BlockData.Span;
while (k <= e)
{
byte z = QuantizationTables.DctZigZag[k];
diff --git a/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
index 7bd71048c0..ca93e96dd5 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
@@ -160,12 +160,16 @@ namespace ImageSharp.Formats.Jpeg.Port
this.frame?.Dispose();
this.components?.Dispose();
this.quantizationTables?.Dispose();
+ this.dcHuffmanTables?.Dispose();
+ this.acHuffmanTables?.Dispose();
this.pixelArea.Dispose();
// Set large fields to null.
this.frame = null;
this.components = null;
this.quantizationTables = null;
+ this.dcHuffmanTables = null;
+ this.acHuffmanTables = null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -696,7 +700,7 @@ namespace ImageSharp.Formats.Jpeg.Port
this.InputStream.Read(huffmanValues.Array, 0, codeLengthSum);
i += 17 + codeLengthSum;
- Debug.WriteLine(huffmanTableSpec >> 4 == 0 ? "this.dcHuffmanTables" : "this.acHuffmanTables");
+
this.BuildHuffmanTable(
huffmanTableSpec >> 4 == 0 ? this.dcHuffmanTables : this.acHuffmanTables,
huffmanTableSpec & 15,