Browse Source

Move pending buffer

af/merge-core
James Jackson-South 6 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>
private int state;
private DeflaterPendingBuffer pending;
private DeflaterEngine engine;
private bool isDisposed;
@ -80,10 +79,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
throw new ArgumentOutOfRangeException(nameof(level));
}
this.pending = new DeflaterPendingBuffer(memoryAllocator);
// 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.Reset();
@ -126,7 +123,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// Gets a value indicating whetherthe stream was finished and no more output bytes
/// are available.
/// </summary>
public bool IsFinished => (this.state == FinishedState) && this.pending.IsFlushed;
public bool IsFinished => (this.state == FinishedState) && this.engine.Pending.IsFlushed;
/// <summary>
/// Gets a value indicating whether the input buffer is empty.
@ -145,7 +142,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
public void Reset()
{
this.state = BusyState;
this.pending.Reset();
this.engine.Pending.Reset();
this.engine.Reset();
}
@ -236,7 +233,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
while (true)
{
int count = this.pending.Flush(output, offset, length);
int count = this.engine.Pending.Flush(output, offset, length);
offset += count;
length -= count;
@ -259,11 +256,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
// We have to supply some lookahead. 8 bit lookahead
// is needed by the zlib inflater, and we must fill
// 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)
{
// Write a static tree block consisting solely of an EOF:
this.pending.WriteBits(2, 10);
this.engine.Pending.WriteBits(2, 10);
neededbits -= 10;
}
}
@ -272,7 +269,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
break;
case FinishingState:
this.pending.AlignToByte();
this.engine.Pending.AlignToByte();
this.state = FinishedState;
break;
}
@ -296,10 +293,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
if (disposing)
{
this.engine.Dispose();
this.pending.Dispose();
}
this.pending = null;
this.engine = null;
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 readonly DeflateStrategy strategy;
private readonly DeflaterPendingBuffer pending;
private DeflaterHuffman huffman;
private bool isDisposed;
@ -145,12 +144,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// Initializes a new instance of the <see cref="DeflaterEngine"/> class.
/// </summary>
/// <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>
public DeflaterEngine(MemoryAllocator memoryAllocator, DeflaterPendingBuffer pending, DeflateStrategy strategy)
public DeflaterEngine(MemoryAllocator memoryAllocator, DeflateStrategy strategy)
{
this.pending = pending;
this.huffman = new DeflaterHuffman(pending);
this.huffman = new DeflaterHuffman(memoryAllocator);
this.Pending = this.huffman.Pending;
this.strategy = strategy;
// 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;
}
/// <summary>
/// Gets the pending buffer to use.
/// </summary>
public DeflaterPendingBuffer Pending { get; }
/// <summary>
/// Deflate drives actual compression of data
/// </summary>
@ -208,7 +211,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
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;
}
@ -834,6 +837,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
{
if (disposing)
{
this.huffman.Dispose();
this.windowBufferHandle.Dispose();
this.windowBuffer.Dispose();
@ -844,6 +849,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.prevBuffer.Dispose();
}
this.huffman = null;
this.isDisposed = true;
}
}

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

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

Loading…
Cancel
Save