Browse Source

Refactor IconImageFormatDetector.

Signed-off-by: 舰队的偶像-岛风酱! <frg2089@outlook.com>
pull/2579/head
舰队的偶像-岛风酱! 2 years ago
parent
commit
794b2a6433
No known key found for this signature in database GPG Key ID: 71F5B3A2B181950C
  1. 59
      src/ImageSharp/Formats/Icon/IconImageFormatDetector.cs

59
src/ImageSharp/Formats/Icon/IconImageFormatDetector.cs

@ -2,7 +2,6 @@
// Licensed under the Six Labors Split License.
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.Formats.Icon;
@ -12,22 +11,58 @@ namespace SixLabors.ImageSharp.Formats.Icon;
public class IconImageFormatDetector : IImageFormatDetector
{
/// <inheritdoc/>
public int HeaderSize { get; } = 4;
public int HeaderSize { get; } = IconDir.Size + IconDirEntry.Size;
/// <inheritdoc/>
public bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format)
{
switch (MemoryMarshal.Cast<byte, uint>(header)[0])
format = this.IsSupportedFileFormat(header) switch
{
case Ico.IcoConstants.FileHeader:
format = Ico.IcoFormat.Instance;
return true;
case Cur.CurConstants.FileHeader:
format = Cur.CurFormat.Instance;
return true;
default:
format = default;
return false;
true => Ico.IcoFormat.Instance,
false => Cur.CurFormat.Instance,
null => default
};
return format is not null;
}
private bool? IsSupportedFileFormat(ReadOnlySpan<byte> header)
{
// There are no magic bytes in the first few bytes of a tga file,
// so we try to figure out if its a valid tga by checking for valid tga header bytes.
if (header.Length < this.HeaderSize)
{
return null;
}
IconDir dir = IconDir.Parse(header);
if (dir is not { Reserved: 0 } // Should be 0.
or not { Type: IconFileType.ICO or IconFileType.CUR } // Unknown Type.
or { Count: 0 }) // Should not be 0.
{
return null;
}
IconDirEntry entry = IconDirEntry.Parse(header[IconDir.Size..]);
if (entry is not { Reserved: 0 } // Should be 0.
or { BytesInRes: 0 } // Should not be 0.
|| entry.ImageOffset < IconDir.Size + (dir.Count * IconDirEntry.Size))
{
return null;
}
if (dir.Type is IconFileType.ICO)
{
if (entry is not { BitCount: 1 or 4 or 8 or 16 or 24 or 32 } or not { Planes: 0 or 1 })
{
return null;
}
return true;
}
else
{
return false;
}
}
}

Loading…
Cancel
Save