diff --git a/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs
index 4ea98d95af..074b04c6b5 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs
@@ -5,9 +5,11 @@ using System;
using System.IO;
using System.IO.Compression;
+using SixLabors.ImageSharp.Compression.Zlib;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils;
using SixLabors.ImageSharp.Formats.Tiff.Compression;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
@@ -33,34 +35,20 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
}
///
- public override void Decompress(Stream stream, int byteCount, Span buffer)
+ protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
- // Read the 'zlib' header information
- int cmf = stream.ReadByte();
- int flag = stream.ReadByte();
-
- if ((cmf & 0x0f) != 8)
- {
- TiffThrowHelper.ThrowBadZlibHeader(cmf);
- }
-
- // If the 'fdict' flag is set then we should skip the next four bytes
- bool fdict = (flag & 32) != 0;
-
- if (fdict)
- {
- stream.ReadByte();
- stream.ReadByte();
- stream.ReadByte();
- stream.ReadByte();
- }
-
- // The subsequent data is the Deflate compressed data (except for the last four bytes of checksum)
- int headerLength = fdict ? 10 : 6;
- var subStream = new SubStream(stream, byteCount - headerLength);
- using (var deflateStream = new DeflateStream(subStream, CompressionMode.Decompress, true))
+ long pos = stream.Position;
+ using (var deframeStream = new ZlibInflateStream(
+ stream,
+ () =>
+ {
+ int left = (int)(byteCount - (stream.Position - pos));
+ return left > 0 ? left : 0;
+ }))
{
- deflateStream.Read(buffer, 0, buffer.Length);
+ deframeStream.AllocateNewBytes(byteCount, true);
+ DeflateStream dataStream = deframeStream.CompressedStream;
+ dataStream.Read(buffer, 0, buffer.Length);
}
if (this.Predictor == TiffPredictor.Horizontal)
diff --git a/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs
index b01f141914..92468a00c2 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs
@@ -3,9 +3,11 @@
using System;
using System.IO;
+
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils;
using SixLabors.ImageSharp.Formats.Tiff.Compression;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
@@ -28,10 +30,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
}
///
- public override void Decompress(Stream stream, int byteCount, Span buffer)
+ protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
- var subStream = new SubStream(stream, byteCount);
- var decoder = new TiffLzwDecoder(subStream, this.Allocator);
+ var decoder = new TiffLzwDecoder(stream, this.Allocator);
decoder.DecodePixels(buffer.Length, 8, buffer);
if (this.Predictor == TiffPredictor.Horizontal)
diff --git a/src/ImageSharp/Formats/Tiff/Compression/ModifiedHuffmanTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/ModifiedHuffmanTiffCompression.cs
index 6176d75652..1d7c2eef57 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/ModifiedHuffmanTiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/ModifiedHuffmanTiffCompression.cs
@@ -5,6 +5,7 @@ using System;
using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
@@ -26,7 +27,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
}
///
- public override void Decompress(Stream stream, int byteCount, Span buffer)
+ protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
bool isWhiteZero = this.PhotometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero;
byte whiteValue = (byte)(isWhiteZero ? 0 : 1);
diff --git a/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs
index a07b42112a..9140a52e04 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs
@@ -5,6 +5,7 @@ using System;
using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
@@ -24,9 +25,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
}
///
- public override void Decompress(Stream stream, int byteCount, Span buffer)
+ protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
- stream.Read(buffer, 0, byteCount);
+ _ = stream.Read(buffer, 0, byteCount);
}
}
}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs
index d77ee78e44..a7c8b93481 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs
@@ -6,6 +6,7 @@ using System.Buffers;
using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
@@ -25,7 +26,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
}
///
- public override void Decompress(Stream stream, int byteCount, Span buffer)
+ protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
using IMemoryOwner compressedDataMemory = this.Allocator.Allocate(byteCount);
diff --git a/src/ImageSharp/Formats/Tiff/Compression/T4TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/T4TiffCompression.cs
index b8649d2101..f0c3a29bdd 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/T4TiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/T4TiffCompression.cs
@@ -5,6 +5,7 @@ using System;
using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
@@ -26,7 +27,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
}
///
- public override void Decompress(Stream stream, int byteCount, Span buffer)
+ protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
bool isWhiteZero = this.PhotometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero;
byte whiteValue = (byte)(isWhiteZero ? 0 : 1);
diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs
index d4f287adc8..4a5962f05d 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs
@@ -6,6 +6,7 @@ using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Tiff.Compression;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
@@ -55,9 +56,32 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
///
/// Decompresses image data into the supplied buffer.
///
- /// The to read image data from.
+ /// The to read image data from.
+ /// The strip offset of stream.
+ /// The number of bytes to read from the input stream.
+ /// The output buffer for uncompressed data.
+ public void Decompress(BufferedReadStream stream, uint stripOffset, uint stripByteCount, Span buffer)
+ {
+ if (stripByteCount > int.MaxValue)
+ {
+ TiffThrowHelper.ThrowImageFormatException("Too big value of StripByteCount.");
+ }
+
+ stream.Seek(stripOffset, SeekOrigin.Begin);
+ this.Decompress(stream, (int)stripByteCount, buffer);
+
+ if (stripOffset + stripByteCount < stream.Position)
+ {
+ TiffThrowHelper.ThrowImageFormatException("Out of range when reading a strip.");
+ }
+ }
+
+ ///
+ /// Decompresses image data into the supplied buffer.
+ ///
+ /// The to read image data from.
/// The number of bytes to read from the input stream.
/// The output buffer for uncompressed data.
- public abstract void Decompress(Stream stream, int byteCount, Span buffer);
+ protected abstract void Decompress(BufferedReadStream stream, int byteCount, Span buffer);
}
}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs
index c261e91d34..2e2fa51458 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs
@@ -13,17 +13,27 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression
switch (compressionType)
{
case TiffDecoderCompressionType.None:
+ DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor");
return new NoneTiffCompression(allocator);
+
case TiffDecoderCompressionType.PackBits:
+ DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor");
return new PackBitsTiffCompression(allocator);
+
case TiffDecoderCompressionType.Deflate:
return new DeflateTiffCompression(allocator, width, bitsPerPixel, predictor);
+
case TiffDecoderCompressionType.Lzw:
return new LzwTiffCompression(allocator, width, bitsPerPixel, predictor);
+
case TiffDecoderCompressionType.T4:
+ DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor");
return new T4TiffCompression(allocator, photometricInterpretation, width);
+
case TiffDecoderCompressionType.HuffmanRle:
+ DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor");
return new ModifiedHuffmanTiffCompression(allocator, photometricInterpretation, width);
+
default:
throw TiffThrowHelper.NotSupportedCompression(nameof(compressionType));
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
index e6595653ce..a62c5946f7 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
@@ -347,8 +347,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
{
int stripIndex = (i * stripsPerPixel) + planeIndex;
- this.inputStream.Seek(stripOffsets[stripIndex], SeekOrigin.Begin);
- decompressor.Decompress(this.inputStream, (int)stripByteCounts[stripIndex], stripBuffers[planeIndex].GetSpan());
+ decompressor.Decompress(this.inputStream, stripOffsets[stripIndex], stripByteCounts[stripIndex], stripBuffers[planeIndex].GetSpan());
}
colorDecoder.Decode(stripBuffers, pixels, 0, rowsPerStrip * i, frame.Width, stripHeight);
@@ -385,8 +384,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
{
int stripHeight = stripIndex < stripOffsets.Length - 1 || frame.Height % rowsPerStrip == 0 ? rowsPerStrip : frame.Height % rowsPerStrip;
- this.inputStream.Seek(stripOffsets[stripIndex], SeekOrigin.Begin);
- decompressor.Decompress(this.inputStream, (int)stripByteCounts[stripIndex], stripBuffer.GetSpan());
+ decompressor.Decompress(this.inputStream, stripOffsets[stripIndex], stripByteCounts[stripIndex], stripBuffer.GetSpan());
colorDecoder.Decode(stripBuffer.GetSpan(), pixels, 0, rowsPerStrip * stripIndex, frame.Width, stripHeight);
}
diff --git a/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs b/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs
index ff44e0d6e4..3709bca04b 100644
--- a/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs
@@ -18,9 +18,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// The error message for the exception.
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowImageFormatException(string errorMessage)
- {
- throw new ImageFormatException(errorMessage);
- }
+ => throw new ImageFormatException(errorMessage);
[MethodImpl(InliningOptions.ColdPath)]
public static Exception TagNotFound(string tagName)
diff --git a/src/ImageSharp/Formats/Tiff/Utils/SubStream.cs b/src/ImageSharp/Formats/Tiff/Utils/SubStream.cs
deleted file mode 100644
index 22cdaf5e8e..0000000000
--- a/src/ImageSharp/Formats/Tiff/Utils/SubStream.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.IO;
-
-namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
-{
- ///
- /// Utility class to encapsulate a sub-portion of another .
- ///
- ///
- /// Note that disposing of the does not dispose the underlying
- /// .
- ///
- internal class SubStream : Stream
- {
- private Stream innerStream;
- private long offset;
- private long endOffset;
- private long length;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The underlying to wrap.
- /// The length of the sub-stream.
- ///
- /// Note that calling the sub-stream with start from the current offset of the
- /// underlying
- ///
- public SubStream(Stream innerStream, long length)
- {
- this.innerStream = innerStream;
- this.offset = this.innerStream.Position;
- this.endOffset = this.offset + length;
- this.length = length;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The underlying to wrap.
- /// The offset of the sub-stream within the underlying .
- /// The length of the sub-stream.
- ///
- /// Note that calling the constructor will immediately move the underlying
- /// to the specified offset.
- ///
- public SubStream(Stream innerStream, long offset, long length)
- {
- this.innerStream = innerStream;
- this.offset = offset;
- this.endOffset = offset + length;
- this.length = length;
-
- innerStream.Seek(offset, SeekOrigin.Begin);
- }
-
- ///
- public override bool CanRead
- {
- get
- {
- return true;
- }
- }
-
- ///
- public override bool CanWrite
- {
- get
- {
- return false;
- }
- }
-
- ///
- public override bool CanSeek
- {
- get
- {
- return this.innerStream.CanSeek;
- }
- }
-
- ///
- public override long Length
- {
- get
- {
- return this.length;
- }
- }
-
- ///
- public override long Position
- {
- get
- {
- return this.innerStream.Position - this.offset;
- }
-
- set
- {
- this.Seek(value, SeekOrigin.Begin);
- }
- }
-
- ///
- public override void Flush()
- {
- throw new NotSupportedException();
- }
-
- ///
- public override int Read(byte[] buffer, int offset, int count)
- {
- long bytesRemaining = this.endOffset - this.innerStream.Position;
-
- if (bytesRemaining < count)
- {
- count = (int)bytesRemaining;
- }
-
- return this.innerStream.Read(buffer, offset, count);
- }
-
- ///
- public override int ReadByte()
- {
- if (this.innerStream.Position < this.endOffset)
- {
- return this.innerStream.ReadByte();
- }
- else
- {
- return -1;
- }
- }
-
- ///
- public override void Write(byte[] array, int offset, int count)
- {
- throw new NotSupportedException();
- }
-
- ///
- public override void WriteByte(byte value)
- {
- throw new NotSupportedException();
- }
-
- ///
- public override long Seek(long offset, SeekOrigin origin)
- {
- switch (origin)
- {
- case SeekOrigin.Current:
- return this.innerStream.Seek(offset, SeekOrigin.Current) - this.offset;
- case SeekOrigin.Begin:
- return this.innerStream.Seek(this.offset + offset, SeekOrigin.Begin) - this.offset;
- case SeekOrigin.End:
- return this.innerStream.Seek(this.endOffset - offset, SeekOrigin.Begin) - this.offset;
- default:
- throw new ArgumentException("Invalid seek origin.");
- }
- }
-
- ///
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
- }
-}
diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs
index 09db488903..3605869256 100644
--- a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs
+++ b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs
@@ -186,7 +186,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
{
int bytesWritten = 0;
using var memoryStream = new MemoryStream();
- using var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, compressionLevel); // TODO: move zlib compression from png to a common place?
+ using var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, compressionLevel);
for (int y = 0; y < image.Height; y++)
{
@@ -534,7 +534,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils
{
int bytesWritten = 0;
using var memoryStream = new MemoryStream();
- using var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, compressionLevel); // TODO: move zlib compression from png to a common place?
+ using var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, compressionLevel);
for (int y = 0; y < image.Height; y++)
{
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs
index fbac89e9ac..18025eecbd 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs
@@ -5,6 +5,8 @@ using System.IO;
using SixLabors.ImageSharp.Compression.Zlib;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
+using SixLabors.ImageSharp.IO;
+
using Xunit;
namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
@@ -20,17 +22,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
[InlineData(new byte[] { 1, 2, 42, 53, 42, 53, 42, 53, 42, 53, 42, 53, 3, 4 })] // Repeated sequence
public void Compress_Decompress_Roundtrip_Works(byte[] data)
{
- using (Stream stream = CreateCompressedStream(data))
+ using (BufferedReadStream stream = CreateCompressedStream(data))
{
var buffer = new byte[data.Length];
- new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, (int)stream.Length, buffer);
+ new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, 0, (uint)stream.Length, buffer);
Assert.Equal(data, buffer);
}
}
- private static Stream CreateCompressedStream(byte[] data)
+ private static BufferedReadStream CreateCompressedStream(byte[] data)
{
Stream compressedStream = new MemoryStream();
@@ -41,7 +43,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
}
compressedStream.Seek(0, SeekOrigin.Begin);
- return compressedStream;
+ return new BufferedReadStream(Configuration.Default, compressedStream);
}
}
}
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs
index 79cc1b1a88..6ba1b32261 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs
@@ -7,6 +7,7 @@ using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using Xunit;
@@ -36,15 +37,15 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
public void Compress_Decompress_Roundtrip_Works(byte[] data)
{
- using Stream stream = CreateCompressedStream(data);
+ using BufferedReadStream stream = CreateCompressedStream(data);
var buffer = new byte[data.Length];
- new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, (int)stream.Length, buffer);
+ new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, 0, (uint)stream.Length, buffer);
Assert.Equal(data, buffer);
}
- private static Stream CreateCompressedStream(byte[] inputData)
+ private static BufferedReadStream CreateCompressedStream(byte[] inputData)
{
Stream compressedStream = new MemoryStream();
using System.Buffers.IMemoryOwner data = Configuration.Default.MemoryAllocator.Allocate(inputData.Length);
@@ -57,7 +58,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
compressedStream.Seek(0, SeekOrigin.Begin);
- return compressedStream;
+ return new BufferedReadStream(Configuration.Default, compressedStream);
}
}
}
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs
index 50a0b29f3d..dcdd327c27 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs
@@ -3,6 +3,8 @@
using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression;
+using SixLabors.ImageSharp.IO;
+
using Xunit;
namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
@@ -13,12 +15,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
[Theory]
[InlineData(new byte[] { 10, 15, 20, 25, 30, 35, 40, 45 }, 8, new byte[] { 10, 15, 20, 25, 30, 35, 40, 45 })]
[InlineData(new byte[] { 10, 15, 20, 25, 30, 35, 40, 45 }, 5, new byte[] { 10, 15, 20, 25, 30 })]
- public void Decompress_ReadsData(byte[] inputData, int byteCount, byte[] expectedResult)
+ public void Decompress_ReadsData(byte[] inputData, uint byteCount, byte[] expectedResult)
{
- Stream stream = new MemoryStream(inputData);
+ var stream = new BufferedReadStream(Configuration.Default, new MemoryStream(inputData));
var buffer = new byte[expectedResult.Length];
- new NoneTiffCompression(null).Decompress(stream, byteCount, buffer);
+ new NoneTiffCompression(null).Decompress(stream, 0, byteCount, buffer);
Assert.Equal(expectedResult, buffer);
}
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs
index e95e6abbb3..f272c7cb9d 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs
@@ -5,6 +5,7 @@ using System;
using System.IO;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression;
+using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using Xunit;
@@ -25,10 +26,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression
[InlineData(new byte[] { 0xFE, 0xAA, 0x02, 0x80, 0x00, 0x2A, 0xFD, 0xAA, 0x03, 0x80, 0x00, 0x2A, 0x22, 0xF7, 0xAA }, new byte[] { 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA })] // Apple PackBits sample
public void Decompress_ReadsData(byte[] inputData, byte[] expectedResult)
{
- Stream stream = new MemoryStream(inputData);
+ var stream = new BufferedReadStream(Configuration.Default, new MemoryStream(inputData));
var buffer = new byte[expectedResult.Length];
- new PackBitsTiffCompression(new ArrayPoolMemoryAllocator()).Decompress(stream, inputData.Length, buffer);
+ new PackBitsTiffCompression(new ArrayPoolMemoryAllocator()).Decompress(stream, 0, (uint)inputData.Length, buffer);
Assert.Equal(expectedResult, buffer);
}
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Utils/SubStreamTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Utils/SubStreamTests.cs
deleted file mode 100644
index 0aefa76cf7..0000000000
--- a/tests/ImageSharp.Tests/Formats/Tiff/Utils/SubStreamTests.cs
+++ /dev/null
@@ -1,328 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.IO;
-
-using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils;
-
-using Xunit;
-
-namespace SixLabors.ImageSharp.Tests.Formats.Tiff
-{
- [Trait("Format", "Tiff")]
- public class SubStreamTests
- {
- [Fact]
- public void Constructor_PositionsStreamCorrectly_WithSpecifiedOffset()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- innerStream.Position = 2;
-
- SubStream stream = new SubStream(innerStream, 4, 6);
-
- Assert.Equal(0, stream.Position);
- Assert.Equal(6, stream.Length);
- Assert.Equal(4, innerStream.Position);
- }
-
- [Fact]
- public void Constructor_PositionsStreamCorrectly_WithCurrentOffset()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- innerStream.Position = 2;
-
- SubStream stream = new SubStream(innerStream, 6);
-
- Assert.Equal(0, stream.Position);
- Assert.Equal(6, stream.Length);
- Assert.Equal(2, innerStream.Position);
- }
-
- [Fact]
- public void CanRead_ReturnsTrue()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.True(stream.CanRead);
- }
-
- [Fact]
- public void CanWrite_ReturnsFalse()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.False(stream.CanWrite);
- }
-
- [Fact]
- public void CanSeek_ReturnsTrue()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.True(stream.CanSeek);
- }
-
- [Fact]
- public void Length_ReturnsTheConstrainedLength()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.Equal(6, stream.Length);
- }
-
- [Fact]
- public void Position_ReturnsZeroBeforeReading()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.Equal(0, stream.Position);
- Assert.Equal(2, innerStream.Position);
- }
-
- [Fact]
- public void Position_ReturnsPositionAfterReading()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Read(new byte[2], 0, 2);
-
- Assert.Equal(2, stream.Position);
- Assert.Equal(4, innerStream.Position);
- }
-
- [Fact]
- public void Position_ReturnsPositionAfterReadingTwice()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Read(new byte[2], 0, 2);
- stream.Read(new byte[2], 0, 2);
-
- Assert.Equal(4, stream.Position);
- Assert.Equal(6, innerStream.Position);
- }
-
- [Fact]
- public void Position_SettingPropertySeeksToNewPosition()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 3;
-
- Assert.Equal(3, stream.Position);
- Assert.Equal(5, innerStream.Position);
- }
-
- [Fact]
- public void Flush_ThrowsNotSupportedException()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.Throws(() => stream.Flush());
- }
-
- [Fact]
- public void Read_Reads_FromStartOfSubStream()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- byte[] buffer = new byte[3];
- var result = stream.Read(buffer, 0, 3);
-
- Assert.Equal(new byte[] { 3, 4, 5 }, buffer);
- Assert.Equal(3, result);
- }
-
- [Theory]
- [InlineData(2, SeekOrigin.Begin)]
- [InlineData(1, SeekOrigin.Current)]
- [InlineData(4, SeekOrigin.End)]
- public void Read_Reads_FromMiddleOfSubStream(long offset, SeekOrigin origin)
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 1;
- stream.Seek(offset, origin);
- byte[] buffer = new byte[3];
- var result = stream.Read(buffer, 0, 3);
-
- Assert.Equal(new byte[] { 5, 6, 7 }, buffer);
- Assert.Equal(3, result);
- }
-
- [Theory]
- [InlineData(3, SeekOrigin.Begin)]
- [InlineData(2, SeekOrigin.Current)]
- [InlineData(3, SeekOrigin.End)]
- public void Read_Reads_FromEndOfSubStream(long offset, SeekOrigin origin)
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 1;
- stream.Seek(offset, origin);
- byte[] buffer = new byte[3];
- var result = stream.Read(buffer, 0, 3);
-
- Assert.Equal(new byte[] { 6, 7, 8 }, buffer);
- Assert.Equal(3, result);
- }
-
- [Theory]
- [InlineData(4, SeekOrigin.Begin)]
- [InlineData(3, SeekOrigin.Current)]
- [InlineData(2, SeekOrigin.End)]
- public void Read_Reads_FromBeyondEndOfSubStream(long offset, SeekOrigin origin)
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 1;
- stream.Seek(offset, origin);
- byte[] buffer = new byte[3];
- var result = stream.Read(buffer, 0, 3);
-
- Assert.Equal(new byte[] { 7, 8, 0 }, buffer);
- Assert.Equal(2, result);
- }
-
- [Fact]
- public void ReadByte_Reads_FromStartOfSubStream()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- var result = stream.ReadByte();
-
- Assert.Equal(3, result);
- }
-
- [Fact]
- public void ReadByte_Reads_FromMiddleOfSubStream()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 3;
- var result = stream.ReadByte();
-
- Assert.Equal(6, result);
- }
-
- [Fact]
- public void ReadByte_Reads_FromEndOfSubStream()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 5;
- var result = stream.ReadByte();
-
- Assert.Equal(8, result);
- }
-
- [Fact]
- public void ReadByte_Reads_FromBeyondEndOfSubStream()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 5;
- stream.ReadByte();
- var result = stream.ReadByte();
-
- Assert.Equal(-1, result);
- }
-
- [Fact]
- public void Write_ThrowsNotSupportedException()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.Throws(() => stream.Write(new byte[] { 1, 2 }, 0, 2));
- }
-
- [Fact]
- public void WriteByte_ThrowsNotSupportedException()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.Throws(() => stream.WriteByte(42));
- }
-
- [Fact]
- public void Seek_MovesToNewPosition_FromBegin()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 1;
- long result = stream.Seek(2, SeekOrigin.Begin);
-
- Assert.Equal(2, result);
- Assert.Equal(2, stream.Position);
- Assert.Equal(4, innerStream.Position);
- }
-
- [Fact]
- public void Seek_MovesToNewPosition_FromCurrent()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 1;
- long result = stream.Seek(2, SeekOrigin.Current);
-
- Assert.Equal(3, result);
- Assert.Equal(3, stream.Position);
- Assert.Equal(5, innerStream.Position);
- }
-
- [Fact]
- public void Seek_MovesToNewPosition_FromEnd()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- stream.Position = 1;
- long result = stream.Seek(2, SeekOrigin.End);
-
- Assert.Equal(4, result);
- Assert.Equal(4, stream.Position);
- Assert.Equal(6, innerStream.Position);
- }
-
- [Fact]
- public void Seek_ThrowsException_WithInvalidOrigin()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- var e = Assert.Throws(() => stream.Seek(2, (SeekOrigin)99));
- Assert.Equal("Invalid seek origin.", e.Message);
- }
-
- [Fact]
- public void SetLength_ThrowsNotSupportedException()
- {
- Stream innerStream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
- SubStream stream = new SubStream(innerStream, 2, 6);
-
- Assert.Throws(() => stream.SetLength(5));
- }
- }
-}