Skip to content

Commit 6e54822

Browse files
committed
Fix review
1 parent bf308b7 commit 6e54822

6 files changed

Lines changed: 115 additions & 175 deletions

File tree

src/ImageSharp/Formats/Png/Chunks/AnimationControl.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,25 @@
55

66
namespace SixLabors.ImageSharp.Formats.Png.Chunks;
77

8-
internal record AnimationControl(
9-
int NumberFrames,
10-
int NumberPlays)
8+
internal readonly struct AnimationControl
119
{
1210
public const int Size = 8;
1311

12+
public AnimationControl(int numberFrames, int numberPlays)
13+
{
14+
this.NumberFrames = numberFrames;
15+
this.NumberPlays = numberPlays;
16+
}
17+
1418
/// <summary>
1519
/// Gets the number of frames
1620
/// </summary>
17-
public int NumberFrames { get; } = NumberFrames;
21+
public int NumberFrames { get; }
1822

1923
/// <summary>
2024
/// Gets the number of times to loop this APNG. 0 indicates infinite looping.
2125
/// </summary>
22-
public int NumberPlays { get; } = NumberPlays;
26+
public int NumberPlays { get; }
2327

2428
/// <summary>
2529
/// Writes the acTL to the given buffer.
@@ -38,6 +42,6 @@ public void WriteTo(Span<byte> buffer)
3842
/// <returns>The parsed acTL.</returns>
3943
public static AnimationControl Parse(ReadOnlySpan<byte> data)
4044
=> new(
41-
NumberFrames: BinaryPrimitives.ReadInt32BigEndian(data[..4]),
42-
NumberPlays: BinaryPrimitives.ReadInt32BigEndian(data[4..8]));
45+
numberFrames: BinaryPrimitives.ReadInt32BigEndian(data[..4]),
46+
numberPlays: BinaryPrimitives.ReadInt32BigEndian(data[4..8]));
4347
}

src/ImageSharp/Formats/Png/Chunks/FrameControl.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,32 +86,32 @@ public void Validate(PngHeader hdr)
8686
{
8787
if (this.XOffset < 0)
8888
{
89-
throw new NotSupportedException($"Invalid XOffset. Expected >= 0. Was '{this.XOffset}'.");
89+
PngThrowHelper.ThrowInvalidParameter(this.XOffset, "Expected >= 0");
9090
}
9191

9292
if (this.YOffset < 0)
9393
{
94-
throw new NotSupportedException($"Invalid YOffset. Expected >= 0. Was '{this.YOffset}'.");
94+
PngThrowHelper.ThrowInvalidParameter(this.YOffset, "Expected >= 0");
9595
}
9696

9797
if (this.Width <= 0)
9898
{
99-
throw new NotSupportedException($"Invalid Width. Expected > 0. Was '{this.Width}'.");
99+
PngThrowHelper.ThrowInvalidParameter(this.Width, "Expected > 0");
100100
}
101101

102102
if (this.Height <= 0)
103103
{
104-
throw new NotSupportedException($"Invalid Height. Expected > 0. Was '{this.Height}'.");
104+
PngThrowHelper.ThrowInvalidParameter(this.Height, "Expected > 0");
105105
}
106106

107107
if (this.XOffset + this.Width > hdr.Width)
108108
{
109-
throw new NotSupportedException($"Invalid XOffset or Width. The sum > PngHeader.Width. Was '{this.XOffset + this.Width}'.");
109+
PngThrowHelper.ThrowInvalidParameter(this.XOffset, this.Width, $"The sum > {nameof(PngHeader)}.{nameof(PngHeader.Width)}");
110110
}
111111

112112
if (this.YOffset + this.Height > hdr.Height)
113113
{
114-
throw new NotSupportedException($"Invalid YOffset or Height. The sum > PngHeader.Height. Was '{this.YOffset + this.Height}'.");
114+
PngThrowHelper.ThrowInvalidParameter(this.YOffset, this.Height, "The sum > PngHeader.Height");
115115
}
116116
}
117117

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
3434
private readonly Configuration configuration;
3535

