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
///