Skip to content

Commit eb6b0ab

Browse files
Do not copy color tables when transcoding.
1 parent b65abe7 commit eb6b0ab

File tree

4 files changed

+15
-72
lines changed

4 files changed

+15
-72
lines changed

src/ImageSharp/Formats/Gif/GifFrameMetadata.cs

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
using System.Numerics;
54
using SixLabors.ImageSharp.PixelFormats;
65

76
namespace SixLabors.ImageSharp.Formats.Gif;
@@ -79,35 +78,15 @@ private GifFrameMetadata(GifFrameMetadata other)
7978
public IDeepCloneable DeepClone() => new GifFrameMetadata(this);
8079

8180
internal static GifFrameMetadata FromAnimatedMetadata(AnimatedImageFrameMetadata metadata)
82-
{
83-
// TODO: v4 How do I link the parent metadata to the frame metadata to get the global color table?
84-
int index = -1;
85-
float background = 1f;
86-
if (metadata.ColorTable.HasValue)
87-
{
88-
ReadOnlySpan<Color> colorTable = metadata.ColorTable.Value.Span;
89-
for (int i = 0; i < colorTable.Length; i++)
90-
{
91-
Vector4 vector = (Vector4)colorTable[i];
92-
if (vector.W < background)
93-
{
94-
index = i;
95-
}
96-
}
97-
}
98-
99-
bool hasTransparency = index >= 0;
100-
101-
return new()
81+
=> new()
10282
{
103-
LocalColorTable = metadata.ColorTable,
83+
// Do not copy the color table or transparency data.
84+
// This will lead to a mismatch when the image is comprised of frames
85+
// extracted individually from a multi-frame image.
10486
ColorTableMode = metadata.ColorTableMode == FrameColorTableMode.Global ? GifColorTableMode.Global : GifColorTableMode.Local,
10587
FrameDelay = (int)Math.Round(metadata.Duration.TotalMilliseconds / 10),
106-
DisposalMethod = GetMode(metadata.DisposalMode),
107-
HasTransparency = hasTransparency,
108-
TransparencyIndex = hasTransparency ? unchecked((byte)index) : byte.MinValue,
88+
DisposalMethod = GetMode(metadata.DisposalMode)
10989
};
110-
}
11190

11291
private static GifDisposalMethod GetMode(FrameDisposalMode mode) => mode switch
11392
{

src/ImageSharp/Formats/Gif/GifMetadata.cs

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,28 +73,12 @@ private GifMetadata(GifMetadata other)
7373
public IDeepCloneable DeepClone() => new GifMetadata(this);
7474

7575
internal static GifMetadata FromAnimatedMetadata(AnimatedImageMetadata metadata)
76-
{
77-
int index = 0;
78-
Color background = metadata.BackgroundColor;
79-
if (metadata.ColorTable.HasValue)
76+
=> new()
8077
{
81-
ReadOnlySpan<Color> colorTable = metadata.ColorTable.Value.Span;
82-
for (int i = 0; i < colorTable.Length; i++)
83-
{
84-
if (background == colorTable[i])
85-
{
86-
index = i;
87-
break;
88-
}
89-
}
90-
}
91-
92-
return new()
93-
{
94-
GlobalColorTable = metadata.ColorTable,
78+
// Do not copy the color table or bit depth.
79+
// This will lead to a mismatch when the image is comprised of frames
80+
// extracted individually from a multi-frame image.
9581
ColorTableMode = metadata.ColorTableMode == FrameColorTableMode.Global ? GifColorTableMode.Global : GifColorTableMode.Local,
9682
RepeatCount = metadata.RepeatCount,
97-
BackgroundColorIndex = (byte)Numerics.Clamp(index, 0, 255),
9883
};
99-
}
10084
}

src/ImageSharp/Formats/Png/PngMetadata.cs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,32 +93,12 @@ private PngMetadata(PngMetadata other)
9393
public IDeepCloneable DeepClone() => new PngMetadata(this);
9494

9595
internal static PngMetadata FromAnimatedMetadata(AnimatedImageMetadata metadata)
96-
{
97-
// Should the conversion be from a format that uses a 24bit palette entries (gif)
98-
// we need to clone and adjust the color table to allow for transparency.
99-
Color[]? colorTable = metadata.ColorTable?.ToArray();
100-
if (colorTable != null)
96+
=> new()
10197
{
102-
for (int i = 0; i < colorTable.Length; i++)
103-
{
104-
ref Color c = ref colorTable[i];
105-
if (c == metadata.BackgroundColor)
106-
{
107-
// Png treats background as fully empty
108-
c = Color.Transparent;
109-
break;
110-
}
111-
}
112-
}
113-
114-
return new()
115-
{
116-
ColorType = colorTable != null ? PngColorType.Palette : null,
117-
BitDepth = colorTable != null
118-
? (PngBitDepth)Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(colorTable.Length), 1, 8)
119-
: null,
120-
ColorTable = colorTable,
98+
// Do not copy the color table or bit depth.
99+
// This will lead to a mismatch when the image is comprised of frames
100+
// extracted individually from a multi-frame image.
101+
ColorType = metadata.ColorTable != null ? PngColorType.Palette : null,
121102
RepeatCount = metadata.RepeatCount,
122103
};
123-
}
124104
}

tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ public void Encode_APng<TPixel>(TestImageProvider<TPixel> provider)
484484
}
485485

486486
[Theory]
487-
[WithFile(TestImages.Gif.Leo, PixelTypes.Rgba32, 0.613F)]
487+
[WithFile(TestImages.Gif.Leo, PixelTypes.Rgba32, 0.7629F)]
488488
[WithFile(TestImages.Gif.Issues.Issue2866, PixelTypes.Rgba32, 1.06F)]
489489
public void Encode_AnimatedFormatTransform_FromGif<TPixel>(TestImageProvider<TPixel> provider, float percentage)
490490
where TPixel : unmanaged, IPixel<TPixel>

0 commit comments

Comments
 (0)