Browse Source

Merge branch 'main' into icc-color-conversion

pull/1567/head
James Jackson-South 9 months ago
parent
commit
6d0c8e898a
  1. 4
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 24
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs
  3. 24
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs
  4. 935
      src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs
  5. 10
      src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
  6. 9
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  7. 18
      src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
  8. 23
      src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
  9. 42
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
  10. 2
      tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs
  11. 2
      tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs
  12. 34
      tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
  13. 10
      tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs
  14. 4
      tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs
  15. 2
      tests/ImageSharp.Tests/Image/ImageFrameTests.cs
  16. 2
      tests/ImageSharp.Tests/Image/ImageTests.cs
  17. 33
      tests/ImageSharp.Tests/TestImages.cs
  18. 2
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
  19. 3
      tests/Images/Input/Jpg/issues/issue-2857-subsub-ifds.jpg
  20. 3
      tests/Images/Input/Tiff/Issues/Issue2909.tiff
  21. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_big_endian_deflate_compressed_predictor.tiff
  22. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_big_endian_lzw_compressed_predictor.tiff
  23. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_little_endian_deflate_compressed_predictor.tiff
  24. 3
      tests/Images/Input/Tiff/tiled_gray_16bit_little_endian_lzw_compressed_predictor.tiff
  25. 3
      tests/Images/Input/Tiff/tiled_gray_32bit_big_endian_deflate_compressed_predictor.tiff
  26. 3
      tests/Images/Input/Tiff/tiled_gray_32bit_big_endian_lzw_compressed_predictor.tiff
  27. 3
      tests/Images/Input/Tiff/tiled_gray_32bit_little_endian_deflate_compressed_predictor.tiff
  28. 3
      tests/Images/Input/Tiff/tiled_gray_32bit_little_endian_lzw_compressed_predictor.tiff
  29. 3
      tests/Images/Input/Tiff/tiled_gray_deflate_compressed_predictor.tiff
  30. 3
      tests/Images/Input/Tiff/tiled_gray_lzw_compressed_predictor.tiff
  31. 3
      tests/Images/Input/Tiff/tiled_rgb_48bit_big_endian_deflate_compressed_predictor.tiff
  32. 3
      tests/Images/Input/Tiff/tiled_rgb_48bit_big_endian_lzw_compressed_predictor.tiff
  33. 3
      tests/Images/Input/Tiff/tiled_rgb_48bit_little_endian_deflate_compressed_predictor.tiff
  34. 3
      tests/Images/Input/Tiff/tiled_rgb_48bit_little_endian_lzw_compressed_predictor.tiff
  35. 3
      tests/Images/Input/Tiff/tiled_rgb_64bit_big_endian_deflate_compressed_predictor.tiff
  36. 3
      tests/Images/Input/Tiff/tiled_rgb_64bit_big_endian_lzw_compressed_predictor.tiff
  37. 3
      tests/Images/Input/Tiff/tiled_rgb_64bit_little_endian_deflate_compressed_predictor.tiff
  38. 3
      tests/Images/Input/Tiff/tiled_rgb_64bit_little_endian_lzw_compressed_predictor.tiff
  39. 3
      tests/Images/Input/Tiff/tiled_rgb_96bit_big_endian_deflate_compressed_predictor.tiff
  40. 3
      tests/Images/Input/Tiff/tiled_rgb_96bit_big_endian_lzw_compressed_predictor.tiff
  41. 3
      tests/Images/Input/Tiff/tiled_rgb_96bit_little_endian_deflate_compressed_predictor.tiff
  42. 3
      tests/Images/Input/Tiff/tiled_rgb_96bit_little_endian_lzw_compressed_predictor.tiff
  43. 3
      tests/Images/Input/Tiff/tiled_rgb_deflate_compressed_predictor.tiff
  44. 3
      tests/Images/Input/Tiff/tiled_rgb_lzw_compressed_predictor.tiff
  45. 3
      tests/Images/Input/Tiff/tiled_rgba_128bit_big_endian_deflate_compressed_predictor.tiff
  46. 3
      tests/Images/Input/Tiff/tiled_rgba_128bit_big_endian_lzw_compressed_predictor.tiff
  47. 3
      tests/Images/Input/Tiff/tiled_rgba_128bit_little_endian_deflate_compressed_predictor.tiff
  48. 3
      tests/Images/Input/Tiff/tiled_rgba_128bit_little_endian_lzw_compressed_predictor.tiff
  49. 3
      tests/Images/Input/Tiff/tiled_rgba_64bit_big_endian_deflate_compressed_predictor.tiff
  50. 3
      tests/Images/Input/Tiff/tiled_rgba_64bit_big_endian_lzw_compressed_predictor.tiff
  51. 3
      tests/Images/Input/Tiff/tiled_rgba_64bit_little_endian_deflate_compressed_predictor.tiff
  52. 3
      tests/Images/Input/Tiff/tiled_rgba_64bit_little_endian_lzw_compressed_predictor.tiff
  53. 3
      tests/Images/Input/Tiff/tiled_rgba_deflate_compressed_predictor.tiff
  54. 3
      tests/Images/Input/Tiff/tiled_rgba_lzw_compressed_predictor.tiff