3636
/// <summary>
37-
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
37+
/// Whether the metadata should be ignored when the image is being decoded.
38+
/// </summary>
39+
private readonly uint maxFrames;
40+
41+
/// <summary>
42+
/// Whether the metadata should be ignored when the image is being decoded.
3843
/// </summary>
3944
private readonly bool skipMetadata;
4045

4146
/// <summary>
42-
/// Gets or sets a value indicating whether to read the IHDR and tRNS chunks only.
47+
/// Whether to read the IHDR and tRNS chunks only.
4348
/// </summary>
4449
private readonly bool colorMetadataOnly;
4550

@@ -61,7 +66,7 @@ internal sealed class PngDecoderCore : IImageDecoderInternals
6166
/// <summary>
6267
/// The png animation control.
6368
/// </summary>
64-
private AnimationControl? animationControl;
69+
private AnimationControl animationControl;
6570

6671
/// <summary>
6772
/// The number of bytes per pixel.
@@ -116,6 +121,7 @@ public PngDecoderCore(DecoderOptions options)
116121
{
117122
this.Options = options;
118123
this.configuration = options.Configuration;
124+
this.maxFrames = options.MaxFrames;
119125
this.skipMetadata = options.SkipMetadata;
120126
this.memoryAllocator = this.configuration.MemoryAllocator;
121127
}
@@ -124,6 +130,7 @@ internal PngDecoderCore(DecoderOptions options, bool colorMetadataOnly)
124130
{
125131
this.Options = options;
126132
this.colorMetadataOnly = colorMetadataOnly;
133+
this.maxFrames = options.MaxFrames;
127134
this.skipMetadata = true;
128135
this.configuration = options.Configuration;
129136
this.memoryAllocator = this.configuration.MemoryAllocator;
@@ -139,6 +146,7 @@ internal PngDecoderCore(DecoderOptions options, bool colorMetadataOnly)
139146
public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancellationToken)
140147
where TPixel : unmanaged, IPixel<TPixel>
141148
{
149+
uint frameCount = 0;
142150
ImageMetadata metadata = new();
143151
PngMetadata pngMetadata = metadata.GetPngMetadata();
144152
this.currentStream = stream;
@@ -174,10 +182,21 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
174182
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
175183
break;
176184
case PngChunkType.FrameControl:
185+
++frameCount;
186+
if (frameCount == this.maxFrames)
187+
{
188+
break;
189+
}
190+
177191
currentFrame = null;
178192
lastFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan());
179193
break;
180194
case PngChunkType.FrameData:
195+
if (frameCount == this.maxFrames)
196+
{
197+
break;
198+
}
199+
181200
if (image is null)
182201
{
183202
PngThrowHelper.ThrowMissingDefaultData();
@@ -290,6 +309,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
290309
/// <inheritdoc/>
291310
public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
292311
{
312+
uint frameCount = 0;
293313
ImageMetadata metadata = new();
294314
PngMetadata pngMetadata = metadata.GetPngMetadata();
295315
this.currentStream = stream;
@@ -331,9 +351,20 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat
331351
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
332352
break;
333353
case PngChunkType.FrameControl:
354+
++frameCount;
355+
if (frameCount == this.maxFrames)
356+
{
357+
break;
358+
}
359+
334360
lastFrameControl = this.ReadFrameControlChunk(chunk.Data.GetSpan());
335361
break;
336362
case PngChunkType.FrameData:
363+
if (frameCount == this.maxFrames)
364+
{
365+
break;
366+
}
367+
337368
if (this.colorMetadataOnly)
338369
{
339370
goto EOF;

src/ImageSharp/Formats/Png/PngEncoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ private void EncodePixels<TPixel>(ImageFrame<TPixel> pixels, IndexedImageFrame<T
10771077
{
10781078
int width = this.width;
10791079
int height = this.height;
1080-
if (pixels.Metadata.TryGetAPngFrameMetadata(out PngFrameMetadata? pngMetadata))
1080+
if (pixels.Metadata.TryGetPngFrameMetadata(out PngFrameMetadata? pngMetadata))
10811081
{
10821082
width = pngMetadata.Width;
10831083
height = pngMetadata.Height;

0 commit comments

Comments
 (0)