diff --git a/src/ImageSharp/Formats/Icon/Cur/CurDecoderCore.cs b/src/ImageSharp/Formats/Icon/Cur/CurDecoderCore.cs
index 44fcc8fcc9..afd751279b 100644
--- a/src/ImageSharp/Formats/Icon/Cur/CurDecoderCore.cs
+++ b/src/ImageSharp/Formats/Icon/Cur/CurDecoderCore.cs
@@ -14,5 +14,5 @@ internal sealed class CurDecoderCore : IconDecoderCore
{
}
- protected override IconFrameMetadata GetFrameMetadata(ImageFrameMetadata metadata) => metadata.GetCurMetadata();
+ protected override void SetFrameMetadata(ImageFrameMetadata metadata, in IconDirEntry entry) => metadata.GetCurMetadata().FromIconDirEntry(entry);
}
diff --git a/src/ImageSharp/Formats/Icon/Cur/CurFrameMetadata.cs b/src/ImageSharp/Formats/Icon/Cur/CurFrameMetadata.cs
index 60ced16eaf..2d1c227768 100644
--- a/src/ImageSharp/Formats/Icon/Cur/CurFrameMetadata.cs
+++ b/src/ImageSharp/Formats/Icon/Cur/CurFrameMetadata.cs
@@ -4,9 +4,9 @@
namespace SixLabors.ImageSharp.Formats.Icon.Cur;
///
-/// IcoFrameMetadata. TODO: Remove base class and merge into this class.
+/// IcoFrameMetadata.
///
-public class CurFrameMetadata : IconFrameMetadata, IDeepCloneable, IDeepCloneable
+public class CurFrameMetadata : IDeepCloneable, IDeepCloneable
{
///
/// Initializes a new instance of the class.
@@ -15,38 +15,92 @@ public class CurFrameMetadata : IconFrameMetadata, IDeepCloneable
- /// Initializes a new instance of the class.
- ///
- /// metadata
- public CurFrameMetadata(IconFrameMetadata metadata)
- : base(metadata)
- {
- }
-
///
/// Initializes a new instance of the class.
///
/// width
/// height
/// colorCount
- /// field1
- /// field2
- public CurFrameMetadata(byte width, byte height, byte colorCount, ushort field1, ushort field2)
- : base(width, height, colorCount, field1, field2)
+ /// hotspotX
+ /// hotspotY
+ public CurFrameMetadata(byte width, byte height, byte colorCount, ushort hotspotX, ushort hotspotY)
{
+ this.EncodingWidth = width;
+ this.EncodingHeight = height;
+ this.ColorCount = colorCount;
+ this.HotspotX = hotspotX;
+ this.HotspotY = hotspotY;
}
+ ///
+ public CurFrameMetadata(CurFrameMetadata metadata)
+ {
+ this.EncodingWidth = metadata.EncodingWidth;
+ this.EncodingHeight = metadata.EncodingHeight;
+ this.ColorCount = metadata.ColorCount;
+ this.HotspotX = metadata.HotspotX;
+ this.HotspotY = metadata.HotspotY;
+ this.Compression = metadata.Compression;
+ }
+
+ ///
+ /// Gets or sets icoFrameCompression.
+ ///
+ public IconFrameCompression Compression { get; set; }
+
+ ///
+ /// Gets or sets ColorCount field.
+ /// Specifies number of colors in the color palette. Should be 0 if the image does not use a color palette.
+ ///
+ // TODO: BmpMetadata does not supported palette yet.
+ public byte ColorCount { get; set; }
+
///
/// Gets or sets Specifies the horizontal coordinates of the hotspot in number of pixels from the left.
///
- public ushort HotspotX { get => this.Field1; set => this.Field1 = value; }
+ public ushort HotspotX { get; set; }
///
/// Gets or sets Specifies the vertical coordinates of the hotspot in number of pixels from the top.
///
- public ushort HotspotY { get => this.Field2; set => this.Field2 = value; }
+ public ushort HotspotY { get; set; }
+
+ ///
+ /// Gets or sets Height field.
+ /// Specifies image height in pixels. Can be any number between 0 and 255. Value 0 means image height is 256 pixels.
+ ///
+ public byte EncodingHeight { get; set; }
+
+ ///
+ /// Gets or sets Width field.
+ /// Specifies image width in pixels. Can be any number between 0 and 255. Value 0 means image width is 256 pixels.
+ ///
+ public byte EncodingWidth { get; set; }
+
+ ///
+ public Bmp.BmpBitsPerPixel BitsPerPixel { get; set; } = Bmp.BmpBitsPerPixel.Pixel24;
///
- public override CurFrameMetadata DeepClone() => new(this);
+ public CurFrameMetadata DeepClone() => new(this);
+
+ ///
+ IDeepCloneable IDeepCloneable.DeepClone() => this.DeepClone();
+
+ internal void FromIconDirEntry(in IconDirEntry entry)
+ {
+ this.EncodingWidth = entry.Width;
+ this.EncodingHeight = entry.Height;
+ this.ColorCount = entry.ColorCount;
+ this.HotspotX = entry.Planes;
+ this.HotspotY = entry.BitCount;
+ }
+
+ internal IconDirEntry ToIconDirEntry() => new()
+ {
+ Width = this.EncodingWidth,
+ Height = this.EncodingHeight,
+ ColorCount = this.ColorCount,
+ Planes = this.HotspotX,
+ BitCount = this.HotspotY,
+ };
}
diff --git a/src/ImageSharp/Formats/Icon/Ico/IcoDecoderCore.cs b/src/ImageSharp/Formats/Icon/Ico/IcoDecoderCore.cs
index 677a9c07a0..4884fdf9a3 100644
--- a/src/ImageSharp/Formats/Icon/Ico/IcoDecoderCore.cs
+++ b/src/ImageSharp/Formats/Icon/Ico/IcoDecoderCore.cs
@@ -14,5 +14,6 @@ internal sealed class IcoDecoderCore : IconDecoderCore
{
}
- protected override IconFrameMetadata GetFrameMetadata(ImageFrameMetadata metadata) => metadata.GetIcoMetadata();
+ protected override void SetFrameMetadata(ImageFrameMetadata metadata, in IconDirEntry entry)
+ => metadata.GetIcoMetadata().FromIconDirEntry(entry);
}
diff --git a/src/ImageSharp/Formats/Icon/Ico/IcoFrameMetadata.cs b/src/ImageSharp/Formats/Icon/Ico/IcoFrameMetadata.cs
index 4f557715dc..82e3c1db38 100644
--- a/src/ImageSharp/Formats/Icon/Ico/IcoFrameMetadata.cs
+++ b/src/ImageSharp/Formats/Icon/Ico/IcoFrameMetadata.cs
@@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Icon.Ico;
///
/// IcoFrameMetadata. TODO: Remove base class and merge into this class.
///
-public class IcoFrameMetadata : IconFrameMetadata, IDeepCloneable, IDeepCloneable
+public class IcoFrameMetadata : IDeepCloneable, IDeepCloneable
{
///
/// Initializes a new instance of the class.
@@ -15,34 +15,78 @@ public class IcoFrameMetadata : IconFrameMetadata, IDeepCloneable
- /// Initializes a new instance of the class.
- ///
- /// metadata
- public IcoFrameMetadata(IconFrameMetadata metadata)
- : base(metadata)
- {
- }
-
///
/// Initializes a new instance of the class.
///
/// width
/// height
/// colorCount
- /// field1
- /// field2
- public IcoFrameMetadata(byte width, byte height, byte colorCount, ushort field1, ushort field2)
- : base(width, height, colorCount, field1, field2)
+ public IcoFrameMetadata(byte width, byte height, byte colorCount)
{
+ this.EncodingWidth = width;
+ this.EncodingHeight = height;
+ this.ColorCount = colorCount;
}
+ ///
+ public IcoFrameMetadata(IcoFrameMetadata metadata)
+ {
+ this.EncodingWidth = metadata.EncodingWidth;
+ this.EncodingHeight = metadata.EncodingHeight;
+ this.ColorCount = metadata.ColorCount;
+ this.Compression = metadata.Compression;
+ }
+
+ ///
+ /// Gets or sets icoFrameCompression.
+ ///
+ public IconFrameCompression Compression { get; set; }
+
+ ///
+ /// Gets or sets ColorCount field.
+ /// Specifies number of colors in the color palette. Should be 0 if the image does not use a color palette.
+ ///
+ // TODO: BmpMetadata does not supported palette yet.
+ public byte ColorCount { get; set; }
+
///
- /// Gets or sets the bits per pixel.
- /// TODO: This needs to be constrained and calculated using the metadata returned from the png/bmp.
+ /// Gets or sets Height field.
+ /// Specifies image height in pixels. Can be any number between 0 and 255. Value 0 means image height is 256 pixels.
///
- public ushort BitCount { get => this.Field2; set => this.Field2 = value; }
+ public byte EncodingHeight { get; set; }
+
+ ///
+ /// Gets or sets Width field.
+ /// Specifies image width in pixels. Can be any number between 0 and 255. Value 0 means image width is 256 pixels.
+ ///
+ public byte EncodingWidth { get; set; }
+
+ ///
+ public Bmp.BmpBitsPerPixel BitsPerPixel { get; set; } = Bmp.BmpBitsPerPixel.Pixel24;
///
- public override IcoFrameMetadata DeepClone() => new(this);
+ public IcoFrameMetadata DeepClone() => new(this);
+
+ ///
+ IDeepCloneable IDeepCloneable.DeepClone() => this.DeepClone();
+
+ internal void FromIconDirEntry(in IconDirEntry entry)
+ {
+ this.EncodingWidth = entry.Width;
+ this.EncodingHeight = entry.Height;
+ this.ColorCount = entry.ColorCount;
+ }
+
+ internal IconDirEntry ToIconDirEntry() => new()
+ {
+ Width = this.EncodingWidth,
+ Height = this.EncodingHeight,
+ ColorCount = this.ColorCount,
+ Planes = 1,
+ BitCount = this.Compression switch
+ {
+ IconFrameCompression.Bmp => (ushort)this.BitsPerPixel,
+ _ => 0,
+ },
+ };
}
diff --git a/src/ImageSharp/Formats/Icon/IconDecoderCore.cs b/src/ImageSharp/Formats/Icon/IconDecoderCore.cs
index 1077bde510..21c0a3bc45 100644
--- a/src/ImageSharp/Formats/Icon/IconDecoderCore.cs
+++ b/src/ImageSharp/Formats/Icon/IconDecoderCore.cs
@@ -93,9 +93,7 @@ internal abstract class IconDecoderCore : IImageDecoderInternals
bmpMetadata = x.Image.Metadata.GetBmpMetadata();
}
- // TODO: The inheriting decoder should be responsible for setting the actual data (FromIconDirEntry)
- // so we can avoid the protected Field1 and Field2 properties and use strong typing.
- this.GetFrameMetadata(target.Metadata).FromIconDirEntry(this.Entries[x.Index]);
+ this.SetFrameMetadata(target.Metadata, this.Entries[x.Index]);
x.Image.Dispose();
@@ -127,15 +125,14 @@ internal abstract class IconDecoderCore : IImageDecoderInternals
// TODO: Use the Identify methods in each decoder to return the
// format specific metadata for the image and frame.
frames[i] = new();
- IconFrameMetadata icoFrameMetadata = this.GetFrameMetadata(frames[i]);
- icoFrameMetadata.FromIconDirEntry(this.Entries[i]);
+ this.SetFrameMetadata(frames[i], this.Entries[i]);
}
// TODO: Use real values from the metadata.
return new(new(32), new(0), metadata, frames);
}
- protected abstract IconFrameMetadata GetFrameMetadata(ImageFrameMetadata metadata);
+ protected abstract void SetFrameMetadata(ImageFrameMetadata metadata, in IconDirEntry entry);
protected void ReadHeader(Stream stream)
{
diff --git a/src/ImageSharp/Formats/Icon/IconFrameMetadata.cs b/src/ImageSharp/Formats/Icon/IconFrameMetadata.cs
deleted file mode 100644
index 5c23388e77..0000000000
--- a/src/ImageSharp/Formats/Icon/IconFrameMetadata.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-namespace SixLabors.ImageSharp.Formats.Icon;
-
-///
-/// IconFrameMetadata
-/// TODO: Delete this. Treat the individual metadata types as separate types so we can avoid Field1, Field2 and use strong typing with constaints.
-///
-public abstract class IconFrameMetadata : IDeepCloneable
-{
- ///
- /// Initializes a new instance of the class.
- ///
- protected IconFrameMetadata()
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// width
- /// height
- /// colorCount
- /// field1
- /// field2
- protected IconFrameMetadata(byte width, byte height, byte colorCount, ushort field1, ushort field2)
- {
- this.EncodingWidth = width;
- this.EncodingHeight = height;
- this.ColorCount = colorCount;
- this.Field1 = field1;
- this.Field2 = field2;
- }
-
- ///
- protected IconFrameMetadata(IconFrameMetadata metadata)
- {
- this.EncodingWidth = metadata.EncodingWidth;
- this.EncodingHeight = metadata.EncodingHeight;
- this.ColorCount = metadata.ColorCount;
- this.Field1 = metadata.Field1;
- this.Field2 = metadata.Field2;
- }
-
- ///
- /// Gets or sets icoFrameCompression.
- ///
- public IconFrameCompression Compression { get; protected set; }
-
- ///
- /// Gets or sets ColorCount field.
- /// Specifies number of colors in the color palette. Should be 0 if the image does not use a color palette.
- ///
- // TODO: BmpMetadata does not supported palette yet.
- public byte ColorCount { get; set; }
-
- ///
- /// Gets or sets Planes field.
- /// In ICO format: Specifies color planes. Should be 0 or 1.
- /// In CUR format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left.
- ///
- protected ushort Field1 { get; set; }
-
- ///
- /// Gets or sets BitCount field.
- /// In ICO format: Specifies bits per pixel.
- /// In CUR format: Specifies the vertical coordinates of the hotspot in number of pixels from the top.
- ///
- protected ushort Field2 { get; set; }
-
- ///
- /// Gets or sets Height field.
- /// Specifies image height in pixels. Can be any number between 0 and 255. Value 0 means image height is 256 pixels.
- ///
- public byte EncodingHeight { get; set; }
-
- ///
- /// Gets or sets Width field.
- /// Specifies image width in pixels. Can be any number between 0 and 255. Value 0 means image width is 256 pixels.
- ///
- public byte EncodingWidth { get; set; }
-
- ///
- public abstract IDeepCloneable DeepClone();
-
- internal void FromIconDirEntry(in IconDirEntry metadata)
- {
- this.EncodingWidth = metadata.Width;
- this.EncodingHeight = metadata.Height;
- this.ColorCount = metadata.ColorCount;
- this.Field1 = metadata.Planes;
- this.Field2 = metadata.BitCount;
- }
-
- internal IconDirEntry ToIconDirEntry() => new()
- {
- Width = this.EncodingWidth,
- Height = this.EncodingHeight,
- ColorCount = this.ColorCount,
- Planes = this.Field1,
- BitCount = this.Field2,
- };
-}