Browse Source

Add FrameDecodingMode. Fix #255

af/merge-core
James Jackson-South 8 years ago
parent
commit
e8dfbccaf9
  1. 21
      src/ImageSharp/Formats/Gif/FrameDecodingMode.cs
  2. 5
      src/ImageSharp/Formats/Gif/GifDecoder.cs
  3. 19
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  4. 5
      src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs
  5. 37
      tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs

21
src/ImageSharp/Formats/Gif/FrameDecodingMode.cs

@ -0,0 +1,21 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Gif
{
/// <summary>
/// Enumerated frame process modes to apply to multi-frame images.
/// </summary>
public enum FrameDecodingMode
{
/// <summary>
/// Decodes all the frames of a multi-frame image.
/// </summary>
All,
/// <summary>
/// Decodes only the first frame of a multi-frame image.
/// </summary>
First
}
}

5
src/ImageSharp/Formats/Gif/GifDecoder.cs

@ -24,6 +24,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// </summary>
public Encoding TextEncoding { get; set; } = GifConstants.DefaultEncoding;
/// <summary>
/// Gets or sets the decoding mode for multi-frame images
/// </summary>
public FrameDecodingMode DecodingMode { get; set; } = FrameDecodingMode.All;
/// <inheritdoc/>
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
where TPixel : struct, IPixel<TPixel>

19
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -84,6 +84,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
{
this.TextEncoding = options.TextEncoding ?? GifConstants.DefaultEncoding;
this.IgnoreMetadata = options.IgnoreMetadata;
this.DecodingMode = options.DecodingMode;
this.configuration = configuration ?? Configuration.Default;
}
@ -97,6 +98,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// </summary>
public Encoding TextEncoding { get; }
/// <summary>
/// Gets the decoding mode for multi-frame images
/// </summary>
public FrameDecodingMode DecodingMode { get; }
/// <summary>
/// Decodes the stream to the image.
/// </summary>
@ -129,6 +135,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
{
if (nextFlag == GifConstants.ImageLabel)
{
if (this.previousFrame != null && this.DecodingMode == FrameDecodingMode.First)
{
break;
}
this.ReadFrame();
}
else if (nextFlag == GifConstants.ExtensionIntroducer)
@ -238,14 +249,6 @@ namespace SixLabors.ImageSharp.Formats.Gif
{
throw new ImageFormatException($"Invalid gif colormap size '{this.logicalScreenDescriptor.GlobalColorTableSize}'");
}
/* // No point doing this as the max width/height is always int.Max and that always bigger than the max size of a gif which is stored in a short.
if (this.logicalScreenDescriptor.Width > Image<TPixel>.MaxWidth || this.logicalScreenDescriptor.Height > Image<TPixel>.MaxHeight)
{
throw new ArgumentOutOfRangeException(
$"The input gif '{this.logicalScreenDescriptor.Width}x{this.logicalScreenDescriptor.Height}' is bigger then the max allowed size '{Image<TPixel>.MaxWidth}x{Image<TPixel>.MaxHeight}'");
}
*/
}
/// <summary>

5
src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs

@ -19,5 +19,10 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// Gets the encoding that should be used when reading comments.
/// </summary>
Encoding TextEncoding { get; }
/// <summary>
/// Gets the decoding mode for multi-frame images
/// </summary>
FrameDecodingMode DecodingMode { get; }
}
}

37
tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System.Text;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
@ -45,12 +44,12 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void Decode_IgnoreMetadataIsFalse_CommentsAreRead()
{
GifDecoder options = new GifDecoder()
var options = new GifDecoder
{
IgnoreMetadata = false
};
TestFile testFile = TestFile.Create(TestImages.Gif.Rings);
var testFile = TestFile.Create(TestImages.Gif.Rings);
using (Image<Rgba32> image = testFile.CreateImage(options))
{
@ -63,12 +62,12 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void Decode_IgnoreMetadataIsTrue_CommentsAreIgnored()
{
GifDecoder options = new GifDecoder()
var options = new GifDecoder
{
IgnoreMetadata = true
};
TestFile testFile = TestFile.Create(TestImages.Gif.Rings);
var testFile = TestFile.Create(TestImages.Gif.Rings);
using (Image<Rgba32> image = testFile.CreateImage(options))
{
@ -79,12 +78,12 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void Decode_TextEncodingSetToUnicode_TextIsReadWithCorrectEncoding()
{
GifDecoder options = new GifDecoder()
var options = new GifDecoder
{
TextEncoding = Encoding.Unicode
};
TestFile testFile = TestFile.Create(TestImages.Gif.Rings);
var testFile = TestFile.Create(TestImages.Gif.Rings);
using (Image<Rgba32> image = testFile.CreateImage(options))
{
@ -92,5 +91,27 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal("浉条卥慨灲", image.MetaData.Properties[0].Value);
}
}
[Theory]
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)]
public void CanDecodeJustOneFrame<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new GifDecoder { DecodingMode = FrameDecodingMode.First }))
{
Assert.Equal(1, image.Frames.Count);
}
}
[Theory]
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)]
public void CanDecodeAllFrames<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new GifDecoder { DecodingMode = FrameDecodingMode.All }))
{
Assert.True(image.Frames.Count > 1);
}
}
}
}
}
Loading…
Cancel
Save