diff --git a/src/ImageSharp/Common/Extensions/ByteExtensions.cs b/src/ImageSharp/Common/Extensions/ByteExtensions.cs
index 89cfe69742..cca0140736 100644
--- a/src/ImageSharp/Common/Extensions/ByteExtensions.cs
+++ b/src/ImageSharp/Common/Extensions/ByteExtensions.cs
@@ -24,7 +24,7 @@ namespace ImageSharp
public static byte[] ToArrayByBitsLength(this byte[] source, int bits)
{
Guard.NotNull(source, nameof(source));
- Guard.MustBeGreaterThan(bits, 0, "bits");
+ Guard.MustBeGreaterThan(bits, 0, nameof(bits));
byte[] result;
diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
index ddcce0b4d0..6cf5c6cdb4 100644
--- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
@@ -17,7 +17,6 @@ namespace ImageSharp.Formats
///
/// The scanline to decode
/// The bytes per pixel.
- /// The
public static void Decode(byte[] scanline, int bytesPerPixel)
{
// Sub(x) + Raw(x-bpp)
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index f8567e45f0..a5fd051b38 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -132,39 +132,49 @@ namespace ImageSharp.Formats
throw new ImageFormatException("Image does not end with end chunk.");
}
- switch (currentChunk.Type)
+ try
{
- case PngChunkTypes.Header:
- this.ReadHeaderChunk(currentChunk.Data);
- this.ValidateHeader();
- break;
- case PngChunkTypes.Physical:
- this.ReadPhysicalChunk(currentImage, currentChunk.Data);
- break;
- case PngChunkTypes.Data:
- dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length);
- break;
- case PngChunkTypes.Palette:
- this.palette = currentChunk.Data;
- image.Quality = this.palette.Length / 3;
- break;
- case PngChunkTypes.PaletteAlpha:
- this.paletteAlpha = currentChunk.Data;
- break;
- case PngChunkTypes.Text:
- this.ReadTextChunk(currentImage, currentChunk.Data);
- break;
- case PngChunkTypes.End:
- isEndChunkReached = true;
- break;
+ switch (currentChunk.Type)
+ {
+ case PngChunkTypes.Header:
+ this.ReadHeaderChunk(currentChunk.Data);
+ this.ValidateHeader();
+ break;
+ case PngChunkTypes.Physical:
+ this.ReadPhysicalChunk(currentImage, currentChunk.Data);
+ break;
+ case PngChunkTypes.Data:
+ dataStream.Write(currentChunk.Data, 0, currentChunk.Length);
+ break;
+ case PngChunkTypes.Palette:
+ byte[] pal = new byte[currentChunk.Length];
+ Buffer.BlockCopy(currentChunk.Data, 0, pal, 0, currentChunk.Length);
+ this.palette = pal;
+ image.Quality = pal.Length / 3;
+ break;
+ case PngChunkTypes.PaletteAlpha:
+ byte[] alpha = new byte[currentChunk.Length];
+ Buffer.BlockCopy(currentChunk.Data, 0, alpha, 0, currentChunk.Length);
+ this.paletteAlpha = alpha;
+ break;
+ case PngChunkTypes.Text:
+ this.ReadTextChunk(currentImage, currentChunk.Data, currentChunk.Length);
+ break;
+ case PngChunkTypes.End:
+ isEndChunkReached = true;
+ break;
+ }
+ }
+ finally
+ {
+ // Data is rented in ReadChunkData()
+ ArrayPool.Shared.Return(currentChunk.Data);
}
}
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}'");
+ 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}'");
}
image.InitPixels(this.header.Width, this.header.Height);
@@ -396,6 +406,10 @@ namespace ImageSharp.Formats
byte b = this.palette[pixelOffset + 2];
color.PackFromBytes(r, g, b, a);
}
+ else
+ {
+ color.PackFromBytes(0, 0, 0, 0);
+ }
pixels[x, row] = color;
}
@@ -460,13 +474,14 @@ namespace ImageSharp.Formats
/// The packed format. uint, long, float.
/// The image to decode to.
/// The containing data.
- private void ReadTextChunk(Image image, byte[] data)
+ /// The maximum length to read.
+ private void ReadTextChunk(Image image, byte[] data, int length)
where TColor : struct, IPackedPixel
where TPacked : struct
{
int zeroIndex = 0;
- for (int i = 0; i < data.Length; i++)
+ for (int i = 0; i < length; i++)
{
if (data[i] == 0)
{
@@ -476,7 +491,7 @@ namespace ImageSharp.Formats
}
string name = Encoding.Unicode.GetString(data, 0, zeroIndex);
- string value = Encoding.Unicode.GetString(data, zeroIndex + 1, data.Length - zeroIndex - 1);
+ string value = Encoding.Unicode.GetString(data, zeroIndex + 1, length - zeroIndex - 1);
image.Properties.Add(new ImageProperty(name, value));
}
@@ -577,7 +592,7 @@ namespace ImageSharp.Formats
Crc32 crc = new Crc32();
crc.Update(this.chunkTypeBuffer);
- crc.Update(chunk.Data);
+ crc.Update(chunk.Data, 0, chunk.Length);
if (crc.Value != chunk.Crc)
{
@@ -591,8 +606,8 @@ namespace ImageSharp.Formats
/// The chunk.
private void ReadChunkData(PngChunk chunk)
{
- // TODO: It might be possible to rent this but that could also lead to issues assigning the data to various properties
- chunk.Data = new byte[chunk.Length];
+ // We rent the buffer here to return it afterwards in Decode()
+ chunk.Data = ArrayPool.Shared.Rent(chunk.Length);
this.currentStream.Read(chunk.Data, 0, chunk.Length);
}
@@ -645,4 +660,4 @@ namespace ImageSharp.Formats
chunk.Length = BitConverter.ToInt32(this.chunkLengthBuffer, 0);
}
}
-}
+}
\ No newline at end of file