Browse Source

Remove lists

af/merge-core
James Jackson-South 9 years ago
parent
commit
f055a858e2
  1. 49
      src/ImageSharp/Formats/Png/PngEncoderCore.cs

49
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -322,29 +322,28 @@ namespace ImageSharp.Formats
private byte[] EncodePixelData() private byte[] EncodePixelData()
{ {
// TODO: Use pointers // TODO: Use pointers
List<byte[]> filteredScanlines = new List<byte[]>(); byte[][] filteredScanlines = new byte[this.height][];
byte[] previousScanline = new byte[this.width * this.bytesPerPixel]; byte[] previousScanline = new byte[this.width * this.bytesPerPixel];
int length = 0;
for (int y = 0; y < this.height; y++) for (int y = 0; y < this.height; y++)
{ {
byte[] rawScanline = this.GetRawScanline(y); byte[] rawScanline = this.GetRawScanline(y);
byte[] filteredScanline = this.GetOptimalFilteredScanline(rawScanline, previousScanline, this.bytesPerPixel); byte[] filteredScanline = this.GetOptimalFilteredScanline(rawScanline, previousScanline, this.bytesPerPixel);
length += filteredScanline.Length;
filteredScanlines.Add(filteredScanline); filteredScanlines[y] = filteredScanline;
previousScanline = rawScanline; previousScanline = rawScanline;
} }
// TODO: We should be able to use a byte array when not using interlaced encoding. // Flatten the jagged array
List<byte> result = new List<byte>(); byte[] result = new byte[length];
for (int i = 0; i < this.height; i++)
foreach (byte[] encodedScanline in filteredScanlines)
{ {
result.AddRange(encodedScanline); int len = filteredScanlines[i].Length;
Buffer.BlockCopy(filteredScanlines[i], 0, result, i * len, len);
} }
return result.ToArray(); return result;
} }
/// <summary> /// <summary>
@ -357,32 +356,24 @@ namespace ImageSharp.Formats
/// <returns>The <see cref="T:byte[]"/></returns> /// <returns>The <see cref="T:byte[]"/></returns>
private byte[] GetOptimalFilteredScanline(byte[] rawScanline, byte[] previousScanline, int byteCount) private byte[] GetOptimalFilteredScanline(byte[] rawScanline, byte[] previousScanline, int byteCount)
{ {
List<Tuple<byte[], int>> candidates = new List<Tuple<byte[], int>>(); Tuple<byte[], int>[] candidates = new Tuple<byte[], int>[4];
if (this.PngColorType == PngColorType.Palette) byte[] sub = SubFilter.Encode(rawScanline, byteCount);
{ candidates[0] = new Tuple<byte[], int>(sub, this.CalculateTotalVariation(sub));
byte[] none = NoneFilter.Encode(rawScanline);
candidates.Add(new Tuple<byte[], int>(none, this.CalculateTotalVariation(none)));
}
else
{
byte[] sub = SubFilter.Encode(rawScanline, byteCount);
candidates.Add(new Tuple<byte[], int>(sub, this.CalculateTotalVariation(sub)));
byte[] up = UpFilter.Encode(rawScanline, previousScanline); byte[] up = UpFilter.Encode(rawScanline, previousScanline);
candidates.Add(new Tuple<byte[], int>(up, this.CalculateTotalVariation(up))); candidates[1] = new Tuple<byte[], int>(up, this.CalculateTotalVariation(up));
byte[] average = AverageFilter.Encode(rawScanline, previousScanline, byteCount); byte[] average = AverageFilter.Encode(rawScanline, previousScanline, byteCount);
candidates.Add(new Tuple<byte[], int>(average, this.CalculateTotalVariation(average))); candidates[2] = new Tuple<byte[], int>(average, this.CalculateTotalVariation(average));
byte[] paeth = PaethFilter.Encode(rawScanline, previousScanline, byteCount); byte[] paeth = PaethFilter.Encode(rawScanline, previousScanline, byteCount);
candidates.Add(new Tuple<byte[], int>(paeth, this.CalculateTotalVariation(paeth))); candidates[3] = new Tuple<byte[], int>(paeth, this.CalculateTotalVariation(paeth));
}
int lowestTotalVariation = int.MaxValue; int lowestTotalVariation = int.MaxValue;
int lowestTotalVariationIndex = 0; int lowestTotalVariationIndex = 0;
for (int i = 0; i < candidates.Count; i++) for (int i = 0; i < 4; i++)
{ {
if (candidates[i].Item2 < lowestTotalVariation) if (candidates[i].Item2 < lowestTotalVariation)
{ {

Loading…
Cancel
Save