88using System . Runtime . Intrinsics ;
99using System . Runtime . Intrinsics . X86 ;
1010using SixLabors . ImageSharp . Advanced ;
11+ using SixLabors . ImageSharp . Formats . Png ;
12+ using SixLabors . ImageSharp . Formats . Webp ;
1113using SixLabors . ImageSharp . Memory ;
1214using SixLabors . ImageSharp . Metadata ;
1315using SixLabors . ImageSharp . Metadata . Profiles . Xmp ;
@@ -86,8 +88,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
8688 Guard . NotNull ( image , nameof ( image ) ) ;
8789 Guard . NotNull ( stream , nameof ( stream ) ) ;
8890
89- ImageMetadata metadata = image . Metadata ;
90- GifMetadata gifMetadata = metadata . GetGifMetadata ( ) ;
91+ GifMetadata gifMetadata = GetGifMetadata ( image ) ;
9192 this . colorTableMode ??= gifMetadata . ColorTableMode ;
9293 bool useGlobalTable = this . colorTableMode == GifColorTableMode . Global ;
9394
@@ -96,7 +97,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
9697
9798 // Work out if there is an explicit transparent index set for the frame. We use that to ensure the
9899 // correct value is set for the background index when quantizing.
99- image . Frames . RootFrame . Metadata . TryGetGifMetadata ( out GifFrameMetadata ? frameMetadata ) ;
100+ GifFrameMetadata ? frameMetadata = GetGifFrameMetadata ( image . Frames . RootFrame , - 1 ) ;
100101 int transparencyIndex = GetTransparentIndex ( quantized , frameMetadata ) ;
101102
102103 if ( this . quantizer is null )
@@ -140,7 +141,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
140141
141142 // Get the number of bits.
142143 int bitDepth = ColorNumerics . GetBitsNeededForColorDepth ( quantized . Palette . Length ) ;
143- this . WriteLogicalScreenDescriptor ( metadata , image . Width , image . Height , backgroundIndex , useGlobalTable , bitDepth , stream ) ;
144+ this . WriteLogicalScreenDescriptor ( image . Metadata , image . Width , image . Height , backgroundIndex , useGlobalTable , bitDepth , stream ) ;
144145
145146 if ( useGlobalTable )
146147 {
@@ -164,15 +165,69 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
164165
165166 quantized . Dispose ( ) ;
166167
167- this . EncodeAdditionalFrames ( stream , image , globalPalette ) ;
168+ this . EncodeAdditionalFrames ( stream , image , globalPalette , transparencyIndex ) ;
168169
169170 stream . WriteByte ( GifConstants . EndIntroducer ) ;
170171 }
171172
173+ private static GifMetadata GetGifMetadata < TPixel > ( Image < TPixel > image )
174+ where TPixel : unmanaged, IPixel < TPixel >
175+ {
176+ if ( image . Metadata . TryGetGifMetadata ( out GifMetadata ? gif ) )
177+ {
178+ return gif ;
179+ }
180+
181+ if ( image . Metadata . TryGetPngMetadata ( out PngMetadata ? png ) )
182+ {
183+ AnimatedImageMetadata ani = png . ToAnimatedImageMetadata ( ) ;
184+ return GifMetadata . FromAnimatedMetadata ( ani ) ;
185+ }
186+
187+ if ( image . Metadata . TryGetWebpMetadata ( out WebpMetadata ? webp ) )
188+ {
189+ AnimatedImageMetadata ani = webp . ToAnimatedImageMetadata ( ) ;
190+ return GifMetadata . FromAnimatedMetadata ( ani ) ;
191+ }
192+
193+ return new ( ) ;
194+ }
195+
196+ private static GifFrameMetadata ? GetGifFrameMetadata < TPixel > ( ImageFrame < TPixel > frame , int transparencyIndex )
197+ where TPixel : unmanaged, IPixel < TPixel >
198+ {
199+ if ( frame . Metadata . TryGetGifFrameMetadata ( out GifFrameMetadata ? gif ) )
200+ {
201+ return gif ;
202+ }
203+
204+ GifFrameMetadata ? metadata = null ;
205+ if ( frame . Metadata . TryGetPngFrameMetadata ( out PngFrameMetadata ? png ) )
206+ {
207+ AnimatedImageFrameMetadata ani = png . ToAnimatedImageFrameMetadata ( ) ;
208+ metadata = GifFrameMetadata . FromAnimatedMetadata ( ani ) ;
209+ }
210+
211+ if ( frame . Metadata . TryGetWebpFrameMetadata ( out WebpFrameMetadata ? webp ) )
212+ {
213+ AnimatedImageFrameMetadata ani = webp . ToAnimatedImageFrameMetadata ( ) ;
214+ metadata = GifFrameMetadata . FromAnimatedMetadata ( ani ) ;
215+ }
216+
217+ if ( metadata ? . ColorTableMode == GifColorTableMode . Global && transparencyIndex > - 1 )
218+ {
219+ metadata . HasTransparency = true ;
220+ metadata . TransparencyIndex = unchecked ( ( byte ) transparencyIndex ) ;
221+ }
222+
223+ return metadata ;
224+ }
225+
172226 private void EncodeAdditionalFrames < TPixel > (
173227 Stream stream ,
174228 Image < TPixel > image ,
175- ReadOnlyMemory < TPixel > globalPalette )
229+ ReadOnlyMemory < TPixel > globalPalette ,
230+ int globalTransparencyIndex )
176231 where TPixel : unmanaged, IPixel < TPixel >
177232 {
178233 if ( image . Frames . Count == 1 )
@@ -195,8 +250,7 @@ private void EncodeAdditionalFrames<TPixel>(
195250 {
196251 // Gather the metadata for this frame.
197252 ImageFrame < TPixel > currentFrame = image . Frames [ i ] ;
198- ImageFrameMetadata metadata = currentFrame . Metadata ;
199- metadata . TryGetGifMetadata ( out GifFrameMetadata ? gifMetadata ) ;
253+ GifFrameMetadata ? gifMetadata = GetGifFrameMetadata ( currentFrame , globalTransparencyIndex ) ;
200254 bool useLocal = this . colorTableMode == GifColorTableMode . Local || ( gifMetadata ? . ColorTableMode == GifColorTableMode . Local ) ;
201255
202256 if ( ! useLocal && ! hasPaletteQuantizer && i > 0 )
0 commit comments