@@ -167,6 +167,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
167167
168168 ImageFrame < TPixel > ? clonedFrame = null ;
169169 ImageFrame < TPixel > currentFrame = image . Frames . RootFrame ;
170+ int currentFrameIndex = 0 ;
170171
171172 bool clearTransparency = this . encoder . TransparentColorMode is PngTransparentColorMode . Clear ;
172173 if ( clearTransparency )
@@ -195,29 +196,50 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
195196
196197 if ( image . Frames . Count > 1 )
197198 {
198- this . WriteAnimationControlChunk ( stream , ( uint ) image . Frames . Count , pngMetadata . RepeatCount ) ;
199+ this . WriteAnimationControlChunk ( stream , ( uint ) ( image . Frames . Count - ( pngMetadata . AnimateRootFrame ? 0 : 1 ) ) , pngMetadata . RepeatCount ) ;
200+ }
201+
202+ // If the first frame isn't animated, write it as usual and skip it when writing animated frames
203+ if ( ! pngMetadata . AnimateRootFrame || image . Frames . Count == 1 )
204+ {
205+ FrameControl frameControl = new ( ( uint ) this . width , ( uint ) this . height ) ;
206+ this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
207+ currentFrameIndex ++ ;
208+ }
199209
200- // Write the first frame.
210+ if ( image . Frames . Count > 1 )
211+ {
212+ // Write the first animated frame.
213+ currentFrame = image . Frames [ currentFrameIndex ] ;
201214 PngFrameMetadata frameMetadata = GetPngFrameMetadata ( currentFrame ) ;
202215 PngDisposalMethod previousDisposal = frameMetadata . DisposalMethod ;
203216 FrameControl frameControl = this . WriteFrameControlChunk ( stream , frameMetadata , currentFrame . Bounds ( ) , 0 ) ;
204- this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
217+ uint sequenceNumber = 1 ;
218+ if ( pngMetadata . AnimateRootFrame )
219+ {
220+ this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
221+ }
222+ else
223+ {
224+ sequenceNumber += this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , true ) ;
225+ }
226+
227+ currentFrameIndex ++ ;
205228
206229 // Capture the global palette for reuse on subsequent frames.
207230 ReadOnlyMemory < TPixel > ? previousPalette = quantized ? . Palette . ToArray ( ) ;
208231
209232 // Write following frames.
210- uint increment = 0 ;
211233 ImageFrame < TPixel > previousFrame = image . Frames . RootFrame ;
212234
213235 // This frame is reused to store de-duplicated pixel buffers.
214236 using ImageFrame < TPixel > encodingFrame = new ( image . Configuration , previousFrame . Size ( ) ) ;
215237
216- for ( int i = 1 ; i < image . Frames . Count ; i ++ )
238+ for ( ; currentFrameIndex < image . Frames . Count ; currentFrameIndex ++ )
217239 {
218240 ImageFrame < TPixel > ? prev = previousDisposal == PngDisposalMethod . RestoreToBackground ? null : previousFrame ;
219- currentFrame = image . Frames [ i ] ;
220- ImageFrame < TPixel > ? nextFrame = i < image . Frames . Count - 1 ? image . Frames [ i + 1 ] : null ;
241+ currentFrame = image . Frames [ currentFrameIndex ] ;
242+ ImageFrame < TPixel > ? nextFrame = currentFrameIndex < image . Frames . Count - 1 ? image . Frames [ currentFrameIndex + 1 ] : null ;
221243
222244 frameMetadata = GetPngFrameMetadata ( currentFrame ) ;
223245 bool blend = frameMetadata . BlendMethod == PngBlendMethod . Over ;
@@ -238,22 +260,17 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
238260 }
239261
240262 // Each frame control sequence number must be incremented by the number of frame data chunks that follow.
241- frameControl = this . WriteFrameControlChunk ( stream , frameMetadata , bounds , ( uint ) i + increment ) ;
263+ frameControl = this . WriteFrameControlChunk ( stream , frameMetadata , bounds , sequenceNumber ) ;
242264
243265 // Dispose of previous quantized frame and reassign.
244266 quantized ? . Dispose ( ) ;
245267 quantized = this . CreateQuantizedImageAndUpdateBitDepth ( pngMetadata , encodingFrame , bounds , previousPalette ) ;
246- increment += this . WriteDataChunks ( frameControl , encodingFrame . PixelBuffer . GetRegion ( bounds ) , quantized , stream , true ) ;
268+ sequenceNumber += this . WriteDataChunks ( frameControl , encodingFrame . PixelBuffer . GetRegion ( bounds ) , quantized , stream , true ) + 1 ;
247269
248270 previousFrame = currentFrame ;
249271 previousDisposal = frameMetadata . DisposalMethod ;
250272 }
251273 }
252- else
253- {
254- FrameControl frameControl = new ( ( uint ) this . width , ( uint ) this . height ) ;
255- this . WriteDataChunks ( frameControl , currentFrame . PixelBuffer . GetRegion ( ) , quantized , stream , false ) ;
256- }
257274
258275 this . WriteEndChunk ( stream ) ;
259276
0 commit comments