@@ -353,7 +353,7 @@ private void ReadFrame<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPixel> p
353353 this . ReadImageDescriptor ( ) ;
354354
355355 IManagedByteBuffer localColorTable = null ;
356- IManagedByteBuffer indices = null ;
356+ Buffer2D < byte > indices = null ;
357357 try
358358 {
359359 // Determine the color table for this frame. If there is a local one, use it otherwise use the global color table.
@@ -364,11 +364,11 @@ private void ReadFrame<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPixel> p
364364 this . stream . Read ( localColorTable . Array , 0 , length ) ;
365365 }
366366
367- indices = this . configuration . MemoryAllocator . AllocateManagedByteBuffer ( this . imageDescriptor . Width * this . imageDescriptor . Height , AllocationOptions . Clean ) ;
367+ indices = this . configuration . MemoryAllocator . Allocate2D < byte > ( this . imageDescriptor . Width , this . imageDescriptor . Height , AllocationOptions . Clean ) ;
368368
369- this . ReadFrameIndices ( this . imageDescriptor , indices . GetSpan ( ) ) ;
369+ this . ReadFrameIndices ( indices ) ;
370370 ReadOnlySpan < Rgb24 > colorTable = MemoryMarshal . Cast < byte , Rgb24 > ( ( localColorTable ?? this . globalColorTable ) . GetSpan ( ) ) ;
371- this . ReadFrameColors ( ref image , ref previousFrame , indices . GetSpan ( ) , colorTable , this . imageDescriptor ) ;
371+ this . ReadFrameColors ( ref image , ref previousFrame , indices , colorTable , this . imageDescriptor ) ;
372372
373373 // Skip any remaining blocks
374374 this . SkipBlock ( ) ;
@@ -383,16 +383,13 @@ private void ReadFrame<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPixel> p
383383 /// <summary>
384384 /// Reads the frame indices marking the color to use for each pixel.
385385 /// </summary>
386- /// <param name="imageDescriptor">The <see cref="GifImageDescriptor"/>.</param>
387- /// <param name="indices">The pixel array to write to.</param>
386+ /// <param name="indices">The 2D pixel buffer to write to.</param>
388387 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
389- private void ReadFrameIndices ( in GifImageDescriptor imageDescriptor , Span < byte > indices )
388+ private void ReadFrameIndices ( Buffer2D < byte > indices )
390389 {
391390 int dataSize = this . stream . ReadByte ( ) ;
392- using ( var lzwDecoder = new LzwDecoder ( this . configuration . MemoryAllocator , this . stream ) )
393- {
394- lzwDecoder . DecodePixels ( imageDescriptor . Width , imageDescriptor . Height , dataSize , indices ) ;
395- }
391+ using var lzwDecoder = new LzwDecoder ( this . configuration . MemoryAllocator , this . stream ) ;
392+ lzwDecoder . DecodePixels ( dataSize , indices ) ;
396393 }
397394
398395 /// <summary>
@@ -404,10 +401,9 @@ private void ReadFrameIndices(in GifImageDescriptor imageDescriptor, Span<byte>
404401 /// <param name="indices">The indexed pixels.</param>
405402 /// <param name="colorTable">The color table containing the available colors.</param>
406403 /// <param name="descriptor">The <see cref="GifImageDescriptor"/></param>
407- private void ReadFrameColors < TPixel > ( ref Image < TPixel > image , ref ImageFrame < TPixel > previousFrame , Span < byte > indices , ReadOnlySpan < Rgb24 > colorTable , in GifImageDescriptor descriptor )
404+ private void ReadFrameColors < TPixel > ( ref Image < TPixel > image , ref ImageFrame < TPixel > previousFrame , Buffer2D < byte > indices , ReadOnlySpan < Rgb24 > colorTable , in GifImageDescriptor descriptor )
408405 where TPixel : unmanaged, IPixel < TPixel >
409406 {
410- ref byte indicesRef = ref MemoryMarshal . GetReference ( indices ) ;
411407 int imageWidth = this . logicalScreenDescriptor . Width ;
412408 int imageHeight = this . logicalScreenDescriptor . Height ;
413409
@@ -440,13 +436,20 @@ private void ReadFrameColors<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPi
440436 this . RestoreToBackground ( imageFrame ) ;
441437 }
442438
443- int i = 0 ;
444439 int interlacePass = 0 ; // The interlace pass
445440 int interlaceIncrement = 8 ; // The interlacing line increment
446441 int interlaceY = 0 ; // The current interlaced line
447-
448- for ( int y = descriptor . Top ; y < descriptor . Top + descriptor . Height ; y ++ )
442+ int descriptorTop = descriptor . Top ;
443+ int descriptorBottom = descriptorTop + descriptor . Height ;
444+ int descriptorLeft = descriptor . Left ;
445+ int descriptorRight = descriptorLeft + descriptor . Width ;
446+ bool transFlag = this . graphicsControlExtension . TransparencyFlag ;
447+ byte transIndex = this . graphicsControlExtension . TransparencyIndex ;
448+
449+ for ( int y = descriptorTop ; y < descriptorBottom && y < imageHeight ; y ++ )
449450 {
451+ ref byte indicesRowRef = ref MemoryMarshal . GetReference ( indices . GetRowSpan ( y - descriptorTop ) ) ;
452+
450453 // Check if this image is interlaced.
451454 int writeY ; // the target y offset to write to
452455 if ( descriptor . InterlaceFlag )
@@ -482,35 +485,29 @@ private void ReadFrameColors<TPixel>(ref Image<TPixel> image, ref ImageFrame<TPi
482485 }
483486
484487 ref TPixel rowRef = ref MemoryMarshal . GetReference ( imageFrame . GetPixelRowSpan ( writeY ) ) ;
485- bool transFlag = this . graphicsControlExtension . TransparencyFlag ;
486488
487489 if ( ! transFlag )
488490 {
489491 // #403 The left + width value can be larger than the image width
490- for ( int x = descriptor . Left ; x < descriptor . Left + descriptor . Width && x < imageWidth ; x ++ )
492+ for ( int x = descriptorLeft ; x < descriptorRight && x < imageWidth ; x ++ )
491493 {
492- int index = Unsafe . Add ( ref indicesRef , i ) ;
494+ int index = Unsafe . Add ( ref indicesRowRef , x - descriptorLeft ) ;
493495 ref TPixel pixel = ref Unsafe . Add ( ref rowRef , x ) ;
494496 Rgb24 rgb = colorTable [ index ] ;
495497 pixel . FromRgb24 ( rgb ) ;
496-
497- i ++ ;
498498 }
499499 }
500500 else
501501 {
502- byte transIndex = this . graphicsControlExtension . TransparencyIndex ;
503- for ( int x = descriptor . Left ; x < descriptor . Left + descriptor . Width && x < imageWidth ; x ++ )
502+ for ( int x = descriptorLeft ; x < descriptorRight && x < imageWidth ; x ++ )
504503 {
505- int index = Unsafe . Add ( ref indicesRef , i ) ;
504+ int index = Unsafe . Add ( ref indicesRowRef , x - descriptorLeft ) ;
506505 if ( transIndex != index )
507506 {
508507 ref TPixel pixel = ref Unsafe . Add ( ref rowRef , x ) ;
509508 Rgb24 rgb = colorTable [ index ] ;
510509 pixel . FromRgb24 ( rgb ) ;
511510 }
512-
513- i ++ ;
514511 }
515512 }
516513 }
0 commit comments