From 8e34f989c91f19d7edd22802e49c59481701bd33 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 3 Dec 2020 19:29:49 +0100 Subject: [PATCH] LzwEncoder now uses the memory allocator --- .../Formats/Tiff/Utils/TiffLzwEncoder.cs | 41 ++++++++++--------- .../Formats/Tiff/Utils/TiffWriter.cs | 4 +- .../Compression/LzwTiffCompressionTests.cs | 2 +- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffLzwEncoder.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffLzwEncoder.cs index b0c20a0db7..96db8e110d 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffLzwEncoder.cs +++ b/src/ImageSharp/Formats/Tiff/Utils/TiffLzwEncoder.cs @@ -79,12 +79,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// /// The hash table. /// - private readonly int[] hashTable; + private readonly IMemoryOwner hashTable; /// /// The code table. /// - private readonly int[] codeTable; + private readonly IMemoryOwner codeTable; /// /// Define the storage for the packet accumulator. @@ -201,16 +201,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// /// The array of indexed pixels. /// The color depth in bits. - public TiffLzwEncoder(IMemoryOwner indexedPixels, int colorDepth) + /// The memory allocator. + public TiffLzwEncoder(MemoryAllocator memoryAllocator, IMemoryOwner indexedPixels, int colorDepth) { this.pixelArray = indexedPixels; this.initialCodeSize = Math.Max(2, colorDepth); - // TODO: use memory allocator - this.hashTable = ArrayPool.Shared.Rent(HashSize); - this.codeTable = ArrayPool.Shared.Rent(HashSize); - Array.Clear(this.hashTable, 0, HashSize); - Array.Clear(this.codeTable, 0, HashSize); + this.hashTable = memoryAllocator.Allocate(HashSize, AllocationOptions.Clean); + this.codeTable = memoryAllocator.Allocate(HashSize, AllocationOptions.Clean); } /// @@ -276,9 +274,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// The hash size. private void ResetCodeTable(int size) { + Span hashTableSpan = this.hashTable.GetSpan(); 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); + Span hashTableSpan = this.hashTable.GetSpan(); + Span codeTableSpan = this.codeTable.GetSpan(); while ((c = this.NextPixel()) != Eof) { fcode = (c << this.maxbits) + ent; int i = (c << hshift) ^ ent /* = 0 */; - if (this.hashTable[i] == fcode) + if (hashTableSpan[i] == fcode) { - ent = this.codeTable[i]; + ent = codeTableSpan[i]; continue; } // Non-empty slot - if (this.hashTable[i] >= 0) + if (hashTableSpan[i] >= 0) { int disp = hsizeReg - i; if (i == 0) @@ -352,15 +353,15 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils i += hsizeReg; } - if (this.hashTable[i] == fcode) + if (hashTableSpan[i] == fcode) { - ent = this.codeTable[i]; + ent = codeTableSpan[i]; break; } } - while (this.hashTable[i] >= 0); + while (hashTableSpan[i] >= 0); - if (this.hashTable[i] == fcode) + if (hashTableSpan[i] == fcode) { continue; } @@ -370,8 +371,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils ent = c; if (this.freeEntry < this.maxmaxcode) { - this.codeTable[i] = this.freeEntry++; // code -> hashtable - this.hashTable[i] = fcode; + codeTableSpan[i] = this.freeEntry++; // code -> hashtable + hashTableSpan[i] = fcode; } else { @@ -487,8 +488,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils if (disposing) { - ArrayPool.Shared.Return(this.hashTable); - ArrayPool.Shared.Return(this.codeTable); + this.hashTable.Dispose(); + this.codeTable.Dispose(); } this.isDisposed = true; diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs index fce6ec4624..1ce03cf2eb 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs +++ b/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)); } - using var lzwEncoder = new TiffLzwEncoder(pixelData, 8); + using var lzwEncoder = new TiffLzwEncoder(this.memoryAllocator, pixelData, 8); lzwEncoder.Encode(memoryStream); byte[] buffer = memoryStream.ToArray(); @@ -568,7 +568,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils 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); byte[] buffer = memoryStream.ToArray(); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs index 775d55af69..730d6f3662 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs @@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression using System.Buffers.IMemoryOwner data = Configuration.Default.MemoryAllocator.Allocate(inputData.Length); 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); }