Browse Source

Move pending buffer

af/merge-core
James Jackson-South 7 years ago
parent
commit
0afece3af1
  1. 19
      src/ImageSharp/Formats/Png/Zlib/Deflater.cs
  2. 19
      src/ImageSharp/Formats/Png/Zlib/DeflaterEngine.cs
  3. 33
      src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs

19
src/ImageSharp/Formats/Png/Zlib/Deflater.cs

@ -50,7 +50,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// </summary> /// </summary>
private int state; private int state;
private DeflaterPendingBuffer pending;
private DeflaterEngine engine; private DeflaterEngine engine;
private bool isDisposed; private bool isDisposed;
@ -80,10 +79,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
throw new ArgumentOutOfRangeException(nameof(level)); throw new ArgumentOutOfRangeException(nameof(level));
} }
this.pending = new DeflaterPendingBuffer(memoryAllocator);
// TODO: Possibly provide DeflateStrategy as an option. // TODO: Possibly provide DeflateStrategy as an option.
this.engine = new DeflaterEngine(memoryAllocator, this.pending, DeflateStrategy.Default); this.engine = new DeflaterEngine(memoryAllocator, DeflateStrategy.Default);
this.SetLevel(level); this.SetLevel(level);
this.Reset(); this.Reset();
@ -126,7 +123,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// Gets a value indicating whetherthe stream was finished and no more output bytes /// Gets a value indicating whetherthe stream was finished and no more output bytes
/// are available. /// are available.
/// </summary> /// </summary>
public bool IsFinished => (this.state == FinishedState) && this.pending.IsFlushed; public bool IsFinished => (this.state == FinishedState) && this.engine.Pending.IsFlushed;
/// <summary> /// <summary>
/// Gets a value indicating whether the input buffer is empty. /// Gets a value indicating whether the input buffer is empty.
@ -145,7 +142,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
public void Reset() public void Reset()
{ {
this.state = BusyState; this.state = BusyState;
this.pending.Reset(); this.engine.Pending.Reset();
this.engine.Reset(); this.engine.Reset();
} }
@ -236,7 +233,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
while (true) while (true)
{ {
int count = this.pending.Flush(output, offset, length); int count = this.engine.Pending.Flush(output, offset, length);
offset += count; offset += count;
length -= count; length -= count;
@ -259,11 +256,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
// We have to supply some lookahead. 8 bit lookahead // We have to supply some lookahead. 8 bit lookahead
// is needed by the zlib inflater, and we must fill // is needed by the zlib inflater, and we must fill
// the next byte, so that all bits are flushed. // the next byte, so that all bits are flushed.
int neededbits = 8 + ((-this.pending.BitCount) & 7); int neededbits = 8 + ((-this.engine.Pending.BitCount) & 7);
while (neededbits > 0) while (neededbits > 0)
{ {
// Write a static tree block consisting solely of an EOF: // Write a static tree block consisting solely of an EOF:
this.pending.WriteBits(2, 10); this.engine.Pending.WriteBits(2, 10);
neededbits -= 10; neededbits -= 10;
} }
} }
@ -272,7 +269,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
break; break;
case FinishingState: case FinishingState:
this.pending.AlignToByte(); this.engine.Pending.AlignToByte();
this.state = FinishedState; this.state = FinishedState;
break; break;
} }
@ -296,10 +293,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
if (disposing) if (disposing)
{ {
this.engine.Dispose(); this.engine.Dispose();
this.pending.Dispose();
} }
this.pending = null;
this.engine = null; this.engine = null;
this.isDisposed = true; this.isDisposed = true;
} }

19
src/ImageSharp/Formats/Png/Zlib/DeflaterEngine.cs

