Browse Source

Reuse buffer and fix error messaging

pull/413/head
James Jackson-South 8 years ago
parent
commit
ed59e3ad43
  1. 65
      src/ImageSharp/Formats/Png/Zlib/ZlibInflateStream.cs

65
src/ImageSharp/Formats/Png/Zlib/ZlibInflateStream.cs

@ -2,10 +2,8 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Text;
namespace SixLabors.ImageSharp.Formats.Png.Zlib namespace SixLabors.ImageSharp.Formats.Png.Zlib
{ {
@ -14,6 +12,13 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// </summary> /// </summary>
internal sealed class ZlibInflateStream : Stream internal sealed class ZlibInflateStream : Stream
{ {
/// <summary>
/// Used to read the Adler-32 and Crc-32 checksums
/// We don't actually use this for anything so it doesn't
/// have to be threadsafe.
/// </summary>
private static readonly byte[] ChecksumBuffer = new byte[4];
/// <summary> /// <summary>
/// The inner raw memory stream /// The inner raw memory stream
/// </summary> /// </summary>
@ -38,9 +43,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private bool isDisposed; private bool isDisposed;
/// <summary> /// <summary>
/// The read crc data. /// Whether the crc value has been read.
/// </summary> /// </summary>
private byte[] crcread; private bool crcRead;
/// <summary> /// <summary>
/// The current data remaining to be read /// The current data remaining to be read
@ -149,14 +154,12 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.compressedStream.Dispose(); this.compressedStream.Dispose();
this.compressedStream = null; this.compressedStream = null;
if (this.crcread == null) if (!this.crcRead)
{ {
// Consume the trailing 4 bytes // Consume the trailing 4 bytes
this.crcread = new byte[4]; this.innerStream.Read(ChecksumBuffer, 0, 4);
for (int i = 0; i < 4; i++) this.currentDataRemaining -= 4;
{ this.crcRead = true;
this.crcread[i] = (byte)this.innerStream.ReadByte();
}
} }
} }
} }
@ -171,11 +174,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private void InitializeInflateStream() private void InitializeInflateStream()
{ {
// The DICT dictionary identifier identifying the used dictionary.
// The preset dictionary.
bool fdict;
// Read the zlib header : http://tools.ietf.org/html/rfc1950 // Read the zlib header : http://tools.ietf.org/html/rfc1950
// CMF(Compression Method and flags) // CMF(Compression Method and flags)
// This byte is divided into a 4 - bit compression method and a // This byte is divided into a 4 - bit compression method and a
@ -195,30 +193,35 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
return; return;
} }
if ((cmf & 0x0f) != 8) if ((cmf & 0x0F) == 8)
{ {
throw new Exception($"Bad compression method for ZLIB header: cmf={cmf}"); // CINFO is the base-2 logarithm of the LZ77 window size, minus eight.
} int cinfo = (cmf & 0xF0) >> 4;
// CINFO is the base-2 logarithm of the LZ77 window size, minus eight. if (cinfo > 7)
// int cinfo = ((cmf & (0xf0)) >> 8); {
fdict = (flag & 32) != 0; // Values of CINFO above 7 are not allowed in RFC1950.
// CINFO is not defined in this specification for CM not equal to 8.
throw new ImageFormatException($"Invalid window size for ZLIB header: cinfo={cinfo}");
}
}
else
{
throw new ImageFormatException($"Bad method for ZLIB header: cmf={cmf}");
}
// The preset dictionary.
bool fdict = (flag & 32) != 0;
if (fdict) if (fdict)
{ {
// The DICT dictionary identifier identifying the used dictionary. // We don't need this for inflate so simply skip by the next four bytes.
byte[] dictId = new byte[4]; // https://tools.ietf.org/html/rfc1950#page-6
this.innerStream.Read(ChecksumBuffer, 0, 4);
for (int i = 0; i < 4; i++) this.currentDataRemaining -= 4;
{
// We consume but don't use this.
dictId[i] = (byte)this.innerStream.ReadByte();
this.currentDataRemaining--;
}
} }
// Initialize the deflate Stream. // Initialize the deflate Stream.
this.compressedStream = new DeflateStream(this, CompressionMode.Decompress, true); this.compressedStream = new DeflateStream(this, CompressionMode.Decompress, true);
} }
} }
} }
Loading…
Cancel
Save