From b00104d769e940d4a0627b1d085376ccd412e06a Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 4 Dec 2020 10:06:23 +0100 Subject: [PATCH] Rework horizontal predictor: Fixes issue with paletted images which use a predictor --- .../Compression/DeflateTiffCompression.cs | 19 ++++- .../Tiff/Compression/HorizontalPredictor.cs | 75 +++++++++++++++++++ .../Tiff/Compression/LzwTiffCompression.cs | 18 ++++- .../Tiff/Compression/NoneTiffCompression.cs | 8 +- .../Compression/PackBitsTiffCompression.cs | 8 +- .../Tiff/Compression/TiffBaseCompression.cs | 19 ++++- .../Compression/TiffCompressionFactory.cs | 6 +- .../Formats/Tiff/TiffBitsPerPixel.cs | 2 +- .../Formats/Tiff/TiffDecoderCore.cs | 60 +++++---------- .../DeflateTiffCompressionTests.cs | 3 +- .../Compression/LzwTiffCompressionTests.cs | 5 +- .../Formats/Tiff/TiffDecoderTests.cs | 4 +- tests/ImageSharp.Tests/TestImages.cs | 7 +- .../Tiff/Calliphora_gray_lzw_predictor.tiff | 3 + .../Images/Input/Tiff/Calliphora_rgb_lzw.tif | 3 + .../Tiff/Calliphora_rgb_lzw_predictor.tiff | 4 +- .../Calliphora_rgb_palette_lzw_predictor.tiff | 3 + 17 files changed, 184 insertions(+), 63 deletions(-) create mode 100644 src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs create mode 100644 tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff create mode 100644 tests/Images/Input/Tiff/Calliphora_rgb_lzw.tif create mode 100644 tests/Images/Input/Tiff/Calliphora_rgb_palette_lzw_predictor.tiff diff --git a/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs index 6e206f0ed8..4cc7008eba 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/DeflateTiffCompression.cs @@ -4,7 +4,10 @@ using System; using System.IO; using System.IO.Compression; + +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; +using SixLabors.ImageSharp.Formats.Tiff.Compression; using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression @@ -17,8 +20,15 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression /// internal class DeflateTiffCompression : TiffBaseCompression { - public DeflateTiffCompression(MemoryAllocator allocator) - : base(allocator) + /// + /// Initializes a new instance of the class. + /// + /// The memoryAllocator to use for buffer allocations. + /// The image width. + /// The bits used per pixel. + /// The tiff predictor used. + public DeflateTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffPredictor predictor) + : base(memoryAllocator, width, bitsPerPixel, predictor) { } @@ -52,6 +62,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { deflateStream.ReadFull(buffer); } + + if (this.Predictor == TiffPredictor.Horizontal) + { + HorizontalPredictor.Undo(buffer, this.Width, this.BitsPerPixel); + } } } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs b/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs new file mode 100644 index 0000000000..3cbe5a81dd --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs @@ -0,0 +1,75 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.InteropServices; + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Formats.Tiff.Compression +{ + /// + /// Methods for undoing the horizontal prediction used in combination with deflate and LZW compressed TIFF images. + /// + public static class HorizontalPredictor + { + /// + /// Inverts the horizontal prediction. + /// + /// Buffer with decompressed pixel data. + /// The width of the image or strip. + /// Bits per pixel. + public static void Undo(Span pixelBytes, int width, int bitsPerPixel) + { + if (bitsPerPixel == 8) + { + Undo8Bit(pixelBytes, width); + } + else if (bitsPerPixel == 24) + { + Undo24Bit(pixelBytes, width); + } + } + + private static void Undo8Bit(Span pixelBytes, int width) + { + var rowBytesCount = width; + int height = pixelBytes.Length / rowBytesCount; + for (int y = 0; y < height; y++) + { + Span rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); + + byte pixelValue = rowBytes[0]; + for (int x = 1; x < width; x++) + { + pixelValue += rowBytes[x]; + rowBytes[x] = pixelValue; + } + } + } + + private static void Undo24Bit(Span pixelBytes, int width) + { + var rowBytesCount = width * 3; + int height = pixelBytes.Length / rowBytesCount; + for (int y = 0; y < height; y++) + { + Span rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); + Span rowRgb = MemoryMarshal.Cast(rowBytes); + + byte r = rowRgb[0].R; + byte g = rowRgb[0].G; + byte b = rowRgb[0].B; + for (int x = 1; x < width; x++) + { + ref Rgb24 pixel = ref rowRgb[x]; + r += rowRgb[x].R; + g += rowRgb[x].G; + b += rowRgb[x].B; + var rgb = new Rgb24(r, g, b); + pixel.FromRgb24(rgb); + } + } + } + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs index 14f45fc9d0..b01f141914 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/LzwTiffCompression.cs @@ -3,7 +3,9 @@ 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.Memory; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression @@ -13,8 +15,15 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression /// internal class LzwTiffCompression : TiffBaseCompression { - public LzwTiffCompression(MemoryAllocator allocator) - : base(allocator) + /// + /// Initializes a new instance of the class. + /// + /// The memoryAllocator to use for buffer allocations. + /// The image width. + /// The bits used per pixel. + /// The tiff predictor used. + public LzwTiffCompression(MemoryAllocator memoryAllocator, int width, int bitsPerPixel, TiffPredictor predictor) + : base(memoryAllocator, width, bitsPerPixel, predictor) { } @@ -24,6 +33,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression var subStream = new SubStream(stream, byteCount); var decoder = new TiffLzwDecoder(subStream, this.Allocator); decoder.DecodePixels(buffer.Length, 8, buffer); + + if (this.Predictor == TiffPredictor.Horizontal) + { + HorizontalPredictor.Undo(buffer, this.Width, this.BitsPerPixel); + } } } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs index 94cf5a9cad..5ca112f3b3 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/NoneTiffCompression.cs @@ -14,8 +14,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression /// internal class NoneTiffCompression : TiffBaseCompression { - public NoneTiffCompression(MemoryAllocator allocator) - : base(allocator) + /// + /// Initializes a new instance of the class. + /// + /// The memoryAllocator to use for buffer allocations. + public NoneTiffCompression(MemoryAllocator memoryAllocator) + : base(memoryAllocator) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs index d49aced440..2fbb7e6f16 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/PackBitsTiffCompression.cs @@ -15,8 +15,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression /// internal class PackBitsTiffCompression : TiffBaseCompression { - public PackBitsTiffCompression(MemoryAllocator allocator) - : base(allocator) + /// + /// Initializes a new instance of the class. + /// + /// The memoryAllocator to use for buffer allocations. + public PackBitsTiffCompression(MemoryAllocator memoryAllocator) + : base(memoryAllocator) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs index 45571d5030..d4f287adc8 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs @@ -5,6 +5,7 @@ using System; using System.IO; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; +using SixLabors.ImageSharp.Formats.Tiff.Compression; using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression @@ -20,21 +21,37 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression private int width; + private int bitsPerPixel; + + private TiffPredictor predictor; + public TiffBaseCompression(MemoryAllocator allocator) => this.allocator = allocator; public TiffBaseCompression(MemoryAllocator allocator, TiffPhotometricInterpretation photometricInterpretation, int width) + : this(allocator) { - this.allocator = allocator; this.photometricInterpretation = photometricInterpretation; this.width = width; } + public TiffBaseCompression(MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor) + : this(allocator) + { + this.width = width; + this.bitsPerPixel = bitsPerPixel; + this.predictor = predictor; + } + protected MemoryAllocator Allocator => this.allocator; protected TiffPhotometricInterpretation PhotometricInterpretation => this.photometricInterpretation; protected int Width => this.width; + protected int BitsPerPixel => this.bitsPerPixel; + + protected TiffPredictor Predictor => this.predictor; + /// /// Decompresses image data into the supplied buffer. /// diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs index 6f785bb31c..c261e91d34 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressionFactory.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { internal static class TiffCompressionFactory { - public static TiffBaseCompression Create(TiffDecoderCompressionType compressionType, MemoryAllocator allocator, TiffPhotometricInterpretation photometricInterpretation, int width) + public static TiffBaseCompression Create(TiffDecoderCompressionType compressionType, MemoryAllocator allocator, TiffPhotometricInterpretation photometricInterpretation, int width, int bitsPerPixel, TiffPredictor predictor) { switch (compressionType) { @@ -17,9 +17,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression case TiffDecoderCompressionType.PackBits: return new PackBitsTiffCompression(allocator); case TiffDecoderCompressionType.Deflate: - return new DeflateTiffCompression(allocator); + return new DeflateTiffCompression(allocator, width, bitsPerPixel, predictor); case TiffDecoderCompressionType.Lzw: - return new LzwTiffCompression(allocator); + return new LzwTiffCompression(allocator, width, bitsPerPixel, predictor); case TiffDecoderCompressionType.T4: return new T4TiffCompression(allocator, photometricInterpretation, width); case TiffDecoderCompressionType.HuffmanRle: diff --git a/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs b/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs index 163876a3f1..0e314e6ee0 100644 --- a/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs +++ b/src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff Pixel1 = 1, /// - /// 8 bits per pixel, grayscale image. Each pixel consists of 1 byte. + /// 8 bits per pixel, grayscale or indexed image. Each pixel consists of 1 byte. /// Pixel8 = 8, diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 3811620931..8a6ac48fed 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -241,6 +241,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff frameMetaData = coreMetadata.GetTiffMetadata(); frameMetaData.Tags = tags; TiffFrameMetadata tiffFormatMetaData = coreMetadata.GetFormatMetadata(TiffFormat.Instance); + TiffPredictor predictor = tiffFormatMetaData.Predictor; this.VerifyAndParseOptions(frameMetaData); @@ -254,52 +255,16 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff if (this.PlanarConfiguration == TiffPlanarConfiguration.Planar) { - this.DecodeStripsPlanar(frame, rowsPerStrip, stripOffsets, stripByteCounts, width); + this.DecodeStripsPlanar(frame, rowsPerStrip, stripOffsets, stripByteCounts, width, predictor); } else { - this.DecodeStripsChunky(frame, rowsPerStrip, stripOffsets, stripByteCounts, width); - } - - if (tiffFormatMetaData.Predictor == TiffPredictor.Horizontal) - { - this.UndoHorizontalPredictor(frame, width, height); + this.DecodeStripsChunky(frame, rowsPerStrip, stripOffsets, stripByteCounts, width, predictor); } return frame; } - /// - /// This will reverse the horizontal prediction operation. - /// - /// The pixel format. - /// The image frame. - /// The width of the image. - /// The height of the image. - private void UndoHorizontalPredictor(ImageFrame frame, int width, int height) - where TPixel : unmanaged, IPixel - { - using System.Buffers.IMemoryOwner rowRgbBuffer = this.memoryAllocator.Allocate(width); - System.Span rowRgb = rowRgbBuffer.GetSpan(); - for (int y = 0; y < height; y++) - { - System.Span pixelRow = frame.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgb24(this.configuration, pixelRow, rowRgb); - byte r = rowRgb[0].R; - byte g = rowRgb[0].G; - byte b = rowRgb[0].B; - for (int x = 1; x < width; x++) - { - ref TPixel pixel = ref pixelRow[x]; - r += rowRgb[x].R; - g += rowRgb[x].G; - b += rowRgb[x].B; - var rgb = new Rgb24(r, g, b); - pixel.FromRgb24(rgb); - } - } - } - /// /// Calculates the size (in bytes) for a pixel buffer using the determined color format. /// @@ -339,11 +304,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// An array of byte offsets to each strip in the image. /// An array of the size of each strip (in bytes). /// The image width. - private void DecodeStripsPlanar(ImageFrame frame, int rowsPerStrip, uint[] stripOffsets, uint[] stripByteCounts, int width) + /// The tiff predictor used. + private void DecodeStripsPlanar(ImageFrame frame, int rowsPerStrip, uint[] stripOffsets, uint[] stripByteCounts, int width, TiffPredictor predictor) where TPixel : unmanaged, IPixel { int stripsPerPixel = this.BitsPerSample.Length; int stripsPerPlane = stripOffsets.Length / stripsPerPixel; + int bitsPerPixel = 0; + foreach (var bits in this.BitsPerSample) + { + bitsPerPixel += bits; + } Buffer2D pixels = frame.PixelBuffer; @@ -357,7 +328,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff stripBuffers[stripIndex] = this.memoryAllocator.AllocateManagedByteBuffer(uncompressedStripSize); } - TiffBaseCompression decompressor = TiffCompressionFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, width); + TiffBaseCompression decompressor = TiffCompressionFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, width, bitsPerPixel, predictor); RgbPlanarTiffColor colorDecoder = TiffColorDecoderFactory.CreatePlanar(this.ColorType, this.BitsPerSample, this.ColorMap); @@ -385,16 +356,21 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff } } - private void DecodeStripsChunky(ImageFrame frame, int rowsPerStrip, uint[] stripOffsets, uint[] stripByteCounts, int width) + private void DecodeStripsChunky(ImageFrame frame, int rowsPerStrip, uint[] stripOffsets, uint[] stripByteCounts, int width, TiffPredictor predictor) where TPixel : unmanaged, IPixel { int uncompressedStripSize = this.CalculateStripBufferSize(frame.Width, rowsPerStrip); + int bitsPerPixel = 0; + foreach (var bits in this.BitsPerSample) + { + bitsPerPixel += bits; + } using IManagedByteBuffer stripBuffer = this.memoryAllocator.AllocateManagedByteBuffer(uncompressedStripSize, AllocationOptions.Clean); Buffer2D pixels = frame.PixelBuffer; - TiffBaseCompression decompressor = TiffCompressionFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, width); + TiffBaseCompression decompressor = TiffCompressionFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, width, bitsPerPixel, predictor); TiffBaseColorDecoder colorDecoder = TiffColorDecoderFactory.Create(this.ColorType, this.BitsPerSample, this.ColorMap); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs index 46e9c2da51..692f92c9f6 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs @@ -3,6 +3,7 @@ using System.IO; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Formats.Png.Zlib; using Xunit; @@ -23,7 +24,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression { var buffer = new byte[data.Length]; - new DeflateTiffCompression(null).Decompress(stream, (int)stream.Length, buffer); + new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, (int)stream.Length, buffer); Assert.Equal(data, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs index 730d6f3662..1837fe98ef 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs @@ -5,6 +5,7 @@ using System; 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.Memory; using Xunit; @@ -25,14 +26,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression using Stream stream = CreateCompressedStream(data); var buffer = new byte[data.Length]; - new LzwTiffCompression(Configuration.Default.MemoryAllocator).Decompress(stream, (int)stream.Length, buffer); + new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, (int)stream.Length, buffer); Assert.Equal(data, buffer); } private static Stream CreateCompressedStream(byte[] inputData) { - using Stream compressedStream = new MemoryStream(); + Stream compressedStream = new MemoryStream(); using System.Buffers.IMemoryOwner data = Configuration.Default.MemoryAllocator.Allocate(inputData.Length); inputData.AsSpan().CopyTo(data.GetSpan()); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index c5e09b65ef..24c0a712b7 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -122,7 +122,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [WithFile(RgbLzwNoPredictorSinglestripMotorola, PixelTypes.Rgba32)] [WithFile(RgbLzwNoPredictorMultistripMotorola, PixelTypes.Rgba32)] [WithFile(RgbLzwMultistripPredictor, PixelTypes.Rgba32)] - [WithFile(Calliphora_RgbLzw_Predictor, PixelTypes.Rgba32)] + [WithFile(Calliphora_RgbPaletteLzw_Predictor, PixelTypes.Rgba32)] + [WithFile(Calliphora_RgbLzwPredictor, PixelTypes.Rgba32)] + [WithFile(Calliphora_GrayscaleLzw_Predictor, PixelTypes.Rgba32)] [WithFile(SmallRgbLzw, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_LzwCompressed(TestImageProvider provider) where TPixel : unmanaged, IPixel diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index ef46e2289e..93277550b9 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -506,11 +506,14 @@ namespace SixLabors.ImageSharp.Tests public const string Calliphora_GrayscaleUncompressed = "Tiff/Calliphora_grayscale_uncompressed.tiff"; public const string Calliphora_GrayscaleDeflate_Predictor = "Tiff/Calliphora_gray_deflate_predictor.tiff"; + public const string Calliphora_GrayscaleLzw_Predictor = "Tiff/Calliphora_gray_lzw_predictor.tiff"; public const string Calliphora_GrayscaleDeflate = "Tiff/Calliphora_gray_deflate.tiff"; - public const string Calliphora_PaletteUncompressed = "Tiff/Calliphora_palette_uncompressed.tiff"; public const string Calliphora_RgbDeflate_Predictor = "Tiff/Calliphora_rgb_deflate_predictor.tiff"; public const string Calliphora_RgbJpeg = "Tiff/Calliphora_rgb_jpeg.tiff"; - public const string Calliphora_RgbLzw_Predictor = "Tiff/Calliphora_rgb_lzw_predictor.tiff"; + public const string Calliphora_PaletteUncompressed = "Tiff/Calliphora_palette_uncompressed.tiff"; + public const string Calliphora_RgbLzwPredictor = "Tiff/Calliphora_rgb_lzw_predictor.tiff"; + public const string Calliphora_RgbPaletteLzw = "Tiff/Calliphora_rgb_palette_lzw.tiff"; + public const string Calliphora_RgbPaletteLzw_Predictor = "Tiff/Calliphora_rgb_palette_lzw_predictor.tiff"; public const string Calliphora_RgbPackbits = "Tiff/Calliphora_rgb_packbits.tiff"; public const string Calliphora_RgbUncompressed = "Tiff/Calliphora_rgb_uncompressed.tiff"; public const string Calliphora_Fax3Compressed = "Tiff/Calliphora_ccitt_fax3.tiff"; diff --git a/tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff b/tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff new file mode 100644 index 0000000000..b14eeba8d5 --- /dev/null +++ b/tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f24fd8f36a4847fcb84a317de4fd2eacd5eb0c58ef4436d33919f0a6658d0d9 +size 698309 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tif b/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tif new file mode 100644 index 0000000000..7450522679 --- /dev/null +++ b/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53006876fcdc655a794462de57eb6b56f4d0cdd3cb8b752c63328db0eb4aa3c1 +size 725085 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff index be84f0a30a..99642af524 100644 --- a/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff +++ b/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29fa2b157c92f6a8bd4036e9d075e24fc451e72ec1a251d97a4b40454e01405c -size 792087 +oid sha256:ecb529e5e3e0eca6f5e407b034fa8ba67bb4b9068af9e9b30425b08d30a249c0 +size 1756355 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_palette_lzw_predictor.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_palette_lzw_predictor.tiff new file mode 100644 index 0000000000..be84f0a30a --- /dev/null +++ b/tests/Images/Input/Tiff/Calliphora_rgb_palette_lzw_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29fa2b157c92f6a8bd4036e9d075e24fc451e72ec1a251d97a4b40454e01405c +size 792087