Browse Source

pooling YCbCrImage contents

af/merge-core
antonfirsov 9 years ago
parent
commit
e6cd068115
  1. 26
      src/ImageSharp/Formats/Jpg/Components/Decoder/JpegPixelArea.cs
  2. 64
      src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs
  3. 10
      src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs
  4. 2
      src/ImageSharp/Formats/Jpg/Utils/CleanPooler.cs

26
src/ImageSharp/Formats/Jpg/Components/Decoder/JpegPixelArea.cs

@ -25,7 +25,7 @@ namespace ImageSharp.Formats.Jpg
int size = width * height;
//var pixels = ArrayPool<byte>.Shared.Rent(size);
//Array.Clear(pixels, 0, size);
var pixels = ArrayPoolManager<byte>.RentCleanArray(size);
var pixels = CleanPooler<byte>.RentCleanArray(size);
return new JpegPixelArea(pixels, width, 0);
}
@ -39,7 +39,7 @@ namespace ImageSharp.Formats.Jpg
public void ReturnPooled()
{
if (this.Pixels == null) return;
ArrayPoolManager<byte>.ReturnArray(this.Pixels);
CleanPooler<byte>.ReturnArray(this.Pixels);
this.Pixels = null;
}
@ -59,27 +59,7 @@ namespace ImageSharp.Formats.Jpg
/// Gets or sets the offset
/// </summary>
public int Offset { get; private set; }
/// <summary>
/// Gets an image made up of a subset of the originals pixels.
/// </summary>
/// <param name="x">The x-coordinate of the image.</param>
/// <param name="y">The y-coordinate of the image.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns>
/// The <see cref="JpegPixelArea"/>.
/// </returns>
public JpegPixelArea Subimage(int x, int y, int width, int height)
{
return new JpegPixelArea
{
Stride = width,
Pixels = this.Pixels,
Offset = (y * this.Stride) + x
};
}
/// <summary>
/// Get the subarea that belongs to the given block indices
/// </summary>

64
src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs

