Browse Source

rework number/ulong arrays

pull/1760/head
Ildar Khayrutdinov 5 years ago
parent
commit
0e3fada06a
  1. 85
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

85
src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

@ -219,21 +219,57 @@ namespace SixLabors.ImageSharp.Formats.Tiff
int rowsPerStrip = tags.GetValue(ExifTag.RowsPerStrip) != null ? (int)tags.GetValue(ExifTag.RowsPerStrip).Value : TiffConstants.RowsPerStripInfinity; int rowsPerStrip = tags.GetValue(ExifTag.RowsPerStrip) != null ? (int)tags.GetValue(ExifTag.RowsPerStrip).Value : TiffConstants.RowsPerStripInfinity;
var stripOffsets = (Array)tags.GetValueInternal(ExifTag.StripOffsets)?.GetValue(); var stripOffsetsArray = (Array)tags.GetValueInternal(ExifTag.StripOffsets).GetValue();
var stripByteCounts = (Array)tags.GetValueInternal(ExifTag.StripByteCounts)?.GetValue(); var stripByteCountsArray = (Array)tags.GetValueInternal(ExifTag.StripByteCounts).GetValue();
IMemoryOwner<ulong> stripOffsetsMemory = this.ConvertNumbers(stripOffsetsArray, out Span<ulong> stripOffsets);
IMemoryOwner<ulong> stripByteCountsMemory = this.ConvertNumbers(stripByteCountsArray, out Span<ulong> stripByteCounts);
if (this.PlanarConfiguration == TiffPlanarConfiguration.Planar) if (this.PlanarConfiguration == TiffPlanarConfiguration.Planar)
{ {
this.DecodeStripsPlanar(frame, rowsPerStrip, stripOffsets, stripByteCounts, cancellationToken); this.DecodeStripsPlanar(
frame,
rowsPerStrip,
stripOffsets,
stripByteCounts,
cancellationToken);
} }
else else
{ {
this.DecodeStripsChunky(frame, rowsPerStrip, stripOffsets, stripByteCounts, cancellationToken); this.DecodeStripsChunky(
frame,
rowsPerStrip,
stripOffsets,
stripByteCounts,
cancellationToken);
} }
stripOffsetsMemory?.Dispose();
stripByteCountsMemory?.Dispose();
return frame; return frame;
} }
private IMemoryOwner<ulong> ConvertNumbers(Array array, out Span<ulong> span)
{
if (array is Number[] numbers)
{
IMemoryOwner<ulong> memory = this.memoryAllocator.Allocate<ulong>(numbers.Length);
span = memory.GetSpan();
for (int i = 0; i < numbers.Length; i++)
{
span[i] = (uint)numbers[i];
}
return memory;
}
else
{
DebugGuard.IsTrue(array is ulong[], $"Expected {nameof(UInt64)} array.");
span = (ulong[])array;
return null;
}
}
/// <summary> /// <summary>
/// Calculates the size (in bytes) for a pixel buffer using the determined color format. /// Calculates the size (in bytes) for a pixel buffer using the determined color format.
/// </summary> /// </summary>
@ -284,7 +320,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// <param name="stripOffsets">An array of byte offsets to each strip in the image.</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> /// <param name="stripByteCounts">An array of the size of each strip (in bytes).</param>
/// <param name="cancellationToken">The token to monitor cancellation.</param> /// <param name="cancellationToken">The token to monitor cancellation.</param>
private void DecodeStripsPlanar<TPixel>(ImageFrame<TPixel> frame, int rowsPerStrip, Array stripOffsets, Array stripByteCounts, CancellationToken cancellationToken) private void DecodeStripsPlanar<TPixel>(ImageFrame<TPixel> frame, int rowsPerStrip, Span<ulong> stripOffsets, Span<ulong> stripByteCounts, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
int stripsPerPixel = this.BitsPerSample.Channels; int stripsPerPixel = this.BitsPerSample.Channels;
@ -335,26 +371,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff
int stripIndex = i; int stripIndex = i;
for (int planeIndex = 0; planeIndex < stripsPerPixel; planeIndex++) for (int planeIndex = 0; planeIndex < stripsPerPixel; planeIndex++)
{ {
ulong offset = stripOffsets.GetValue(stripIndex) switch
{
ulong val => val,
Number val => (uint)val,
_ => throw TiffThrowHelper.ThrowImageFormatException("Expected Number or Long8 array")
};
ulong count = stripByteCounts.GetValue(stripIndex) switch
{
ulong val => val,
Number val => (uint)val,
_ => throw TiffThrowHelper.ThrowImageFormatException("Expected Number or Long8 array")
};
decompressor.Decompress( decompressor.Decompress(
this.inputStream, this.inputStream,
offset, stripOffsets[stripIndex],
count, stripByteCounts[stripIndex],
stripHeight, stripHeight,
stripBuffers[planeIndex].GetSpan()); stripBuffers[planeIndex].GetSpan());
stripIndex += stripsPerPlane; stripIndex += stripsPerPlane;
} }
@ -379,7 +402,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// <param name="stripOffsets">The strip offsets.</param> /// <param name="stripOffsets">The strip offsets.</param>
/// <param name="stripByteCounts">The strip byte counts.</param> /// <param name="stripByteCounts">The strip byte counts.</param>
/// <param name="cancellationToken">The token to monitor cancellation.</param> /// <param name="cancellationToken">The token to monitor cancellation.</param>
private void DecodeStripsChunky<TPixel>(ImageFrame<TPixel> frame, int rowsPerStrip, Array stripOffsets, Array stripByteCounts, CancellationToken cancellationToken) private void DecodeStripsChunky<TPixel>(ImageFrame<TPixel> frame, int rowsPerStrip, Span<ulong> stripOffsets, Span<ulong> stripByteCounts, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
// If the rowsPerStrip has the default value, which is effectively infinity. That is, the entire image is one strip. // If the rowsPerStrip has the default value, which is effectively infinity. That is, the entire image is one strip.
@ -435,24 +458,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff
break; break;
} }
ulong offset = stripOffsets.GetValue(stripIndex) switch
{
ulong val => val,
Number val => (uint)val,
_ => throw TiffThrowHelper.ThrowImageFormatException("Expected Number or Long8 array")
};
ulong count = stripByteCounts.GetValue(stripIndex) switch
{
ulong val => val,
Number val => (uint)val,
_ => throw TiffThrowHelper.ThrowImageFormatException("Expected Number or Long8 array")
};
decompressor.Decompress( decompressor.Decompress(
this.inputStream, this.inputStream,
offset, stripOffsets[stripIndex],
count, stripByteCounts[stripIndex],
stripHeight, stripHeight,
stripBufferSpan); stripBufferSpan);

Loading…
Cancel
Save