Browse Source

LzwEncoder now uses the memory allocator

pull/1467/head
Brian Popow 6 years ago
parent
commit
8118818365
  1. 41
      src/ImageSharp/Formats/Tiff/Utils/TiffLzwEncoder.cs
  2. 4
      src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs
  3. 2
      tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs

41
src/ImageSharp/Formats/Tiff/Utils/TiffLzwEncoder.cs

@ -79,12 +79,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
/// <summary> /// <summary>
/// The hash table. /// The hash table.
/// </summary> /// </summary>
private readonly int[] hashTable; private readonly IMemoryOwner<int> hashTable;
/// <summary> /// <summary>
/// The code table. /// The code table.
/// </summary> /// </summary>
private readonly int[] codeTable; private readonly IMemoryOwner<int> codeTable;
/// <summary> /// <summary>
/// Define the storage for the packet accumulator. /// Define the storage for the packet accumulator.
@ -201,16 +201,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
/// </summary> /// </summary>
/// <param name="indexedPixels">The array of indexed pixels.</param> /// <param name="indexedPixels">The array of indexed pixels.</param>
/// <param name="colorDepth">The color depth in bits.</param> /// <param name="colorDepth">The color depth in bits.</param>
public TiffLzwEncoder(IMemoryOwner<byte> indexedPixels, int colorDepth) /// <param name="memoryAllocator">The memory allocator.</param>
public TiffLzwEncoder(MemoryAllocator memoryAllocator, IMemoryOwner<byte> indexedPixels, int colorDepth)
{ {
this.pixelArray = indexedPixels; this.pixelArray = indexedPixels;
this.initialCodeSize = Math.Max(2, colorDepth); this.initialCodeSize = Math.Max(2, colorDepth);
// TODO: use memory allocator this.hashTable = memoryAllocator.Allocate<int>(HashSize, AllocationOptions.Clean);
this.hashTable = ArrayPool<int>.Shared.Rent(HashSize); this.codeTable = memoryAllocator.Allocate<int>(HashSize, AllocationOptions.Clean);
this.codeTable = ArrayPool<int>.Shared.Rent(HashSize);
Array.Clear(this.hashTable, 0, HashSize);
Array.Clear(this.codeTable, 0, HashSize);
} }
/// <summary> /// <summary>
@ -276,9 +274,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
/// <param name="size">The hash size.</param> /// <param name="size">The hash size.</param>
private void ResetCodeTable(int size) private void ResetCodeTable(int size)
{ {
Span<int> hashTableSpan = this.hashTable.GetSpan();
for (int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
{ {
this.hashTable[i] = -1; hashTableSpan[i] = -1;
} }
} }
@ -325,19 +324,21 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
this.Output(this.clearCode, stream); this.Output(this.clearCode, stream);
Span<int> hashTableSpan = this.hashTable.GetSpan();
Span<int> codeTableSpan = this.codeTable.GetSpan();
while ((c = this.NextPixel()) != Eof) while ((c = this.NextPixel()) != Eof)
{ {
fcode = (c << this.maxbits) + ent; fcode = (c << this.maxbits) + ent;
int i = (c << hshift) ^ ent /* = 0 */; int i = (c << hshift) ^ ent /* = 0 */;
if (this.hashTable[i] == fcode) if (hashTableSpan[i] == fcode)
{ {
ent = this.codeTable[i]; ent = codeTableSpan[i];
continue; continue;
} }
// Non-empty slot // Non-empty slot
if (this.hashTable[i] >= 0) if (hashTableSpan[i] >= 0)
{ {
int disp = hsizeReg - i; int disp = hsizeReg - i;
if (i == 0) if (i == 0)
@ -352,15 +353,15 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
i += hsizeReg; i += hsizeReg;
} }
if (this.hashTable[i] == fcode) if (hashTableSpan[i] == fcode)
{ {
ent = this.codeTable[i]; ent = codeTableSpan[i];
break; break;
} }
} }
while (this.hashTable[i] >= 0); while (hashTableSpan[i] >= 0);
if (this.hashTable[i] == fcode) if (hashTableSpan[i] == fcode)
{ {
continue; continue;
} }
@ -370,8 +371,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
ent = c; ent = c;
if (this.freeEntry < this.maxmaxcode) if (this.freeEntry < this.maxmaxcode)
{ {
this.codeTable[i] = this.freeEntry++; // code -> hashtable codeTableSpan[i] = this.freeEntry++; // code -> hashtable
this.hashTable[i] = fcode; hashTableSpan[i] = fcode;
} }
else else
{ {
@ -487,8 +488,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
if (disposing) if (disposing)
{ {
ArrayPool<int>.Shared.Return(this.hashTable); this.hashTable.Dispose();
ArrayPool<int>.Shared.Return(this.codeTable); this.codeTable.Dispose();
} }
this.isDisposed = true; this.isDisposed = true;

4
src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs

@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
rowSpan.CopyTo(pixels.Slice(y * image.Width * 3)); rowSpan.CopyTo(pixels.Slice(y * image.Width * 3));
} }
using var lzwEncoder = new TiffLzwEncoder(pixelData, 8); using var lzwEncoder = new TiffLzwEncoder(this.memoryAllocator, pixelData, 8);
lzwEncoder.Encode(memoryStream); lzwEncoder.Encode(memoryStream);
byte[] buffer = memoryStream.ToArray(); byte[] buffer = memoryStream.ToArray();
@ -568,7 +568,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
rowSpan.CopyTo(pixels.Slice(y * image.Width)); rowSpan.CopyTo(pixels.Slice(y * image.Width));
} }
using var lzwEncoder = new TiffLzwEncoder(pixelData, 8); using var lzwEncoder = new TiffLzwEncoder(this.memoryAllocator, pixelData, 8);
lzwEncoder.Encode(memoryStream); lzwEncoder.Encode(memoryStream);
byte[] buffer = memoryStream.ToArray(); byte[] buffer = memoryStream.ToArray();

2
tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs

@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
using System.Buffers.IMemoryOwner<byte> data = Configuration.Default.MemoryAllocator.Allocate<byte>(inputData.Length); using System.Buffers.IMemoryOwner<byte> data = Configuration.Default.MemoryAllocator.Allocate<byte>(inputData.Length);
inputData.AsSpan().CopyTo(data.GetSpan()); inputData.AsSpan().CopyTo(data.GetSpan());
using (var encoder = new TiffLzwEncoder(data, 8)) using (var encoder = new TiffLzwEncoder(Configuration.Default.MemoryAllocator, data, 8))
{ {
encoder.Encode(compressedStream); encoder.Encode(compressedStream);
} }

Loading…
Cancel
Save