4
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -1597,8 +1597,8 @@ internal sealed class BmpDecoderCore : ImageDecoderCore
if (palette.Length > 0)
{
Color[] colorTable = new Color[palette.Length / Unsafe.SizeOf<Bgr24>()];
ReadOnlySpan<Bgr24> rgbTable = MemoryMarshal.Cast<byte, Bgr24>(palette);
Color[] colorTable = new Color[palette.Length / Unsafe.SizeOf<Bgra32>()];
ReadOnlySpan<Bgra32> rgbTable = MemoryMarshal.Cast<byte, Bgra32>(palette);
Color.FromPixel(rgbTable, colorTable);
this.bmpMetadata.ColorTable = colorTable;
}

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

@ -22,6 +22,12 @@ internal sealed class DeflateTiffCompression : TiffBaseDecompressor
private readonly TiffColorType colorType;
private readonly bool isTiled;
private readonly int tileWidth;
private readonly int tileHeight;
/// <summary>
/// Initializes a new instance of the <see cref="DeflateTiffCompression" /> class.
/// </summary>
@ -31,11 +37,17 @@ internal sealed class DeflateTiffCompression : 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 DeflateTiffCompression(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>
/// <param name="tileHeight">Number of rows in a tile.</param>
public DeflateTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffColorType colorType, TiffPredictor predictor, bool isBigEndian, bool isTiled, int tileWidth, int tileHeight)
: base(memoryAllocator, width, bitsPerPixel, predictor)
{
this.colorType = colorType;
this.isBigEndian = isBigEndian;
this.isTiled = isTiled;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
}
/// <inheritdoc/>
@ -70,7 +82,15 @@ internal sealed class DeflateTiffCompression : 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.tileHeight, this.colorType, this.isBigEndian);
}
else
{
HorizontalPredictor.Undo(buffer, this.Width, this.colorType, this.isBigEndian);
}
}
}

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

@ -17,6 +17,12 @@ internal sealed class LzwTiffCompression : TiffBaseDecompressor
private readonly TiffColorType colorType;
private readonly bool isTiled;
private readonly int tileWidth;
private readonly int tileHeight;
/// <summary>
/// Initializes a new instance of the <see cref="LzwTiffCompression" /> class.
/// </summary>
@ -26,11 +32,17 @@ 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>
/// <param name="tileHeight">Number of rows in a tile.</param>
public LzwTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffColorType colorType, TiffPredictor predictor, bool isBigEndian, bool isTiled, int tileWidth, int tileHeight)
: base(memoryAllocator, width, bitsPerPixel, predictor)
{
this.colorType = colorType;
this.isBigEndian = isBigEndian;
this.isTiled = isTiled;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
}
/// <inheritdoc/>
@ -41,7 +53,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.tileHeight, this.colorType, this.isBigEndian);
}
else
{
HorizontalPredictor.Undo(buffer, this.Width, this.colorType, this.isBigEndian);
}
}
}

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

File diff suppressed because it is too large

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

