From a8481c80fbd6b5dda642f95415ce6f76432010ef Mon Sep 17 00:00:00 2001 From: Mykhailo Matviiv Date: Fri, 5 May 2017 20:03:18 +0300 Subject: [PATCH] Remove DecodedBlockArray and replace usages with Buffer to centralize memory management. --- .../Components/Decoder/DecodedBlockArray.cs | 55 ------------------- .../Components/Decoder/JpegBlockProcessor.cs | 8 +-- .../Components/Decoder/JpegScanDecoder.cs | 6 +- .../Formats/Jpeg/JpegDecoderCore.cs | 12 ++-- 4 files changed, 13 insertions(+), 68 deletions(-) delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlockArray.cs diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlockArray.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlockArray.cs deleted file mode 100644 index 97a79dd61..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/DecodedBlockArray.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Formats.Jpg -{ - using System; - using System.Buffers; - - /// - /// Because has no information for rented arrays, - /// we need to store the count and the buffer separately when storing pooled arrays. - /// - internal struct DecodedBlockArray : IDisposable - { - /// - /// The used to pool data in . - /// Should always clean arrays when returning! - /// - private static readonly ArrayPool ArrayPool = ArrayPool.Create(); - - /// - /// Initializes a new instance of the struct. Rents a buffer. - /// - /// The number of valid -s - public DecodedBlockArray(int count) - { - this.Count = count; - this.Buffer = ArrayPool.Rent(count); - } - - /// - /// Gets the number of actual -s inside - /// - public int Count { get; } - - /// - /// Gets the rented buffer. - /// - public DecodedBlock[] Buffer { get; private set; } - - /// - /// Returns the rented buffer to the pool. - /// - public void Dispose() - { - if (this.Buffer != null) - { - ArrayPool.Return(this.Buffer, true); - this.Buffer = null; - } - } - } -} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs index 0acee3a10..0ce233739 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockProcessor.cs @@ -9,7 +9,7 @@ namespace ImageSharp.Formats.Jpg using System.Runtime.InteropServices; /// - /// Encapsulates the implementation of processing "raw" -s into Jpeg image channels. + /// Encapsulates the implementation of processing "raw" -s into Jpeg image channels. /// [StructLayout(LayoutKind.Sequential)] internal unsafe struct JpegBlockProcessor @@ -47,10 +47,10 @@ namespace ImageSharp.Formats.Jpg /// The instance public void ProcessAllBlocks(JpegDecoderCore decoder) { - DecodedBlockArray blockArray = decoder.DecodedBlocks[this.componentIndex]; - for (int i = 0; i < blockArray.Count; i++) + Buffer blockArray = decoder.DecodedBlocks[this.componentIndex]; + for (int i = 0; i < blockArray.Length; i++) { - this.ProcessBlockColors(decoder, ref blockArray.Buffer[i]); + this.ProcessBlockColors(decoder, ref blockArray[i]); } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs index c6362a871..2a9b0c6b2 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegScanDecoder.cs @@ -171,7 +171,7 @@ namespace ImageSharp.Formats.Jpg // Take an existing block (required when progressive): int blockIndex = this.GetBlockIndex(decoder); - this.data.Block = decoder.DecodedBlocks[this.ComponentIndex].Buffer[blockIndex].Block; + this.data.Block = decoder.DecodedBlocks[this.ComponentIndex][blockIndex].Block; if (!decoder.InputProcessor.UnexpectedEndOfStreamReached) { @@ -179,8 +179,8 @@ namespace ImageSharp.Formats.Jpg } // Store the decoded block - DecodedBlockArray blocks = decoder.DecodedBlocks[this.ComponentIndex]; - blocks.Buffer[blockIndex].SaveBlock(this.bx, this.by, ref this.data.Block); + Buffer blocks = decoder.DecodedBlocks[this.ComponentIndex]; + blocks[blockIndex].SaveBlock(this.bx, this.by, ref this.data.Block); } // for j diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 22c14ca4e..da519a6ac 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -111,7 +111,7 @@ namespace ImageSharp.Formats this.QuantizationTables = new Block8x8F[MaxTq + 1]; this.Temp = new byte[2 * Block8x8F.ScalarCount]; this.ComponentArray = new Component[MaxComponents]; - this.DecodedBlocks = new DecodedBlockArray[MaxComponents]; + this.DecodedBlocks = new Buffer[MaxComponents]; } /// @@ -125,12 +125,12 @@ namespace ImageSharp.Formats public HuffmanTree[] HuffmanTrees { get; } /// - /// Gets the array of -s storing the "raw" frequency-domain decoded blocks. + /// Gets the array of -s storing the "raw" frequency-domain decoded blocks. /// We need to apply IDCT, dequantiazition and unzigging to transform them into color-space blocks. /// This is done by . /// When ==true, we are touching these blocks multiple times - each time we process a Scan. /// - public DecodedBlockArray[] DecodedBlocks { get; } + public Buffer[] DecodedBlocks { get; } /// /// Gets the quantization tables, in zigzag order. @@ -216,9 +216,9 @@ namespace ImageSharp.Formats this.HuffmanTrees[i].Dispose(); } - foreach (DecodedBlockArray blockArray in this.DecodedBlocks) + foreach (Buffer blockArray in this.DecodedBlocks) { - blockArray.Dispose(); + blockArray?.Dispose(); } this.ycbcrImage?.Dispose(); @@ -1308,7 +1308,7 @@ namespace ImageSharp.Formats { int count = this.TotalMCUCount * this.ComponentArray[i].HorizontalFactor * this.ComponentArray[i].VerticalFactor; - this.DecodedBlocks[i] = new DecodedBlockArray(count); + this.DecodedBlocks[i] = Buffer.CreateClean(count); } } }