diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 4ce409035..6f5ea55d9 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -6,11 +6,12 @@ namespace ImageSharp.Formats { using System; + using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; - + /// /// Performs the png decoding operation. /// @@ -111,8 +112,7 @@ namespace ImageSharp.Formats /// Thrown if the image is larger than the maximum allowable size. /// public void Decode(Image image, Stream stream) - where TColor : struct, IPackedPixel - where TPacked : struct + where TColor : struct, IPackedPixel where TPacked : struct { Image currentImage = image; this.currentStream = stream; @@ -161,8 +161,8 @@ namespace ImageSharp.Formats if (this.header.Width > image.MaxWidth || this.header.Height > image.MaxHeight) { throw new ArgumentOutOfRangeException( - $"The input png '{this.header.Width}x{this.header.Height}' is bigger than the " - + $"max allowed size '{image.MaxWidth}x{image.MaxHeight}'"); + $"The input png '{this.header.Width}x{this.header.Height}' is bigger than the " + + $"max allowed size '{image.MaxWidth}x{image.MaxHeight}'"); } image.InitPixels(this.header.Width, this.header.Height); @@ -182,8 +182,7 @@ namespace ImageSharp.Formats /// The image to read to. /// The data containing physical data. private void ReadPhysicalChunk(Image image, byte[] data) - where TColor : struct, IPackedPixel - where TPacked : struct + where TColor : struct, IPackedPixel where TPacked : struct { data.ReverseBytes(0, 4); data.ReverseBytes(4, 4); @@ -244,8 +243,7 @@ namespace ImageSharp.Formats /// The containing data. /// The pixel data. private void ReadScanlines(MemoryStream dataStream, PixelAccessor pixels) - where TColor : struct, IPackedPixel - where TPacked : struct + where TColor : struct, IPackedPixel where TPacked : struct { this.bytesPerPixel = this.CalculateBytesPerPixel(); this.bytesPerScanline = this.CalculateScanlineLength() + 1; @@ -270,60 +268,66 @@ namespace ImageSharp.Formats /// The compressed pixel data stream. /// The image pixel accessor. private void DecodePixelData(Stream compressedStream, PixelAccessor pixels) - where TColor : struct, IPackedPixel - where TPacked : struct + where TColor : struct, IPackedPixel where TPacked : struct { - // TODO: ArrayPool.Shared.Rent(this.bytesPerScanline) - byte[] previousScanline = new byte[this.bytesPerScanline]; - byte[] scanline = new byte[this.bytesPerScanline]; - - for (int y = 0; y < this.header.Height; y++) + byte[] previousScanline = ArrayPool.Shared.Rent(this.bytesPerScanline); + byte[] scanline = ArrayPool.Shared.Rent(this.bytesPerScanline); + + try { - compressedStream.Read(scanline, 0, this.bytesPerScanline); + for (int y = 0; y < this.header.Height; y++) + { + compressedStream.Read(scanline, 0, this.bytesPerScanline); - FilterType filterType = (FilterType)scanline[0]; + FilterType filterType = (FilterType)scanline[0]; - switch (filterType) - { - case FilterType.None: + switch (filterType) + { + case FilterType.None: - NoneFilter.Decode(scanline); + NoneFilter.Decode(scanline); - break; + break; - case FilterType.Sub: + case FilterType.Sub: - SubFilter.Decode(scanline, this.bytesPerPixel); + SubFilter.Decode(scanline, this.bytesPerPixel); - break; + break; - case FilterType.Up: + case FilterType.Up: - UpFilter.Decode(scanline, previousScanline); + UpFilter.Decode(scanline, previousScanline); - break; + break; - case FilterType.Average: + case FilterType.Average: - AverageFilter.Decode(scanline, previousScanline, this.bytesPerPixel); + AverageFilter.Decode(scanline, previousScanline, this.bytesPerPixel); - break; + break; - case FilterType.Paeth: + case FilterType.Paeth: - PaethFilter.Decode(scanline, previousScanline, this.bytesPerPixel); + PaethFilter.Decode(scanline, previousScanline, this.bytesPerPixel); - break; + break; - default: - throw new ImageFormatException("Unknown filter type."); - } + default: + throw new ImageFormatException("Unknown filter type."); + } - this.ProcessDefilteredScanline(scanline, y, pixels); + this.ProcessDefilteredScanline(scanline, y, pixels); - byte[] temp = previousScanline; - previousScanline = scanline; - scanline = temp; + byte[] temp = previousScanline; + previousScanline = scanline; + scanline = temp; + } + } + finally + { + ArrayPool.Shared.Return(previousScanline); + ArrayPool.Shared.Return(scanline); } } @@ -618,10 +622,7 @@ namespace ImageSharp.Formats /// /// Calculates the length of the given chunk. /// - /// he chunk. - /// - /// The representing the chunk length. - /// + /// The chunk. /// /// Thrown if the input stream is not valid. ///