diff --git a/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegPixelArea.cs b/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegPixelArea.cs index c4168dd1f1..0161542d8e 100644 --- a/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegPixelArea.cs +++ b/src/ImageSharp/Formats/Jpg/Components/Decoder/JpegPixelArea.cs @@ -25,7 +25,7 @@ namespace ImageSharp.Formats.Jpg int size = width * height; //var pixels = ArrayPool.Shared.Rent(size); //Array.Clear(pixels, 0, size); - var pixels = ArrayPoolManager.RentCleanArray(size); + var pixels = CleanPooler.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.ReturnArray(this.Pixels); + CleanPooler.ReturnArray(this.Pixels); this.Pixels = null; } @@ -59,27 +59,7 @@ namespace ImageSharp.Formats.Jpg /// Gets or sets the offset /// public int Offset { get; private set; } - - /// - /// Gets an image made up of a subset of the originals pixels. - /// - /// The x-coordinate of the image. - /// The y-coordinate of the image. - /// The width. - /// The height. - /// - /// The . - /// - public JpegPixelArea Subimage(int x, int y, int width, int height) - { - return new JpegPixelArea - { - Stride = width, - Pixels = this.Pixels, - Offset = (y * this.Stride) + x - }; - } - + /// /// Get the subarea that belongs to the given block indices /// diff --git a/src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs b/src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs index 6ae1d3540b..bd0d58dd28 100644 --- a/src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs +++ b/src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs @@ -5,12 +5,13 @@ namespace ImageSharp.Formats.Jpg { + using System; using System.Buffers; /// /// Represents an image made up of three color components (luminance, blue chroma, red chroma) /// - internal class YCbCrImage + internal class YCbCrImage : IDisposable { /// /// Initializes a new instance of the class. @@ -18,14 +19,16 @@ namespace ImageSharp.Formats.Jpg /// The width. /// The height. /// The ratio. - 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.RentCleanArray(width * height); + this.CbPixels = CleanPooler.RentCleanArray(cw * ch); + this.CrPixels = CleanPooler.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 /// /// Prevents a default instance of the class from being created. /// - private YCbCrImage() + private YCbCrImage(int yOffset, int cOffset) { + this.YOffset = yOffset; + this.COffset = cOffset; } /// @@ -84,38 +89,38 @@ namespace ImageSharp.Formats.Jpg /// /// Gets or sets the luminance components channel. /// - public byte[] YPixels { get; private set; } + public byte[] YPixels { get; } /// /// Gets or sets the blue chroma components channel. /// - public byte[] CbPixels { get; private set; } + public byte[] CbPixels { get; } /// /// Gets or sets the red chroma components channel. /// - public byte[] CrPixels { get; private set; } + public byte[] CrPixels { get; } /// /// Gets or sets the Y slice index delta between vertically adjacent pixels. /// - public int YStride { get; private set; } + public int YStride { get; } /// /// Gets or sets the red and blue chroma slice index delta between vertically adjacent pixels /// that map to separate chroma samples. /// - public int CStride { get; private set; } + public int CStride { get; } /// /// Gets or sets the index of the first luminance element. /// - public int YOffset { get; private set; } + public int YOffset { get; } /// /// Gets or sets the index of the first element of red or blue chroma. /// - public int COffset { get; private set; } + public int COffset { get; } /// /// Gets or sets the horizontal position. @@ -132,32 +137,6 @@ namespace ImageSharp.Formats.Jpg /// public YCbCrSubsampleRatio Ratio { get; set; } - ///// - ///// Gets an image made up of a subset of the originals pixels. - ///// - ///// The x-coordinate of the image. - ///// The y-coordinate of the image. - ///// The width. - ///// The height. - ///// - ///// The . - ///// - //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; - //} - /// /// Returns the offset of the first luminance component at the given row /// @@ -236,5 +215,12 @@ namespace ImageSharp.Formats.Jpg break; } } + + public void Dispose() + { + CleanPooler.ReturnArray(this.YPixels); + CleanPooler.ReturnArray(this.CrPixels); + CleanPooler.ReturnArray(this.CbPixels); + } } } diff --git a/src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs index 2b53ebaaf2..08fcb1018d 100644 --- a/src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs +++ b/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; diff --git a/src/ImageSharp/Formats/Jpg/Utils/ArrayPoolManager.cs b/src/ImageSharp/Formats/Jpg/Utils/CleanPooler.cs similarity index 88% rename from src/ImageSharp/Formats/Jpg/Utils/ArrayPoolManager.cs rename to src/ImageSharp/Formats/Jpg/Utils/CleanPooler.cs index cb3cd0fe5d..a181eeee0a 100644 --- a/src/ImageSharp/Formats/Jpg/Utils/ArrayPoolManager.cs +++ b/src/ImageSharp/Formats/Jpg/Utils/CleanPooler.cs @@ -2,7 +2,7 @@ { using System.Buffers; - internal class ArrayPoolManager + internal class CleanPooler { private static readonly ArrayPool Pool = ArrayPool.Create();