Browse Source

Impove disposal

pull/298/head
James Jackson-South 9 years ago
parent
commit
c1025a6ea0
  1. 27
      src/ImageSharp/Formats/Jpeg/Port/Components/ComponentBlocks.cs
  2. 33
      src/ImageSharp/Formats/Jpeg/Port/Components/Frame.cs
  3. 16
      src/ImageSharp/Formats/Jpeg/Port/Components/QuantizationTables.cs
  4. 53
      src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs

27
src/ImageSharp/Formats/Jpeg/Port/Components/ComponentBlocks.cs

@ -10,10 +10,8 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
/// <summary> /// <summary>
/// Contains all the decoded component blocks /// Contains all the decoded component blocks
/// </summary> /// </summary>
internal class ComponentBlocks : IDisposable internal sealed class ComponentBlocks : IDisposable
{ {
private bool isDisposed;
/// <summary> /// <summary>
/// Gets or sets the component blocks /// Gets or sets the component blocks
/// </summary> /// </summary>
@ -22,31 +20,14 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
this.Dispose(true); if (this.Components != null)
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <param name="disposing">Whether to dispose of managed objects</param>
protected virtual void Dispose(bool disposing)
{
if (!this.isDisposed)
{ {
if (disposing) for (int i = 0; i < this.Components.Length; i++)
{ {
if (this.Components != null) this.Components[i].Dispose();
{
for (int i = 0; i < this.Components.Length; i++)
{
this.Components[i].Dispose();
}
}
} }
// Set large fields to null.
this.Components = null; this.Components = null;
this.isDisposed = true;
} }
} }
} }

33
src/ImageSharp/Formats/Jpeg/Port/Components/Frame.cs

@ -10,10 +10,8 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
/// <summary> /// <summary>
/// Represent a single jpeg frame /// Represent a single jpeg frame
/// </summary> /// </summary>
internal class Frame : IDisposable internal sealed class Frame : IDisposable
{ {
private bool isDisposed;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether the frame uses the extended specification /// Gets or sets a value indicating whether the frame uses the extended specification
/// </summary> /// </summary>
@ -77,34 +75,15 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
this.Dispose(true); if (this.Components != null)
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <param name="disposing">Whether to dispose of managed objects</param>
protected virtual void Dispose(bool disposing)
{
if (this.isDisposed)
{ {
return; for (int i = 0; i < this.Components.Length; i++)
}
if (disposing)
{
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.Components = null; }
this.isDisposed = true;
} }
} }
} }

16
src/ImageSharp/Formats/Jpeg/Port/Components/QuantizationTables.cs

@ -5,15 +5,15 @@
namespace ImageSharp.Formats.Jpeg.Port.Components namespace ImageSharp.Formats.Jpeg.Port.Components
{ {
using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using ImageSharp.Memory; using ImageSharp.Memory;
/// <summary> /// <summary>
/// Contains the quantization tables. /// Contains the quantization tables.
/// TODO: This all needs optimizing for memory. I'm just stubbing out functionality for now.
/// </summary> /// </summary>
internal class QuantizationTables internal sealed class QuantizationTables : IDisposable
{ {
/// <summary> /// <summary>
/// Gets the ZigZag scan table /// Gets the ZigZag scan table
@ -46,6 +46,16 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
/// <summary> /// <summary>
/// Gets or sets the quantization tables. /// Gets or sets the quantization tables.
/// </summary> /// </summary>
public Fast2DArray<short> Tables { get; set; } = new Fast2DArray<short>(64, 4); public Buffer2D<short> Tables { get; set; }
/// <inheritdoc/>
public void Dispose()
{
if (this.Tables != null)
{
this.Tables.Dispose();
this.Tables = null;
}
}
} }
} }

53
src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs

