From 4175fb8bf63a3fd66ca98068b0fafe705cfaa7bb Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 7 Dec 2020 15:16:09 +0100 Subject: [PATCH] Add tests for tiff encoder options --- .../Formats/Tiff/Compression/T4BitReader.cs | 1 - .../Formats/Tiff/Compression/T4BitWriter.cs | 5 +- .../Formats/Tiff/TiffEncoderCore.cs | 10 ++++ .../Formats/Tiff/Utils/TiffWriter.cs | 2 +- .../Formats/Tiff/TiffEncoderTests.cs | 46 +++++++++++++++++-- 5 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Compression/T4BitReader.cs b/src/ImageSharp/Formats/Tiff/Compression/T4BitReader.cs index d5435f546..a614235be 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/T4BitReader.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/T4BitReader.cs @@ -6,7 +6,6 @@ using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression diff --git a/src/ImageSharp/Formats/Tiff/Compression/T4BitWriter.cs b/src/ImageSharp/Formats/Tiff/Compression/T4BitWriter.cs index 72605b74c..2e168de59 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/T4BitWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/T4BitWriter.cs @@ -314,9 +314,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression } // Write the compressed data to the stream. - stream.Write(compressedData.Slice(0, this.bytePosition)); + int bytesToWrite = this.bitPosition != 0 ? this.bytePosition + 1 : this.bytePosition; + stream.Write(compressedData.Slice(0, bytesToWrite)); - return this.bytePosition; + return bytesToWrite; } private void WriteEndOfLine(Span compressedData) diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index 11775bd70..50f93f71f 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -426,6 +426,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff private ushort GetCompressionType() { + if (this.CompressionType == TiffEncoderCompression.Deflate && this.Mode == TiffEncodingMode.Default) + { + return (ushort)TiffCompression.Deflate; + } + if (this.CompressionType == TiffEncoderCompression.Deflate && this.Mode == TiffEncodingMode.Rgb) { return (ushort)TiffCompression.Deflate; @@ -436,6 +441,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff return (ushort)TiffCompression.Lzw; } + if (this.CompressionType == TiffEncoderCompression.PackBits && this.Mode == TiffEncodingMode.Default) + { + return (ushort)TiffCompression.PackBits; + } + if (this.CompressionType == TiffEncoderCompression.PackBits && this.Mode == TiffEncodingMode.Rgb) { return (ushort)TiffCompression.PackBits; diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs index f08241fbf..bec317031 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Utils/TiffWriter.cs @@ -764,7 +764,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils where TPixel : unmanaged, IPixel { // Worst case is that the actual compressed data is larger then the input data. In this case we need 1 additional byte per 127 bits. - int additionalBytes = (image.Width / 127) + 1; + int additionalBytes = (image.Width / 127) + 2; int compressedRowBytes = (image.Width / 8) + additionalBytes; using IManagedByteBuffer compressedRow = this.memoryAllocator.AllocateManagedByteBuffer(compressedRowBytes, AllocationOptions.Clean); Span compressedRowSpan = compressedRow.GetSpan(); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index 86b4e32ac..01196da50 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -5,6 +5,7 @@ using System.IO; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Experimental.Tiff; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; @@ -23,11 +24,50 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public static readonly TheoryData TiffBitsPerPixelFiles = new TheoryData { - { TestImages.Tiff.Calliphora_BiColorUncompressed, TiffBitsPerPixel.Pixel1 }, - { TestImages.Tiff.GrayscaleUncompressed, TiffBitsPerPixel.Pixel8 }, - { TestImages.Tiff.RgbUncompressed, TiffBitsPerPixel.Pixel24 }, + { Calliphora_BiColorUncompressed, TiffBitsPerPixel.Pixel1 }, + { GrayscaleUncompressed, TiffBitsPerPixel.Pixel8 }, + { RgbUncompressed, TiffBitsPerPixel.Pixel24 }, }; + [Theory] + [InlineData(TiffEncodingMode.Default, TiffEncoderCompression.None, TiffBitsPerPixel.Pixel24, TiffCompression.None)] + [InlineData(TiffEncodingMode.Rgb, TiffEncoderCompression.None, TiffBitsPerPixel.Pixel24, TiffCompression.None)] + [InlineData(TiffEncodingMode.ColorPalette, TiffEncoderCompression.None, TiffBitsPerPixel.Pixel8, TiffCompression.None)] + [InlineData(TiffEncodingMode.Gray, TiffEncoderCompression.None, TiffBitsPerPixel.Pixel8, TiffCompression.None)] + [InlineData(TiffEncodingMode.BiColor, TiffEncoderCompression.None, TiffBitsPerPixel.Pixel1, TiffCompression.None)] + [InlineData(TiffEncodingMode.Default, TiffEncoderCompression.Deflate, TiffBitsPerPixel.Pixel24, TiffCompression.Deflate)] + [InlineData(TiffEncodingMode.Rgb, TiffEncoderCompression.Deflate, TiffBitsPerPixel.Pixel24, TiffCompression.Deflate)] + [InlineData(TiffEncodingMode.ColorPalette, TiffEncoderCompression.Deflate, TiffBitsPerPixel.Pixel8, TiffCompression.Deflate)] + [InlineData(TiffEncodingMode.Gray, TiffEncoderCompression.Deflate, TiffBitsPerPixel.Pixel8, TiffCompression.Deflate)] + [InlineData(TiffEncodingMode.BiColor, TiffEncoderCompression.Deflate, TiffBitsPerPixel.Pixel1, TiffCompression.Deflate)] + [InlineData(TiffEncodingMode.Default, TiffEncoderCompression.PackBits, TiffBitsPerPixel.Pixel24, TiffCompression.PackBits)] + [InlineData(TiffEncodingMode.Rgb, TiffEncoderCompression.PackBits, TiffBitsPerPixel.Pixel24, TiffCompression.PackBits)] + [InlineData(TiffEncodingMode.ColorPalette, TiffEncoderCompression.PackBits, TiffBitsPerPixel.Pixel8, TiffCompression.PackBits)] + [InlineData(TiffEncodingMode.Gray, TiffEncoderCompression.PackBits, TiffBitsPerPixel.Pixel8, TiffCompression.PackBits)] + [InlineData(TiffEncodingMode.BiColor, TiffEncoderCompression.PackBits, TiffBitsPerPixel.Pixel1, TiffCompression.PackBits)] + [InlineData(TiffEncodingMode.Rgb, TiffEncoderCompression.Lzw, TiffBitsPerPixel.Pixel24, TiffCompression.Lzw)] + [InlineData(TiffEncodingMode.ColorPalette, TiffEncoderCompression.Lzw, TiffBitsPerPixel.Pixel8, TiffCompression.Lzw)] + [InlineData(TiffEncodingMode.Gray, TiffEncoderCompression.Lzw, TiffBitsPerPixel.Pixel8, TiffCompression.Lzw)] + [InlineData(TiffEncodingMode.BiColor, TiffEncoderCompression.CcittGroup3Fax, TiffBitsPerPixel.Pixel1, TiffCompression.CcittGroup3Fax)] + [InlineData(TiffEncodingMode.BiColor, TiffEncoderCompression.ModifiedHuffman, TiffBitsPerPixel.Pixel1, TiffCompression.Ccitt1D)] + public void EncoderOptions_Work(TiffEncodingMode mode, TiffEncoderCompression compression, TiffBitsPerPixel expectedBitsPerPixel, TiffCompression expectedCompression) + { + // arrange + var tiffEncoder = new TiffEncoder { Mode = mode, Compression = compression }; + Image input = new Image(10, 10); + using var memStream = new MemoryStream(); + + // act + input.Save(memStream, tiffEncoder); + + // assert + memStream.Position = 0; + using var output = Image.Load(memStream); + TiffMetadata meta = output.Metadata.GetTiffMetadata(); + Assert.Equal(expectedBitsPerPixel, meta.BitsPerPixel); + Assert.Equal(expectedCompression, meta.Compression); + } + [Theory] [MemberData(nameof(TiffBitsPerPixelFiles))] public void TiffEncoder_PreserveBitsPerPixel(string imagePath, TiffBitsPerPixel expectedBitsPerPixel)