Browse Source

ArrayPool

af/merge-core
Anton Firszov 9 years ago
parent
commit
00c2b59732
  1. 43
      src/ImageSharp46/Formats/Jpg/Components/Block.cs
  2. 4
      src/ImageSharp46/Formats/Jpg/Components/IDCT.cs
  3. 6
      src/ImageSharp46/Formats/Jpg/JpegDecoder.cs
  4. 35
      src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs
  5. 37
      src/ImageSharp46/Formats/Jpg/JpegEncoderCore.cs
  6. 3
      tests/ImageSharp.Tests46/JpegSandbox.cs

43
src/ImageSharp46/Formats/Jpg/Components/Block.cs

@ -3,6 +3,7 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
using System;
using System.Buffers;
namespace ImageSharp.Formats
@ -10,8 +11,10 @@ namespace ImageSharp.Formats
/// <summary>
/// Represents an 8x8 block of coefficients to transform and encode.
/// </summary>
internal struct Block
internal struct Block : IDisposable
{
private static ArrayPool<int> IntArrayPool => ArrayPool<int>.Shared; /*= ArrayPool<int>.Create(BlockSize, 50);*/
/// <summary>
/// Gets the size of the block.
/// </summary>
@ -32,7 +35,25 @@ namespace ImageSharp.Formats
public void Init()
{
this.Data = new int[BlockSize];
//this.Data = new int[BlockSize];
this.Data = IntArrayPool.Rent(BlockSize);
}
public static Block Create()
{
var block = new Block();
block.Init();
return block;
}
public static Block[] CreateArray(int size)
{
Block[] result = new Block[size];
for (int i = 0; i < result.Length; i++)
{
result[i].Init();
}
return result;
}
public bool IsInitialized => this.Data != null;
@ -49,5 +70,23 @@ namespace ImageSharp.Formats
get { return this.Data[index]; }
set { this.Data[index] = value; }
}
// TODO: Refactor Block.Dispose() callers to always use 'using' or 'finally' statement!
public void Dispose()
{
if (Data != null)
{
IntArrayPool.Return(Data, true);
Data = null;
}
}
public static void DisposeAll(Block[] blocks)
{
for (int i = 0; i < blocks.Length; i++)
{
blocks[i].Dispose();
}
}
}
}

4
src/ImageSharp46/Formats/Jpg/Components/IDCT.cs

@ -41,10 +41,8 @@ namespace ImageSharp.Formats
/// ASSP, Vol. ASSP- 32, pp. 803-816, Aug. 1984.
/// </summary>
/// <param name="src">The source block of coefficients</param>
public static void Transform(ref Block block)
public static void Transform(ref Block src)
{
var src = block.Data;
// Horizontal 1-D IDCT.
for (int y = 0; y < 8; y++)
{

6
src/ImageSharp46/Formats/Jpg/JpegDecoder.cs

@ -83,8 +83,10 @@ namespace ImageSharp.Formats
Guard.NotNull(image, "image");
Guard.NotNull(stream, "stream");
JpegDecoderCore decoder = new JpegDecoderCore();
decoder.Decode(image, stream, false);
using (JpegDecoderCore decoder = new JpegDecoderCore())
{
decoder.Decode(image, stream, false);
}
}
/// <summary>

35
src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs

@ -12,7 +12,7 @@ namespace ImageSharp.Formats
/// <summary>
/// Performs the jpeg decoding operation.
/// </summary>
internal class JpegDecoderCore
internal class JpegDecoderCore : IDisposable
{
/// <summary>
/// The maximum (inclusive) number of bits in a Huffman code.
@ -201,7 +201,7 @@ namespace ImageSharp.Formats
//this.huffmanTrees = new Huffman[MaxTc + 1, MaxTh + 1];
this.huffmanTrees = new Huffman[(MaxTc + 1)*(MaxTh + 1)];
this.quantizationTables = new Block[MaxTq + 1];
this.quantizationTables = Block.CreateArray(MaxTq + 1);
this.temp = new byte[2 * Block.BlockSize];
this.componentArray = new Component[MaxComponents];
this.progCoeffs = new Block[MaxComponents][];
@ -219,11 +219,11 @@ namespace ImageSharp.Formats
}
}
for (int i = 0; i < this.quantizationTables.Length; i++)
{
//this.quantizationTables[i] = new Block();
this.quantizationTables[i].Init();
}
//for (int i = 0; i < this.quantizationTables.Length; i++)
//{
// //this.quantizationTables[i] = new Block();
// this.quantizationTables[i].Init();
//}
//for (int i = 0; i < this.componentArray.Length; i++)
//{
@ -1576,7 +1576,7 @@ namespace ImageSharp.Formats
int compIndex = scan[i].Index;
if (this.progCoeffs[compIndex] == null)
{
this.progCoeffs[compIndex] = new Block[mxx * myy * this.componentArray[compIndex].HorizontalFactor * this.componentArray[compIndex].VerticalFactor];
this.progCoeffs[compIndex] = Block.CreateArray(mxx * myy * this.componentArray[compIndex].HorizontalFactor * this.componentArray[compIndex].VerticalFactor);
for (int j = 0; j < this.progCoeffs[compIndex].Length; j++)
{
@ -1668,11 +1668,13 @@ namespace ImageSharp.Formats
}
else
{
var b = new Block();
b.Init();
var b = Block.Create();
ProcessBlockImpl(ah, ref b, scan, i, zigStart, zigEnd, al, dc, compIndex, @by, mxx, hi,
bx, ref this.quantizationTables[qtIndex]
);
b.Dispose();
}
}
@ -2252,5 +2254,18 @@ namespace ImageSharp.Formats
private class EOFException : Exception
{
}
public void Dispose()
{
Block.DisposeAll(this.quantizationTables);
foreach (Block[] blocks in progCoeffs)
{
if (blocks != null)
{
Block.DisposeAll(blocks);
}
}
}
}
}

