Skip to content

Commit 386088f

Browse files
committed
Split IcoFrameMetadata into BMP/PNG special format
Signed-off-by: 舰队的偶像-岛风酱! <[email protected]>
1 parent 42e0725 commit 386088f

20 files changed

+618
-96
lines changed

src/ImageSharp/Formats/Bmp/BmpMetadata.cs

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

44
namespace SixLabors.ImageSharp.Formats.Bmp;
55

66
/// <summary>
77
/// Provides Bmp specific metadata information for the image.
88
/// </summary>
9-
public class BmpMetadata : IDeepCloneable
9+
public class BmpMetadata : IDeepCloneable, IBmpMetadata
1010
{
1111
/// <summary>
1212
/// Initializes a new instance of the <see cref="BmpMetadata"/> class.
@@ -25,14 +25,10 @@ private BmpMetadata(BmpMetadata other)
2525
this.InfoHeaderType = other.InfoHeaderType;
2626
}
2727

28-
/// <summary>
29-
/// Gets or sets the bitmap info header type.
30-
/// </summary>
28+
/// <inheritdoc/>
3129
public BmpInfoHeaderType InfoHeaderType { get; set; }
3230

33-
/// <summary>
34-
/// Gets or sets the number of bits per pixel.
35-
/// </summary>
31+
/// <inheritdoc/>
3632
public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Pixel24;
3733

