diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index ad5c6a2dc..f0f209a0c 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -2,6 +2,7 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
//
+
namespace ImageSharp.Formats
{
using System;
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index f7e79a52c..b1517299b 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -174,6 +174,7 @@ namespace ImageSharp.Formats
this.WriteHeaderChunk(stream, header);
// Collect the pixel data
+ // TODO: Avoid doing this all at once and try row by row.
if (this.PngColorType == PngColorType.Palette)
{
this.CollectIndexedBytes(image, stream, header);
@@ -328,38 +329,17 @@ namespace ImageSharp.Formats
/// Encodes the pixel data line by line.
/// Each scanline is encoded in the most optimal manner to improve compression.
///
+ /// The row.
+ /// The previous scanline.
+ /// The raw scanline.
+ /// The number of bytes per scanline.
/// The
- private byte[] EncodePixelData()
+ private byte[] EncodePixelRow(int row, byte[] previousScanline, byte[] rawScanline, int bytesPerScanline)
{
- byte[][] filteredScanlines = new byte[this.height][];
- int bytesPerScanline = this.width * this.bytesPerPixel;
- int length = 0;
-
- byte[] previousScanline = new byte[bytesPerScanline];
- byte[] rawScanline = new byte[bytesPerScanline];
-
- for (int y = 0; y < this.height; y++)
- {
- Buffer.BlockCopy(this.pixelData, y * bytesPerScanline, rawScanline, 0, bytesPerScanline);
- byte[] filteredScanline = this.GetOptimalFilteredScanline(rawScanline, previousScanline, bytesPerScanline, this.bytesPerPixel);
- length += filteredScanline.Length;
- filteredScanlines[y] = filteredScanline;
-
- // Do a bit of shuffling;
- byte[] tmp = rawScanline;
- rawScanline = previousScanline;
- previousScanline = tmp;
- }
-
- // Flatten the jagged array
- byte[] result = new byte[length];
- for (int i = 0; i < this.height; i++)
- {
- int len = filteredScanlines[i].Length;
- Buffer.BlockCopy(filteredScanlines[i], 0, result, i * len, len);
- }
+ Buffer.BlockCopy(this.pixelData, row * bytesPerScanline, rawScanline, 0, bytesPerScanline);
+ byte[] filteredScanline = this.GetOptimalFilteredScanline(rawScanline, previousScanline, bytesPerScanline, this.bytesPerPixel);
- return result;
+ return filteredScanline;
}
///
@@ -590,28 +570,39 @@ namespace ImageSharp.Formats
///
/// Writes the pixel information to the stream.
- /// TODO: This is WHACK! We should be able to do this without creating yet another array.
///
/// The stream.
private void WriteDataChunks(Stream stream)
{
- byte[] data = this.EncodePixelData();
+ int bytesPerScanline = this.width * this.bytesPerPixel;
+
+ // TODO: These could be rented
+ byte[] previousScanline = new byte[bytesPerScanline];
+ byte[] rawScanline = new byte[bytesPerScanline];
byte[] buffer;
int bufferLength;
-
MemoryStream memoryStream = null;
try
{
memoryStream = new MemoryStream();
-
using (ZlibDeflateStream deflateStream = new ZlibDeflateStream(memoryStream, this.CompressionLevel))
{
- deflateStream.Write(data, 0, data.Length);
- }
+ for (int y = 0; y < this.height; y++)
+ {
+ byte[] data = this.EncodePixelRow(y, previousScanline, rawScanline, bytesPerScanline);
+ deflateStream.Write(data, 0, data.Length);
+ deflateStream.Flush();
+
+ // Do a bit of shuffling;
+ byte[] tmp = rawScanline;
+ rawScanline = previousScanline;
+ previousScanline = tmp;
+ }
- bufferLength = (int)memoryStream.Length;
- buffer = memoryStream.ToArray();
+ bufferLength = (int)memoryStream.Length;
+ buffer = memoryStream.ToArray();
+ }
}
finally
{
diff --git a/src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs b/src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs
index 3fa61ff56..2deb7dcf0 100644
--- a/src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs
+++ b/src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs
@@ -37,7 +37,9 @@ namespace ImageSharp.Formats
///
private bool isDisposed;
- // The stream responsible for decompressing the input stream.
+ ///
+ /// The stream responsible for compressing the input stream.
+ ///
private DeflateStream deflateStream;
///