Browse Source

update AniFrameFormat

pull/2899/head
Poker 2 years ago
parent
commit
256934344c
No known key found for this signature in database GPG Key ID: C65A6AD457D5C8F8
  1. 46
      src/ImageSharp/Formats/Ani/AniDecoderCore.cs
  2. 25
      src/ImageSharp/Formats/Ani/AniFrameFormat.cs
  3. 6
      src/ImageSharp/Formats/Ani/AniFrameMetadata.cs

46
src/ImageSharp/Formats/Ani/AniDecoderCore.cs

@ -36,13 +36,6 @@ internal class AniDecoderCore : ImageDecoderCore
: base(options) =>
this.configuration = options.Configuration;
private enum ListIconChunkType : byte
{
Ico = 1,
Cur,
Bmp
}
protected override Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancellationToken)
{
this.currentStream = stream;
@ -54,7 +47,7 @@ internal class AniDecoderCore : ImageDecoderCore
ImageMetadata metadata = new();
AniMetadata aniMetadata = this.ReadHeader(dataStartPosition, dataSize, metadata);
List<(ListIconChunkType Type, Image<TPixel> Image)> frames = [];
List<(AniFrameFormat Type, Image<TPixel> Image)> frames = [];
this.HandleRiffChunk(out Span<int> sequence, out Span<uint> rate, dataStartPosition, dataSize, aniMetadata, frames, DecodeFrameChunk);
List<ImageFrame<TPixel>> list = [];
@ -62,7 +55,7 @@ internal class AniDecoderCore : ImageDecoderCore
for (int i = 0; i < sequence.Length; i++)
{
int sequenceIndex = sequence[i];
(ListIconChunkType type, Image<TPixel>? img) = frames[sequenceIndex];
(AniFrameFormat type, Image<TPixel>? img) = frames[sequenceIndex];
AniFrameMetadata aniFrameMetadata = new()
{
@ -80,23 +73,24 @@ internal class AniDecoderCore : ImageDecoderCore
AniFrameMetadata clonedMetadata = aniFrameMetadata.DeepClone();
source.Metadata.SetFormatMetadata(AniFormat.Instance, clonedMetadata);
clonedMetadata.FrameFormat = type;
switch (type)
{
case ListIconChunkType.Ico:
case AniFrameFormat.Ico:
IcoFrameMetadata icoFrameMetadata = source.Metadata.GetIcoMetadata();
// TODO source.Metadata.SetFormatMetadata(IcoFormat.Instance, null);
clonedMetadata.IcoFrameMetadata = icoFrameMetadata;
clonedMetadata.EncodingWidth = icoFrameMetadata.EncodingWidth;
clonedMetadata.EncodingHeight = icoFrameMetadata.EncodingHeight;
break;
case ListIconChunkType.Cur:
case AniFrameFormat.Cur:
CurFrameMetadata curFrameMetadata = source.Metadata.GetCurMetadata();
// TODO source.Metadata.SetFormatMetadata(CurFormat.Instance, null);
clonedMetadata.CurFrameMetadata = curFrameMetadata;
clonedMetadata.EncodingWidth = curFrameMetadata.EncodingWidth;
clonedMetadata.EncodingHeight = curFrameMetadata.EncodingHeight;
break;
case ListIconChunkType.Bmp:
case AniFrameFormat.Bmp:
clonedMetadata.EncodingWidth = Narrow(source.Width);
clonedMetadata.EncodingHeight = Narrow(source.Height);
break;
@ -108,7 +102,7 @@ internal class AniDecoderCore : ImageDecoderCore
}));
}
foreach ((ListIconChunkType _, Image<TPixel> img) in frames)
foreach ((AniFrameFormat _, Image<TPixel> img) in frames)
{
img.Dispose();
}
@ -128,7 +122,7 @@ internal class AniDecoderCore : ImageDecoderCore
long endPosition = this.currentStream.Position + chunk.Size;
Image<TPixel>? frame = null;
ListIconChunkType type = default;
AniFrameFormat type = default;
if (aniMetadata.Flags.HasFlag(AniHeaderFlags.IsIcon))
{
if (this.currentStream.TryReadUnmanaged(out IconDir dir))
@ -139,11 +133,11 @@ internal class AniDecoderCore : ImageDecoderCore
{
case IconFileType.CUR:
frame = CurDecoder.Instance.Decode<TPixel>(this.Options, this.currentStream);
type = ListIconChunkType.Cur;
type = AniFrameFormat.Cur;
break;
case IconFileType.ICO:
frame = IcoDecoder.Instance.Decode<TPixel>(this.Options, this.currentStream);
type = ListIconChunkType.Ico;
type = AniFrameFormat.Ico;
break;
}
}
@ -151,7 +145,7 @@ internal class AniDecoderCore : ImageDecoderCore
else
{
frame = BmpDecoder.Instance.Decode<TPixel>(this.Options, this.currentStream);
type = ListIconChunkType.Bmp;
type = AniFrameFormat.Bmp;
}
if (frame is not null)
@ -176,7 +170,7 @@ internal class AniDecoderCore : ImageDecoderCore
ImageMetadata metadata = new();
AniMetadata aniMetadata = this.ReadHeader(dataStartPosition, dataSize, metadata);
List<(ListIconChunkType Type, ImageInfo Info)> infoList = [];
List<(AniFrameFormat Type, ImageInfo Info)> infoList = [];
this.HandleRiffChunk(out Span<int> sequence, out Span<uint> rate, dataStartPosition, dataSize, aniMetadata, infoList, IdentifyFrameChunk);
List<ImageFrameMetadata> frameMetadataCollection = new(sequence.Length);
@ -184,7 +178,7 @@ internal class AniDecoderCore : ImageDecoderCore
for (int i = 0; i < sequence.Length; i++)
{
int sequenceIndex = sequence[i];
(ListIconChunkType type, ImageInfo info) = infoList[sequenceIndex];
(AniFrameFormat type, ImageInfo info) = infoList[sequenceIndex];
AniFrameMetadata aniFrameMetadata = new()
{
@ -199,16 +193,17 @@ internal class AniDecoderCore : ImageDecoderCore
{
AniFrameMetadata clonedMetadata = aniFrameMetadata.DeepClone();
frameMetadata.SetFormatMetadata(AniFormat.Instance, clonedMetadata);
clonedMetadata.FrameFormat = type;
switch (type)
{
case ListIconChunkType.Ico:
case AniFrameFormat.Ico:
IcoFrameMetadata icoFrameMetadata = frameMetadata.GetIcoMetadata();
// TODO source.Metadata.SetFormatMetadata(IcoFormat.Instance, null);
clonedMetadata.IcoFrameMetadata = icoFrameMetadata;
clonedMetadata.EncodingWidth = icoFrameMetadata.EncodingWidth;
clonedMetadata.EncodingHeight = icoFrameMetadata.EncodingHeight;
break;
case ListIconChunkType.Cur:
case AniFrameFormat.Cur:
CurFrameMetadata curFrameMetadata = frameMetadata.GetCurMetadata();
// TODO source.Metadata.SetFormatMetadata(CurFormat.Instance, null);
clonedMetadata.CurFrameMetadata = curFrameMetadata;
@ -227,6 +222,7 @@ internal class AniDecoderCore : ImageDecoderCore
{
aniFrameMetadata.EncodingWidth = Narrow(info.Width);
aniFrameMetadata.EncodingHeight = Narrow(info.Height);
aniFrameMetadata.FrameFormat = type;
ImageFrameMetadata frameMetadata = new();
frameMetadata.SetFormatMetadata(AniFormat.Instance, aniFrameMetadata);
frameMetadataCollection.Add(frameMetadata);
@ -248,7 +244,7 @@ internal class AniDecoderCore : ImageDecoderCore
long endPosition = this.currentStream.Position + chunk.Size;
ImageInfo? info = null;
ListIconChunkType type = default;
AniFrameFormat type = default;
if (aniMetadata.Flags.HasFlag(AniHeaderFlags.IsIcon))
{
if (this.currentStream.TryReadUnmanaged(out IconDir dir))
@ -259,11 +255,11 @@ internal class AniDecoderCore : ImageDecoderCore
{
case IconFileType.CUR:
info = CurDecoder.Instance.Identify(this.Options, this.currentStream);
type = ListIconChunkType.Cur;
type = AniFrameFormat.Cur;
break;
case IconFileType.ICO:
info = IcoDecoder.Instance.Identify(this.Options, this.currentStream);
type = ListIconChunkType.Ico;
type = AniFrameFormat.Ico;
break;
}
}
@ -271,7 +267,7 @@ internal class AniDecoderCore : ImageDecoderCore
else
{
info = BmpDecoder.Instance.Identify(this.Options, this.currentStream);
type = ListIconChunkType.Bmp;
type = AniFrameFormat.Bmp;
}
if (info is not null)

25
src/ImageSharp/Formats/Ani/AniFrameFormat.cs

@ -0,0 +1,25 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Formats.Ani;
/// <summary>
/// Specifies the format of the frame data.
/// </summary>
public enum AniFrameFormat
{
/// <summary>
/// The frame data is in ICO format.
/// </summary>
Ico = 1,
/// <summary>
/// The frame data is in CUR format.
/// </summary>
Cur,
/// <summary>
/// The frame data is in BMP format.
/// </summary>
Bmp
}

6
src/ImageSharp/Formats/Ani/AniFrameMetadata.cs

@ -43,11 +43,9 @@ public class AniFrameMetadata : IFormatFrameMetadata<AniFrameMetadata>
public byte? EncodingHeight { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the frame will be encoded as an ICO or CUR file.
/// Gets or sets a value indicating whether the frame will be encoded as an ICO or CUR or BMP file.
/// </summary>
[MemberNotNullWhen(true, nameof(IcoFrameMetadata))]
[MemberNotNullWhen(false, nameof(CurFrameMetadata))]
public bool IsIco { get; set; }
public AniFrameFormat FrameFormat { get; set; }
/// <summary>
/// Gets or sets the <see cref="IcoFrameMetadata"/> of one "icon" chunk.

Loading…
Cancel
Save