3834
/// <inheritdoc/>
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
namespace SixLabors.ImageSharp.Formats.Bmp;
5+
6+
/// <summary>
7+
/// Provides Bmp specific metadata information for the image.
8+
/// </summary>
9+
internal interface IBmpMetadata
10+
{
11+
/// <summary>
12+
/// Gets or sets the number of bits per pixel.
13+
/// </summary>
14+
BmpBitsPerPixel BitsPerPixel { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the bitmap info header type.
18+
/// </summary>
19+
BmpInfoHeaderType InfoHeaderType { get; set; }
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using SixLabors.ImageSharp.Formats.Bmp;
5+
using SixLabors.ImageSharp.Formats.Ico.Common;
6+
7+
namespace SixLabors.ImageSharp.Formats.Cur;
8+
9+
/// <summary>
10+
/// Provides Cur specific bmp metadata information for the image.
11+
/// </summary>
12+
public class CurBmpFrameMetadata : CurFrameMetadata, IDeepCloneable<CurBmpFrameMetadata>, IBmpMetadata
13+
{
14+
/// <summary>
15+
/// Initializes a new instance of the <see cref="CurBmpFrameMetadata"/> class.
16+
/// </summary>
17+
public CurBmpFrameMetadata()
18+
{
19+
}
20+
21+
private CurBmpFrameMetadata(CurFrameMetadata metadata)
22+
: base(metadata)
23+
{
24+
}
25+
26+
/// <summary>
27+
/// Initializes a new instance of the <see cref="CurBmpFrameMetadata"/> class.
28+
/// </summary>
29+
/// <param name="width">width</param>
30+
/// <param name="height">height</param>
31+
/// <param name="colorCount">colorCount</param>
32+
/// <param name="planes">planes</param>
33+
/// <param name="bitCount">bitCount</param>
34+
public CurBmpFrameMetadata(byte width, byte height, byte colorCount, ushort planes, ushort bitCount)
35+
: base(width, height, colorCount, planes, bitCount)
36+
{
37+
}
38+
39+
/// <inheritdoc/>
40+
public override IcoLikeFrameCompression Compression { get; } = IcoLikeFrameCompression.Bmp;
41+
42+
/// <inheritdoc/>
43+
public BmpInfoHeaderType InfoHeaderType { get; set; }
44+
45+
/// <inheritdoc/>
46+
public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Pixel24;
47+
48+
/// <inheritdoc/>
49+
public override CurBmpFrameMetadata DeepClone() => new(this);
50+
51+
internal override void FromMetadata(IDeepCloneable other)
52+
{
53+
if (other is not BmpMetadata metadata)
54+
{
55+
return;
56+
}
57+
58+
this.BitsPerPixel = metadata.BitsPerPixel;
59+
this.InfoHeaderType = metadata.InfoHeaderType;
60+
}
61+
62+
internal override BmpMetadata ToMetadata() => new()
63+
{
64+
BitsPerPixel = this.BitsPerPixel,
65+
InfoHeaderType = this.InfoHeaderType,
66+
};
67+
}

src/ImageSharp/Formats/Cur/CurFormat.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,11 @@ private CurFormat()
3333
public CurMetadata CreateDefaultFormatMetadata() => new();
3434

3535
/// <inheritdoc/>
36-
public CurFrameMetadata CreateDefaultFormatFrameMetadata() => new();
36+
public CurFrameMetadata CreateDefaultFormatFrameMetadata() => CreateBmpFormatFrameMetadata();
37+
38+
/// <inheritdoc cref="CreateDefaultFormatFrameMetadata()"/>
39+
public static CurFrameMetadata CreateBmpFormatFrameMetadata() => new CurBmpFrameMetadata();
40+
41+
/// <inheritdoc cref="CreateDefaultFormatFrameMetadata()"/>
42+
public static CurFrameMetadata CreatePngFormatFrameMetadata() => new CurPngFrameMetadata();
3743
}

src/ImageSharp/Formats/Cur/CurFrameMetadata.cs

+6-10
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ namespace SixLabors.ImageSharp.Formats.Cur;
88
/// <summary>
99
/// Provides Cur specific metadata information for the image.
1010
/// </summary>
11-
public class CurFrameMetadata : IcoLikeFrameMetadata<CurFrameMetadata>
11+
public abstract class CurFrameMetadata : IcoLikeFrameMetadata
1212
{
1313
/// <summary>
1414
/// Initializes a new instance of the <see cref="CurFrameMetadata"/> class.
1515
/// </summary>
16-
public CurFrameMetadata()
16+
protected CurFrameMetadata()
1717
: base()
1818
{
1919
}
@@ -26,14 +26,13 @@ public CurFrameMetadata()
2626
/// <param name="colorCount">colorCount</param>
2727
/// <param name="hotspotX">hotspotX</param>
2828
/// <param name="hotspotY">hotspotY</param>
29-
/// <param name="bytesInRes">bytesInRes</param>
30-
/// <param name="imageOffset">imageOffset</param>
31-
public CurFrameMetadata(byte width, byte height, byte colorCount, ushort hotspotX, ushort hotspotY, uint bytesInRes, uint imageOffset)
32-
: base(width, height, colorCount, hotspotX, hotspotY, bytesInRes, imageOffset)
29+
protected CurFrameMetadata(byte width, byte height, byte colorCount, ushort hotspotX, ushort hotspotY)
30+
: base(width, height, colorCount, hotspotX, hotspotY)
3331
{
3432
}
3533

36-
private CurFrameMetadata(CurFrameMetadata metadata)
34+
/// <inheritdoc cref="CurFrameMetadata()"/>
35+
protected CurFrameMetadata(CurFrameMetadata metadata)
3736
: base(metadata)
3837
{
3938
}
@@ -47,7 +46,4 @@ private CurFrameMetadata(CurFrameMetadata metadata)
4746
/// Gets or sets Specifies the vertical coordinates of the hotspot in number of pixels from the top.
4847
/// </summary>
4948
public ushort HotspotY { get => this.Field2; set => this.Field2 = value; }
50-
51-
/// <inheritdoc/>
52-
public override CurFrameMetadata DeepClone() => new(this);
5349
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using SixLabors.ImageSharp.Formats.Ico.Common;
5+
using SixLabors.ImageSharp.Formats.Png;
6+
using SixLabors.ImageSharp.Formats.Png.Chunks;
7+
8+
namespace SixLabors.ImageSharp.Formats.Cur;
9+
10+
/// <summary>
11+
/// Provides Cur specific png metadata information for the image.
12+
/// </summary>
13+
public class CurPngFrameMetadata : CurFrameMetadata, IDeepCloneable<CurPngFrameMetadata>, IPngMetadata
14+
{
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="CurPngFrameMetadata"/> class.
17+
/// </summary>
18+
public CurPngFrameMetadata()
19+
{
20+
}
21+
22+
private CurPngFrameMetadata(CurFrameMetadata metadata)
23+
: base(metadata)
24+
{
25+
}
26+
27+
/// <summary>
28+
/// Initializes a new instance of the <see cref="CurPngFrameMetadata"/> class.
29+
/// </summary>
30+
/// <param name="width">width</param>
31+
/// <param name="height">height</param>
32+
/// <param name="colorCount">colorCount</param>
33+
/// <param name="planes">planes</param>
34+
/// <param name="bitCount">bitCount</param>
35+
public CurPngFrameMetadata(byte width, byte height, byte colorCount, ushort planes, ushort bitCount)
36+
: base(width, height, colorCount, planes, bitCount)
37+
{
38+
}
39+
40+
/// <inheritdoc/>
41+
public override IcoLikeFrameCompression Compression { get; } = IcoLikeFrameCompression.Png;
42+
43+
/// <summary>
44+
/// Gets or sets the number of bits per sample or per palette index (not per pixel).
45+
/// Not all values are allowed for all <see cref="ColorType"/> values.
46+
/// </summary>
47+
public PngBitDepth? BitDepth { get; set; }
48+
49+
/// <summary>
50+
/// Gets or sets the color type.
51+
/// </summary>
52+
public PngColorType? ColorType { get; set; }
53+
54+
/// <summary>
55+
/// Gets or sets a value indicating whether this instance should write an Adam7 interlaced image.
56+
/// </summary>
57+
public PngInterlaceMode? InterlaceMethod { get; set; } = PngInterlaceMode.None;
58+
59+
/// <summary>
60+
/// Gets or sets the gamma value for the image.
61+
/// </summary>
62+
public float Gamma { get; set; }
63+
64+
/// <summary>
65+
/// Gets or sets the color table, if any.
66+
/// </summary>
67+
public ReadOnlyMemory<Color>? ColorTable { get; set; }
68+
69+
/// <summary>
70+
/// Gets or sets the transparent color used with non palette based images, if a transparency chunk and markers were decoded.
71+
/// </summary>
72+
public Color? TransparentColor { get; set; }
73+
74+
/// <summary>
75+
/// Gets or sets the collection of text data stored within the iTXt, tEXt, and zTXt chunks.
76+
/// Used for conveying textual information associated with the image.
77+
/// </summary>
78+
public IList<PngTextData> TextData { get; set; } = new List<PngTextData>();
79+
80+
/// <summary>
81+
/// Gets or sets the number of times to loop this APNG. 0 indicates infinite looping.
82+
/// </summary>
83+
public int RepeatCount { get; set; }
84+
85+
/// <inheritdoc/>
86+
public override CurPngFrameMetadata DeepClone() => new(this);
87+
88+
internal override void FromMetadata(IDeepCloneable other)
89+
{
90+
if (other is not PngMetadata metadata)
91+
{
92+
return;
93+
}
94+
95+
this.BitDepth = metadata.BitDepth;
96+
this.ColorType = metadata.ColorType;
97+
this.Gamma = metadata.Gamma;
98+
this.InterlaceMethod = metadata.InterlaceMethod;
99+
this.TransparentColor = metadata.TransparentColor;
100+
this.RepeatCount = metadata.RepeatCount;
101+
102+
if (metadata.ColorTable?.Length > 0)
103+
{
104+
this.ColorTable = metadata.ColorTable.Value.ToArray();
105+
}
106+
107+
for (int i = 0; i < metadata.TextData.Count; i++)
108+
{
109+
this.TextData.Add(metadata.TextData[i]);
110+
}
111+
}
112+
113+
internal override PngMetadata ToMetadata()
114+
{
115+
PngMetadata result = new()
116+
{
117+
BitDepth = this.BitDepth,
118+
ColorType = this.ColorType,
119+
Gamma = this.Gamma,
120+
InterlaceMethod = this.InterlaceMethod,
121+
TransparentColor = this.TransparentColor,
122+
RepeatCount = this.RepeatCount,
123+
};
124+
125+
if (this.ColorTable?.Length > 0)
126+
{
127+
result.ColorTable = this.ColorTable.Value.ToArray();
128+
}
129+
130+
for (int i = 0; i < this.TextData.Count; i++)
131+
{
132+
result.TextData.Add(this.TextData[i]);
133+
}
134+
135+
return result;
136+
}
137+
}

src/ImageSharp/Formats/Cur/MetadataExtensions.cs

+10-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@ public static CurMetadata GetCurMetadata(this ImageMetadata source)
2424
/// </summary>
2525
/// <param name="source">The metadata this method extends.</param>
2626
/// <returns>The <see cref="CurFrameMetadata"/>.</returns>
27-
public static CurFrameMetadata GetCurMetadata(this ImageFrameMetadata source)
28-
=> source.GetFormatMetadata(CurFormat.Instance);
27+
public static CurFrameMetadata GetCurMetadataWithBmp(this ImageFrameMetadata source)
28+
=> source.GetFormatMetadata(CurFormat.Instance, CurFormat.CreateBmpFormatFrameMetadata);
29+
30+
/// <summary>
31+
/// Gets the Cur format specific metadata for the image frame.
32+
/// </summary>
33+
/// <param name="source">The metadata this method extends.</param>
34+
/// <returns>The <see cref="CurFrameMetadata"/>.</returns>
35+
public static CurFrameMetadata GetCurMetadataWithPng(this ImageFrameMetadata source)
36+
=> source.GetFormatMetadata(CurFormat.Instance, CurFormat.CreatePngFormatFrameMetadata);
2937

3038
/// <summary>
3139
/// Gets the Cur format specific metadata for the image frame.

src/ImageSharp/Formats/Ico/Common/IcoAssert.cs

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ namespace SixLabors.ImageSharp.Formats.Ico.Common;
55

66
internal class IcoAssert
77
{
8+
internal static void CanSeek(Stream stream)
9+
{
10+
if (!stream.CanSeek)
11+
{
12+
throw new NotSupportedException("This stream cannot support seek");
13+
}
14+
}
15+
816
internal static int EndOfStream(int v, int length)
917
{
1018
if (v != length)

src/ImageSharp/Formats/Ico/Common/IcoDir.cs

+11
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,15 @@ internal struct IcoDir
1212
public ushort Reserved;
1313
public IcoFileType Type;
1414
public ushort Count;
15+
16+
public IcoDir(IcoFileType type)
17+
: this(0, type, 0)
18+
=> this.Type = type;
19+
20+
public IcoDir(ushort reserved, IcoFileType type, ushort count)
21+
{
22+
this.Reserved = reserved;
23+
this.Type = type;
24+
this.Count = count;
25+
}
1526
}

0 commit comments

Comments
 (0)