@@ -608,7 +608,7 @@ private void DecodeTilesPlanar<TPixel>(
608
608
}
609
609
610
610
/// <summary>
611
- /// Decodes the image data for Tiff's which arrange the pixel data in tiles and the chunky configuration.
611
+ /// Decodes the image data for TIFFs which arrange the pixel data in tiles and the chunky configuration.
612
612
/// </summary>
613
613
/// <typeparam name="TPixel">The pixel format.</typeparam>
614
614
/// <param name="frame">The image frame to decode into.</param>
@@ -634,28 +634,26 @@ private void DecodeTilesChunky<TPixel>(
634
634
int width = pixels . Width ;
635
635
int height = pixels . Height ;
636
636
int bitsPerPixel = this . BitsPerPixel ;
637
-
638
- int bytesPerRow = RoundUpToMultipleOfEight ( width * bitsPerPixel ) ;
639
637
int bytesPerTileRow = RoundUpToMultipleOfEight ( tileWidth * bitsPerPixel ) ;
640
- int uncompressedTilesSize = bytesPerTileRow * tileLength ;
641
- using IMemoryOwner < byte > tileBuffer = this . memoryAllocator . Allocate < byte > ( uncompressedTilesSize , AllocationOptions . Clean ) ;
642
- using IMemoryOwner < byte > uncompressedPixelBuffer = this . memoryAllocator . Allocate < byte > ( tilesDown * tileLength * bytesPerRow , AllocationOptions . Clean ) ;
638
+
639
+ using IMemoryOwner < byte > tileBuffer = this . memoryAllocator . Allocate < byte > ( bytesPerTileRow * tileLength , AllocationOptions . Clean ) ;
643
640
Span < byte > tileBufferSpan = tileBuffer . GetSpan ( ) ;
644
- Span < byte > uncompressedPixelBufferSpan = uncompressedPixelBuffer . GetSpan ( ) ;
645
641
646
642
using TiffBaseDecompressor decompressor = this . CreateDecompressor < TPixel > ( frame . Width , bitsPerPixel ) ;
647
643
TiffBaseColorDecoder < TPixel > colorDecoder = this . CreateChunkyColorDecoder < TPixel > ( ) ;
648
644
649
645
int tileIndex = 0 ;
650
646
for ( int tileY = 0 ; tileY < tilesDown ; tileY ++ )
651
647
{
652
- int remainingPixelsInRow = width ;
648
+ int rowStartY = tileY * tileLength ;
649
+ int rowEndY = Math . Min ( rowStartY + tileLength , height ) ;
650
+
653
651
for ( int tileX = 0 ; tileX < tilesAcross ; tileX ++ )
654
652
{
655
653
cancellationToken . ThrowIfCancellationRequested ( ) ;
656
654
657
- int uncompressedPixelBufferOffset = tileY * tileLength * bytesPerRow ;
658
655
bool isLastHorizontalTile = tileX == tilesAcross - 1 ;
656
+ int remainingPixelsInRow = width - ( tileX * tileWidth ) ;
659
657
660
658
decompressor . Decompress (
661
659
this . inputStream ,
@@ -666,22 +664,21 @@ private void DecodeTilesChunky<TPixel>(
666
664
cancellationToken ) ;
667
665
668
666
int tileBufferOffset = 0 ;
669
- uncompressedPixelBufferOffset += bytesPerTileRow * tileX ;
670
667
int bytesToCopy = isLastHorizontalTile ? RoundUpToMultipleOfEight ( bitsPerPixel * remainingPixelsInRow ) : bytesPerTileRow ;
671
- for ( int y = 0 ; y < tileLength ; y ++ )
668
+ int rowWidth = Math . Min ( tileWidth , remainingPixelsInRow ) ;
669
+ int left = tileX * tileWidth ;
670
+
671
+ for ( int y = rowStartY ; y < rowEndY ; y ++ )
672
672
{
673
- Span < byte > uncompressedPixelRow = uncompressedPixelBufferSpan . Slice ( uncompressedPixelBufferOffset , bytesToCopy ) ;
674
- tileBufferSpan . Slice ( tileBufferOffset , bytesToCopy ) . CopyTo ( uncompressedPixelRow ) ;
673
+ // Decode the tile row directly into the pixel buffer.
674
+ ReadOnlySpan < byte > tileRowSpan = tileBufferSpan . Slice ( tileBufferOffset , bytesToCopy ) ;
675
+ colorDecoder . Decode ( tileRowSpan , pixels , left , y , rowWidth , 1 ) ;
675
676
tileBufferOffset += bytesPerTileRow ;
676
- uncompressedPixelBufferOffset += bytesPerRow ;
677
677
}
678
678
679
- remainingPixelsInRow -= tileWidth ;
680
679
tileIndex ++ ;
681
680
}
682
681
}
683
-
684
- colorDecoder . Decode ( uncompressedPixelBufferSpan , pixels , 0 , 0 , width , height ) ;
685
682
}
686
683
687
684
private TiffBaseColorDecoder < TPixel > CreateChunkyColorDecoder < TPixel > ( )
0 commit comments