Browse Source

Update PngDecoderCore.cs

pull/1861/head
James Jackson-South 4 years ago
parent
commit
f6b83835ad
  1. 53
      src/ImageSharp/Formats/Png/PngDecoderCore.cs

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

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Formats.Png
private readonly bool ignoreMetadata;
/// <summary>
/// Gets or sets a value indicating whether to read the header and trns chunks only.
/// Gets or sets a value indicating whether to read the IHDR and tRNS chunks only.
/// </summary>
private readonly bool colorMetadataOnly;
@ -82,16 +82,6 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </summary>
private byte[] paletteAlpha;
/// <summary>
/// A value indicating whether the header chunk has been reached.
/// </summary>
private bool isHeaderChunkReached;
/// <summary>
/// A value indicating whether the end chunk has been reached.
/// </summary>
private bool isEndChunkReached;
/// <summary>
/// Previous scanline processed.
/// </summary>
@ -161,7 +151,7 @@ namespace SixLabors.ImageSharp.Formats.Png
Image<TPixel> image = null;
try
{
while (!this.isEndChunkReached && this.TryReadChunk(out PngChunk chunk))
while (this.TryReadChunk(out PngChunk chunk))
{
try
{
@ -215,8 +205,7 @@ namespace SixLabors.ImageSharp.Formats.Png
break;
case PngChunkType.End:
this.isEndChunkReached = true;
break;
goto EOF;
case PngChunkType.ProprietaryApple:
PngThrowHelper.ThrowInvalidChunkType("Proprietary Apple PNG detected! This PNG file is not conform to the specification and cannot be decoded.");
break;
@ -228,6 +217,7 @@ namespace SixLabors.ImageSharp.Formats.Png
}
}
EOF:
if (image is null)
{
PngThrowHelper.ThrowNoData();
@ -251,7 +241,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.currentStream.Skip(8);
try
{
while (!this.isEndChunkReached && this.TryReadChunk(out PngChunk chunk))
while (this.TryReadChunk(out PngChunk chunk))
{
try
{
@ -259,7 +249,6 @@ namespace SixLabors.ImageSharp.Formats.Png
{
case PngChunkType.Header:
this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan());
this.isHeaderChunkReached = true;
break;
case PngChunkType.Physical:
if (this.colorMetadataOnly)
@ -280,6 +269,13 @@ namespace SixLabors.ImageSharp.Formats.Png
this.ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
break;
case PngChunkType.Data:
// Spec says tRNS must be before IDAT so safe to exit.
if (this.colorMetadataOnly)
{
goto EOF;
}
this.SkipChunkDataAndCrc(chunk);
break;
case PngChunkType.Transparency:
@ -288,10 +284,9 @@ namespace SixLabors.ImageSharp.Formats.Png
this.paletteAlpha = alpha;
this.AssignTransparentMarkers(alpha, pngMetadata);
if (this.colorMetadataOnly && this.isHeaderChunkReached)
if (this.colorMetadataOnly)
{
// Quick exit
this.isEndChunkReached = true;
goto EOF;
}
break;
@ -338,8 +333,7 @@ namespace SixLabors.ImageSharp.Formats.Png
break;
case PngChunkType.End:
this.isEndChunkReached = true;
break;
goto EOF;
}
}
finally
@ -347,19 +341,20 @@ namespace SixLabors.ImageSharp.Formats.Png
chunk.Data?.Dispose(); // Data is rented in ReadChunkData()
}
}
EOF:
if (this.header.Width == 0 && this.header.Height == 0)
{
PngThrowHelper.ThrowNoHeader();
}
return new ImageInfo(new PixelTypeInfo(this.CalculateBitsPerPixel()), this.header.Width, this.header.Height, metadata);
}
finally
{
this.scanline?.Dispose();
this.previousScanline?.Dispose();
}
if (this.header.Width == 0 && this.header.Height == 0)
{
PngThrowHelper.ThrowNoHeader();
}
return new ImageInfo(new PixelTypeInfo(this.CalculateBitsPerPixel()), this.header.Width, this.header.Height, metadata);
}
/// <summary>
@ -1212,7 +1207,7 @@ namespace SixLabors.ImageSharp.Formats.Png
PngChunkType type = this.ReadChunkType();
// NOTE: Reading the Data chunk is the responsible of the caller
// If we're reading color metadata only we're only interested in the Header and Transparancy chunks.
// If we're reading color metadata only we're only interested in the IHDR and tRNS chunks.
// We can skip all other chunk data in the stream for better performance.
if (type == PngChunkType.Data || (this.colorMetadataOnly && type != PngChunkType.Header && type != PngChunkType.Transparency))
{

Loading…
Cancel
Save