diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs
index 017591e53f..9b12dc90ff 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs
@@ -22,11 +22,12 @@ internal class ModifiedHuffmanTiffCompression : T4TiffCompression
/// Initializes a new instance of the class.
///
/// The memory allocator.
+ /// The logical order of bits within a byte.
/// The image width.
/// The number of bits per pixel.
/// The photometric interpretation.
- public ModifiedHuffmanTiffCompression(MemoryAllocator allocator, int width, int bitsPerPixel, TiffPhotometricInterpretation photometricInterpretation)
- : base(allocator, width, bitsPerPixel, FaxCompressionOptions.None, photometricInterpretation)
+ public ModifiedHuffmanTiffCompression(MemoryAllocator allocator, TiffFillOrder fillOrder, int width, int bitsPerPixel, TiffPhotometricInterpretation photometricInterpretation)
+ : base(allocator, fillOrder, width, bitsPerPixel, FaxCompressionOptions.None, photometricInterpretation)
{
bool isWhiteZero = photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero;
this.whiteValue = (byte)(isWhiteZero ? 0 : 1);
@@ -36,7 +37,7 @@ public ModifiedHuffmanTiffCompression(MemoryAllocator allocator, int width, int
///
protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
- using var bitReader = new T4BitReader(stream, byteCount, this.Allocator, eolPadding: false, isModifiedHuffman: true);
+ using var bitReader = new T4BitReader(stream, this.FillOrder, byteCount, this.Allocator, eolPadding: false, isModifiedHuffman: true);
buffer.Clear();
uint bitsWritten = 0;
diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs
index 09f8c71f72..384be1cf24 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4BitReader.cs
@@ -5,7 +5,8 @@
using System.Buffers;
using System.Collections.Generic;
using System.IO;
-
+using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
@@ -20,6 +21,11 @@ internal class T4BitReader : IDisposable
///
private int bitsRead;
+ ///
+ /// The logical order of bits within a byte.
+ ///
+ private readonly TiffFillOrder fillOrder;
+
///
/// Current value.
///
@@ -221,12 +227,14 @@ internal class T4BitReader : IDisposable
/// Initializes a new instance of the class.
///
/// The compressed input stream.
+ /// The logical order of bits within a byte.
/// The number of bytes to read from the stream.
/// The memory allocator.
/// Indicates, if fill bits have been added as necessary before EOL codes such that EOL always ends on a byte boundary. Defaults to false.
/// Indicates, if its the modified huffman code variation. Defaults to false.
- public T4BitReader(Stream input, int bytesToRead, MemoryAllocator allocator, bool eolPadding = false, bool isModifiedHuffman = false)
+ public T4BitReader(Stream input, TiffFillOrder fillOrder, int bytesToRead, MemoryAllocator allocator, bool eolPadding = false, bool isModifiedHuffman = false)
{
+ this.fillOrder = fillOrder;
this.Data = allocator.Allocate(bytesToRead);
this.ReadImageDataFromStream(input, bytesToRead);
@@ -375,7 +383,7 @@ public void ReadNextRun()
break;
}
- var currBit = this.ReadValue(1);
+ uint currBit = this.ReadValue(1);
this.value = (this.value << 1) | currBit;
if (this.IsEndOfScanLine)
@@ -816,7 +824,7 @@ private uint GetBit()
Span dataSpan = this.Data.GetSpan();
int shift = 8 - this.bitsRead - 1;
- var bit = (uint)((dataSpan[(int)this.position] & (1 << shift)) != 0 ? 1 : 0);
+ uint bit = (uint)((dataSpan[(int)this.position] & (1 << shift)) != 0 ? 1 : 0);
this.bitsRead++;
return bit;
@@ -837,6 +845,19 @@ private void ReadImageDataFromStream(Stream input, int bytesToRead)
{
Span dataSpan = this.Data.GetSpan();
input.Read(dataSpan, 0, bytesToRead);
+
+ if (this.fillOrder == TiffFillOrder.LeastSignificantBitFirst)
+ {
+ for (int i = 0; i < dataSpan.Length; i++)
+ {
+ dataSpan[i] = ReverseBits(dataSpan[i]);
+ }
+ }
}
+
+ // http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static byte ReverseBits(byte b) =>
+ (byte)((((b * 0x80200802UL) & 0x0884422110UL) * 0x0101010101UL) >> 32);
}
}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs
index 76f0883643..a79ef3fe5e 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs
@@ -20,24 +20,33 @@ internal class T4TiffCompression : TiffBaseDecompressor
private readonly byte blackValue;
+ private readonly int width;
+
///
/// Initializes a new instance of the class.
///
/// The memory allocator.
+ /// The logical order of bits within a byte.
/// The image width.
/// The number of bits per pixel.
/// Fax compression options.
/// The photometric interpretation.
- public T4TiffCompression(MemoryAllocator allocator, int width, int bitsPerPixel, FaxCompressionOptions faxOptions, TiffPhotometricInterpretation photometricInterpretation)
+ public T4TiffCompression(MemoryAllocator allocator, TiffFillOrder fillOrder, int width, int bitsPerPixel, FaxCompressionOptions faxOptions, TiffPhotometricInterpretation photometricInterpretation)
: base(allocator, width, bitsPerPixel)
{
this.faxCompressionOptions = faxOptions;
-
+ this.FillOrder = fillOrder;
+ this.width = width;
bool isWhiteZero = photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero;
this.whiteValue = (byte)(isWhiteZero ? 0 : 1);
this.blackValue = (byte)(isWhiteZero ? 1 : 0);
}
+ ///
+ /// Gets the logical order of bits within a byte.
+ ///
+ protected TiffFillOrder FillOrder { get; }
+
///
protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer)
{
@@ -46,27 +55,22 @@ protected override void Decompress(BufferedReadStream stream, int byteCount, Spa
TiffThrowHelper.ThrowNotSupported("TIFF CCITT 2D compression is not yet supported");
}
- var eolPadding = this.faxCompressionOptions.HasFlag(FaxCompressionOptions.EolPadding);
- using var bitReader = new T4BitReader(stream, byteCount, this.Allocator, eolPadding);
+ bool eolPadding = this.faxCompressionOptions.HasFlag(FaxCompressionOptions.EolPadding);
+ using var bitReader = new T4BitReader(stream, this.FillOrder, byteCount, this.Allocator, eolPadding);
buffer.Clear();
uint bitsWritten = 0;
+ uint pixelWritten = 0;
while (bitReader.HasMoreData)
{
bitReader.ReadNextRun();
if (bitReader.RunLength > 0)
{
- if (bitReader.IsWhiteRun)
- {
- BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.whiteValue);
- bitsWritten += bitReader.RunLength;
- }
- else
- {
- BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.blackValue);
- bitsWritten += bitReader.RunLength;
- }
+ this.WritePixelRun(buffer, bitReader, bitsWritten);
+
+ bitsWritten += bitReader.RunLength;
+ pixelWritten += bitReader.RunLength;
}
if (bitReader.IsEndOfScanLine)
@@ -78,8 +82,29 @@ protected override void Decompress(BufferedReadStream stream, int byteCount, Spa
BitWriterUtils.WriteBits(buffer, (int)bitsWritten, pad, 0);
bitsWritten += pad;
}
+
+ pixelWritten = 0;
}
}
+
+ // Edge case for when we are at the last byte, but there are still some unwritten pixels left.
+ if (pixelWritten > 0 && pixelWritten < this.width)
+ {
+ bitReader.ReadNextRun();
+ this.WritePixelRun(buffer, bitReader, bitsWritten);
+ }
+ }
+
+ private void WritePixelRun(Span buffer, T4BitReader bitReader, uint bitsWritten)
+ {
+ if (bitReader.IsWhiteRun)
+ {
+ BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.whiteValue);
+ }
+ else
+ {
+ BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.blackValue);
+ }
}
///
diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
index a6d44f4d3c..ff04edab70 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
@@ -16,7 +16,8 @@ public static TiffBaseDecompressor Create(
int width,
int bitsPerPixel,
TiffPredictor predictor,
- FaxCompressionOptions faxOptions)
+ FaxCompressionOptions faxOptions,
+ TiffFillOrder fillOrder)
{
switch (method)
{
@@ -40,11 +41,11 @@ public static TiffBaseDecompressor Create(
case TiffDecoderCompressionType.T4:
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");
- return new T4TiffCompression(allocator, width, bitsPerPixel, faxOptions, photometricInterpretation);
+ return new T4TiffCompression(allocator, fillOrder, width, bitsPerPixel, faxOptions, photometricInterpretation);
case TiffDecoderCompressionType.HuffmanRle:
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");
- return new ModifiedHuffmanTiffCompression(allocator, width, bitsPerPixel, photometricInterpretation);
+ return new ModifiedHuffmanTiffCompression(allocator, fillOrder, width, bitsPerPixel, photometricInterpretation);
default:
throw TiffThrowHelper.NotSupportedDecompressor(nameof(method));
diff --git a/src/ImageSharp/Formats/Tiff/README.md b/src/ImageSharp/Formats/Tiff/README.md
index 5b116b819a..7b7c0efd53 100644
--- a/src/ImageSharp/Formats/Tiff/README.md
+++ b/src/ImageSharp/Formats/Tiff/README.md
@@ -25,7 +25,7 @@
## Implementation Status
-- The Decoder and Encoder currently only supports a single frame per image.
+- The Decoder currently only supports a single frame per image.
- Some compression formats are not yet supported. See the list below.
### Deviations from the TIFF spec (to be fixed)
@@ -81,7 +81,7 @@
|Thresholding | | | |
|CellWidth | | | |
|CellLength | | | |
-|FillOrder | | - | Ignore. In practice is very uncommon, and is not recommended. |
+|FillOrder | | Y | |
|ImageDescription | Y | Y | |
|Make | Y | Y | |
|Model | Y | Y | |
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
index 63185619d4..8477ba2d20 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
@@ -85,6 +85,11 @@ public TiffDecoderCore(Configuration configuration, ITiffDecoderOptions options)
///
public FaxCompressionOptions FaxCompressionOptions { get; set; }
+ ///
+ /// Gets or sets the the logical order of bits within a byte.
+ ///
+ public TiffFillOrder FillOrder { get; set; }
+
///
/// Gets or sets the planar configuration type to use when decoding the image.
///
@@ -264,7 +269,15 @@ private void DecodeStripsPlanar(ImageFrame frame, int rowsPerStr
stripBuffers[stripIndex] = this.memoryAllocator.Allocate(uncompressedStripSize);
}
- using TiffBaseDecompressor decompressor = TiffDecompressorsFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, frame.Width, bitsPerPixel, this.Predictor, this.FaxCompressionOptions);
+ using TiffBaseDecompressor decompressor = TiffDecompressorsFactory.Create(
+ this.CompressionType,
+ this.memoryAllocator,
+ this.PhotometricInterpretation,
+ frame.Width,
+ bitsPerPixel,
+ this.Predictor,
+ this.FaxCompressionOptions,
+ this.FillOrder);
TiffBasePlanarColorDecoder colorDecoder = TiffColorDecoderFactory.CreatePlanar(this.ColorType, this.BitsPerSample, this.ColorMap, this.byteOrder);
@@ -314,7 +327,8 @@ private void DecodeStripsChunky(ImageFrame frame, int rowsPerStr
frame.Width,
bitsPerPixel,
this.Predictor,
- this.FaxCompressionOptions);
+ this.FaxCompressionOptions,
+ this.FillOrder);
TiffBaseColorDecoder colorDecoder = TiffColorDecoderFactory.Create(this.Configuration, this.ColorType, this.BitsPerSample, this.ColorMap, this.byteOrder);
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
index 8590203a70..f59a9fbbab 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
@@ -35,9 +35,9 @@ public static void VerifyAndParse(this TiffDecoderCore options, ExifProfile exif
}
TiffFillOrder fillOrder = (TiffFillOrder?)exifProfile.GetValue(ExifTag.FillOrder)?.Value ?? TiffFillOrder.MostSignificantBitFirst;
- if (fillOrder != TiffFillOrder.MostSignificantBitFirst)
+ if (fillOrder == TiffFillOrder.LeastSignificantBitFirst && frameMetadata.BitsPerPixel != TiffBitsPerPixel.Bit1)
{
- TiffThrowHelper.ThrowNotSupported("The lower-order bits of the byte FillOrder is not supported.");
+ TiffThrowHelper.ThrowNotSupported("The lower-order bits of the byte FillOrder is only supported in combination with 1bit per pixel bicolor tiff's.");
}
if (frameMetadata.Predictor == TiffPredictor.FloatingPoint)
@@ -69,6 +69,7 @@ public static void VerifyAndParse(this TiffDecoderCore options, ExifProfile exif
options.PhotometricInterpretation = frameMetadata.PhotometricInterpretation ?? TiffPhotometricInterpretation.Rgb;
options.BitsPerPixel = frameMetadata.BitsPerPixel != null ? (int)frameMetadata.BitsPerPixel.Value : (int)TiffBitsPerPixel.Bit24;
options.BitsPerSample = frameMetadata.BitsPerSample ?? new TiffBitsPerSample(0, 0, 0);
+ options.FillOrder = fillOrder;
options.ParseColorType(exifProfile);
options.ParseCompression(frameMetadata.Compression, exifProfile);
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
index 182fafa33e..77a8153c50 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
@@ -279,6 +279,11 @@ public void TiffDecoder_CanDecode_HuffmanCompressed(TestImageProvider(TestImageProvider provider)
where TPixel : unmanaged, IPixel => TestTiffDecoder(provider);
+ [Theory]
+ [WithFile(CcittFax3LowerOrderBitsFirst, PixelTypes.Rgba32)]
+ public void TiffDecoder_CanDecode_Compressed_LowerOrderBitsFirst(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel => TestTiffDecoder(provider);
+
[Theory]
[WithFile(Calliphora_RgbPackbits, PixelTypes.Rgba32)]
[WithFile(RgbPackbits, PixelTypes.Rgba32)]
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
index 47b6fcf727..712c8502ab 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
@@ -117,7 +117,11 @@ public void EncoderOptions_UnsupportedBitPerPixel_DefaultTo24Bits(TiffBitsPerPix
[InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.Jpeg, TiffBitsPerPixel.Bit24, TiffCompression.None)]
[InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.OldDeflate, TiffBitsPerPixel.Bit24, TiffCompression.None)]
[InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.OldJpeg, TiffBitsPerPixel.Bit24, TiffCompression.None)]
- public void EncoderOptions_SetPhotometricInterpretationAndCompression_Works(TiffPhotometricInterpretation? photometricInterpretation, TiffCompression compression, TiffBitsPerPixel expectedBitsPerPixel, TiffCompression expectedCompression)
+ public void EncoderOptions_SetPhotometricInterpretationAndCompression_Works(
+ TiffPhotometricInterpretation? photometricInterpretation,
+ TiffCompression compression,
+ TiffBitsPerPixel expectedBitsPerPixel,
+ TiffCompression expectedCompression)
{
// arrange
var tiffEncoder = new TiffEncoder { PhotometricInterpretation = photometricInterpretation, Compression = compression };
diff --git a/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs
index 50ec09ce3f..7620d63deb 100644
--- a/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs
+++ b/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs
@@ -11,6 +11,7 @@
namespace SixLabors.ImageSharp.Tests.Memory.Allocators
{
+ [Collection("RunSerial")]
public class ArrayPoolMemoryAllocatorTests
{
private const int MaxPooledBufferSizeInBytes = 2048;
@@ -56,19 +57,14 @@ public void WhenPassedOnly_MaxPooledBufferSizeInBytes_SmallerThresholdValueIsAut
[Fact]
public void When_PoolSelectorThresholdInBytes_IsGreaterThan_MaxPooledBufferSizeInBytes_ExceptionIsThrown()
- {
- Assert.ThrowsAny(() => new ArrayPoolMemoryAllocator(100, 200));
- }
+ => Assert.ThrowsAny(() => new ArrayPoolMemoryAllocator(100, 200));
}
[Theory]
[InlineData(32)]
[InlineData(512)]
[InlineData(MaxPooledBufferSizeInBytes - 1)]
- public void SmallBuffersArePooled_OfByte(int size)
- {
- Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer(size));
- }
+ public void SmallBuffersArePooled_OfByte(int size) => Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer(size));
[Theory]
[InlineData(128 * 1024 * 1024)]
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 8eaaec4935..059e51cec9 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -539,6 +539,8 @@ public static class Tiff
public const string CcittFax3AllMakeupCodes = "Tiff/ccitt_fax3_all_makeup_codes.tiff";
public const string HuffmanRleAllTermCodes = "Tiff/huffman_rle_all_terminating_codes.tiff";
public const string HuffmanRleAllMakeupCodes = "Tiff/huffman_rle_all_makeup_codes.tiff";
+ public const string CcittFax3LowerOrderBitsFirst = "Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff";
+ public const string HuffmanRleLowerOrderBitsFirst = "Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff";
// Test case for an issue, that the last bits in a row got ignored.
public const string HuffmanRle_basi3p02 = "Tiff/basi3p02_huffman_rle.tiff";
@@ -619,7 +621,6 @@ public static class Tiff
public const string MultiframeDifferentSize = "Tiff/multipage_differentSize.tiff";
public const string MultiframeDifferentVariants = "Tiff/multipage_differentVariants.tiff";
- public const string FillOrder2 = "Tiff/b0350_fillorder2.tiff";
public const string LittleEndianByteOrder = "Tiff/little_endian.tiff";
public const string Fax4_Motorola = "Tiff/moy.tiff";
@@ -634,7 +635,7 @@ public static class Tiff
public static readonly string[] Metadata = { SampleMetadata };
- public static readonly string[] NotSupported = { Calliphora_RgbJpeg, RgbJpeg, RgbUncompressedTiled, MultiframeDifferentSize, MultiframeDifferentVariants, FillOrder2, Calliphora_Fax4Compressed, Fax4_Motorola };
+ public static readonly string[] NotSupported = { Calliphora_RgbJpeg, RgbJpeg, RgbUncompressedTiled, MultiframeDifferentSize, MultiframeDifferentVariants, Calliphora_Fax4Compressed, Fax4_Motorola };
}
}
}
diff --git a/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff b/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff
index 5574bd58ed..24a4141f56 100644
--- a/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff
+++ b/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:622d69dba0a8a67aa3b87e384a2b9ea8d29689eaa5cb5d0eee857f98ed660517
-size 15154924
+oid sha256:579db6b2bd34566846de992f255c6b341d0f88d957a0eb02b01caad3f20c5b44
+size 78794
diff --git a/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff b/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff
index 39852d5345..d2761d2919 100644
--- a/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff
+++ b/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8b9b105857723bca5f478a9ab23c0aeca93abe863781019bbd2da47f18c46f24
-size 125778
+oid sha256:bba35f1e43c8425f3bcfab682efae4d2c00c62f0d8a4b411e646d32047469526
+size 125802
diff --git a/tests/Images/Input/Tiff/b0350_fillorder2.tiff b/tests/Images/Input/Tiff/b0350_fillorder2.tiff
deleted file mode 100644
index 3b7ee6ac3a..0000000000
--- a/tests/Images/Input/Tiff/b0350_fillorder2.tiff
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:37c6a28f460d8781fdc3bcf0cc9bd23f633b03899563546bfc6234a8478f67f0
-size 68637
diff --git a/tests/Images/Input/Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff b/tests/Images/Input/Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff
new file mode 100644
index 0000000000..d9b5a5bfb7
--- /dev/null
+++ b/tests/Images/Input/Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eb56b3582c5c7d91d712e68181110ab0bf74d21992030629f05803c420b7b483
+size 388
diff --git a/tests/Images/Input/Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff b/tests/Images/Input/Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff
new file mode 100644
index 0000000000..6ab0603246
--- /dev/null
+++ b/tests/Images/Input/Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5ac3e56a93996464a579ae19cf5f8d9531e2f08db36879aaba176731c24951a5
+size 352
diff --git a/tests/Images/Input/Tiff/f8179f8f5e566349cf3583a1ff3ea95c.tiff b/tests/Images/Input/Tiff/f8179f8f5e566349cf3583a1ff3ea95c.tiff
new file mode 100644
index 0000000000..9dc10018e4
--- /dev/null
+++ b/tests/Images/Input/Tiff/f8179f8f5e566349cf3583a1ff3ea95c.tiff
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cf75c4b679d2449e239f228cdee6a25adc7d7b16dde3fb9061a07b2fb0699db1
+size 735412
diff --git a/tests/Images/Input/Tiff/g3test.tiff b/tests/Images/Input/Tiff/g3test.tiff
new file mode 100644
index 0000000000..62207de3ad
--- /dev/null
+++ b/tests/Images/Input/Tiff/g3test.tiff
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d5b2e1a17338133aa95cb8a16d82a171f5b50f7b9ae1a51ab06227dc3daa81d5
+size 50401