Browse Source

Add test cases for tiled lzw compressed images

pull/2878/head
Brian Popow 12 months ago
parent
commit
7a5be7287e
  1. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs
  2. 20
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs
  3. 7
      src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs
  4. 2
      src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
  5. 2
      tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs
  6. 17
      tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
  7. 15
      tests/ImageSharp.Tests/TestImages.cs
  8. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_big_endian_lzw_compressed_predictor.tiff
  9. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_little_endian_lzw_compressed_predictor.tiff
  10. 3
      tests/Images/Input/Tiff/tiled_gray_32bit_big_endian_lzw_compressed_predictor.tiff
  11. 3
      tests/Images/Input/Tiff/tiled_gray_32bit_little_endian_lzw_compressed_predictor.tiff
  12. 3
      tests/Images/Input/Tiff/tiled_gray_lzw_compressed_predictor.tiff
  13. 3
      tests/Images/Input/Tiff/tiled_rgb_48bit_big_endian_lzw_compressed_predictor.tiff
  14. 3
      tests/Images/Input/Tiff/tiled_rgb_48bit_little_endian_lzw_compressed_predictor.tiff
  15. 3
      tests/Images/Input/Tiff/tiled_rgb_64bit_big_endian_lzw_compressed_predictor.tiff
  16. 3
      tests/Images/Input/Tiff/tiled_rgb_64bit_little_endian_lzw_compressed_predictor.tiff
  17. 3
      tests/Images/Input/Tiff/tiled_rgb_96bit_big_endian_lzw_compressed_predictor.tiff
  18. 3
      tests/Images/Input/Tiff/tiled_rgb_96bit_little_endian_lzw_compressed_predictor.tiff
  19. 3
      tests/Images/Input/Tiff/tiled_rgb_lzw_compressed_predictor.tiff
  20. 3
      tests/Images/Input/Tiff/tiled_rgba_128bit_big_endian_lzw_compressed_predictor.tiff
  21. 3
      tests/Images/Input/Tiff/tiled_rgba_128bit_little_endian_lzw_compressed_predictor.tiff
  22. 3
      tests/Images/Input/Tiff/tiled_rgba_lzw_compressed_predictor.tiff

2
src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs

@ -76,11 +76,11 @@ internal sealed class DeflateTiffCompression : TiffBaseDecompressor
}
}
// When the image is tiled, undoing the horizontal predictor will be done for each tile row in the DecodeTilesChunky() method.
if (this.Predictor == TiffPredictor.Horizontal)
{
if (this.isTiled)
{
// When the image is tiled, undoing the horizontal predictor will be done for each tile row.
HorizontalPredictor.UndoTile(buffer, this.tileWidth, this.colorType, this.isBigEndian);
}
else

20
src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs

@ -17,6 +17,10 @@ internal sealed class LzwTiffCompression : TiffBaseDecompressor
private readonly TiffColorType colorType;
private readonly bool isTiled;
private readonly int tileWidth;
/// <summary>
/// Initializes a new instance of the <see cref="LzwTiffCompression" /> class.
/// </summary>
@ -26,11 +30,15 @@ internal sealed class LzwTiffCompression : TiffBaseDecompressor
/// <param name="colorType">The color type of the pixel data.</param>
/// <param name="predictor">The tiff predictor used.</param>
/// <param name="isBigEndian">if set to <c>true</c> decodes the pixel data as big endian, otherwise as little endian.</param>
public LzwTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffColorType colorType, TiffPredictor predictor, bool isBigEndian)
/// <param name="isTiled">Flag indicates, if the image is a tiled image.</param>
/// <param name="tileWidth">Number of pixels in a tile row.</param>
public LzwTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffColorType colorType, TiffPredictor predictor, bool isBigEndian, bool isTiled, int tileWidth)
: base(memoryAllocator, width, bitsPerPixel, predictor)
{
this.colorType = colorType;
this.isBigEndian = isBigEndian;
this.isTiled = isTiled;
this.tileWidth = tileWidth;
}
/// <inheritdoc/>
@ -41,7 +49,15 @@ internal sealed class LzwTiffCompression : TiffBaseDecompressor
if (this.Predictor == TiffPredictor.Horizontal)
{
HorizontalPredictor.Undo(buffer, this.Width, this.colorType, this.isBigEndian);
if (this.isTiled)
{
// When the image is tiled, undoing the horizontal predictor will be done for each tile row.
HorizontalPredictor.UndoTile(buffer, this.tileWidth, this.colorType, this.isBigEndian);
}
else
{
HorizontalPredictor.Undo(buffer, this.Width, this.colorType, this.isBigEndian);
}
}
}

