diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index b6348803a..72e3ed144 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -376,7 +376,17 @@ namespace SixLabors.ImageSharp.Formats.Gif indices = this.Configuration.MemoryAllocator.Allocate2D(this.imageDescriptor.Width, this.imageDescriptor.Height, AllocationOptions.Clean); this.ReadFrameIndices(indices); - ReadOnlySpan colorTable = MemoryMarshal.Cast((localColorTable ?? this.globalColorTable).GetSpan()); + Span rawColorTable = default; + if (localColorTable != null) + { + rawColorTable = localColorTable.GetSpan(); + } + else if (this.globalColorTable != null) + { + rawColorTable = this.globalColorTable.GetSpan(); + } + + ReadOnlySpan colorTable = MemoryMarshal.Cast(rawColorTable); this.ReadFrameColors(ref image, ref previousFrame, indices, colorTable, this.imageDescriptor); // Skip any remaining blocks @@ -415,6 +425,7 @@ namespace SixLabors.ImageSharp.Formats.Gif { int imageWidth = this.logicalScreenDescriptor.Width; int imageHeight = this.logicalScreenDescriptor.Height; + bool transFlag = this.graphicsControlExtension.TransparencyFlag; ImageFrame prevFrame = null; ImageFrame currentFrame = null; @@ -422,8 +433,15 @@ namespace SixLabors.ImageSharp.Formats.Gif if (previousFrame is null) { - // This initializes the image to become fully transparent because the alpha channel is zero. - image = new Image(this.Configuration, imageWidth, imageHeight, this.metadata); + if (!transFlag) + { + image = new Image(this.Configuration, imageWidth, imageHeight, Color.Black.ToPixel(), this.metadata); + } + else + { + // This initializes the image to become fully transparent because the alpha channel is zero. + image = new Image(this.Configuration, imageWidth, imageHeight, this.metadata); + } this.SetFrameMetadata(image.Frames.RootFrame.Metadata); @@ -445,6 +463,11 @@ namespace SixLabors.ImageSharp.Formats.Gif this.RestoreToBackground(imageFrame); } + if (colorTable.Length == 0) + { + return; + } + int interlacePass = 0; // The interlace pass int interlaceIncrement = 8; // The interlacing line increment int interlaceY = 0; // The current interlaced line @@ -452,7 +475,6 @@ namespace SixLabors.ImageSharp.Formats.Gif int descriptorBottom = descriptorTop + descriptor.Height; int descriptorLeft = descriptor.Left; int descriptorRight = descriptorLeft + descriptor.Width; - bool transFlag = this.graphicsControlExtension.TransparencyFlag; byte transIndex = this.graphicsControlExtension.TransparencyIndex; int colorTableMaxIdx = colorTable.Length - 1; @@ -635,10 +657,13 @@ namespace SixLabors.ImageSharp.Formats.Gif int globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3; this.gifMetadata.GlobalColorTableLength = globalColorTableLength; - this.globalColorTable = this.MemoryAllocator.Allocate(globalColorTableLength, AllocationOptions.Clean); + if (globalColorTableLength > 0) + { + this.globalColorTable = this.MemoryAllocator.Allocate(globalColorTableLength, AllocationOptions.Clean); - // Read the global color table data from the stream - stream.Read(this.globalColorTable.GetSpan()); + // Read the global color table data from the stream + stream.Read(this.globalColorTable.GetSpan()); + } } } } diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs index 6bf606ac9..c8ecdb717 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs @@ -247,5 +247,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif "Disco") .Dispose(); } + + // https://github.com/SixLabors/ImageSharp/issues/1962 + [Theory] + [WithFile(TestImages.Gif.Issues.Issue1962NoColorTable, PixelTypes.Rgba32)] + public void Issue1962(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(); + image.DebugSave(provider); + + image.CompareFirstFrameToReferenceOutput(ImageComparer.Exact, provider); + } } } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index b0537817b..8b943194a 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -451,6 +451,7 @@ namespace SixLabors.ImageSharp.Tests public const string Issue1505 = "Gif/issues/issue1505_argumentoutofrange.png"; public const string Issue1530 = "Gif/issues/issue1530.gif"; public const string InvalidColorIndex = "Gif/issues/issue1668_invalidcolorindex.gif"; + public const string Issue1962NoColorTable = "Gif/issues/issue1962_tiniest_gif_1st.gif"; } public static readonly string[] All = { Rings, Giphy, Cheers, Trans, Kumin, Leo, Ratio4x1, Ratio1x4 }; diff --git a/tests/Images/External/ReferenceOutput/GifDecoderTests/Issue1962_Rgba32_issue1962_tiniest_gif_1st.png b/tests/Images/External/ReferenceOutput/GifDecoderTests/Issue1962_Rgba32_issue1962_tiniest_gif_1st.png new file mode 100644 index 000000000..24f5e9c0c --- /dev/null +++ b/tests/Images/External/ReferenceOutput/GifDecoderTests/Issue1962_Rgba32_issue1962_tiniest_gif_1st.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f8c6d416f09671777934e57bc67fb52ccc97145dc6f1869e628d9ffd7d8f6e7 +size 119 diff --git a/tests/Images/Input/Gif/issues/issue1962_tiniest_gif_1st.gif b/tests/Images/Input/Gif/issues/issue1962_tiniest_gif_1st.gif new file mode 100644 index 000000000..a5bc432d8 --- /dev/null +++ b/tests/Images/Input/Gif/issues/issue1962_tiniest_gif_1st.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b7b8a4b411ddf8db9bacc2f3aabf406f8e4c0c087829b336ca331c40adfdff1 +size 26