diff --git a/src/ImageSharp/Compression/Zlib/Deflater.cs b/src/ImageSharp/Compression/Zlib/Deflater.cs
index 800c96703..7ff8342aa 100644
--- a/src/ImageSharp/Compression/Zlib/Deflater.cs
+++ b/src/ImageSharp/Compression/Zlib/Deflater.cs
@@ -222,7 +222,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
/// The number of compressed bytes added to the output, or 0 if either
/// or returns true or length is zero.
///
- public int Deflate(byte[] output, int offset, int length)
+ public int Deflate(Span output, int offset, int length)
{
int origLength = length;
diff --git a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs
index d3cfa7c3d..506b0f2c1 100644
--- a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs
@@ -130,9 +130,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib
/// This array contains the part of the uncompressed stream that
/// is of relevance. The current character is indexed by strstart.
///
- private IManagedByteBuffer windowMemoryOwner;
+ private IMemoryOwner windowMemoryOwner;
private MemoryHandle windowMemoryHandle;
- private readonly byte[] window;
+ private readonly Memory window;
private readonly byte* pinnedWindowPointer;
private int maxChain;
@@ -153,19 +153,19 @@ namespace SixLabors.ImageSharp.Compression.Zlib
// Create pinned pointers to the various buffers to allow indexing
// without bounds checks.
- this.windowMemoryOwner = memoryAllocator.AllocateManagedByteBuffer(2 * DeflaterConstants.WSIZE);
- this.window = this.windowMemoryOwner.Array;
- this.windowMemoryHandle = this.windowMemoryOwner.Memory.Pin();
+ this.windowMemoryOwner = memoryAllocator.Allocate(2 * DeflaterConstants.WSIZE);
+ this.window = this.windowMemoryOwner.Memory;
+ this.windowMemoryHandle = this.window.Pin();
this.pinnedWindowPointer = (byte*)this.windowMemoryHandle.Pointer;
this.headMemoryOwner = memoryAllocator.Allocate(DeflaterConstants.HASH_SIZE);
this.head = this.headMemoryOwner.Memory;
- this.headMemoryHandle = this.headMemoryOwner.Memory.Pin();
+ this.headMemoryHandle = this.head.Pin();
this.pinnedHeadPointer = (short*)this.headMemoryHandle.Pointer;
this.prevMemoryOwner = memoryAllocator.Allocate(DeflaterConstants.WSIZE);
this.prev = this.prevMemoryOwner.Memory;
- this.prevMemoryHandle = this.prevMemoryOwner.Memory.Pin();
+ this.prevMemoryHandle = this.prev.Pin();
this.pinnedPrevPointer = (short*)this.prevMemoryHandle.Pointer;
// We start at index 1, to avoid an implementation deficiency, that
@@ -303,7 +303,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
case DeflaterConstants.DEFLATE_STORED:
if (this.strstart > this.blockStart)
{
- this.huffman.FlushStoredBlock(this.window, this.blockStart, this.strstart - this.blockStart, false);
+ this.huffman.FlushStoredBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, false);
this.blockStart = this.strstart;
}
@@ -313,7 +313,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
case DeflaterConstants.DEFLATE_FAST:
if (this.strstart > this.blockStart)
{
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, false);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, false);
this.blockStart = this.strstart;
}
@@ -327,7 +327,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
if (this.strstart > this.blockStart)
{
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, false);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, false);
this.blockStart = this.strstart;
}
@@ -362,7 +362,10 @@ namespace SixLabors.ImageSharp.Compression.Zlib
more = this.inputEnd - this.inputOff;
}
- Buffer.BlockCopy(this.inputBuf, this.inputOff, this.window, this.strstart + this.lookahead, more);
+ Unsafe.CopyBlockUnaligned(
+ ref this.window.Span[this.strstart + this.lookahead],
+ ref this.inputBuf[this.inputOff],
+ unchecked((uint)more));
this.inputOff += more;
this.lookahead += more;
@@ -426,7 +429,11 @@ namespace SixLabors.ImageSharp.Compression.Zlib
private void SlideWindow()
{
- Unsafe.CopyBlockUnaligned(ref this.window[0], ref this.window[DeflaterConstants.WSIZE], DeflaterConstants.WSIZE);
+ Unsafe.CopyBlockUnaligned(
+ ref this.window.Span[0],
+ ref this.window.Span[DeflaterConstants.WSIZE],
+ DeflaterConstants.WSIZE);
+
this.matchStart -= DeflaterConstants.WSIZE;
this.strstart -= DeflaterConstants.WSIZE;
this.blockStart -= DeflaterConstants.WSIZE;
@@ -663,7 +670,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
lastBlock = false;
}
- this.huffman.FlushStoredBlock(this.window, this.blockStart, storedLength, lastBlock);
+ this.huffman.FlushStoredBlock(this.window.Span, this.blockStart, storedLength, lastBlock);
this.blockStart += storedLength;
return !(lastBlock || storedLength == 0);
}
@@ -683,7 +690,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
if (this.lookahead == 0)
{
// We are flushing everything
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, finish);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, finish);
this.blockStart = this.strstart;
return false;
}
@@ -743,7 +750,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
if (this.huffman.IsFull())
{
bool lastBlock = finish && (this.lookahead == 0);
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, lastBlock);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, lastBlock);
this.blockStart = this.strstart;
return !lastBlock;
}
@@ -771,7 +778,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
this.prevAvailable = false;
// We are flushing everything
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, finish);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, finish);
this.blockStart = this.strstart;
return false;
}
@@ -846,7 +853,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
}
bool lastBlock = finish && (this.lookahead == 0) && !this.prevAvailable;
- this.huffman.FlushBlock(this.window, this.blockStart, len, lastBlock);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, len, lastBlock);
this.blockStart += len;
return !lastBlock;
}
diff --git a/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs b/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
index d6892dfd2..27a8d5671 100644
--- a/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
@@ -41,11 +41,11 @@ namespace SixLabors.ImageSharp.Compression.Zlib
private Tree blTree;
// Buffer for distances
- private readonly IMemoryOwner distanceManagedBuffer;
+ private readonly IMemoryOwner distanceMemoryOwner;
private readonly short* pinnedDistanceBuffer;
private MemoryHandle distanceBufferHandle;
- private readonly IMemoryOwner literalManagedBuffer;
+ private readonly IMemoryOwner literalMemoryOwner;
private readonly short* pinnedLiteralBuffer;
private MemoryHandle literalBufferHandle;
@@ -65,12 +65,12 @@ namespace SixLabors.ImageSharp.Compression.Zlib
this.distTree = new Tree(memoryAllocator, DistanceNumber, 1, 15);
this.blTree = new Tree(memoryAllocator, BitLengthNumber, 4, 7);
- this.distanceManagedBuffer = memoryAllocator.Allocate(BufferSize);
- this.distanceBufferHandle = this.distanceManagedBuffer.Memory.Pin();
+ this.distanceMemoryOwner = memoryAllocator.Allocate(BufferSize);
+ this.distanceBufferHandle = this.distanceMemoryOwner.Memory.Pin();
this.pinnedDistanceBuffer = (short*)this.distanceBufferHandle.Pointer;
- this.literalManagedBuffer = memoryAllocator.Allocate(BufferSize);
- this.literalBufferHandle = this.literalManagedBuffer.Memory.Pin();
+ this.literalMemoryOwner = memoryAllocator.Allocate(BufferSize);
+ this.literalBufferHandle = this.literalMemoryOwner.Memory.Pin();
this.pinnedLiteralBuffer = (short*)this.literalBufferHandle.Pointer;
}
@@ -239,7 +239,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
/// Count of bytes to write
/// True if this is the last block
[MethodImpl(InliningOptions.ShortMethod)]
- public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
+ public void FlushStoredBlock(ReadOnlySpan stored, int storedOffset, int storedLength, bool lastBlock)
{
this.Pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);
this.Pending.AlignToByte();
@@ -256,7 +256,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
/// Index of first byte to flush
/// Count of bytes to flush
/// True if this is the last block
- public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
+ public void FlushBlock(ReadOnlySpan stored, int storedOffset, int storedLength, bool lastBlock)
{
this.literalTree.Frequencies[EofSymbol]++;
@@ -286,13 +286,13 @@ namespace SixLabors.ImageSharp.Compression.Zlib
+ this.extraBits;
int static_len = this.extraBits;
- ref byte staticLLengthRef = ref MemoryMarshal.GetReference(StaticLLength);
+ ref byte staticLLengthRef = ref MemoryMarshal.GetReference(StaticLLength);
for (int i = 0; i < LiteralNumber; i++)
{
static_len += this.literalTree.Frequencies[i] * Unsafe.Add(ref staticLLengthRef, i);
}
- ref byte staticDLengthRef = ref MemoryMarshal.GetReference(StaticDLength);
+ ref byte staticDLengthRef = ref MemoryMarshal.GetReference(StaticDLength);
for (int i = 0; i < DistanceNumber; i++)
{
static_len += this.distTree.Frequencies[i] * Unsafe.Add(ref staticDLengthRef, i);
@@ -419,9 +419,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib
{
this.Pending.Dispose();
this.distanceBufferHandle.Dispose();
- this.distanceManagedBuffer.Dispose();
+ this.distanceMemoryOwner.Dispose();
this.literalBufferHandle.Dispose();
- this.literalManagedBuffer.Dispose();
+ this.literalMemoryOwner.Dispose();
this.literalTree.Dispose();
this.blTree.Dispose();
@@ -484,7 +484,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
private IMemoryOwner frequenciesMemoryOwner;
private MemoryHandle frequenciesMemoryHandle;
- private IManagedByteBuffer lengthsMemoryOwner;
+ private IMemoryOwner lengthsMemoryOwner;
private MemoryHandle lengthsMemoryHandle;
public Tree(MemoryAllocator memoryAllocator, int elements, int minCodes, int maxLength)
@@ -498,7 +498,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
this.frequenciesMemoryHandle = this.frequenciesMemoryOwner.Memory.Pin();
this.Frequencies = (short*)this.frequenciesMemoryHandle.Pointer;
- this.lengthsMemoryOwner = memoryAllocator.AllocateManagedByteBuffer(elements);
+ this.lengthsMemoryOwner = memoryAllocator.Allocate(elements);
this.lengthsMemoryHandle = this.lengthsMemoryOwner.Memory.Pin();
this.Length = (byte*)this.lengthsMemoryHandle.Pointer;
diff --git a/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs b/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs
index cbbf7ea79..d949ddf38 100644
--- a/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using System.Buffers;
using System.IO;
using SixLabors.ImageSharp.Memory;
@@ -14,8 +15,8 @@ namespace SixLabors.ImageSharp.Compression.Zlib
internal sealed class DeflaterOutputStream : Stream
{
private const int BufferLength = 512;
- private IManagedByteBuffer memoryOwner;
- private readonly byte[] buffer;
+ private IMemoryOwner memoryOwner;
+ private readonly Memory buffer;
private Deflater deflater;
private readonly Stream rawStream;
private bool isDisposed;
@@ -29,8 +30,8 @@ namespace SixLabors.ImageSharp.Compression.Zlib
public DeflaterOutputStream(MemoryAllocator memoryAllocator, Stream rawStream, int compressionLevel)
{
this.rawStream = rawStream;
- this.memoryOwner = memoryAllocator.AllocateManagedByteBuffer(BufferLength);
- this.buffer = this.memoryOwner.Array;
+ this.memoryOwner = memoryAllocator.Allocate(BufferLength);
+ this.buffer = this.memoryOwner.Memory;
this.deflater = new Deflater(memoryAllocator, compressionLevel);
}
@@ -49,15 +50,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib
///
public override long Position
{
- get
- {
- return this.rawStream.Position;
- }
+ get => this.rawStream.Position;
- set
- {
- throw new NotSupportedException();
- }
+ set => throw new NotSupportedException();
}
///
@@ -93,14 +88,14 @@ namespace SixLabors.ImageSharp.Compression.Zlib
{
while (flushing || !this.deflater.IsNeedingInput)
{
- int deflateCount = this.deflater.Deflate(this.buffer, 0, BufferLength);
+ int deflateCount = this.deflater.Deflate(this.buffer.Span, 0, BufferLength);
if (deflateCount <= 0)
{
break;
}
- this.rawStream.Write(this.buffer, 0, deflateCount);
+ this.rawStream.Write(this.buffer.Span.Slice(0, deflateCount));
}
if (!this.deflater.IsNeedingInput)
@@ -114,13 +109,13 @@ namespace SixLabors.ImageSharp.Compression.Zlib
this.deflater.Finish();
while (!this.deflater.IsFinished)
{
- int len = this.deflater.Deflate(this.buffer, 0, BufferLength);
+ int len = this.deflater.Deflate(this.buffer.Span, 0, BufferLength);
if (len <= 0)
{
break;
}
- this.rawStream.Write(this.buffer, 0, len);
+ this.rawStream.Write(this.buffer.Span.Slice(0, len));
}
if (!this.deflater.IsFinished)
diff --git a/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs b/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs
index 36dfd92da..8f2c8d398 100644
--- a/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs
@@ -4,6 +4,7 @@
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Compression.Zlib
@@ -13,9 +14,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib
///
internal sealed unsafe class DeflaterPendingBuffer : IDisposable
{
- private readonly byte[] buffer;
+ private readonly Memory buffer;
private readonly byte* pinnedBuffer;
- private IManagedByteBuffer bufferMemoryOwner;
+ private IMemoryOwner bufferMemoryOwner;
private MemoryHandle bufferMemoryHandle;
private int start;
@@ -29,9 +30,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib
/// The memory allocator to use for buffer allocations.
public DeflaterPendingBuffer(MemoryAllocator memoryAllocator)
{
- this.bufferMemoryOwner = memoryAllocator.AllocateManagedByteBuffer(DeflaterConstants.PENDING_BUF_SIZE);
- this.buffer = this.bufferMemoryOwner.Array;
- this.bufferMemoryHandle = this.bufferMemoryOwner.Memory.Pin();
+ this.bufferMemoryOwner = memoryAllocator.Allocate(DeflaterConstants.PENDING_BUF_SIZE);
+ this.buffer = this.bufferMemoryOwner.Memory;
+ this.bufferMemoryHandle = this.buffer.Pin();
this.pinnedBuffer = (byte*)this.bufferMemoryHandle.Pointer;
}
@@ -70,9 +71,13 @@ namespace SixLabors.ImageSharp.Compression.Zlib
/// The offset of first byte to write.
/// The number of bytes to write.
[MethodImpl(InliningOptions.ShortMethod)]
- public void WriteBlock(byte[] block, int offset, int length)
+ public void WriteBlock(ReadOnlySpan block, int offset, int length)
{
- Unsafe.CopyBlockUnaligned(ref this.buffer[this.end], ref block[offset], unchecked((uint)length));
+ Unsafe.CopyBlockUnaligned(
+ ref this.buffer.Span[this.end],
+ ref MemoryMarshal.GetReference(block.Slice(offset)),
+ unchecked((uint)length));
+
this.end += length;
}
@@ -136,7 +141,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
/// The offset into output array.
/// The maximum number of bytes to store.
/// The number of bytes flushed.
- public int Flush(byte[] output, int offset, int length)
+ public int Flush(Span output, int offset, int length)
{
if (this.BitCount >= 8)
{
@@ -149,13 +154,19 @@ namespace SixLabors.ImageSharp.Compression.Zlib
{
length = this.end - this.start;
- Unsafe.CopyBlockUnaligned(ref output[offset], ref this.buffer[this.start], unchecked((uint)length));
+ Unsafe.CopyBlockUnaligned(
+ ref output[offset],
+ ref this.buffer.Span[this.start],
+ unchecked((uint)length));
this.start = 0;
this.end = 0;
}
else
{
- Unsafe.CopyBlockUnaligned(ref output[offset], ref this.buffer[this.start], unchecked((uint)length));
+ Unsafe.CopyBlockUnaligned(
+ ref output[offset],
+ ref this.buffer.Span[this.start],
+ unchecked((uint)length));
this.start += length;
}