7
src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs

@ -62,6 +62,13 @@ internal static class HorizontalPredictor
}
}
/// <summary>
/// Inverts the horizontal predictor for each tile row.
/// </summary>
/// <param name="pixelBytes">Buffer with decompressed pixel data for a tile.</param>
/// <param name="tileWidth">Tile with in pixels.</param>
/// <param name="colorType">The color type of the pixel data.</param>
/// <param name="isBigEndian">If set to <c>true</c> decodes the pixel data as big endian, otherwise as little endian.</param>
public static void UndoTile(Span<byte> pixelBytes, int tileWidth, TiffColorType colorType, bool isBigEndian)
{
for (int y = 0; y < tileWidth; y++)

2
src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs

@ -45,7 +45,7 @@ internal static class TiffDecompressorsFactory
case TiffDecoderCompressionType.Lzw:
DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected");
return new LzwTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian);
return new LzwTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian, isTiled, tileWidth);
case TiffDecoderCompressionType.T4:
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");

2
tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs

@ -37,7 +37,7 @@ public class LzwTiffCompressionTests
using BufferedReadStream stream = CreateCompressedStream(data);
byte[] buffer = new byte[data.Length];
using var decompressor = new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false);
using var decompressor = new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false, false, 0);
decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer, default);
Assert.Equal(data, buffer);

17
tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs

