diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 7c8efad0f4..ab84dd31e9 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -224,26 +224,44 @@ namespace ImageSharp.Formats int rowsPerStrip = (int)this.ReadUnsignedInteger(ref rowsPerStripEntry); uint[] stripOffsets = this.ReadUnsignedIntegerArray(ref stripOffsetsEntry); uint[] stripByteCounts = this.ReadUnsignedIntegerArray(ref stripByteCountsEntry); + DecodeImageStrips(image, rowsPerStrip, stripOffsets, stripByteCounts); + } - int uncompressedStripSize = this.CalculateImageBufferSize(width, rowsPerStrip); + return image; + } - using (PixelAccessor pixels = image.Lock()) - { - byte[] stripBytes = ArrayPool.Shared.Rent(uncompressedStripSize); + /// + /// Decodes the image data for strip encoded data. + /// + /// The pixel format. + /// The image to decode data into. + /// The number of rows per strip of data. + /// An array of byte offsets to each strip in the image. + /// An array of the size of each strip (in bytes). + private void DecodeImageStrips(Image image, int rowsPerStrip, uint[] stripOffsets, uint[] stripByteCounts) + where TColor : struct, IPixel + { + int uncompressedStripSize = this.CalculateImageBufferSize(image.Width, rowsPerStrip); - try - { - this.DecompressImageBlock(stripOffsets[0], stripByteCounts[0], stripBytes); - this.ProcessImageBlock(stripBytes, pixels, 0, 0, width, rowsPerStrip); - } - finally + using (PixelAccessor pixels = image.Lock()) + { + byte[] stripBytes = ArrayPool.Shared.Rent(uncompressedStripSize); + + try + { + for (int i = 0; i < stripOffsets.Length; i++) { - ArrayPool.Shared.Return(stripBytes); + int stripHeight = i < stripOffsets.Length - 1 || image.Height % rowsPerStrip == 0 ? rowsPerStrip : image.Height % rowsPerStrip; + + this.DecompressImageBlock(stripOffsets[i], stripByteCounts[i], stripBytes); + this.ProcessImageBlock(stripBytes, pixels, 0, rowsPerStrip * i, image.Width, stripHeight); } } + finally + { + ArrayPool.Shared.Return(stripBytes); + } } - - return image; } ///