@@ -648,7 +648,7 @@ private void DecodeTilesPlanar<TPixel>(
648
648
}
649
649
650
650
/// <summary>
651
- /// Decodes the image data for Tiff's which arrange the pixel data in tiles and the chunky configuration.
651
+ /// Decodes the image data for TIFFs which arrange the pixel data in tiles and the chunky configuration.
652
652
/// </summary>
653
653
/// <typeparam name="TPixel">The pixel format.</typeparam>
654
654
/// <param name="frame">The image frame to decode into.</param>
@@ -674,28 +674,26 @@ private void DecodeTilesChunky<TPixel>(
674
674
int width = pixels . Width ;
675
675
int height = pixels . Height ;
676
676
int bitsPerPixel = this . BitsPerPixel ;
677
-
678
- int bytesPerRow = RoundUpToMultipleOfEight ( width * bitsPerPixel ) ;
679
677
int bytesPerTileRow = RoundUpToMultipleOfEight ( tileWidth * bitsPerPixel ) ;
680
- int uncompressedTilesSize = bytesPerTileRow * tileLength ;
681
- using IMemoryOwner < byte > tileBuffer = this . memoryAllocator . Allocate < byte > ( uncompressedTilesSize , AllocationOptions . Clean ) ;
682
- using IMemoryOwner < byte > uncompressedPixelBuffer = this . memoryAllocator . Allocate < byte > ( tilesDown * tileLength * bytesPerRow , AllocationOptions . Clean ) ;
678
+
679
+ using IMemoryOwner < byte > tileBuffer = this . memoryAllocator . Allocate < byte > ( bytesPerTileRow * tileLength , AllocationOptions . Clean ) ;
683
680
Span < byte > tileBufferSpan = tileBuffer . GetSpan ( ) ;
684
- Span < byte > uncompressedPixelBufferSpan = uncompressedPixelBuffer . GetSpan ( ) ;
685
681
686
682
using TiffBaseDecompressor decompressor = this . CreateDecompressor < TPixel > ( frame . Width , bitsPerPixel ) ;
687
683
TiffBaseColorDecoder < TPixel > colorDecoder = this . CreateChunkyColorDecoder < TPixel > ( ) ;
688
684
689
685
int tileIndex = 0 ;
690
686
for ( int tileY = 0 ; tileY < tilesDown ; tileY ++ )
691
687
{
692
- int remainingPixelsInRow = width ;
688
+ int rowStartY = tileY * tileLength ;
689
+ int rowEndY = Math . Min ( rowStartY + tileLength , height ) ;
690
+
693
691
for ( int tileX = 0 ; tileX < tilesAcross ; tileX ++ )
694
692
{
695
693
cancellationToken . ThrowIfCancellationRequested ( ) ;
696
694
697
- int uncompressedPixelBufferOffset = tileY * tileLength * bytesPerRow ;
698
695
bool isLastHorizontalTile = tileX == tilesAcross - 1 ;
696
+ int remainingPixelsInRow = width - ( tileX * tileWidth ) ;
699
697
700
698
decompressor . Decompress (
701
699
this . inputStream ,
@@ -706,22 +704,21 @@ private void DecodeTilesChunky<TPixel>(
706
704
cancellationToken ) ;
707
705
708
706
int tileBufferOffset = 0 ;
709
- uncompressedPixelBufferOffset += bytesPerTileRow * tileX ;
710
707
int bytesToCopy = isLastHorizontalTile ? RoundUpToMultipleOfEight ( bitsPerPixel * remainingPixelsInRow ) : bytesPerTileRow ;
711
- for ( int y = 0 ; y < tileLength ; y ++ )
708
+ int rowWidth = Math . Min ( tileWidth , remainingPixelsInRow ) ;
709
+ int left = tileX * tileWidth ;
710
+
711
+ for ( int y = rowStartY ; y < rowEndY ; y ++ )
712
712
{
713
- Span < byte > uncompressedPixelRow = uncompressedPixelBufferSpan . Slice ( uncompressedPixelBufferOffset , bytesToCopy ) ;
714
- tileBufferSpan . Slice ( tileBufferOffset , bytesToCopy ) . CopyTo ( uncompressedPixelRow ) ;
713
+ // Decode the tile row directly into the pixel buffer.
714
+ ReadOnlySpan < byte > tileRowSpan = tileBufferSpan . Slice ( tileBufferOffset , bytesToCopy ) ;
715
+ colorDecoder . Decode ( tileRowSpan , pixels , left , y , rowWidth , 1 ) ;
715
716
tileBufferOffset += bytesPerTileRow ;
716
- uncompressedPixelBufferOffset += bytesPerRow ;
717
717
}
718
718
719
- remainingPixelsInRow -= tileWidth ;
720
719
tileIndex ++ ;
721
720
}
722
721
}
723
-
724
- colorDecoder . Decode ( uncompressedPixelBufferSpan , pixels , 0 , 0 , width , height ) ;
725
722
}
726
723
727
724
private TiffBaseColorDecoder < TPixel > CreateChunkyColorDecoder < TPixel > ( )
0 commit comments