@ -107,6 +107,23 @@ public class TiffDecoderTests : TiffDecoderBaseTester
public void TiffDecoder_CanDecode_Tiled_Deflate_Compressed<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
[Theory]
[WithFile(TiledRgbaLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgbLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGrayLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray16BitLittleEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray16BitBigEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray32BitLittleEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray32BitBigEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb48BitLittleEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb48BitBigEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgba64BitLittleEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgba64BitBigEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb96BitLittleEndianLzwCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb96BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
public void TiffDecoder_CanDecode_Tiled_Lzw_Compressed<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
[Theory]
[WithFile(Rgba8BitPlanarUnassociatedAlpha, PixelTypes.Rgba32)]
public void TiffDecoder_CanDecode_Planar_32Bit<TPixel>(TestImageProvider<TPixel> provider)

15
tests/ImageSharp.Tests/TestImages.cs

@ -1003,6 +1003,21 @@ public static class TestImages
public const string TiledRgb96BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_96bit_big_endian_deflate_compressed_predictor.tiff";
public const string TiledRgba128BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_128bit_little_endian_deflate_compressed_predictor.tiff";
public const string TiledRgba128BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_128bit_big_endian_deflate_compressed_predictor.tiff";
public const string TiledRgbaLzwCompressedWithPredictor = "Tiff/tiled_rgba_lzw_compressed_predictor.tiff";
public const string TiledRgbLzwCompressedWithPredictor = "Tiff/tiled_rgb_lzw_compressed_predictor.tiff";
public const string TiledGrayLzwCompressedWithPredictor = "Tiff/tiled_gray_lzw_compressed_predictor.tiff";
public const string TiledGray16BitLittleEndianLzwCompressedWithPredictor = "Tiff/tiled_gray_16bit_little_endian_lzw_compressed_predictor.tiff";
public const string TiledGray16BitBigEndianLzwCompressedWithPredictor = "Tiff/tiled_gray_16bit_big_endian_lzw_compressed_predictor.tiff";
public const string TiledGray32BitLittleEndianLzwCompressedWithPredictor = "Tiff/tiled_gray_32bit_little_endian_lzw_compressed_predictor.tiff";
public const string TiledGray32BitBigEndianLzwCompressedWithPredictor = "Tiff/tiled_gray_32bit_big_endian_lzw_compressed_predictor.tiff";
public const string TiledRgb48BitLittleEndianLzwCompressedWithPredictor = "Tiff/tiled_rgb_48bit_little_endian_lzw_compressed_predictor.tiff";
public const string TiledRgb48BitBigEndianLzwCompressedWithPredictor = "Tiff/tiled_rgb_48bit_big_endian_lzw_compressed_predictor.tiff";
public const string TiledRgba64BitLittleEndianLzwCompressedWithPredictor = "Tiff/tiled_rgba_64bit_little_endian_lzw_compressed_predictor.tiff";
public const string TiledRgba64BitBigEndianLzwCompressedWithPredictor = "Tiff/tiled_rgba_64bit_big_endian_lzw_compressed_predictor.tiff";
public const string TiledRgb96BitLittleEndianLzwCompressedWithPredictor = "Tiff/tiled_rgb_96bit_little_endian_lzw_compressed_predictor.tiff";
public const string TiledRgb96BitBigEndianLzwCompressedWithPredictor = "Tiff/tiled_rgb_96bit_big_endian_lzw_compressed_predictor.tiff";
public const string TiledRgba128BitLittleEndianLzwCompressedWithPredictor = "Tiff/tiled_rgba_128bit_little_endian_lzw_compressed_predictor.tiff";
public const string TiledRgba128BitBigEndianLzwCompressedWithPredictor = "Tiff/tiled_rgba_128bit_big_endian_lzw_compressed_predictor.tiff";
// Images with alpha channel.
public const string Rgba2BitUnassociatedAlpha = "Tiff/RgbaUnassociatedAlpha2bit.tiff";

3
tests/Images/Input/Tiff/tiled_gray_16bit_big_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d1cf5098ff98ded0a55cfa73f823cef9c324a66e38ce4a82bae2d3ef4c058c3e
size 78817

3
tests/Images/Input/Tiff/tiled_gray_16bit_little_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:879bacee73f5fea767439071aa6057d66d2d61bc554b109abb7b79765873730b
size 78795

3
tests/Images/Input/Tiff/tiled_gray_32bit_big_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:41140a44fde93ea15514b153f1fd4d15f8e69fc8ca0c88336f01c700c4d06f93
size 104333

3
tests/Images/Input/Tiff/tiled_gray_32bit_little_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b7c32da6db17088b0c3e2c21ffbdd7c43fc4944b03c2cdb9b863c296656b898d
size 103239

3
tests/Images/Input/Tiff/tiled_gray_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:63deeb0eecf0ce51000a5bba275d5a7e40fb833a962b50e6b85c4493a3719911
size 61555

3
tests/Images/Input/Tiff/tiled_rgb_48bit_big_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:45f06403f1dc24991450331c3388ba8c4f5fd004f48787c541fad0b1c104b964
size 212595

3
tests/Images/Input/Tiff/tiled_rgb_48bit_little_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4fdb91eda4e04df41df9dfb98702349308b0f104ca49051726db084c595d912b
size 212463

3
tests/Images/Input/Tiff/tiled_rgb_64bit_big_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a0ddd2ec8f73c784b060ff790e70f586bba70905b75f3cf8ae18f2b054e1eb06
size 244677

3
tests/Images/Input/Tiff/tiled_rgb_64bit_little_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d8e05d9ca953045d732c4304575588d2db2ead50177b2ed9416922568760ee1f
size 244625

3
tests/Images/Input/Tiff/tiled_rgb_96bit_big_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f99d456c3fbf25ca307026a355230d7e68ac89c73d5739cceca1a2a600214483
size 282887

3
tests/Images/Input/Tiff/tiled_rgb_96bit_little_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3bdbf90168ec824eab9f66ebd12d5dd09971363719a7b382111f50344751bbfa
size 281055

3
tests/Images/Input/Tiff/tiled_rgb_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:12382128d89ddddf8b7ec0cf70bdfcac26c9b093bb1a2b77f61ddf75a824bfd7
size 163249

3
tests/Images/Input/Tiff/tiled_rgba_128bit_big_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:81819483cbde5fddbbbf274da327a85a38db7d9946187cb5fa8c00cb03e2828d
size 336229

3
tests/Images/Input/Tiff/tiled_rgba_128bit_little_endian_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ed8cd226de68190ea5740d59ec0ef95095a6802ffb40539e9e2db0d9cd0ab276
size 334413

3
tests/Images/Input/Tiff/tiled_rgba_lzw_compressed_predictor.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3b9a1da29756a4bbac7ea7266067748f8468619191e9a7635e84e5eac8acc3b8
size 183629
Loading…
Cancel
Save