@ -5,12 +5,13 @@
namespace ImageSharp.Formats.Jpg
{
using System;
using System.Buffers;
/// <summary>
/// Represents an image made up of three color components (luminance, blue chroma, red chroma)
/// </summary>
internal class YCbCrImage
internal class YCbCrImage : IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="YCbCrImage"/> class.
@ -18,14 +19,16 @@ namespace ImageSharp.Formats.Jpg
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="ratio">The ratio.</param>
public YCbCrImage(int width, int height, YCbCrSubsampleRatio ratio)
public YCbCrImage(int width, int height, YCbCrSubsampleRatio ratio, int yOffset, int cOffset)
{
int cw, ch;
YCbCrSize(width, height, ratio, out cw, out ch);
this.YPixels = new byte[width * height];
this.CbPixels = new byte[cw * ch];
this.CrPixels = new byte[cw * ch];
this.YPixels = CleanPooler<byte>.RentCleanArray(width * height);
this.CbPixels = CleanPooler<byte>.RentCleanArray(cw * ch);
this.CrPixels = CleanPooler<byte>.RentCleanArray(cw * ch);
this.Ratio = ratio;
this.YOffset = yOffset;
this.COffset = cOffset;
this.YStride = width;
this.CStride = cw;
this.X = 0;
@ -41,8 +44,10 @@ namespace ImageSharp.Formats.Jpg
/// <summary>
/// Prevents a default instance of the <see cref="YCbCrImage"/> class from being created.
/// </summary>
private YCbCrImage()
private YCbCrImage(int yOffset, int cOffset)
{
this.YOffset = yOffset;
this.COffset = cOffset;
}
/// <summary>
@ -84,38 +89,38 @@ namespace ImageSharp.Formats.Jpg
/// <summary>
/// Gets or sets the luminance components channel.
/// </summary>
public byte[] YPixels { get; private set; }
public byte[] YPixels { get; }
/// <summary>
/// Gets or sets the blue chroma components channel.
/// </summary>
public byte[] CbPixels { get; private set; }
public byte[] CbPixels { get; }
/// <summary>
/// Gets or sets the red chroma components channel.
/// </summary>
public byte[] CrPixels { get; private set; }
public byte[] CrPixels { get; }
/// <summary>
/// Gets or sets the Y slice index delta between vertically adjacent pixels.
/// </summary>
public int YStride { get; private set; }
public int YStride { get; }
/// <summary>
/// Gets or sets the red and blue chroma slice index delta between vertically adjacent pixels
/// that map to separate chroma samples.
/// </summary>
public int CStride { get; private set; }
public int CStride { get; }
/// <summary>
/// Gets or sets the index of the first luminance element.
/// </summary>
public int YOffset { get; private set; }
public int YOffset { get; }
/// <summary>
/// Gets or sets the index of the first element of red or blue chroma.
/// </summary>
public int COffset { get; private set; }
public int COffset { get; }
/// <summary>
/// Gets or sets the horizontal position.
@ -132,32 +137,6 @@ namespace ImageSharp.Formats.Jpg
/// </summary>
public YCbCrSubsampleRatio Ratio { get; set; }
///// <summary>
///// Gets an image made up of a subset of the originals pixels.
///// </summary>
///// <param name="x">The x-coordinate of the image.</param>
///// <param name="y">The y-coordinate of the image.</param>
///// <param name="width">The width.</param>
///// <param name="height">The height.</param>
///// <returns>
///// The <see cref="YCbCrImage"/>.
///// </returns>
//public YCbCrImage Subimage(int x, int y, int width, int height)
//{
// YCbCrImage ret = new YCbCrImage
// {
// YPixels = this.YPixels,
// CbPixels = this.CbPixels,
// CrPixels = this.CrPixels,
// Ratio = this.Ratio,
// YStride = this.YStride,
// CStride = this.CStride,
// YOffset = (y * this.YStride) + x,
// COffset = (y * this.CStride) + x
// };
// return ret;
//}
/// <summary>
/// Returns the offset of the first luminance component at the given row
/// </summary>
@ -236,5 +215,12 @@ namespace ImageSharp.Formats.Jpg
break;
}
}
public void Dispose()
{
CleanPooler<byte>.ReturnArray(this.YPixels);
CleanPooler<byte>.ReturnArray(this.CrPixels);
CleanPooler<byte>.ReturnArray(this.CbPixels);
}
}
}

10
src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs

@ -472,6 +472,7 @@ namespace ImageSharp.Formats
this.huffmanTrees[i].Dispose();
}
this.ycbcrImage?.Dispose();
this.bytes.Dispose();
this.grayImage.ReturnPooled();
this.blackImage.ReturnPooled();
@ -2059,8 +2060,8 @@ namespace ImageSharp.Formats
if (this.componentCount == 1)
{
JpegPixelArea gray = JpegPixelArea.CreatePooled(8 * mxx, 8 * myy);
this.grayImage = gray.Subimage(0, 0, this.imageWidth, this.imageHeight);
this.grayImage = JpegPixelArea.CreatePooled(8 * mxx, 8 * myy);
//this.grayImage = gray.Subimage(0, 0, this.imageWidth, this.imageHeight);
}
else
{
@ -2092,9 +2093,8 @@ namespace ImageSharp.Formats
break;
}
this.ycbcrImage = new YCbCrImage(8 * h0 * mxx, 8 * v0 * myy, ratio);
//this.ycbcrImage = ycbcr.Subimage(0, 0, this.imageWidth, this.imageHeight);
this.ycbcrImage = new YCbCrImage(8 * h0 * mxx, 8 * v0 * myy, ratio, 0, 0);
if (this.componentCount == 4)
{
int h3 = this.componentArray[3].HorizontalFactor;

2
src/ImageSharp/Formats/Jpg/Utils/ArrayPoolManager.cs → src/ImageSharp/Formats/Jpg/Utils/CleanPooler.cs

@ -2,7 +2,7 @@
{
using System.Buffers;
internal class ArrayPoolManager<T>
internal class CleanPooler<T>
{
private static readonly ArrayPool<T> Pool = ArrayPool<T>.Create();
Loading…
Cancel
Save