@ -100,7 +100,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private int inputEnd; private int inputEnd;
private readonly DeflateStrategy strategy; private readonly DeflateStrategy strategy;
private readonly DeflaterPendingBuffer pending;
private DeflaterHuffman huffman; private DeflaterHuffman huffman;
private bool isDisposed; private bool isDisposed;
@ -145,12 +144,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// Initializes a new instance of the <see cref="DeflaterEngine"/> class. /// Initializes a new instance of the <see cref="DeflaterEngine"/> class.
/// </summary> /// </summary>
/// <param name="memoryAllocator">The memory allocator to use for buffer allocations.</param> /// <param name="memoryAllocator">The memory allocator to use for buffer allocations.</param>
/// <param name="pending">The pending buffer to use.</param>
/// <param name="strategy">The deflate strategy to use.</param> /// <param name="strategy">The deflate strategy to use.</param>
public DeflaterEngine(MemoryAllocator memoryAllocator, DeflaterPendingBuffer pending, DeflateStrategy strategy) public DeflaterEngine(MemoryAllocator memoryAllocator, DeflateStrategy strategy)
{ {
this.pending = pending; this.huffman = new DeflaterHuffman(memoryAllocator);
this.huffman = new DeflaterHuffman(pending); this.Pending = this.huffman.Pending;
this.strategy = strategy; this.strategy = strategy;
// Create pinned pointers to the various buffers to allow indexing // Create pinned pointers to the various buffers to allow indexing
@ -175,6 +173,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.blockStart = this.strstart = 1; this.blockStart = this.strstart = 1;
} }
/// <summary>
/// Gets the pending buffer to use.
/// </summary>
public DeflaterPendingBuffer Pending { get; }
/// <summary> /// <summary>
/// Deflate drives actual compression of data /// Deflate drives actual compression of data
/// </summary> /// </summary>
@ -208,7 +211,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
break; break;
} }
} }
while (this.pending.IsFlushed && progress); // repeat while we have no pending output and progress was made while (this.Pending.IsFlushed && progress); // repeat while we have no pending output and progress was made
return progress; return progress;
} }
@ -834,6 +837,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
{ {
if (disposing) if (disposing)
{ {
this.huffman.Dispose();
this.windowBufferHandle.Dispose(); this.windowBufferHandle.Dispose();
this.windowBuffer.Dispose(); this.windowBuffer.Dispose();
@ -844,6 +849,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.prevBuffer.Dispose(); this.prevBuffer.Dispose();
} }
this.huffman = null;
this.isDisposed = true; this.isDisposed = true;
} }
} }

33
src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using SixLabors.Memory;
namespace SixLabors.ImageSharp.Formats.Png.Zlib namespace SixLabors.ImageSharp.Formats.Png.Zlib
{ {
@ -15,7 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// ///
/// author of the original java version : Jochen Hoenicke /// author of the original java version : Jochen Hoenicke
/// </summary> /// </summary>
public class DeflaterHuffman public sealed class DeflaterHuffman : IDisposable
{ {
private const int BufferSize = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6); private const int BufferSize = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);
@ -60,6 +61,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private byte[] literalBuffer; private byte[] literalBuffer;
private int lastLiteral; private int lastLiteral;
private int extraBits; private int extraBits;
private bool isDisposed;
static DeflaterHuffman() static DeflaterHuffman()
{ {
@ -106,10 +108,10 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DeflaterHuffman"/> class. /// Initializes a new instance of the <see cref="DeflaterHuffman"/> class.
/// </summary> /// </summary>
/// <param name="pending">Pending buffer to use</param> /// <param name="memoryAllocator">The memory allocator to use for buffer allocations.</param>
public DeflaterHuffman(DeflaterPendingBuffer pending) public DeflaterHuffman(MemoryAllocator memoryAllocator)
{ {
this.Pending = pending; this.Pending = new DeflaterPendingBuffer(memoryAllocator);
this.literalTree = new Tree(this, LiteralNumber, 257, 15); this.literalTree = new Tree(this, LiteralNumber, 257, 15);
this.distTree = new Tree(this, DistanceNumber, 1, 15); this.distTree = new Tree(this, DistanceNumber, 1, 15);
@ -122,7 +124,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// <summary> /// <summary>
/// Gets the pending buffer to use. /// Gets the pending buffer to use.
/// </summary> /// </summary>
public DeflaterPendingBuffer Pending { get; } public DeflaterPendingBuffer Pending { get; private set; }
/// <summary> /// <summary>
/// Reset internal state /// Reset internal state
@ -351,6 +353,13 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
Bit4Reverse[toReverse >> 12]); Bit4Reverse[toReverse >> 12]);
} }
/// <inheritdoc/>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
private static int Lcode(int length) private static int Lcode(int length)
{ {
if (length == 255) if (length == 255)
@ -380,6 +389,20 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
return code + distance; return code + distance;
} }
private void Dispose(bool disposing)
{
if (!this.isDisposed)
{
if (disposing)
{
this.Pending.Dispose();
}
this.Pending = null;
this.isDisposed = true;
}
}
private class Tree private class Tree
{ {
private readonly int minNumCodes; private readonly int minNumCodes;

Loading…
Cancel
Save