@ -4,7 +4,6 @@
using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Tiff.Compression;
@ -24,7 +23,10 @@ internal static class TiffDecompressorsFactory
byte[] jpegTables,
uint oldJpegStartOfImageMarker,
TiffFillOrder fillOrder,
ByteOrder byteOrder)
ByteOrder byteOrder,
bool isTiled = false,
int tileWidth = 0,
int tileHeight = 0)
{
switch (method)
{
@ -40,11 +42,11 @@ internal static class TiffDecompressorsFactory
case TiffDecoderCompressionType.Deflate:
DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected");
return new DeflateTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian);
return new DeflateTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian, isTiled, tileWidth, tileHeight);
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, tileHeight);
case TiffDecoderCompressionType.T4:
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");

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

@ -679,7 +679,7 @@ internal class TiffDecoderCore : ImageDecoderCore
using IMemoryOwner<byte> tileBuffer = this.memoryAllocator.Allocate<byte>(bytesPerTileRow * tileLength, AllocationOptions.Clean);
Span<byte> tileBufferSpan = tileBuffer.GetSpan();
using TiffBaseDecompressor decompressor = this.CreateDecompressor<TPixel>(frame.Width, bitsPerPixel);
using TiffBaseDecompressor decompressor = this.CreateDecompressor<TPixel>(frame.Width, bitsPerPixel, true, tileWidth, tileLength);
TiffBaseColorDecoder<TPixel> colorDecoder = this.CreateChunkyColorDecoder<TPixel>();
int tileIndex = 0;
@ -747,7 +747,7 @@ internal class TiffDecoderCore : ImageDecoderCore
this.YcbcrSubSampling,
this.byteOrder);
private TiffBaseDecompressor CreateDecompressor<TPixel>(int frameWidth, int bitsPerPixel)
private TiffBaseDecompressor CreateDecompressor<TPixel>(int frameWidth, int bitsPerPixel, bool isTiled = false, int tileWidth = 0, int tileHeight = 0)
where TPixel : unmanaged, IPixel<TPixel> =>
TiffDecompressorsFactory.Create(
this.Options,
@ -762,7 +762,10 @@ internal class TiffDecoderCore : ImageDecoderCore
this.JpegTables,
this.OldJpegCompressionStartOfImageMarker.GetValueOrDefault(),
this.FillOrder,
this.byteOrder);
this.byteOrder,
isTiled,
tileWidth,
tileHeight);
private IMemoryOwner<ulong> ConvertNumbers(Array array, out Span<ulong> span)
{

18
src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs

@ -222,15 +222,6 @@ internal sealed class TiffEncoderCore
height = Math.Min(height, frame.Height);
Size encodingSize = new(width, height);
using TiffBaseCompressor compressor = TiffCompressorFactory.Create(
compression,
writer.BaseStream,
this.memoryAllocator,
width,
(int)bitsPerPixel,
this.compressionLevel,
this.HorizontalPredictor == TiffPredictor.Horizontal ? this.HorizontalPredictor.Value : TiffPredictor.None);
TiffEncoderEntriesCollector entriesCollector = new();
using TiffBaseColorWriter<TPixel> colorWriter = TiffColorWriterFactory.Create(
this.PhotometricInterpretation,
@ -243,6 +234,15 @@ internal sealed class TiffEncoderCore
entriesCollector,
(int)bitsPerPixel);
using TiffBaseCompressor compressor = TiffCompressorFactory.Create(
compression,
writer.BaseStream,
this.memoryAllocator,
width,
colorWriter.BitsPerPixel,
this.compressionLevel,
this.HorizontalPredictor == TiffPredictor.Horizontal ? this.HorizontalPredictor.Value : TiffPredictor.None);
int rowsPerStrip = CalcRowsPerStrip(height, colorWriter.BytesPerRow, this.CompressionType);
colorWriter.Write(compressor, rowsPerStrip);

23
src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs

@ -7,6 +7,7 @@ using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using SixLabors.ImageSharp.Memory;
@ -187,11 +188,21 @@ internal abstract class BaseExifReader
protected void ReadSubIfd(List<IExifValue> values)
{
if (this.subIfds is not null)
if (this.subIfds != null)
{
foreach (ulong subIfdOffset in this.subIfds)
const int maxSubIfds = 8;
const int maxNestingLevel = 8;
Span<ulong> buf = stackalloc ulong[maxSubIfds];
for (int i = 0; i < maxNestingLevel && this.subIfds.Count > 0; i++)
{
this.ReadValues(values, (uint)subIfdOffset);
int sz = Math.Min(this.subIfds.Count, maxSubIfds);
CollectionsMarshal.AsSpan(this.subIfds)[..sz].CopyTo(buf);
this.subIfds.Clear();
foreach (ulong subIfdOffset in buf[..sz])
{
this.ReadValues(values, (uint)subIfdOffset);
}
}
}
}
@ -447,6 +458,7 @@ internal abstract class BaseExifReader
ExifTagValue.TileByteCounts => new ExifLong8Array(ExifTagValue.TileByteCounts),
_ => ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents),
};
if (exifValue is null)
{
this.AddInvalidTag(new UnkownExifTag(tag));
@ -481,8 +493,9 @@ internal abstract class BaseExifReader
foreach (IExifValue val in values)
{
// Sometimes duplicates appear, can compare val.Tag == exif.Tag
if (val == exif)
// to skip duplicates must be used Equals method,
// == operator not defined for ExifValue and IExifValue
if (exif.Equals(val))
{
Debug.WriteLine($"Duplicate Exif tag: tag={exif.Tag}, dataType={exif.DataType}");
return;

42
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs

@ -439,9 +439,8 @@ public partial class JpegDecoderTests
Assert.Equal(expectedComment, metadata.Comments.ElementAtOrDefault(0).ToString());
image.DebugSave(provider);
image.CompareToOriginal(provider);
}
// https://github.com/SixLabors/ImageSharp/issues/2758
[Theory]
[WithFile(TestImages.Jpeg.Issues.Issue2758, PixelTypes.L8)]
@ -468,6 +467,45 @@ public partial class JpegDecoderTests
image.Save(ms, new JpegEncoder());
}
// https://github.com/SixLabors/ImageSharp/issues/2857
[Theory]
[WithFile(TestImages.Jpeg.Issues.Issue2857, PixelTypes.Rgb24)]
public void Issue2857_SubSubIfds<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage(JpegDecoder.Instance);
Assert.Equal(5616, image.Width);
Assert.Equal(3744, image.Height);
JpegMetadata meta = image.Metadata.GetJpegMetadata();
Assert.Equal(92, meta.LuminanceQuality);
Assert.Equal(93, meta.ChrominanceQuality);
ExifProfile exifProfile = image.Metadata.ExifProfile;
Assert.NotNull(exifProfile);
using MemoryStream ms = new();
bool hasThumbnail = exifProfile.TryCreateThumbnail(out _);
Assert.False(hasThumbnail);
Assert.Equal("BilderBox - Erwin Wodicka / wodicka@aon.at", exifProfile.GetValue(ExifTag.Copyright).Value);
Assert.Equal("Adobe Photoshop CS3 Windows", exifProfile.GetValue(ExifTag.Software).Value);
Assert.Equal("Carers; seniors; caregiver; senior care; retirement home; hands; old; elderly; elderly caregiver; elder care; elderly care; geriatric care; nursing home; age; old age care; outpatient; needy; health care; home nurse; home care; sick; retirement; medical; mobile; the elderly; nursing department; nursing treatment; nursing; care services; nursing services; nursing care; nursing allowance; nursing homes; home nursing; care category; nursing class; care; nursing shortage; nursing patient care staff\0", exifProfile.GetValue(ExifTag.XPKeywords).Value);
Assert.Equal(
new EncodedString(EncodedString.CharacterCode.ASCII, "StockSubmitter|Miscellaneous||Miscellaneous$|00|0000330000000110000000000000000|22$@NA_1005010.460@145$$@Miscellaneous.Miscellaneous$$@$@26$$@$@$@$@205$@$@$@$@$@$@$@$@$@43$@$@$@$$@Miscellaneous.Miscellaneous$$@90$$@22$@$@$@$@$@$@$|||"),
exifProfile.GetValue(ExifTag.UserComment).Value);
// the profile contains 4 duplicated UserComment
Assert.Equal(1, exifProfile.Values.Count(t => t.Tag == ExifTag.UserComment));
image.Mutate(x => x.Crop(new(0, 0, 100, 100)));
image.Save(ms, new JpegEncoder());
}
private static void VerifyEncodedStrings(ExifProfile exif)
{
Assert.NotNull(exif);

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

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

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, 0);
decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer, default);
Assert.Equal(data, buffer);

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

