Browse Source

Unify PngDecoder buffer

af/merge-core
Jason Nelson 8 years ago
parent
commit
49fb759f29
  1. 51
      src/ImageSharp/Formats/Png/PngDecoderCore.cs

51
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -38,19 +38,9 @@ namespace SixLabors.ImageSharp.Formats.Png
}; };
/// <summary> /// <summary>
/// Reusable buffer for reading chunk types. /// Reusable buffer.
/// </summary> /// </summary>
private readonly byte[] chunkTypeBuffer = new byte[4]; private readonly byte[] buffer = new byte[4];
/// <summary>
/// Reusable buffer for reading chunk lengths.
/// </summary>
private readonly byte[] chunkLengthBuffer = new byte[4];
/// <summary>
/// Reusable buffer for reading crc values.
/// </summary>
private readonly byte[] crcBuffer = new byte[4];
/// <summary> /// <summary>
/// Reusable crc for validating chunks. /// Reusable crc for validating chunks.
@ -1001,7 +991,7 @@ namespace SixLabors.ImageSharp.Formats.Png
return 0; return 0;
} }
this.currentStream.Read(this.crcBuffer, 0, 4); this.currentStream.Read(this.buffer, 0, 4);
if (this.TryReadChunk(out PngChunk chunk)) if (this.TryReadChunk(out PngChunk chunk))
{ {
@ -1086,13 +1076,17 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="chunk">The <see cref="PngChunk"/>.</param> /// <param name="chunk">The <see cref="PngChunk"/>.</param>
private void ValidateChunk(in PngChunk chunk) private void ValidateChunk(in PngChunk chunk)
{ {
Span<byte> chunkType = stackalloc byte[4];
BinaryPrimitives.WriteUInt32BigEndian(chunkType, (uint)chunk.Type);
this.crc.Reset(); this.crc.Reset();
this.crc.Update(this.chunkTypeBuffer); this.crc.Update(chunkType);
this.crc.Update(chunk.Data.GetSpan()); this.crc.Update(chunk.Data.GetSpan());
if (this.crc.Value != chunk.Crc) if (this.crc.Value != chunk.Crc)
{ {
string chunkTypeName = Encoding.UTF8.GetString(this.chunkTypeBuffer, 0, 4); string chunkTypeName = Encoding.UTF8.GetString(chunkType.ToArray(), 0, 4);
throw new ImageFormatException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!"); throw new ImageFormatException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!");
} }
@ -1106,14 +1100,9 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </exception> /// </exception>
private uint ReadChunkCrc() private uint ReadChunkCrc()
{ {
int numBytes = this.currentStream.Read(this.crcBuffer, 0, 4); return this.currentStream.Read(this.buffer, 0, 4) == 4
? BinaryPrimitives.ReadUInt32BigEndian(this.buffer)
if (numBytes >= 1 && numBytes <= 3) : throw new ImageFormatException("Image stream is not valid!");
{
throw new ImageFormatException("Image stream is not valid!");
}
return BinaryPrimitives.ReadUInt32BigEndian(this.crcBuffer);
} }
/// <summary> /// <summary>
@ -1148,22 +1137,22 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </exception> /// </exception>
private PngChunkType ReadChunkType() private PngChunkType ReadChunkType()
{ {
return this.currentStream.Read(this.chunkTypeBuffer, 0, 4) == 4 return this.currentStream.Read(this.buffer, 0, 4) == 4
? (PngChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.chunkTypeBuffer.AsSpan()) ? (PngChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.buffer)
: throw new ImageFormatException("Invalid PNG data."); : throw new ImageFormatException("Invalid PNG data.");
} }
/// <summary> /// <summary>
/// Calculates the length of the given chunk. /// Attempts to read the length of the next chunk.
/// </summary> /// </summary>
/// <exception cref="ImageFormatException"> /// <returns>
/// Thrown if the input stream is not valid. /// Whether the the length was read.
/// </exception> /// </returns>
private bool TryReadChunkLength(out int result) private bool TryReadChunkLength(out int result)
{ {
if (this.currentStream.Read(this.chunkLengthBuffer, 0, 4) == 4) if (this.currentStream.Read(this.buffer, 0, 4) == 4)
{ {
result = BinaryPrimitives.ReadInt32BigEndian(this.chunkLengthBuffer); result = BinaryPrimitives.ReadInt32BigEndian(this.buffer);
return true; return true;
} }

Loading…
Cancel
Save