37
src/ImageSharp46/Formats/Jpg/JpegEncoderCore.cs

@ -579,7 +579,7 @@ namespace ImageSharp.Formats
/// </summary>
/// <param name="destination">The destination block array</param>
/// <param name="source">The source block array.</param>
private void Scale16X16To8X8(Block destination, Block[] source)
private void Scale16X16To8X8(ref Block destination, Block[] source)
{
for (int i = 0; i < 4; i++)
{
@ -849,9 +849,9 @@ namespace ImageSharp.Formats
where TColor : struct, IPackedPixel<TPacked>
where TPacked : struct
{
Block b = new Block();
Block cb = new Block();
Block cr = new Block();
Block b = Block.Create();
Block cb = Block.Create();
Block cr = Block.Create();
// ReSharper disable once InconsistentNaming
int prevDCY = 0, prevDCCb = 0, prevDCCr = 0;
@ -865,6 +865,9 @@ namespace ImageSharp.Formats
prevDCCr = this.WriteBlock(ref cr, QuantIndex.Chrominance, prevDCCr);
}
}
b.Dispose();
cb.Dispose();
cr.Dispose();
}
/// <summary>
@ -878,22 +881,12 @@ namespace ImageSharp.Formats
where TColor : struct, IPackedPixel<TPacked>
where TPacked : struct
{
Block b = new Block();
Block[] cb = new Block[4];
Block[] cr = new Block[4];
Block b = Block.Create();
Block[] cb = Block.CreateArray(4);
Block[] cr = Block.CreateArray(4);
// ReSharper disable once InconsistentNaming
int prevDCY = 0, prevDCCb = 0, prevDCCr = 0;
for (int i = 0; i < 4; i++)
{
cb[i] = new Block();
}
for (int i = 0; i < 4; i++)
{
cr[i] = new Block();
}
for (int y = 0; y < pixels.Height; y += 16)
{
for (int x = 0; x < pixels.Width; x += 16)
@ -907,12 +900,16 @@ namespace ImageSharp.Formats
prevDCY = this.WriteBlock(ref b, QuantIndex.Luminance, prevDCY);
}
this.Scale16X16To8X8(b, cb);
this.Scale16X16To8X8(ref b, cb);
prevDCCb = this.WriteBlock(ref b, QuantIndex.Chrominance, prevDCCb);
this.Scale16X16To8X8(b, cr);
this.Scale16X16To8X8(ref b, cr);
prevDCCr = this.WriteBlock(ref b, QuantIndex.Chrominance, prevDCCr);
}
}
b.Dispose();
Block.DisposeAll(cb);
Block.DisposeAll(cr);
}
/// <summary>

3
tests/ImageSharp.Tests46/JpegSandbox.cs

@ -68,6 +68,9 @@ namespace ImageSharp.Tests
{
Vector<int> hej = new Vector<int>();
Output.WriteLine(Vector<int>.Count.ToString());
}
}

Loading…
Cancel
Save