diff --git a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
index 7a94ee32b..de494d42d 100644
--- a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
@@ -19,14 +19,15 @@ namespace ImageSharp.Formats
///
/// The scanline to decode
/// The previous scanline.
+ /// The number of bytes per scanline
/// The bytes per pixel.
- public static void Decode(byte[] scanline, byte[] previousScanline, int bytesPerPixel)
+ public static void Decode(byte[] scanline, byte[] previousScanline, int bytesPerScanline, int bytesPerPixel)
{
// Average(x) + floor((Raw(x-bpp)+Prior(x))/2)
fixed (byte* scan = scanline)
fixed (byte* prev = previousScanline)
{
- for (int x = 1; x < scanline.Length; x++)
+ for (int x = 1; x < bytesPerScanline; x++)
{
byte left = (x - bytesPerPixel < 1) ? (byte)0 : scan[x - bytesPerPixel];
byte above = prev[x];
diff --git a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
index f257641e9..323611fbc 100644
--- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
@@ -20,14 +20,15 @@ namespace ImageSharp.Formats
///
/// The scanline to decode
/// The previous scanline.
+ /// The number of bytes per scanline
/// The bytes per pixel.
- public static void Decode(byte[] scanline, byte[] previousScanline, int bytesPerPixel)
+ public static void Decode(byte[] scanline, byte[] previousScanline, int bytesPerScanline, int bytesPerPixel)
{
// Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp))
fixed (byte* scan = scanline)
fixed (byte* prev = previousScanline)
{
- for (int x = 1; x < scanline.Length; x++)
+ for (int x = 1; x < bytesPerScanline; x++)
{
byte left = (x - bytesPerPixel < 1) ? (byte)0 : scan[x - bytesPerPixel];
byte above = prev[x];
diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
index a098a242c..65e86f4f1 100644
--- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
@@ -16,13 +16,14 @@ namespace ImageSharp.Formats
/// Decodes the scanline
///
/// The scanline to decode
+ /// The number of bytes per scanline
/// The bytes per pixel.
- public static void Decode(byte[] scanline, int bytesPerPixel)
+ public static void Decode(byte[] scanline, int bytesPerScanline, int bytesPerPixel)
{
// Sub(x) + Raw(x-bpp)
fixed (byte* scan = scanline)
{
- for (int x = 1; x < scanline.Length; x++)
+ for (int x = 1; x < bytesPerScanline; x++)
{
byte priorRawByte = (x - bytesPerPixel < 1) ? (byte)0 : scan[x - bytesPerPixel];
scan[x] = (byte)((scan[x] + priorRawByte) % 256);
diff --git a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
index 9b8d78e81..036862ddc 100644
--- a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
@@ -17,13 +17,14 @@ namespace ImageSharp.Formats
///
/// The scanline to decode
/// The previous scanline.
- public static void Decode(byte[] scanline, byte[] previousScanline)
+ /// The number of bytes per scanline
+ public static void Decode(byte[] scanline, byte[] previousScanline, int bytesPerScanline)
{
// Up(x) + Prior(x)
fixed (byte* scan = scanline)
fixed (byte* prev = previousScanline)
{
- for (int x = 1; x < scanline.Length; x++)
+ for (int x = 1; x < bytesPerScanline; x++)
{
byte above = prev[x];
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 07761ae90..91578aede 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -197,11 +197,12 @@ namespace ImageSharp.Formats
/// by a the specified number of bits.
///
/// The bytes to convert from. Cannot be null.
+ /// The number of bytes per scanline
/// The number of bits per value.
/// The resulting array. Is never null.
/// is null.
/// is less than or equals than zero.
- private static byte[] ToArrayByBitsLength(byte[] source, int bits)
+ private static byte[] ToArrayByBitsLength(byte[] source, int bytesPerScanline, int bits)
{
Guard.NotNull(source, nameof(source));
Guard.MustBeGreaterThan(bits, 0, nameof(bits));
@@ -210,12 +211,12 @@ namespace ImageSharp.Formats
if (bits < 8)
{
- result = new byte[source.Length * 8 / bits];
+ result = new byte[bytesPerScanline * 8 / bits];
int mask = 0xFF >> (8 - bits);
int resultOffset = 0;
// ReSharper disable once ForCanBeConvertedToForeach
- for (int i = 0; i < source.Length; i++)
+ for (int i = 0; i < bytesPerScanline; i++)
{
byte b = source[i];
for (int shift = 0; shift < 8; shift += bits)
@@ -338,6 +339,9 @@ namespace ImageSharp.Formats
byte[] previousScanline = ArrayPool.Shared.Rent(this.bytesPerScanline);
byte[] scanline = ArrayPool.Shared.Rent(this.bytesPerScanline);
+ // Zero out the previousScanline, because the bytes that are rented from the arraypool may not be zero.
+ Array.Clear(previousScanline, 0, this.bytesPerScanline);
+
try
{
for (int y = 0; y < this.header.Height; y++)
@@ -356,25 +360,25 @@ namespace ImageSharp.Formats
case FilterType.Sub:
- SubFilter.Decode(scanline, this.bytesPerPixel);
+ SubFilter.Decode(scanline, this.bytesPerScanline, this.bytesPerPixel);
break;
case FilterType.Up:
- UpFilter.Decode(scanline, previousScanline);
+ UpFilter.Decode(scanline, previousScanline, this.bytesPerScanline);
break;
case FilterType.Average:
- AverageFilter.Decode(scanline, previousScanline, this.bytesPerPixel);
+ AverageFilter.Decode(scanline, previousScanline, this.bytesPerScanline, this.bytesPerPixel);
break;
case FilterType.Paeth:
- PaethFilter.Decode(scanline, previousScanline, this.bytesPerPixel);
+ PaethFilter.Decode(scanline, previousScanline, this.bytesPerScanline, this.bytesPerPixel);
break;
@@ -411,7 +415,7 @@ namespace ImageSharp.Formats
{
case PngColorType.Grayscale:
int factor = 255 / ((int)Math.Pow(2, this.header.BitDepth) - 1);
- byte[] newScanline1 = ToArrayByBitsLength(defilteredScanline, this.header.BitDepth);
+ byte[] newScanline1 = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth);
for (int x = 0; x < this.header.Width; x++)
{
int offset = 1 + ((x + 1) * this.bytesPerPixel);
@@ -439,7 +443,7 @@ namespace ImageSharp.Formats
case PngColorType.Palette:
- byte[] newScanline = ToArrayByBitsLength(defilteredScanline, this.header.BitDepth);
+ byte[] newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth);
if (this.paletteAlpha != null && this.paletteAlpha.Length > 0)
{