diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 4a859d5420..73edd55b78 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -470,7 +470,7 @@ namespace ImageSharp.Formats throw new ImageFormatException("Unknown filter type."); } - this.ProcessDefilteredScanline(this.scanline, this.currentRow, pixels); + this.ProcessDefilteredScanline(this.scanline, pixels); Swap(ref this.scanline, ref this.previousScanline); this.currentRow++; @@ -571,12 +571,13 @@ namespace ImageSharp.Formats /// /// The pixel format. /// The de-filtered scanline - /// The current image row. /// The image pixels - private void ProcessDefilteredScanline(byte[] defilteredScanline, int row, PixelAccessor pixels) + private void ProcessDefilteredScanline(byte[] defilteredScanline, PixelAccessor pixels) where TPixel : struct, IPixel { TPixel color = default(TPixel); + BufferSpan pixelBuffer = pixels.GetRowSpan(this.currentRow); + BufferSpan scanlineBuffer = new BufferSpan(defilteredScanline); switch (this.PngColorType) { case PngColorType.Grayscale: @@ -586,7 +587,7 @@ namespace ImageSharp.Formats { byte intensity = (byte)(newScanline1[x] * factor); color.PackFromBytes(intensity, intensity, intensity, 255); - pixels[x, row] = color; + pixels[x, this.currentRow] = color; } break; @@ -601,7 +602,7 @@ namespace ImageSharp.Formats byte alpha = defilteredScanline[offset + this.bytesPerSample]; color.PackFromBytes(intensity, intensity, intensity, alpha); - pixels[x, row] = color; + pixels[x, this.currentRow] = color; } break; @@ -633,7 +634,7 @@ namespace ImageSharp.Formats color.PackFromBytes(0, 0, 0, 0); } - pixels[x, row] = color; + pixels[x, this.currentRow] = color; } } else @@ -648,7 +649,7 @@ namespace ImageSharp.Formats byte b = this.palette[pixelOffset + 2]; color.PackFromBytes(r, g, b, 255); - pixels[x, row] = color; + pixels[x, this.currentRow] = color; } } @@ -665,40 +666,19 @@ namespace ImageSharp.Formats byte b = defilteredScanline[offset + (2 * this.bytesPerSample)]; color.PackFromBytes(r, g, b, 255); - pixels[x, row] = color; + pixels[x, this.currentRow] = color; } break; case PngColorType.RgbWithAlpha: - this.RgbWithAlpha(defilteredScanline, pixels); + BulkPixelOperations.Instance.PackFromXyzwBytes(scanlineBuffer, pixelBuffer, this.header.Width); break; } } - /// - /// Processing the RGB with Alpha is a straight copy - /// - /// The type of pixel - /// The completed scanline - /// The pixel accessor - private unsafe void RgbWithAlpha(byte[] defilteredScanline, PixelAccessor pixels) - where TPixel : struct, IPixel - { - int offset = this.bytesPerSample * 4; - int width = this.header.Width * offset; - int pixelId = this.currentRow * this.header.Width; - Rgba32[] pixelArray = pixels.PixelArray as Rgba32[]; - - fixed (byte* defilteredPointer = defilteredScanline) - fixed (Rgba32* pixelPtr = pixelArray) - { - Unsafe.CopyBlock(pixelPtr + pixelId, defilteredPointer + 1, (uint)(defilteredScanline.Length - 1)); - } - } - /// /// Processes the interlaced de-filtered scanline filling the image pixel data ///