diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/ComponentBlocks.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/ComponentBlocks.cs
index 5b66ad598..a72835e75 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/ComponentBlocks.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/ComponentBlocks.cs
@@ -10,10 +10,8 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
///
/// Contains all the decoded component blocks
///
- internal class ComponentBlocks : IDisposable
+ internal sealed class ComponentBlocks : IDisposable
{
- private bool isDisposed;
-
///
/// Gets or sets the component blocks
///
@@ -22,31 +20,14 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
///
public void Dispose()
{
- this.Dispose(true);
- }
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- /// Whether to dispose of managed objects
- protected virtual void Dispose(bool disposing)
- {
- if (!this.isDisposed)
+ if (this.Components != null)
{
- if (disposing)
+ for (int i = 0; i < this.Components.Length; i++)
{
- if (this.Components != null)
- {
- for (int i = 0; i < this.Components.Length; i++)
- {
- this.Components[i].Dispose();
- }
- }
+ this.Components[i].Dispose();
}
- // Set large fields to null.
this.Components = null;
- this.isDisposed = true;
}
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/Frame.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/Frame.cs
index 20fd2e9e8..06b4bbc24 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/Frame.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/Frame.cs
@@ -10,10 +10,8 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
///
/// Represent a single jpeg frame
///
- internal class Frame : IDisposable
+ internal sealed class Frame : IDisposable
{
- private bool isDisposed;
-
///
/// Gets or sets a value indicating whether the frame uses the extended specification
///
@@ -77,34 +75,15 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
///
public void Dispose()
{
- this.Dispose(true);
- }
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- /// Whether to dispose of managed objects
- protected virtual void Dispose(bool disposing)
- {
- if (this.isDisposed)
+ if (this.Components != null)
{
- return;
- }
-
- if (disposing)
- {
- if (this.Components != null)
+ for (int i = 0; i < this.Components.Length; i++)
{
- for (int i = 0; i < this.Components.Length; i++)
- {
- this.Components[i].Dispose();
- }
+ this.Components[i].Dispose();
}
- }
- // Set large fields to null.
- this.Components = null;
- this.isDisposed = true;
+ this.Components = null;
+ }
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/QuantizationTables.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/QuantizationTables.cs
index 1ca31b31b..fa57a18dd 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/QuantizationTables.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/QuantizationTables.cs
@@ -5,15 +5,15 @@
namespace ImageSharp.Formats.Jpeg.Port.Components
{
+ using System;
using System.Runtime.CompilerServices;
using ImageSharp.Memory;
///
/// Contains the quantization tables.
- /// TODO: This all needs optimizing for memory. I'm just stubbing out functionality for now.
///
- internal class QuantizationTables
+ internal sealed class QuantizationTables : IDisposable
{
///
/// Gets the ZigZag scan table
@@ -46,6 +46,16 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
///
/// Gets or sets the quantization tables.
///
- public Fast2DArray Tables { get; set; } = new Fast2DArray(64, 4);
+ public Buffer2D Tables { get; set; }
+
+ ///
+ public void Dispose()
+ {
+ if (this.Tables != null)
+ {
+ this.Tables.Dispose();
+ this.Tables = null;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
index deeec34fc..8d3cec616 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
@@ -19,7 +19,7 @@ namespace ImageSharp.Formats.Jpeg.Port
/// Performs the jpeg decoding operation.
/// Ported from
///
- internal class JpegDecoderCore : IDisposable
+ internal sealed class JpegDecoderCore : IDisposable
{
///
/// The decoder options.
@@ -66,11 +66,6 @@ namespace ImageSharp.Formats.Jpeg.Port
///
private Adobe adobe;
- ///
- /// A value indicating whether the decoder has been disposed
- ///
- private bool isDisposed;
-
///
/// Initializes a new instance of the class.
///
@@ -210,28 +205,14 @@ namespace ImageSharp.Formats.Jpeg.Port
///
public void Dispose()
{
- this.Dispose(true);
- }
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- /// Whether to dispose of managed objects
- protected virtual void Dispose(bool disposing)
- {
- if (!this.isDisposed)
- {
- if (disposing)
- {
- this.frame.Dispose();
- this.components.Dispose();
- }
-
- // Set large fields to null.
- this.frame = null;
- this.components = null;
- this.isDisposed = true;
- }
+ this.frame.Dispose();
+ this.components.Dispose();
+ this.quantizationTables.Dispose();
+
+ // Set large fields to null.
+ this.frame = null;
+ this.components = null;
+ this.quantizationTables = null;
}
private void ParseStream()
@@ -253,11 +234,12 @@ namespace ImageSharp.Formats.Jpeg.Port
while (fileMarker.Marker != JpegConstants.Markers.EOI)
{
// Get the marker length
- int remaining = this.ReadUint16() - 2;
+ int remaining;
switch (fileMarker.Marker)
{
case JpegConstants.Markers.APP0:
+ remaining = this.ReadUint16() - 2;
this.ProcessApplicationHeaderMarker(remaining);
break;
@@ -277,6 +259,7 @@ namespace ImageSharp.Formats.Jpeg.Port
break;
case JpegConstants.Markers.APP14:
+ remaining = this.ReadUint16() - 2;
this.ProcessApp14Marker(remaining);
break;
@@ -287,24 +270,29 @@ namespace ImageSharp.Formats.Jpeg.Port
break;
case JpegConstants.Markers.DQT:
+ remaining = this.ReadUint16() - 2;
this.ProcessDqtMarker(remaining);
break;
case JpegConstants.Markers.SOF0:
case JpegConstants.Markers.SOF1:
case JpegConstants.Markers.SOF2:
+ remaining = this.ReadUint16() - 2;
this.ProcessStartOfFrameMarker(remaining, fileMarker);
break;
case JpegConstants.Markers.DHT:
+ remaining = this.ReadUint16() - 2;
this.ProcessDefineHuffmanTablesMarker(remaining);
break;
case JpegConstants.Markers.DRI:
+ remaining = this.ReadUint16() - 2;
this.ProcessDefineRestartIntervalMarker(remaining);
break;
case JpegConstants.Markers.SOS:
+ this.InputStream.Skip(2);
this.ProcessStartOfScanMarker();
break;
@@ -312,11 +300,6 @@ namespace ImageSharp.Formats.Jpeg.Port
if ((byte)this.InputStream.ReadByte() != 0xFF)
{
// Avoid skipping a valid marker
- this.InputStream.Position -= 2;
- }
- else
- {
- // Rewind that last byte we read
this.InputStream.Position -= 1;
}
@@ -453,6 +436,8 @@ namespace ImageSharp.Formats.Jpeg.Port
///
private void ProcessDqtMarker(int remaining)
{
+ // Pooled. Disposed on disposal of decoder
+ this.quantizationTables.Tables = new Buffer2D(64, 4);
while (remaining > 0)
{
bool done = false;