From 210c4817e45e328d18b5216d867418aa2ea50dff Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Tue, 28 Apr 2020 10:15:58 +0200 Subject: [PATCH] Additional gif test cases --- src/ImageSharp/Formats/Gif/README.md | 8 +- .../Formats/Gif/GifDecoderTests.cs | 82 ++++++++++-------- tests/ImageSharp.Tests/TestImages.cs | 7 ++ tests/Images/Input/Gif/image-zero-height.gif | Bin 0 -> 30 bytes tests/Images/Input/Gif/image-zero-size.gif | Bin 0 -> 30 bytes tests/Images/Input/Gif/image-zero-width.gif | Bin 0 -> 30 bytes tests/Images/Input/Gif/max-height.gif | Bin 0 -> 405 bytes tests/Images/Input/Gif/max-width.gif | Bin 0 -> 405 bytes 8 files changed, 59 insertions(+), 38 deletions(-) create mode 100644 tests/Images/Input/Gif/image-zero-height.gif create mode 100644 tests/Images/Input/Gif/image-zero-size.gif create mode 100644 tests/Images/Input/Gif/image-zero-width.gif create mode 100644 tests/Images/Input/Gif/max-height.gif create mode 100644 tests/Images/Input/Gif/max-width.gif diff --git a/src/ImageSharp/Formats/Gif/README.md b/src/ImageSharp/Formats/Gif/README.md index d47a4c683..eeda20c06 100644 --- a/src/ImageSharp/Formats/Gif/README.md +++ b/src/ImageSharp/Formats/Gif/README.md @@ -1,4 +1,6 @@ -Encoder/Decoder adapted and extended from: +Encoder/Decoder adapted and extended from: -https://github.com/yufeih/Nine.Imaging/ -https://imagetools.codeplex.com/ +- [Nine.Imaging](https://github.com/yufeih/Nine.Imaging/) +- [imagetools.codeplex](https://imagetools.codeplex.com/) + +A useful set of gif test images can be found at [pygif](https://github.com/robert-ancell/pygif/tree/master/test-suite) \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index b3a99aa1c..199c6c0b2 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -2,11 +2,9 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Collections.Generic; using System.IO; using Microsoft.DotNet.RemoteExecutor; -using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata; @@ -30,32 +28,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif TestImages.Gif.Giphy, TestImages.Gif.Kumin }; - public static readonly string[] BasicVerificationFiles = - { - TestImages.Gif.Cheers, - TestImages.Gif.Rings, - - // previously DecodeBadApplicationExtensionLength: - TestImages.Gif.Issues.BadAppExtLength, - TestImages.Gif.Issues.BadAppExtLength_2, - - // previously DecodeBadDescriptorDimensionsLength: - TestImages.Gif.Issues.BadDescriptorWidth - }; - - private static readonly Dictionary BasicVerificationFrameCount = - new Dictionary - { - [TestImages.Gif.Cheers] = 93, - [TestImages.Gif.Issues.BadDescriptorWidth] = 36, - }; - - public static readonly string[] BadAppExtFiles = - { - TestImages.Gif.Issues.BadAppExtLength, - TestImages.Gif.Issues.BadAppExtLength_2 - }; - [Theory] [WithFileCollection(nameof(MultiFrameTestFiles), PixelTypes.Rgba32)] public void Decode_VerifyAllFrames(TestImageProvider provider) @@ -100,15 +72,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif } [Theory] - [WithFileCollection(nameof(BasicVerificationFiles), PixelTypes.Rgba32)] - public void Decode_VerifyRootFrameAndFrameCount(TestImageProvider provider) + [WithFile(TestImages.Gif.Cheers, PixelTypes.Rgba32, 93)] + [WithFile(TestImages.Gif.Rings, PixelTypes.Rgba32, 1)] + [WithFile(TestImages.Gif.Issues.BadDescriptorWidth, PixelTypes.Rgba32, 36)] + public void Decode_VerifyRootFrameAndFrameCount(TestImageProvider provider, int expectedFrameCount) where TPixel : unmanaged, IPixel { - if (!BasicVerificationFrameCount.TryGetValue(provider.SourceFileOrDescription, out int expectedFrameCount)) - { - expectedFrameCount = 1; - } - using (Image image = provider.GetImage()) { Assert.Equal(expectedFrameCount, image.Frames.Count); @@ -153,6 +122,35 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif } } + [Theory] + [WithFile(TestImages.Gif.ZeroSize, PixelTypes.Rgba32)] + [WithFile(TestImages.Gif.ZeroWidth, PixelTypes.Rgba32)] + [WithFile(TestImages.Gif.ZeroHeight, PixelTypes.Rgba32)] + public void Decode_WithInvalidDimensions_DoesThrowException(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + System.Exception ex = Record.Exception( + () => + { + using Image image = provider.GetImage(GifDecoder); + }); + Assert.NotNull(ex); + Assert.Contains("Width or height should not be 0", ex.Message); + } + + [Theory] + [WithFile(TestImages.Gif.MaxWidth, PixelTypes.Rgba32, 65535, 1)] + [WithFile(TestImages.Gif.MaxHeight, PixelTypes.Rgba32, 1, 65535)] + public void Decode_WithMaxDimensions_Works(TestImageProvider provider, int expectedWidth, int expectedHeight) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(GifDecoder)) + { + Assert.Equal(expectedWidth, image.Width); + Assert.Equal(expectedHeight, image.Height); + } + } + [Fact] public void CanDecodeIntermingledImages() { @@ -172,6 +170,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif } } + // https://github.com/SixLabors/ImageSharp/issues/405 + [Theory] + [WithFile(TestImages.Gif.Issues.BadAppExtLength, PixelTypes.Rgba32)] + [WithFile(TestImages.Gif.Issues.BadAppExtLength_2, PixelTypes.Rgba32)] + public void Issue405_BadApplicationExtensionBlockLength(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage()) + { + image.DebugSave(provider); + image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider); + } + } + [Theory] [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)] [WithFile(TestImages.Gif.Kumin, PixelTypes.Rgba32)] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index bec0c6624..141a8d1c3 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -397,6 +397,13 @@ namespace SixLabors.ImageSharp.Tests public const string Ratio1x4 = "Gif/base_1x4.gif"; public const string LargeComment = "Gif/large_comment.gif"; + // Test images from https://github.com/robert-ancell/pygif/tree/master/test-suite + public const string ZeroSize = "Gif/image-zero-size.gif"; + public const string ZeroHeight = "Gif/image-zero-height.gif"; + public const string ZeroWidth = "Gif/image-zero-width.gif"; + public const string MaxWidth = "Gif/max-width.gif"; + public const string MaxHeight = "Gif/max-height.gif"; + public static class Issues { public const string BadAppExtLength = "Gif/issues/issue405_badappextlength252.gif"; diff --git a/tests/Images/Input/Gif/image-zero-height.gif b/tests/Images/Input/Gif/image-zero-height.gif new file mode 100644 index 0000000000000000000000000000000000000000..ddd3c43e885ff6c1a89cddd39d4ab477600edaf2 GIT binary patch literal 30 fcmZ?wbhEHbWMp7u_`t{j1poj4*8$NWPJ=Z7YKI1a literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Gif/image-zero-size.gif b/tests/Images/Input/Gif/image-zero-size.gif new file mode 100644 index 0000000000000000000000000000000000000000..8cb8c9e80f1d1d4878e2314ed9da92e61b219102 GIT binary patch literal 30 fcmZ?wbhEHbWMp7u_`t{j1poj4*8$NW&|nP!YJmoT literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Gif/image-zero-width.gif b/tests/Images/Input/Gif/image-zero-width.gif new file mode 100644 index 0000000000000000000000000000000000000000..ba61320c8a1bf1cb52572e845dc556724d333c32 GIT binary patch literal 30 gcmZ?wbhEHbWMp7u_`t{j1poj4*8$NCKoJIO0BMB=0RR91 literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Gif/max-height.gif b/tests/Images/Input/Gif/max-height.gif new file mode 100644 index 0000000000000000000000000000000000000000..586d03071bbb0384dfe23646ae4a2cd34b711e6b GIT binary patch literal 405 zcmV;G0c!q7Nk%w1VF3XD|MCC;00030|Ns900093000930|Ns90|Ns90EC2ui00991 z{{RF37`oj4Fv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ z$!t2G(5Q4uty-_xtai)odcWYXcuX#v&*-#z&2GEj@VIs;jK6uCK7Mva__cwzs&s zy1Tr+zQ4f1!o$SH#>dFX%FE2n&d<=%($mz{*4NnC+S}aS-rwNi;^XAy=I7|?>g(+7 z?(gvN^7Hid_V@Vt`uqI-{{H|23LHqVpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$F zqsNaRLy8oJq5$&6_xL>fFh*r_Y~2g9;r=w5ZXeNRujE z%CxD|r%}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ z$!t2G(5Q4uty-_xtai)odcWYXcuX#v&*-#z&2GEj@VIs;jK6uCK7Mva__cwzs&s zy1Tr+zQ4f1!o$SH#>dFX%FE2n&d<=%($mz{*4NnC+S}aS-rwNi;^XAy=I7|?>g(+7 z?(gvN^7Hid_V@Vt`uqI-{{H|23LHqVpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$F zqsNaRLy8oJq5$&6_xL>fFh*r_Y~2g9;r=w5ZXeNRujE z%CxD|r%