Browse Source

Merge 73a9278a82 into 5a0a74fecc

pull/3024/merge
Stefan Nikolei 2 days ago
committed by GitHub
parent
commit
d508af1261
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      src/ImageSharp/Formats/Png/Chunks/PngHeader.cs
  2. 15
      src/ImageSharp/Formats/Png/PngChunk.cs
  3. 52
      src/ImageSharp/Formats/Png/PngDecoderCore.cs

3
src/ImageSharp/Formats/Png/Chunks/PngHeader.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Buffers.Binary; using System.Buffers.Binary;
@ -88,7 +87,7 @@ internal readonly struct PngHeader
/// </exception> /// </exception>
public void Validate() public void Validate()
{ {
if (!PngConstants.ColorTypes.TryGetValue(this.ColorType, out byte[] supportedBitDepths)) if (!PngConstants.ColorTypes.TryGetValue(this.ColorType, out byte[]? supportedBitDepths))
{ {
throw new NotSupportedException($"Invalid or unsupported color type. Was '{this.ColorType}'."); throw new NotSupportedException($"Invalid or unsupported color type. Was '{this.ColorType}'.");
} }

15
src/ImageSharp/Formats/Png/PngChunk.cs

@ -1,8 +1,8 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Buffers; using System.Buffers;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Png; namespace SixLabors.ImageSharp.Formats.Png;
@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Formats.Png;
/// </summary> /// </summary>
internal readonly struct PngChunk internal readonly struct PngChunk
{ {
public PngChunk(int length, PngChunkType type, IMemoryOwner<byte> data = null) public PngChunk(int length, PngChunkType type, IMemoryOwner<byte>? data = null)
{ {
this.Length = length; this.Length = length;
this.Type = type; this.Type = type;
@ -36,7 +36,16 @@ internal readonly struct PngChunk
/// Gets the data bytes appropriate to the chunk type, if any. /// Gets the data bytes appropriate to the chunk type, if any.
/// This field can be of zero length or null. /// This field can be of zero length or null.
/// </summary> /// </summary>
public IMemoryOwner<byte> Data { get; } public IMemoryOwner<byte>? Data { get; }
public ReadOnlySpan<byte> DataSpan
{
get
{
DebugGuard.NotNull(this.Data);
return this.Data.GetSpan();
}
}
/// <summary> /// <summary>
/// Gets a value indicating whether the given chunk is critical to decoding /// Gets a value indicating whether the given chunk is critical to decoding

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

@ -202,24 +202,24 @@ internal sealed class PngDecoderCore : ImageDecoderCore
PngThrowHelper.ThrowInvalidHeader(); PngThrowHelper.ThrowInvalidHeader();
} }
this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan()); this.ReadHeaderChunk(pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.AnimationControl: case PngChunkType.AnimationControl:
this.ReadAnimationControlChunk(pngMetadata, chunk.Data.GetSpan()); this.ReadAnimationControlChunk(pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.Physical: case PngChunkType.Physical:
ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); ReadPhysicalChunk(metadata, chunk.DataSpan);
break; break;
case PngChunkType.Gamma: case PngChunkType.Gamma:
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); ReadGammaChunk(pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.Cicp: case PngChunkType.Cicp:
ReadCicpChunk(metadata, chunk.Data.GetSpan()); ReadCicpChunk(metadata, chunk.DataSpan);
break; break;
case PngChunkType.FrameControl: case PngChunkType.FrameControl:
frameCount++; frameCount++;
currentFrame = null; currentFrame = null;
currentFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan()); currentFrameControl = this.ReadFrameControlChunk(chunk.DataSpan);
break; break;
case PngChunkType.FrameData: case PngChunkType.FrameData:
{ {
@ -293,32 +293,32 @@ internal sealed class PngDecoderCore : ImageDecoderCore
} }
case PngChunkType.Palette: case PngChunkType.Palette:
this.palette = chunk.Data.GetSpan().ToArray(); this.palette = chunk.DataSpan.ToArray();
break; break;
case PngChunkType.Transparency: case PngChunkType.Transparency:
this.paletteAlpha = chunk.Data.GetSpan().ToArray(); this.paletteAlpha = chunk.DataSpan.ToArray();
this.AssignTransparentMarkers(this.paletteAlpha, pngMetadata); this.AssignTransparentMarkers(this.paletteAlpha, pngMetadata);
break; break;
case PngChunkType.Text: case PngChunkType.Text:
this.ReadTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); this.ReadTextChunk(metadata, pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.CompressedText: case PngChunkType.CompressedText:
this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.InternationalText: case PngChunkType.InternationalText:
this.ReadInternationalTextChunk(metadata, chunk.Data.GetSpan()); this.ReadInternationalTextChunk(metadata, chunk.DataSpan);
break; break;
case PngChunkType.Exif: case PngChunkType.Exif:
if (!this.skipMetadata) if (!this.skipMetadata)
{ {
byte[] exifData = new byte[chunk.Length]; byte[] exifData = new byte[chunk.Length];
chunk.Data.GetSpan().CopyTo(exifData); chunk.DataSpan.CopyTo(exifData);
MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true);
} }
break; break;
case PngChunkType.EmbeddedColorProfile: case PngChunkType.EmbeddedColorProfile:
this.ReadColorProfileChunk(metadata, chunk.Data.GetSpan()); this.ReadColorProfileChunk(metadata, chunk.DataSpan);
break; break;
case PngChunkType.End: case PngChunkType.End:
goto EOF; goto EOF;
@ -377,10 +377,10 @@ internal sealed class PngDecoderCore : ImageDecoderCore
switch (chunk.Type) switch (chunk.Type)
{ {
case PngChunkType.Header: case PngChunkType.Header:
this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan()); this.ReadHeaderChunk(pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.AnimationControl: case PngChunkType.AnimationControl:
this.ReadAnimationControlChunk(pngMetadata, chunk.Data.GetSpan()); this.ReadAnimationControlChunk(pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.Physical: case PngChunkType.Physical:
if (this.colorMetadataOnly) if (this.colorMetadataOnly)
@ -389,7 +389,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
} }
ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); ReadPhysicalChunk(metadata, chunk.DataSpan);
break; break;
case PngChunkType.Gamma: case PngChunkType.Gamma:
if (this.colorMetadataOnly) if (this.colorMetadataOnly)
@ -398,7 +398,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
} }
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); ReadGammaChunk(pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.Cicp: case PngChunkType.Cicp:
if (this.colorMetadataOnly) if (this.colorMetadataOnly)
@ -407,7 +407,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
} }
ReadCicpChunk(metadata, chunk.Data.GetSpan()); ReadCicpChunk(metadata, chunk.DataSpan);
break; break;
case PngChunkType.FrameControl: case PngChunkType.FrameControl:
++frameCount; ++frameCount;
@ -416,7 +416,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
} }
currentFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan()); currentFrameControl = this.ReadFrameControlChunk(chunk.DataSpan);
break; break;
case PngChunkType.FrameData: case PngChunkType.FrameData:
@ -467,11 +467,11 @@ internal sealed class PngDecoderCore : ImageDecoderCore
this.SkipChunkDataAndCrc(chunk); this.SkipChunkDataAndCrc(chunk);
break; break;
case PngChunkType.Palette: case PngChunkType.Palette:
this.palette = chunk.Data.GetSpan().ToArray(); this.palette = chunk.DataSpan.ToArray();
break; break;
case PngChunkType.Transparency: case PngChunkType.Transparency:
this.paletteAlpha = chunk.Data.GetSpan().ToArray(); this.paletteAlpha = chunk.DataSpan.ToArray();
this.AssignTransparentMarkers(this.paletteAlpha, pngMetadata); this.AssignTransparentMarkers(this.paletteAlpha, pngMetadata);
// Spec says tRNS must be after PLTE so safe to exit. // Spec says tRNS must be after PLTE so safe to exit.
@ -488,7 +488,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
} }
this.ReadTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); this.ReadTextChunk(metadata, pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.CompressedText: case PngChunkType.CompressedText:
if (this.colorMetadataOnly) if (this.colorMetadataOnly)
@ -497,7 +497,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
} }
this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.DataSpan);
break; break;
case PngChunkType.InternationalText: case PngChunkType.InternationalText:
if (this.colorMetadataOnly) if (this.colorMetadataOnly)
@ -506,7 +506,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
} }
this.ReadInternationalTextChunk(metadata, chunk.Data.GetSpan()); this.ReadInternationalTextChunk(metadata, chunk.DataSpan);
break; break;
case PngChunkType.Exif: case PngChunkType.Exif:
if (this.colorMetadataOnly) if (this.colorMetadataOnly)
@ -518,7 +518,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
if (!this.skipMetadata) if (!this.skipMetadata)
{ {
byte[] exifData = new byte[chunk.Length]; byte[] exifData = new byte[chunk.Length];
chunk.Data.GetSpan().CopyTo(exifData); chunk.DataSpan.CopyTo(exifData);
MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true);
} }
@ -2355,7 +2355,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
this.crc32.Reset(); this.crc32.Reset();
this.crc32.Append(chunkType); this.crc32.Append(chunkType);
this.crc32.Append(chunk.Data.GetSpan()); this.crc32.Append(chunk.DataSpan);
if (this.crc32.GetCurrentHashAsUInt32() != inputCrc) if (this.crc32.GetCurrentHashAsUInt32() != inputCrc)
{ {

Loading…
Cancel
Save