diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index 7f5276a250..776cb0e3c2 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -716,7 +716,7 @@ internal sealed class GifDecoderCore : IImageDecoderInternals colorTable[i] = new Color(Unsafe.Add(ref localBase, (uint)i)); } - gifMeta.DecodedLocalColorTable = colorTable; + gifMeta.LocalColorTable = colorTable; } // Graphics control extensions is optional. @@ -793,7 +793,7 @@ internal sealed class GifDecoderCore : IImageDecoderInternals colorTable[i] = new Color(Unsafe.Add(ref globalBase, (uint)i)); } - this.gifMetadata.DecodedGlobalColorTable = colorTable; + this.gifMetadata.GlobalColorTable = colorTable; } } } diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index 0bcb3ef0fa..90e7a8b1ea 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -102,10 +102,10 @@ internal sealed class GifEncoderCore : IImageEncoderInternals if (this.quantizer is null) { // Is this a gif with color information. If so use that, otherwise use octree. - if (gifMetadata.ColorTableMode == GifColorTableMode.Global && gifMetadata.DecodedGlobalColorTable.Length > 0) + if (gifMetadata.ColorTableMode == GifColorTableMode.Global && gifMetadata.GlobalColorTable?.Length > 0) { // We avoid dithering by default to preserve the original colors. - this.quantizer = new PaletteQuantizer(gifMetadata.DecodedGlobalColorTable, new() { Dither = null }); + this.quantizer = new PaletteQuantizer(gifMetadata.GlobalColorTable.Value, new() { Dither = null }); } else { @@ -234,11 +234,11 @@ internal sealed class GifEncoderCore : IImageEncoderInternals if (useLocal) { // Reassign using the current frame and details. - if (metadata?.DecodedLocalColorTable.Length > 0) + if (metadata?.LocalColorTable?.Length > 0) { // We can use the color data from the decoded metadata here. // We avoid dithering by default to preserve the original colors. - PaletteQuantizer localQuantizer = new(metadata.DecodedLocalColorTable, new() { Dither = null }); + PaletteQuantizer localQuantizer = new(metadata.LocalColorTable.Value, new() { Dither = null }); using IQuantizer frameQuantizer = localQuantizer.CreatePixelSpecificQuantizer(this.configuration, localQuantizer.Options); quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(frame, frame.Bounds()); } diff --git a/src/ImageSharp/Formats/Gif/GifFrameMetadata.cs b/src/ImageSharp/Formats/Gif/GifFrameMetadata.cs index bcf990db53..f7959ac12b 100644 --- a/src/ImageSharp/Formats/Gif/GifFrameMetadata.cs +++ b/src/ImageSharp/Formats/Gif/GifFrameMetadata.cs @@ -25,9 +25,9 @@ public class GifFrameMetadata : IDeepCloneable this.FrameDelay = other.FrameDelay; this.DisposalMethod = other.DisposalMethod; - if (other.DecodedLocalColorTable.Length > 0) + if (other.LocalColorTable?.Length > 0) { - this.DecodedLocalColorTable = other.DecodedLocalColorTable.ToArray(); + this.LocalColorTable = other.LocalColorTable.Value.ToArray(); } this.HasTransparency = other.HasTransparency; @@ -40,9 +40,9 @@ public class GifFrameMetadata : IDeepCloneable public GifColorTableMode ColorTableMode { get; set; } /// - /// Gets the decoded global color table, if any. + /// Gets or sets the local color table, if any. /// - public ReadOnlyMemory DecodedLocalColorTable { get; internal set; } + public ReadOnlyMemory? LocalColorTable { get; set; } /// /// Gets or sets a value indicating whether the frame has transparency diff --git a/src/ImageSharp/Formats/Gif/GifMetadata.cs b/src/ImageSharp/Formats/Gif/GifMetadata.cs index 251cde0bbb..184ccd644f 100644 --- a/src/ImageSharp/Formats/Gif/GifMetadata.cs +++ b/src/ImageSharp/Formats/Gif/GifMetadata.cs @@ -25,9 +25,9 @@ public class GifMetadata : IDeepCloneable this.ColorTableMode = other.ColorTableMode; this.BackgroundColor = other.BackgroundColor; - if (other.DecodedGlobalColorTable.Length > 0) + if (other.GlobalColorTable?.Length > 0) { - this.DecodedGlobalColorTable = other.DecodedGlobalColorTable.ToArray(); + this.GlobalColorTable = other.GlobalColorTable.Value.ToArray(); } for (int i = 0; i < other.Comments.Count; i++) @@ -50,12 +50,12 @@ public class GifMetadata : IDeepCloneable public GifColorTableMode ColorTableMode { get; set; } /// - /// Gets the decoded global color table, if any. + /// Gets or sets the global color table, if any. /// - public ReadOnlyMemory DecodedGlobalColorTable { get; internal set; } + public ReadOnlyMemory? GlobalColorTable { get; set; } /// - /// Gets or sets the index at the for the background color. + /// Gets or sets the index at the for the background color. /// The background color is the color used for those pixels on the screen that are not covered by an image. /// public byte BackgroundColor { get; set; } diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs index 0b8034572f..de70077745 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs @@ -175,11 +175,11 @@ public class GifEncoderTests int maxColors; if (colorMode == GifColorTableMode.Global) { - maxColors = metaData.DecodedGlobalColorTable.Length; + maxColors = metaData.GlobalColorTable.Value.Length; } else { - maxColors = frameMetadata.DecodedLocalColorTable.Length; + maxColors = frameMetadata.LocalColorTable.Value.Length; } GifEncoder encoder = new() @@ -201,11 +201,11 @@ public class GifEncoderTests colorMode = cloneMetadata.ColorTableMode; if (colorMode == GifColorTableMode.Global) { - maxColors = metaData.DecodedGlobalColorTable.Length; + maxColors = metaData.GlobalColorTable.Value.Length; } else { - maxColors = frameMetadata.DecodedLocalColorTable.Length; + maxColors = frameMetadata.LocalColorTable.Value.Length; } Assert.Equal(64, maxColors); @@ -217,7 +217,7 @@ public class GifEncoderTests if (iMeta.ColorTableMode == GifColorTableMode.Local) { - Assert.Equal(iMeta.DecodedLocalColorTable.Length, cMeta.DecodedLocalColorTable.Length); + Assert.Equal(iMeta.LocalColorTable.Value.Length, cMeta.LocalColorTable.Value.Length); } Assert.Equal(iMeta.FrameDelay, cMeta.FrameDelay); diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifFrameMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifFrameMetadataTests.cs index 70d75cdd49..774638311d 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifFrameMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifFrameMetadataTests.cs @@ -15,18 +15,18 @@ public class GifFrameMetadataTests { FrameDelay = 1, DisposalMethod = GifDisposalMethod.RestoreToBackground, - DecodedLocalColorTable = new[] { Color.Black, Color.White } + LocalColorTable = new[] { Color.Black, Color.White } }; GifFrameMetadata clone = (GifFrameMetadata)meta.DeepClone(); clone.FrameDelay = 2; clone.DisposalMethod = GifDisposalMethod.RestoreToPrevious; - clone.DecodedLocalColorTable = new[] { Color.Black }; + clone.LocalColorTable = new[] { Color.Black }; Assert.False(meta.FrameDelay.Equals(clone.FrameDelay)); Assert.False(meta.DisposalMethod.Equals(clone.DisposalMethod)); - Assert.False(meta.DecodedLocalColorTable.Length == clone.DecodedLocalColorTable.Length); - Assert.Equal(1, clone.DecodedLocalColorTable.Length); + Assert.False(meta.LocalColorTable.Value.Length == clone.LocalColorTable.Value.Length); + Assert.Equal(1, clone.LocalColorTable.Value.Length); } } diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs index 82a999b696..fb4445cdac 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs @@ -34,7 +34,7 @@ public class GifMetadataTests { RepeatCount = 1, ColorTableMode = GifColorTableMode.Global, - DecodedGlobalColorTable = new[] { Color.Black, Color.White }, + GlobalColorTable = new[] { Color.Black, Color.White }, Comments = new List { "Foo" } }; @@ -42,12 +42,12 @@ public class GifMetadataTests clone.RepeatCount = 2; clone.ColorTableMode = GifColorTableMode.Local; - clone.DecodedGlobalColorTable = new[] { Color.Black }; + clone.GlobalColorTable = new[] { Color.Black }; Assert.False(meta.RepeatCount.Equals(clone.RepeatCount)); Assert.False(meta.ColorTableMode.Equals(clone.ColorTableMode)); - Assert.False(meta.DecodedGlobalColorTable.Length == clone.DecodedGlobalColorTable.Length); - Assert.Equal(1, clone.DecodedGlobalColorTable.Length); + Assert.False(meta.GlobalColorTable.Value.Length == clone.GlobalColorTable.Value.Length); + Assert.Equal(1, clone.GlobalColorTable.Value.Length); Assert.False(meta.Comments.Equals(clone.Comments)); Assert.True(meta.Comments.SequenceEqual(clone.Comments)); } @@ -208,7 +208,7 @@ public class GifMetadataTests if (colorTableMode == GifColorTableMode.Global) { - Assert.Equal(globalColorTableLength, gifMetadata.DecodedGlobalColorTable.Length); + Assert.Equal(globalColorTableLength, gifMetadata.GlobalColorTable.Value.Length); } Assert.Equal(frameDelay, gifFrameMetadata.FrameDelay); diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs index 7c1150b774..9cfd393906 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs @@ -318,7 +318,7 @@ public abstract partial class ImageFrameCollectionTests if (aData.ColorTableMode == GifColorTableMode.Local && bData.ColorTableMode == GifColorTableMode.Local) { - Assert.Equal(aData.DecodedLocalColorTable.Length, bData.DecodedLocalColorTable.Length); + Assert.Equal(aData.LocalColorTable.Value.Length, bData.LocalColorTable.Value.Length); } } } diff --git a/tests/ImageSharp.Tests/Metadata/ImageFrameMetadataTests.cs b/tests/ImageSharp.Tests/Metadata/ImageFrameMetadataTests.cs index 9d11bb897a..bcc9675404 100644 --- a/tests/ImageSharp.Tests/Metadata/ImageFrameMetadataTests.cs +++ b/tests/ImageSharp.Tests/Metadata/ImageFrameMetadataTests.cs @@ -26,14 +26,14 @@ public class ImageFrameMetadataTests ImageFrameMetadata metaData = new(); GifFrameMetadata gifFrameMetadata = metaData.GetGifMetadata(); gifFrameMetadata.FrameDelay = frameDelay; - gifFrameMetadata.DecodedLocalColorTable = Enumerable.Repeat(Color.HotPink, colorTableLength).ToArray(); + gifFrameMetadata.LocalColorTable = Enumerable.Repeat(Color.HotPink, colorTableLength).ToArray(); gifFrameMetadata.DisposalMethod = disposalMethod; ImageFrameMetadata clone = new(metaData); GifFrameMetadata cloneGifFrameMetadata = clone.GetGifMetadata(); Assert.Equal(frameDelay, cloneGifFrameMetadata.FrameDelay); - Assert.Equal(colorTableLength, cloneGifFrameMetadata.DecodedLocalColorTable.Length); + Assert.Equal(colorTableLength, cloneGifFrameMetadata.LocalColorTable.Value.Length); Assert.Equal(disposalMethod, cloneGifFrameMetadata.DisposalMethod); } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 409378b179..065c5bbf84 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -482,6 +482,8 @@ public static class TestImages public const string Issue2288_B = "Gif/issues/issue_2288_2.gif"; public const string Issue2288_C = "Gif/issues/issue_2288_3.gif"; public const string Issue2288_D = "Gif/issues/issue_2288_4.gif"; + public const string Issue2450 = "Gif/issues/issue_2450.gif"; + public const string Issue2198 = "Gif/issues/issue_2198.gif"; } public static readonly string[] All = { Rings, Giphy, Cheers, Trans, Kumin, Leo, Ratio4x1, Ratio1x4 };