@ -19,7 +19,7 @@ namespace ImageSharp.Formats.Jpeg.Port
/// Performs the jpeg decoding operation. /// Performs the jpeg decoding operation.
/// Ported from <see href="https://github.com/mozilla/pdf.js/blob/master/src/core/jpg.js"/> /// Ported from <see href="https://github.com/mozilla/pdf.js/blob/master/src/core/jpg.js"/>
/// </summary> /// </summary>
internal class JpegDecoderCore : IDisposable internal sealed class JpegDecoderCore : IDisposable
{ {
/// <summary> /// <summary>
/// The decoder options. /// The decoder options.
@ -66,11 +66,6 @@ namespace ImageSharp.Formats.Jpeg.Port
/// </summary> /// </summary>
private Adobe adobe; private Adobe adobe;
/// <summary>
/// A value indicating whether the decoder has been disposed
/// </summary>
private bool isDisposed;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JpegDecoderCore" /> class. /// Initializes a new instance of the <see cref="JpegDecoderCore" /> class.
/// </summary> /// </summary>
@ -210,28 +205,14 @@ namespace ImageSharp.Formats.Jpeg.Port
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
this.Dispose(true); this.frame.Dispose();
} this.components.Dispose();
this.quantizationTables.Dispose();
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. // Set large fields to null.
/// </summary> this.frame = null;
/// <param name="disposing">Whether to dispose of managed objects</param> this.components = null;
protected virtual void Dispose(bool disposing) this.quantizationTables = null;
{
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;
}
} }
private void ParseStream() private void ParseStream()
@ -253,11 +234,12 @@ namespace ImageSharp.Formats.Jpeg.Port
while (fileMarker.Marker != JpegConstants.Markers.EOI) while (fileMarker.Marker != JpegConstants.Markers.EOI)
{ {
// Get the marker length // Get the marker length
int remaining = this.ReadUint16() - 2; int remaining;
switch (fileMarker.Marker) switch (fileMarker.Marker)
{ {
case JpegConstants.Markers.APP0: case JpegConstants.Markers.APP0:
remaining = this.ReadUint16() - 2;
this.ProcessApplicationHeaderMarker(remaining); this.ProcessApplicationHeaderMarker(remaining);
break; break;
@ -277,6 +259,7 @@ namespace ImageSharp.Formats.Jpeg.Port
break; break;
case JpegConstants.Markers.APP14: case JpegConstants.Markers.APP14:
remaining = this.ReadUint16() - 2;
this.ProcessApp14Marker(remaining); this.ProcessApp14Marker(remaining);
break; break;
@ -287,24 +270,29 @@ namespace ImageSharp.Formats.Jpeg.Port
break; break;
case JpegConstants.Markers.DQT: case JpegConstants.Markers.DQT:
remaining = this.ReadUint16() - 2;
this.ProcessDqtMarker(remaining); this.ProcessDqtMarker(remaining);
break; break;
case JpegConstants.Markers.SOF0: case JpegConstants.Markers.SOF0:
case JpegConstants.Markers.SOF1: case JpegConstants.Markers.SOF1:
case JpegConstants.Markers.SOF2: case JpegConstants.Markers.SOF2:
remaining = this.ReadUint16() - 2;
this.ProcessStartOfFrameMarker(remaining, fileMarker); this.ProcessStartOfFrameMarker(remaining, fileMarker);
break; break;
case JpegConstants.Markers.DHT: case JpegConstants.Markers.DHT:
remaining = this.ReadUint16() - 2;
this.ProcessDefineHuffmanTablesMarker(remaining); this.ProcessDefineHuffmanTablesMarker(remaining);
break; break;
case JpegConstants.Markers.DRI: case JpegConstants.Markers.DRI:
remaining = this.ReadUint16() - 2;
this.ProcessDefineRestartIntervalMarker(remaining); this.ProcessDefineRestartIntervalMarker(remaining);
break; break;
case JpegConstants.Markers.SOS: case JpegConstants.Markers.SOS:
this.InputStream.Skip(2);
this.ProcessStartOfScanMarker(); this.ProcessStartOfScanMarker();
break; break;
@ -312,11 +300,6 @@ namespace ImageSharp.Formats.Jpeg.Port
if ((byte)this.InputStream.ReadByte() != 0xFF) if ((byte)this.InputStream.ReadByte() != 0xFF)
{ {
// Avoid skipping a valid marker // Avoid skipping a valid marker
this.InputStream.Position -= 2;
}
else
{
// Rewind that last byte we read
this.InputStream.Position -= 1; this.InputStream.Position -= 1;
} }
@ -453,6 +436,8 @@ namespace ImageSharp.Formats.Jpeg.Port
/// </exception> /// </exception>
private void ProcessDqtMarker(int remaining) private void ProcessDqtMarker(int remaining)
{ {
// Pooled. Disposed on disposal of decoder
this.quantizationTables.Tables = new Buffer2D<short>(64, 4);
while (remaining > 0) while (remaining > 0)
{ {
bool done = false; bool done = false;

Loading…
Cancel
Save