diff --git a/src/ImageSharp/Formats/Icon/IconDecoderCore.cs b/src/ImageSharp/Formats/Icon/IconDecoderCore.cs index 874e93411..1077bde51 100644 --- a/src/ImageSharp/Formats/Icon/IconDecoderCore.cs +++ b/src/ImageSharp/Formats/Icon/IconDecoderCore.cs @@ -139,12 +139,18 @@ internal abstract class IconDecoderCore : IImageDecoderInternals protected void ReadHeader(Stream stream) { - // TODO: Check length and throw if the header cannot be read. - _ = Read(stream, out this.fileHeader, IconDir.Size); + Span buffer = stackalloc byte[IconDirEntry.Size]; + + // ICONDIR + _ = IconAssert.EndOfStream(stream.Read(buffer[..IconDir.Size]), IconDir.Size); + this.fileHeader = IconDir.Parse(buffer); + + // ICONDIRENTRY this.Entries = new IconDirEntry[this.FileHeader.Count]; for (int i = 0; i < this.Entries.Length; i++) { - _ = Read(stream, out this.Entries[i], IconDirEntry.Size); + _ = IconAssert.EndOfStream(stream.Read(buffer[..IconDirEntry.Size]), IconDirEntry.Size); + this.Entries[i] = IconDirEntry.Parse(buffer); } int width = 0; @@ -175,18 +181,6 @@ internal abstract class IconDecoderCore : IImageDecoderInternals this.Dimensions = new(width, height); } - private static int Read(Stream stream, out T data, int size) - where T : unmanaged - { - // TODO: Use explicit parsing methods for each T type. - // See PngHeader.Parse() for example. - Span buffer = stackalloc byte[size]; - - _ = IconAssert.EndOfStream(stream.Read(buffer), size); - data = MemoryMarshal.Cast(buffer)[0]; - return size; - } - private IImageDecoderInternals GetDecoder(bool isPng) { if (isPng) diff --git a/src/ImageSharp/Formats/Icon/IconDir.cs b/src/ImageSharp/Formats/Icon/IconDir.cs index f1281a568..53b87bc9f 100644 --- a/src/ImageSharp/Formats/Icon/IconDir.cs +++ b/src/ImageSharp/Formats/Icon/IconDir.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Runtime.InteropServices; @@ -15,12 +15,21 @@ internal struct IconDir public IconDir(IconFileType type) : this(type, 0) - => this.Type = type; + { + } public IconDir(IconFileType type, ushort count) + : this(0, type, count) + { + } + + public IconDir(ushort reserved, IconFileType type, ushort count) { - this.Reserved = 0; + this.Reserved = reserved; this.Type = type; this.Count = count; } + + public static IconDir Parse(in ReadOnlySpan data) + => MemoryMarshal.Cast(data)[0]; } diff --git a/src/ImageSharp/Formats/Icon/IconDirEntry.cs b/src/ImageSharp/Formats/Icon/IconDirEntry.cs index 43254f89d..edd778f7e 100644 --- a/src/ImageSharp/Formats/Icon/IconDirEntry.cs +++ b/src/ImageSharp/Formats/Icon/IconDirEntry.cs @@ -25,4 +25,7 @@ internal struct IconDirEntry public uint BytesInRes; public uint ImageOffset; + + public static IconDirEntry Parse(in ReadOnlySpan data) + => MemoryMarshal.Cast(data)[0]; }