Browse Source

Add support for multi-strip TIFF files

pull/119/head
Andrew Wilkinson 9 years ago
parent
commit
756b8ab4bc
  1. 44
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

44
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<TColor> pixels = image.Lock())
{
byte[] stripBytes = ArrayPool<byte>.Shared.Rent(uncompressedStripSize);
/// <summary>
/// Decodes the image data for strip encoded data.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="image">The image to decode data into.</param>
/// <param name="rowsPerStrip">The number of rows per strip of data.</param>
/// <param name="stripOffsets">An array of byte offsets to each strip in the image.</param>
/// <param name="stripByteCounts">An array of the size of each strip (in bytes).</param>
private void DecodeImageStrips<TColor>(Image<TColor> image, int rowsPerStrip, uint[] stripOffsets, uint[] stripByteCounts)
where TColor : struct, IPixel<TColor>
{
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<TColor> pixels = image.Lock())
{
byte[] stripBytes = ArrayPool<byte>.Shared.Rent(uncompressedStripSize);
try
{
for (int i = 0; i < stripOffsets.Length; i++)
{
ArrayPool<byte>.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<byte>.Shared.Return(stripBytes);
}
}
return image;
}
/// <summary>

Loading…
Cancel
Save