Skip to content

Commit f6b8383

Browse files
Update PngDecoderCore.cs
1 parent a63bf58 commit f6b8383

File tree

1 file changed

+24
-29
lines changed

1 file changed

+24
-29
lines changed

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
3838
private readonly bool ignoreMetadata;
3939

4040
/// <summary>
41-
/// Gets or sets a value indicating whether to read the header and trns chunks only.
41+
/// Gets or sets a value indicating whether to read the IHDR and tRNS chunks only.
4242
/// </summary>
4343
private readonly bool colorMetadataOnly;
4444

@@ -82,16 +82,6 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
8282
/// </summary>
8383
private byte[] paletteAlpha;
8484

85-
/// <summary>
86-
/// A value indicating whether the header chunk has been reached.
87-
/// </summary>
88-
private bool isHeaderChunkReached;
89-
90-
/// <summary>
91-
/// A value indicating whether the end chunk has been reached.
92-
/// </summary>
93-
private bool isEndChunkReached;
94-
9585
/// <summary>
9686
/// Previous scanline processed.
9787
/// </summary>
@@ -161,7 +151,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
161151
Image<TPixel> image = null;
162152
try
163153
{
164-
while (!this.isEndChunkReached && this.TryReadChunk(out PngChunk chunk))
154+
while (this.TryReadChunk(out PngChunk chunk))
165155
{
166156
try
167157
{
@@ -215,8 +205,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
215205

216206
break;
217207
case PngChunkType.End:
218-
this.isEndChunkReached = true;
219-
break;
208+
goto EOF;
220209
case PngChunkType.ProprietaryApple:
221210
PngThrowHelper.ThrowInvalidChunkType("Proprietary Apple PNG detected! This PNG file is not conform to the specification and cannot be decoded.");
222211
break;
@@ -228,6 +217,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
228217
}
229218
}
230219

220+
EOF:
231221
if (image is null)
232222
{
233223
PngThrowHelper.ThrowNoData();
@@ -251,15 +241,14 @@ public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancella
251241
this.currentStream.Skip(8);
252242
try
253243
{
254-
while (!this.isEndChunkReached && this.TryReadChunk(out PngChunk chunk))
244+
while (this.TryReadChunk(out PngChunk chunk))
255245
{
256246
try
257247
{
258248
switch (chunk.Type)
259249
{
260250
case PngChunkType.Header:
261251
this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan());
262-
this.isHeaderChunkReached = true;
263252
break;
264253
case PngChunkType.Physical:
265254
if (this.colorMetadataOnly)
@@ -280,6 +269,13 @@ public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancella
280269
this.ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
281270
break;
282271
case PngChunkType.Data:
272+
273+
// Spec says tRNS must be before IDAT so safe to exit.
274+
if (this.colorMetadataOnly)
275+
{
276+
goto EOF;
277+
}
278+
283279
this.SkipChunkDataAndCrc(chunk);
284280
break;
285281
case PngChunkType.Transparency:
@@ -288,10 +284,9 @@ public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancella
288284
this.paletteAlpha = alpha;
289285
this.AssignTransparentMarkers(alpha, pngMetadata);
290286

291-
if (this.colorMetadataOnly && this.isHeaderChunkReached)
287+
if (this.colorMetadataOnly)
292288
{
293-
// Quick exit
294-
this.isEndChunkReached = true;
289+
goto EOF;
295290
}
296291

297292
break;
@@ -338,28 +333,28 @@ public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancella
338333

339334
break;
340335
case PngChunkType.End:
341-
this.isEndChunkReached = true;
342-
break;
336+
goto EOF;
343337
}
344338
}
345339
finally
346340
{
347341
chunk.Data?.Dispose(); // Data is rented in ReadChunkData()
348342
}
349343
}
344+
345+
EOF:
346+
if (this.header.Width == 0 && this.header.Height == 0)
347+
{
348+
PngThrowHelper.ThrowNoHeader();
349+
}
350+
351+
return new ImageInfo(new PixelTypeInfo(this.CalculateBitsPerPixel()), this.header.Width, this.header.Height, metadata);
350352
}
351353
finally
352354
{
353355
this.scanline?.Dispose();
354356
this.previousScanline?.Dispose();
355357
}
356-
357-
if (this.header.Width == 0 && this.header.Height == 0)
358-
{
359-
PngThrowHelper.ThrowNoHeader();
360-
}
361-
362-
return new ImageInfo(new PixelTypeInfo(this.CalculateBitsPerPixel()), this.header.Width, this.header.Height, metadata);
363358
}
364359

365360
/// <summary>
@@ -1212,7 +1207,7 @@ private bool TryReadChunk(out PngChunk chunk)
12121207
PngChunkType type = this.ReadChunkType();
12131208

12141209
// NOTE: Reading the Data chunk is the responsible of the caller
1215-
// If we're reading color metadata only we're only interested in the Header and Transparancy chunks.
1210+
// If we're reading color metadata only we're only interested in the IHDR and tRNS chunks.
12161211
// We can skip all other chunk data in the stream for better performance.
12171212
if (type == PngChunkType.Data || (this.colorMetadataOnly && type != PngChunkType.Header && type != PngChunkType.Transparency))
12181213
{

0 commit comments

Comments
 (0)