@ -90,6 +90,40 @@ public class TiffDecoderTests : TiffDecoderBaseTester
public void TiffDecoder_CanDecode_Tiled<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);
[Theory]
[WithFile(TiledRgbaDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgbDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGrayDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray16BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray16BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray32BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledGray32BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb48BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb48BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgba64BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgba64BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb96BitLittleEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
[WithFile(TiledRgb96BitBigEndianDeflateCompressedWithPredictor, PixelTypes.Rgba32)]
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)

10
tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs

@ -579,6 +579,16 @@ public class TiffEncoderTests : TiffEncoderBaseTester
public void TiffEncoder_EncodeBiColor_WithModifiedHuffmanCompression_BlackIsZero_Works<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit1, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Ccitt1D);
[Theory]
[WithFile(Issue2909, PixelTypes.Rgba32)]
public void TiffEncoder_WithLzwCompression_Works<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, null, TiffCompression.Lzw, imageDecoder: TiffDecoder.Instance);
[Theory]
[WithFile(Issue2909, PixelTypes.Rgba32)]
public void TiffEncoder_WithDeflateCompression_Works<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, null, TiffCompression.Deflate, imageDecoder: TiffDecoder.Instance);
[Theory]
[WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.PackBits)]
[WithFile(GrayscaleUncompressed16Bit, PixelTypes.L16, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.PackBits)]

