diff --git a/src/ImageSharp/Formats/Png/Chunks/PngHeader.cs b/src/ImageSharp/Formats/Png/Chunks/PngHeader.cs index 77fb706f60..1ee2d01bde 100644 --- a/src/ImageSharp/Formats/Png/Chunks/PngHeader.cs +++ b/src/ImageSharp/Formats/Png/Chunks/PngHeader.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Buffers.Binary; @@ -88,7 +87,7 @@ internal readonly struct PngHeader /// 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}'."); } diff --git a/src/ImageSharp/Formats/Png/PngChunk.cs b/src/ImageSharp/Formats/Png/PngChunk.cs index bbf1a88bf2..5d0b81f973 100644 --- a/src/ImageSharp/Formats/Png/PngChunk.cs +++ b/src/ImageSharp/Formats/Png/PngChunk.cs @@ -1,8 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Buffers; +using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Png; @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Formats.Png; /// internal readonly struct PngChunk { - public PngChunk(int length, PngChunkType type, IMemoryOwner data = null) + public PngChunk(int length, PngChunkType type, IMemoryOwner? data = null) { this.Length = length; this.Type = type; @@ -36,7 +36,16 @@ internal readonly struct PngChunk /// Gets the data bytes appropriate to the chunk type, if any. /// This field can be of zero length or null. /// - public IMemoryOwner Data { get; } + public IMemoryOwner? Data { get; } + + public ReadOnlySpan DataSpan + { + get + { + DebugGuard.NotNull(this.Data); + return this.Data.GetSpan(); + } + } /// /// Gets a value indicating whether the given chunk is critical to decoding diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 84245254a2..4960d436cd 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -202,24 +202,24 @@ internal sealed class PngDecoderCore : ImageDecoderCore PngThrowHelper.ThrowInvalidHeader(); } - this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan()); + this.ReadHeaderChunk(pngMetadata, chunk.DataSpan); break; case PngChunkType.AnimationControl: - this.ReadAnimationControlChunk(pngMetadata, chunk.Data.GetSpan()); + this.ReadAnimationControlChunk(pngMetadata, chunk.DataSpan); break; case PngChunkType.Physical: - ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); + ReadPhysicalChunk(metadata, chunk.DataSpan); break; case PngChunkType.Gamma: - ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); + ReadGammaChunk(pngMetadata, chunk.DataSpan); break; case PngChunkType.Cicp: - ReadCicpChunk(metadata, chunk.Data.GetSpan()); + ReadCicpChunk(metadata, chunk.DataSpan); break; case PngChunkType.FrameControl: frameCount++; currentFrame = null; - currentFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan()); + currentFrameControl = this.ReadFrameControlChunk(chunk.DataSpan); break; case PngChunkType.FrameData: { @@ -293,32 +293,32 @@ internal sealed class PngDecoderCore : ImageDecoderCore } case PngChunkType.Palette: - this.palette = chunk.Data.GetSpan().ToArray(); + this.palette = chunk.DataSpan.ToArray(); break; case PngChunkType.Transparency: - this.paletteAlpha = chunk.Data.GetSpan().ToArray(); + this.paletteAlpha = chunk.DataSpan.ToArray(); this.AssignTransparentMarkers(this.paletteAlpha, pngMetadata); break; case PngChunkType.Text: - this.ReadTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); + this.ReadTextChunk(metadata, pngMetadata, chunk.DataSpan); break; case PngChunkType.CompressedText: - this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); + this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.DataSpan); break; case PngChunkType.InternationalText: - this.ReadInternationalTextChunk(metadata, chunk.Data.GetSpan()); + this.ReadInternationalTextChunk(metadata, chunk.DataSpan); break; case PngChunkType.Exif: if (!this.skipMetadata) { byte[] exifData = new byte[chunk.Length]; - chunk.Data.GetSpan().CopyTo(exifData); + chunk.DataSpan.CopyTo(exifData); MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); } break; case PngChunkType.EmbeddedColorProfile: - this.ReadColorProfileChunk(metadata, chunk.Data.GetSpan()); + this.ReadColorProfileChunk(metadata, chunk.DataSpan); break; case PngChunkType.End: goto EOF; @@ -377,10 +377,10 @@ internal sealed class PngDecoderCore : ImageDecoderCore switch (chunk.Type) { case PngChunkType.Header: - this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan()); + this.ReadHeaderChunk(pngMetadata, chunk.DataSpan); break; case PngChunkType.AnimationControl: - this.ReadAnimationControlChunk(pngMetadata, chunk.Data.GetSpan()); + this.ReadAnimationControlChunk(pngMetadata, chunk.DataSpan); break; case PngChunkType.Physical: if (this.colorMetadataOnly) @@ -389,7 +389,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore break; } - ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); + ReadPhysicalChunk(metadata, chunk.DataSpan); break; case PngChunkType.Gamma: if (this.colorMetadataOnly) @@ -398,7 +398,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore break; } - ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); + ReadGammaChunk(pngMetadata, chunk.DataSpan); break; case PngChunkType.Cicp: if (this.colorMetadataOnly) @@ -407,7 +407,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore break; } - ReadCicpChunk(metadata, chunk.Data.GetSpan()); + ReadCicpChunk(metadata, chunk.DataSpan); break; case PngChunkType.FrameControl: ++frameCount; @@ -416,7 +416,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore break; } - currentFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan()); + currentFrameControl = this.ReadFrameControlChunk(chunk.DataSpan); break; case PngChunkType.FrameData: @@ -467,11 +467,11 @@ internal sealed class PngDecoderCore : ImageDecoderCore this.SkipChunkDataAndCrc(chunk); break; case PngChunkType.Palette: - this.palette = chunk.Data.GetSpan().ToArray(); + this.palette = chunk.DataSpan.ToArray(); break; case PngChunkType.Transparency: - this.paletteAlpha = chunk.Data.GetSpan().ToArray(); + this.paletteAlpha = chunk.DataSpan.ToArray(); this.AssignTransparentMarkers(this.paletteAlpha, pngMetadata); // Spec says tRNS must be after PLTE so safe to exit. @@ -488,7 +488,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore break; } - this.ReadTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); + this.ReadTextChunk(metadata, pngMetadata, chunk.DataSpan); break; case PngChunkType.CompressedText: if (this.colorMetadataOnly) @@ -497,7 +497,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore break; } - this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.Data.GetSpan()); + this.ReadCompressedTextChunk(metadata, pngMetadata, chunk.DataSpan); break; case PngChunkType.InternationalText: if (this.colorMetadataOnly) @@ -506,7 +506,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore break; } - this.ReadInternationalTextChunk(metadata, chunk.Data.GetSpan()); + this.ReadInternationalTextChunk(metadata, chunk.DataSpan); break; case PngChunkType.Exif: if (this.colorMetadataOnly) @@ -518,7 +518,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore if (!this.skipMetadata) { byte[] exifData = new byte[chunk.Length]; - chunk.Data.GetSpan().CopyTo(exifData); + chunk.DataSpan.CopyTo(exifData); MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); } @@ -2355,7 +2355,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore this.crc32.Reset(); this.crc32.Append(chunkType); - this.crc32.Append(chunk.Data.GetSpan()); + this.crc32.Append(chunk.DataSpan); if (this.crc32.GetCurrentHashAsUInt32() != inputCrc) {