4
tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs

@ -106,7 +106,7 @@ public class WebpCommonUtilsTests
174, 183, 189, 255,
148, 158, 158, 255,
};
Span<Bgra32> row = MemoryMarshal.Cast<byte, Bgra32>(rowBytes);
Span<Bgra32> row = MemoryMarshal.Cast<byte, Bgra32>((Span<byte>)rowBytes);
bool noneOpaque;
for (int length = 8; length < row.Length; length += 8)
@ -188,7 +188,7 @@ public class WebpCommonUtilsTests
174, 183, 189, 255,
148, 158, 158, 255,
};
Span<Bgra32> row = MemoryMarshal.Cast<byte, Bgra32>(rowBytes);
Span<Bgra32> row = MemoryMarshal.Cast<byte, Bgra32>((Span<byte>)rowBytes);
bool noneOpaque;
for (int length = 8; length < row.Length; length += 8)

2
tests/ImageSharp.Tests/Image/ImageFrameTests.cs

@ -112,7 +112,7 @@ public class ImageFrameTests
}
byte[] expected = TestUtils.FillImageWithRandomBytes(image);
byte[] actual = new byte[expected.Length];
Span<byte> actual = new byte[expected.Length];
if (byteSpan)
{
image.Frames.RootFrame.CopyPixelDataTo(actual);

2
tests/ImageSharp.Tests/Image/ImageTests.cs

@ -190,7 +190,7 @@ public partial class ImageTests
}
byte[] expected = TestUtils.FillImageWithRandomBytes(image);
byte[] actual = new byte[expected.Length];
Span<byte> actual = new byte[expected.Length];
if (byteSpan)
{
image.CopyPixelDataTo(actual);

33
tests/ImageSharp.Tests/TestImages.cs

@ -336,6 +336,7 @@ public static class TestImages
public const string Issue2067_CommentMarker = "Jpg/issues/issue-2067-comment.jpg";
public const string Issue2638 = "Jpg/issues/Issue2638.jpg";
public const string Issue2758 = "Jpg/issues/issue-2758.jpg";
public const string Issue2857 = "Jpg/issues/issue-2857-subsub-ifds.jpg";
public static class Fuzz
{
@ -999,6 +1000,36 @@ public static class TestImages
public const string QuadTile = "Tiff/quad-tile.tiff";
public const string TiledChunky = "Tiff/rgb_uncompressed_tiled_chunky.tiff";
public const string TiledPlanar = "Tiff/rgb_uncompressed_tiled_planar.tiff";
public const string TiledRgbaDeflateCompressedWithPredictor = "Tiff/tiled_rgba_deflate_compressed_predictor.tiff";
public const string TiledRgbDeflateCompressedWithPredictor = "Tiff/tiled_rgb_deflate_compressed_predictor.tiff";
public const string TiledGrayDeflateCompressedWithPredictor = "Tiff/tiled_gray_deflate_compressed_predictor.tiff";
public const string TiledGray16BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_16bit_little_endian_deflate_compressed_predictor.tiff";
public const string TiledGray16BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_16bit_big_endian_deflate_compressed_predictor.tiff";
public const string TiledGray32BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_32bit_little_endian_deflate_compressed_predictor.tiff";
public const string TiledGray32BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_gray_32bit_big_endian_deflate_compressed_predictor.tiff";
public const string TiledRgb48BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_48bit_little_endian_deflate_compressed_predictor.tiff";
public const string TiledRgb48BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_48bit_big_endian_deflate_compressed_predictor.tiff";
public const string TiledRgba64BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_64bit_little_endian_deflate_compressed_predictor.tiff";
public const string TiledRgba64BitBigEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgba_64bit_big_endian_deflate_compressed_predictor.tiff";
public const string TiledRgb96BitLittleEndianDeflateCompressedWithPredictor = "Tiff/tiled_rgb_96bit_little_endian_deflate_compressed_predictor.tiff";
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";
@ -1087,6 +1118,8 @@ public static class TestImages
public const string InvalidIptcData = "Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff";
public const string IptcData = "Tiff/iptc.tiff";
public const string Issue2909 = "Tiff/Issues/Issue2909.tiff";
public static readonly string[] Multiframes = { MultiframeDeflateWithPreview, MultiframeLzwPredictor /*, MultiFrameDifferentSize, MultiframeDifferentSizeTiled, MultiFrameDifferentVariants,*/ };
public static readonly string[] Metadata = { SampleMetadata };

2
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs

@ -79,7 +79,7 @@ public class MagickReferenceDecoder : ImageDecoder
FromRgba32Bytes(configuration, data, framePixels);
}
else if (magicFrame.Depth is 16 or 14)
else if (magicFrame.Depth is 14 or 16 or 32)
{
if (this.imageFormat is PngFormat png)
{

3
tests/Images/Input/Jpg/issues/issue-2857-subsub-ifds.jpg

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

3
tests/Images/Input/Tiff/Issues/Issue2909.tiff

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

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

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

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:190a4968abd4bbd39273020f0f8bee0e0e48573931653eaea5e49b49d3961206
size 87301

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

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

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_deflate_compressed_predictor.tiff

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

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:f4bebd7e62dbe54456923981b27dcc1415362c30a7c3c0ca665acf8dbdfe1cc8
size 115129

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

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

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:e618556125236e2b0034b8654ab7b3e8956cf6db3c7c35ae365445ce85b2ea3d
size 114137

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

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

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:2942e3a2e83ee1e10cc238299c21dcc9ccad7058b0b389f69dcf3186cbd215a1
size 67849

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

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

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:8f69c65b66041cc34bfe894628bbe39a9e09cc9a8e7eccaefad42b672b2d2e3b
size 234705

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

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

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:c6715b725ac4ac2ba57f7c9f6b8fd89182b6d2c5a6b8d9141f204783bc44a8c5
size 234697

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

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

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:74dbdcc550fd0c9a425a02bb48a458e2c285030fd3fdaa8e6359bae1f4e06096
size 270201

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

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

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:e7364b83b36201d4f40144a619c7bf551f0ff27509aba3db3c7a1dbc01a881d8
size 270305

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

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

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:1c0b50066a4480b02c36ee97885e30498b0c9a702de6d317c648a7908a2d119d
size 313111

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

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

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:02e12574235e0861f4cad850869f53893b35334142c36d7c27d317382167ed68
size 311165

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

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

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:c47d681bfefa0cb12a25d685f13cc9fd01b3e0cb99828b97ccd948b43c138cfa
size 180641

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

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

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:9b8e0812543f47ce79701ddc57a6473f8f3c6e016520cdc76cf4c1c11a5f54a0
size 370941

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

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

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:50620e1aeeb1d99fc108d08215f51eb7ef648cba506a1b657a74ee138b9e3a5f
size 369133

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

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

3
tests/Images/Input/Tiff/tiled_rgba_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_rgba_64bit_little_endian_deflate_compressed_predictor.tiff

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

3
tests/Images/Input/Tiff/tiled_rgba_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_rgba_deflate_compressed_predictor.tiff

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

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:183e011bc22048d65cd1945d60dc25dc9cb688d9141afefa1c66ae0edfca8309
size 202825
Loading…
Cancel
Save