From 586f8e5ee25186b5212d609c7ec840631efb2a2a Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sat, 6 Feb 2021 22:59:43 +0300 Subject: [PATCH 01/15] Report 1-bit mode bug. Enable test images. Change test files. --- .../Codecs/DecodeTiff.cs | 12 +++---- .../Codecs/EncodeTiff.cs | 18 +++++++--- tests/ImageSharp.Benchmarks/Config.cs | 2 +- .../Formats/Tiff/TiffEncoderTests.cs | 34 +++++++++++++++++++ 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs b/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs index fb506528f9..44ffae1d98 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs @@ -53,12 +53,12 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs [Params( TestImages.Tiff.CcittFax3AllTermCodes, TestImages.Tiff.HuffmanRleAllMakeupCodes, - TestImages.Tiff.GrayscaleUncompressed, - TestImages.Tiff.PaletteUncompressed, - TestImages.Tiff.RgbDeflate, - TestImages.Tiff.RgbLzwPredictor, - TestImages.Tiff.RgbPackbits, - TestImages.Tiff.RgbUncompressed)] + TestImages.Tiff.Calliphora_GrayscaleUncompressed, + TestImages.Tiff.Calliphora_RgbPaletteLzw_Predictor, + TestImages.Tiff.Calliphora_RgbDeflate_Predictor, + TestImages.Tiff.Calliphora_RgbLzwPredictor, + TestImages.Tiff.Calliphora_RgbPackbits, + TestImages.Tiff.Calliphora_RgbUncompressed)] public string TestImage { get; set; } #endif diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs index 8080b16073..e40907c8ed 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs @@ -24,14 +24,14 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); - [Params(TestImages.Tiff.RgbUncompressed)] + [Params(TestImages.Tiff.Calliphora_RgbUncompressed)] public string TestImage { get; set; } [Params( TiffEncoderCompression.None, - ////TiffEncoderCompression.Deflate, + TiffEncoderCompression.Deflate, TiffEncoderCompression.Lzw, - ////TiffEncoderCompression.PackBits, + TiffEncoderCompression.PackBits, TiffEncoderCompression.CcittGroup3Fax, TiffEncoderCompression.ModifiedHuffman)] public TiffEncoderCompression Compression { get; set; } @@ -70,7 +70,15 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs [Benchmark(Description = "ImageSharp Tiff")] public void TiffCore() { - var encoder = new TiffEncoder() { Compression = this.Compression }; + TiffEncodingMode mode = TiffEncodingMode.Default; + + // workaround for 1-bit bug + if (this.Compression == TiffEncoderCompression.CcittGroup3Fax || this.Compression == TiffEncoderCompression.ModifiedHuffman) + { + mode = TiffEncodingMode.BiColor; + } + + var encoder = new TiffEncoder() { Compression = this.Compression, Mode = mode }; using var memoryStream = new MemoryStream(); this.core.SaveAsTiff(memoryStream, encoder); } @@ -107,7 +115,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs return EncoderValue.CompressionLZW; default: - throw new System.ArgumentOutOfRangeException(nameof(compression)); + throw new System.NotSupportedException(compression.ToString()); } } } diff --git a/tests/ImageSharp.Benchmarks/Config.cs b/tests/ImageSharp.Benchmarks/Config.cs index 16999ea7df..63064eec5b 100644 --- a/tests/ImageSharp.Benchmarks/Config.cs +++ b/tests/ImageSharp.Benchmarks/Config.cs @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Benchmarks } #endif - this.SummaryStyle = SummaryStyle.Default.WithMaxParameterColumnWidth(40); + this.SummaryStyle = SummaryStyle.Default.WithMaxParameterColumnWidth(50); } public class MultiFramework : Config diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index fd4432c5eb..7eaf735c97 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -90,6 +90,40 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Assert.Equal(expectedBitsPerPixel, meta.BitsPerPixel); } + [Theory] + [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncoderCompression.CcittGroup3Fax, TiffCompression.CcittGroup3Fax)] + [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncoderCompression.ModifiedHuffman, TiffCompression.Ccitt1D)] + [WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffEncoderCompression.CcittGroup3Fax, TiffCompression.CcittGroup3Fax)] + [WithFile(PaletteDeflateMultistrip, PixelTypes.L8, TiffEncoderCompression.ModifiedHuffman, TiffCompression.Ccitt1D)] + public void TiffEncoder_CorrectBiMode_Bug(TestImageProvider provider, TiffEncoderCompression compression, TiffCompression expectedCompression) + where TPixel : unmanaged, IPixel + { + // arrange + var encoder = new TiffEncoder() { Compression = compression }; + using Image input = provider.GetImage(); + using var memStream = new MemoryStream(); + + // act + input.Save(memStream, encoder); + + // assert + memStream.Position = 0; + using var output = Image.Load(this.configuration, memStream); + TiffMetadata meta = output.Metadata.GetTiffMetadata(); + + // This is bug! + // BitsPerPixel must be 1, and compression must be eqals which was setted in encoder + Assert.NotEqual(TiffBitsPerPixel.Pixel1, meta.BitsPerPixel); + Assert.NotEqual(expectedCompression, meta.Compression); + + Assert.Equal(input.Metadata.GetTiffMetadata().BitsPerPixel, meta.BitsPerPixel); + Assert.Equal(TiffCompression.None, meta.Compression); + + // expected values + //// Assert.Equal(TiffBitsPerPixel.Pixel1, meta.BitsPerPixel); + //// Assert.Equal(expectedCompression, meta.Compression); + } + [Theory] [WithFile(Calliphora_RgbUncompressed, PixelTypes.Rgba32)] public void TiffEncoder_EncodeRgb_Works(TestImageProvider provider) From 48796f82413da7655f55a37b401706faea7e2825 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sun, 7 Feb 2021 12:00:15 +0300 Subject: [PATCH 02/15] Add benchmarks results --- ...hmarks.Codecs.DecodeTiff-report-default.md | 85 ++++++++++++++++++ ...chmarks.Codecs.DecodeTiff-report-github.md | 87 +++++++++++++++++++ ...p.Benchmarks.Codecs.DecodeTiff-report.html | 81 +++++++++++++++++ ...hmarks.Codecs.EncodeTiff-report-default.md | 74 ++++++++++++++++ ...chmarks.Codecs.EncodeTiff-report-github.md | 76 ++++++++++++++++ ...p.Benchmarks.Codecs.EncodeTiff-report.html | 68 +++++++++++++++ 6 files changed, 471 insertions(+) create mode 100644 tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md create mode 100644 tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md create mode 100644 tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html create mode 100644 tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-default.md create mode 100644 tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-github.md create mode 100644 tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report.html diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md new file mode 100644 index 0000000000..6b35c6fe83 --- /dev/null +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md @@ -0,0 +1,85 @@ + +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 +Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + Job-EMDSBW : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT + Job-KCUIVJ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT + Job-NIWDJE : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT + +InvocationCount=1 IterationCount=3 LaunchCount=1 +UnrollFactor=1 WarmupCount=3 + + Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +---------------------- |----------- |-------------- |----------------------------------------------- |------------:|--------------:|-------------:|------:|--------:|------:|------:|------:|----------:| + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_grayscale_uncompressed.tiff** | **1,107.9 μs** | **260.10 μs** | **14.26 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **974848 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_grayscale_uncompressed.tiff | 29,794.8 μs | 3,103.68 μs | 170.12 μs | 26.90 | 0.49 | - | - | - | 32768 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 1,020.4 μs | 641.11 μs | 35.14 μs | 1.00 | 0.00 | - | - | - | 968832 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 12,593.4 μs | 4,807.87 μs | 263.54 μs | 12.36 | 0.67 | - | - | - | 29976 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 987.2 μs | 2,211.93 μs | 121.24 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 44,255.5 μs | 13,031.10 μs | 714.28 μs | 45.23 | 4.88 | - | - | - | 29896 B | + | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_deflate_predictor.tiff** | **16,118.9 μs** | **2,095.51 μs** | **114.86 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **1483440 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 25,967.5 μs | 4,545.04 μs | 249.13 μs | 1.61 | 0.01 | - | - | - | 848240 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,465.6 μs | 7,761.65 μs | 425.44 μs | 1.00 | 0.00 | - | - | - | 1480344 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,536.9 μs | 3,415.62 μs | 187.22 μs | 1.13 | 0.02 | - | - | - | 68176 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,216.2 μs | 3,288.12 μs | 180.23 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 20,740.6 μs | 54,608.55 μs | 2,993.28 μs | 1.28 | 0.17 | - | - | - | 65120 B | + | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_lzw_predictor.tiff** | **83,012.1 μs** | **14,786.35 μs** | **810.49 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2545736 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 64,895.5 μs | 11,397.89 μs | 624.76 μs | 0.78 | 0.01 | - | - | - | 24576 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 82,854.1 μs | 45,495.28 μs | 2,493.75 μs | 1.00 | 0.00 | - | - | - | 2541376 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 44,307.1 μs | 15,595.85 μs | 854.86 μs | 0.53 | 0.01 | - | - | - | 23832 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 83,297.5 μs | 15,796.71 μs | 865.87 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 59,464.0 μs | 13,870.15 μs | 760.27 μs | 0.71 | 0.01 | - | - | - | 23760 B | + | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_packbits.tiff** | **3,707.2 μs** | **6,293.27 μs** | **344.96 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2916008 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_packbits.tiff | 7,526.9 μs | 5,965.86 μs | 327.01 μs | 2.04 | 0.24 | - | - | - | 81920 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,037.7 μs | 9,243.97 μs | 506.69 μs | 1.00 | 0.00 | - | - | - | 2903544 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,395.7 μs | 1,394.13 μs | 76.42 μs | 1.10 | 0.15 | - | - | - | 80256 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,456.3 μs | 4,443.73 μs | 243.58 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,542.9 μs | 3,820.61 μs | 209.42 μs | 1.32 | 0.13 | - | - | - | 80184 B | + | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_palette_lzw_predictor.tiff** | **60,298.5 μs** | **24,263.76 μs** | **1,329.98 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **827416 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 76,021.3 μs | 4,206.79 μs | 230.59 μs | 1.26 | 0.02 | - | - | - | 49152 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 59,122.1 μs | 9,681.07 μs | 530.65 μs | 1.00 | 0.00 | - | - | - | 825648 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 45,789.3 μs | 7,453.72 μs | 408.56 μs | 0.77 | 0.00 | - | - | - | 45936 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 61,361.5 μs | 25,759.90 μs | 1,411.99 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 68,134.6 μs | 303,212.80 μs | 16,620.12 μs | 1.11 | 0.25 | - | - | - | 45864 B | + | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **3,431.7 μs** | **7,649.10 μs** | **419.27 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2915944 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | 6,382.4 μs | 2,573.27 μs | 141.05 μs | 1.87 | 0.18 | - | - | - | 57344 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,636.1 μs | 8,607.66 μs | 471.81 μs | 1.00 | 0.00 | - | - | - | 2905840 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,018.7 μs | 1,662.68 μs | 91.14 μs | 1.12 | 0.16 | - | - | - | 51472 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 2,970.8 μs | 5,028.62 μs | 275.64 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,009.6 μs | 3,007.19 μs | 164.83 μs | 1.36 | 0.17 | - | - | - | 51400 B | + | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/ccitt_fax3_all_terminating_codes.tiff** | **178.4 μs** | **375.89 μs** | **20.60 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 634.5 μs | 251.14 μs | 13.77 μs | 3.58 | 0.37 | - | - | - | 24576 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 171.7 μs | 606.95 μs | 33.27 μs | 1.00 | 0.00 | - | - | - | 2032 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 421.0 μs | 31.60 μs | 1.73 μs | 2.51 | 0.49 | - | - | - | 17848 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 137.2 μs | 78.18 μs | 4.29 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 888.5 μs | 495.11 μs | 27.14 μs | 6.47 | 0.05 | - | - | - | 17768 B | + | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/huffman_rle_all_makeup_codes.tiff** | **189.8 μs** | **818.95 μs** | **44.89 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | + 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/huffman_rle_all_makeup_codes.tiff | 9,137.1 μs | 1,178.82 μs | 64.62 μs | 49.85 | 10.86 | - | - | - | 24576 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 298.5 μs | 1,361.33 μs | 74.62 μs | 1.00 | 0.00 | - | - | - | 2088 B | + 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 5,717.5 μs | 2,533.21 μs | 138.85 μs | 19.89 | 4.51 | - | - | - | 18328 B | + | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 159.5 μs | 140.52 μs | 7.70 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 15,047.7 μs | 2,686.03 μs | 147.23 μs | 94.47 | 4.56 | - | - | - | 18248 B | diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md new file mode 100644 index 0000000000..a07b5d1f86 --- /dev/null +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md @@ -0,0 +1,87 @@ +``` ini + +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 +Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + Job-EMDSBW : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT + Job-KCUIVJ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT + Job-NIWDJE : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT + +InvocationCount=1 IterationCount=3 LaunchCount=1 +UnrollFactor=1 WarmupCount=3 + +``` +| Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|---------------------- |----------- |-------------- |----------------------------------------------- |------------:|--------------:|-------------:|------:|--------:|------:|------:|------:|----------:| +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_grayscale_uncompressed.tiff** | **1,107.9 μs** | **260.10 μs** | **14.26 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **974848 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_grayscale_uncompressed.tiff | 29,794.8 μs | 3,103.68 μs | 170.12 μs | 26.90 | 0.49 | - | - | - | 32768 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 1,020.4 μs | 641.11 μs | 35.14 μs | 1.00 | 0.00 | - | - | - | 968832 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 12,593.4 μs | 4,807.87 μs | 263.54 μs | 12.36 | 0.67 | - | - | - | 29976 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 987.2 μs | 2,211.93 μs | 121.24 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 44,255.5 μs | 13,031.10 μs | 714.28 μs | 45.23 | 4.88 | - | - | - | 29896 B | +| | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_deflate_predictor.tiff** | **16,118.9 μs** | **2,095.51 μs** | **114.86 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **1483440 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 25,967.5 μs | 4,545.04 μs | 249.13 μs | 1.61 | 0.01 | - | - | - | 848240 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,465.6 μs | 7,761.65 μs | 425.44 μs | 1.00 | 0.00 | - | - | - | 1480344 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,536.9 μs | 3,415.62 μs | 187.22 μs | 1.13 | 0.02 | - | - | - | 68176 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,216.2 μs | 3,288.12 μs | 180.23 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 20,740.6 μs | 54,608.55 μs | 2,993.28 μs | 1.28 | 0.17 | - | - | - | 65120 B | +| | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_lzw_predictor.tiff** | **83,012.1 μs** | **14,786.35 μs** | **810.49 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2545736 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 64,895.5 μs | 11,397.89 μs | 624.76 μs | 0.78 | 0.01 | - | - | - | 24576 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 82,854.1 μs | 45,495.28 μs | 2,493.75 μs | 1.00 | 0.00 | - | - | - | 2541376 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 44,307.1 μs | 15,595.85 μs | 854.86 μs | 0.53 | 0.01 | - | - | - | 23832 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 83,297.5 μs | 15,796.71 μs | 865.87 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 59,464.0 μs | 13,870.15 μs | 760.27 μs | 0.71 | 0.01 | - | - | - | 23760 B | +| | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_packbits.tiff** | **3,707.2 μs** | **6,293.27 μs** | **344.96 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2916008 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_packbits.tiff | 7,526.9 μs | 5,965.86 μs | 327.01 μs | 2.04 | 0.24 | - | - | - | 81920 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,037.7 μs | 9,243.97 μs | 506.69 μs | 1.00 | 0.00 | - | - | - | 2903544 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,395.7 μs | 1,394.13 μs | 76.42 μs | 1.10 | 0.15 | - | - | - | 80256 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,456.3 μs | 4,443.73 μs | 243.58 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,542.9 μs | 3,820.61 μs | 209.42 μs | 1.32 | 0.13 | - | - | - | 80184 B | +| | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_palette_lzw_predictor.tiff** | **60,298.5 μs** | **24,263.76 μs** | **1,329.98 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **827416 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 76,021.3 μs | 4,206.79 μs | 230.59 μs | 1.26 | 0.02 | - | - | - | 49152 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 59,122.1 μs | 9,681.07 μs | 530.65 μs | 1.00 | 0.00 | - | - | - | 825648 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 45,789.3 μs | 7,453.72 μs | 408.56 μs | 0.77 | 0.00 | - | - | - | 45936 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 61,361.5 μs | 25,759.90 μs | 1,411.99 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 68,134.6 μs | 303,212.80 μs | 16,620.12 μs | 1.11 | 0.25 | - | - | - | 45864 B | +| | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **3,431.7 μs** | **7,649.10 μs** | **419.27 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2915944 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | 6,382.4 μs | 2,573.27 μs | 141.05 μs | 1.87 | 0.18 | - | - | - | 57344 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,636.1 μs | 8,607.66 μs | 471.81 μs | 1.00 | 0.00 | - | - | - | 2905840 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,018.7 μs | 1,662.68 μs | 91.14 μs | 1.12 | 0.16 | - | - | - | 51472 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 2,970.8 μs | 5,028.62 μs | 275.64 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,009.6 μs | 3,007.19 μs | 164.83 μs | 1.36 | 0.17 | - | - | - | 51400 B | +| | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/ccitt_fax3_all_terminating_codes.tiff** | **178.4 μs** | **375.89 μs** | **20.60 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 634.5 μs | 251.14 μs | 13.77 μs | 3.58 | 0.37 | - | - | - | 24576 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 171.7 μs | 606.95 μs | 33.27 μs | 1.00 | 0.00 | - | - | - | 2032 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 421.0 μs | 31.60 μs | 1.73 μs | 2.51 | 0.49 | - | - | - | 17848 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 137.2 μs | 78.18 μs | 4.29 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 888.5 μs | 495.11 μs | 27.14 μs | 6.47 | 0.05 | - | - | - | 17768 B | +| | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/huffman_rle_all_makeup_codes.tiff** | **189.8 μs** | **818.95 μs** | **44.89 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | +| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/huffman_rle_all_makeup_codes.tiff | 9,137.1 μs | 1,178.82 μs | 64.62 μs | 49.85 | 10.86 | - | - | - | 24576 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 298.5 μs | 1,361.33 μs | 74.62 μs | 1.00 | 0.00 | - | - | - | 2088 B | +| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 5,717.5 μs | 2,533.21 μs | 138.85 μs | 19.89 | 4.51 | - | - | - | 18328 B | +| | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 159.5 μs | 140.52 μs | 7.70 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 15,047.7 μs | 2,686.03 μs | 147.23 μs | 94.47 | 4.56 | - | - | - | 18248 B | diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html new file mode 100644 index 0000000000..86292073ba --- /dev/null +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html @@ -0,0 +1,81 @@ + + + + +SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-20210207-115335 + + + + +

+BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
+Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores
+.NET Core SDK=5.0.101
+  [Host]     : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
+  Job-EMDSBW : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT
+  Job-KCUIVJ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT
+  Job-NIWDJE : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
+
+
InvocationCount=1  IterationCount=3  LaunchCount=1  
+UnrollFactor=1  WarmupCount=3  
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method JobRuntime TestImage Mean ErrorStdDevRatioRatioSDGen 0Gen 1Gen 2Allocated
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_grayscale_uncompressed.tiff1,107.9 μs260.10 μs14.26 μs1.000.00---974848 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_grayscale_uncompressed.tiff29,794.8 μs3,103.68 μs170.12 μs26.900.49---32768 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_grayscale_uncompressed.tiff1,020.4 μs641.11 μs35.14 μs1.000.00---968832 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_grayscale_uncompressed.tiff12,593.4 μs4,807.87 μs263.54 μs12.360.67---29976 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_grayscale_uncompressed.tiff987.2 μs2,211.93 μs121.24 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_grayscale_uncompressed.tiff44,255.5 μs13,031.10 μs714.28 μs45.234.88---29896 B
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_deflate_predictor.tiff16,118.9 μs2,095.51 μs114.86 μs1.000.00---1483440 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_deflate_predictor.tiff25,967.5 μs4,545.04 μs249.13 μs1.610.01---848240 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_deflate_predictor.tiff16,465.6 μs7,761.65 μs425.44 μs1.000.00---1480344 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_deflate_predictor.tiff18,536.9 μs3,415.62 μs187.22 μs1.130.02---68176 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_deflate_predictor.tiff16,216.2 μs3,288.12 μs180.23 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_deflate_predictor.tiff20,740.6 μs54,608.55 μs2,993.28 μs1.280.17---65120 B
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_lzw_predictor.tiff83,012.1 μs14,786.35 μs810.49 μs1.000.00---2545736 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_lzw_predictor.tiff64,895.5 μs11,397.89 μs624.76 μs0.780.01---24576 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_lzw_predictor.tiff82,854.1 μs45,495.28 μs2,493.75 μs1.000.00---2541376 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_lzw_predictor.tiff44,307.1 μs15,595.85 μs854.86 μs0.530.01---23832 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_lzw_predictor.tiff83,297.5 μs15,796.71 μs865.87 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_lzw_predictor.tiff59,464.0 μs13,870.15 μs760.27 μs0.710.01---23760 B
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_packbits.tiff3,707.2 μs6,293.27 μs344.96 μs1.000.00---2916008 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_packbits.tiff7,526.9 μs5,965.86 μs327.01 μs2.040.24---81920 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_packbits.tiff4,037.7 μs9,243.97 μs506.69 μs1.000.00---2903544 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_packbits.tiff4,395.7 μs1,394.13 μs76.42 μs1.100.15---80256 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_packbits.tiff3,456.3 μs4,443.73 μs243.58 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_packbits.tiff4,542.9 μs3,820.61 μs209.42 μs1.320.13---80184 B
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_palette_lzw_predictor.tiff60,298.5 μs24,263.76 μs1,329.98 μs1.000.00---827416 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_palette_lzw_predictor.tiff76,021.3 μs4,206.79 μs230.59 μs1.260.02---49152 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff59,122.1 μs9,681.07 μs530.65 μs1.000.00---825648 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff45,789.3 μs7,453.72 μs408.56 μs0.770.00---45936 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff61,361.5 μs25,759.90 μs1,411.99 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff68,134.6 μs303,212.80 μs16,620.12 μs1.110.25---45864 B
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiff3,431.7 μs7,649.10 μs419.27 μs1.000.00---2915944 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiff6,382.4 μs2,573.27 μs141.05 μs1.870.18---57344 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiff3,636.1 μs8,607.66 μs471.81 μs1.000.00---2905840 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiff4,018.7 μs1,662.68 μs91.14 μs1.120.16---51472 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiff2,970.8 μs5,028.62 μs275.64 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiff4,009.6 μs3,007.19 μs164.83 μs1.360.17---51400 B
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/ccitt_fax3_all_terminating_codes.tiff178.4 μs375.89 μs20.60 μs1.000.00---8192 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/ccitt_fax3_all_terminating_codes.tiff634.5 μs251.14 μs13.77 μs3.580.37---24576 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/ccitt_fax3_all_terminating_codes.tiff171.7 μs606.95 μs33.27 μs1.000.00---2032 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/ccitt_fax3_all_terminating_codes.tiff421.0 μs31.60 μs1.73 μs2.510.49---17848 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/ccitt_fax3_all_terminating_codes.tiff137.2 μs78.18 μs4.29 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/ccitt_fax3_all_terminating_codes.tiff888.5 μs495.11 μs27.14 μs6.470.05---17768 B
'System.Drawing Tiff'Job-EMDSBW.NET 4.7.2Tiff/huffman_rle_all_makeup_codes.tiff189.8 μs818.95 μs44.89 μs1.000.00---8192 B
'ImageSharp Tiff'Job-EMDSBW.NET 4.7.2Tiff/huffman_rle_all_makeup_codes.tiff9,137.1 μs1,178.82 μs64.62 μs49.8510.86---24576 B
'System.Drawing Tiff'Job-KCUIVJ.NET Core 2.1Tiff/huffman_rle_all_makeup_codes.tiff298.5 μs1,361.33 μs74.62 μs1.000.00---2088 B
'ImageSharp Tiff'Job-KCUIVJ.NET Core 2.1Tiff/huffman_rle_all_makeup_codes.tiff5,717.5 μs2,533.21 μs138.85 μs19.894.51---18328 B
'System.Drawing Tiff'Job-NIWDJE.NET Core 3.1Tiff/huffman_rle_all_makeup_codes.tiff159.5 μs140.52 μs7.70 μs1.000.00---176 B
'ImageSharp Tiff'Job-NIWDJE.NET Core 3.1Tiff/huffman_rle_all_makeup_codes.tiff15,047.7 μs2,686.03 μs147.23 μs94.474.56---18248 B
+ + diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-default.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-default.md new file mode 100644 index 0000000000..c1d7004423 --- /dev/null +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-default.md @@ -0,0 +1,74 @@ + +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 +Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + Job-BXRYWG : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT + Job-YFKMTZ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT + Job-ONTENJ : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT + +IterationCount=3 LaunchCount=1 WarmupCount=3 + + Method | Job | Runtime | TestImage | Compression | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +---------------------- |----------- |-------------- |-------------------------------------- |---------------- |-----------:|------------:|-----------:|------:|--------:|----------:|----------:|----------:|-----------:| + **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **None** | **6.520 ms** | **2.1764 ms** | **0.1193 ms** | **1.00** | **0.00** | **984.3750** | **984.3750** | **984.3750** | **11570062 B** | + 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.698 ms | 8.2629 ms | 0.4529 ms | 0.87 | 0.06 | 539.0625 | 500.0000 | 492.1875 | 9919288 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 6.851 ms | 1.4499 ms | 0.0795 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 11562768 B | + 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 4.294 ms | 2.0150 ms | 0.1104 ms | 0.63 | 0.02 | 539.0625 | 500.0000 | 492.1875 | 9918144 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.835 ms | 1.7302 ms | 0.0948 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 8672224 B | + 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.167 ms | 1.1793 ms | 0.0646 ms | 0.89 | 0.02 | 539.0625 | 500.0000 | 492.1875 | 9918112 B | + | | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Deflate** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | + 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 125.909 ms | 2.8957 ms | 0.1587 ms | ? | ? | 750.0000 | 750.0000 | 750.0000 | 11167960 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | + 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 125.041 ms | 6.3920 ms | 0.3504 ms | ? | ? | 750.0000 | 750.0000 | 750.0000 | 11164792 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | + 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 125.139 ms | 16.3106 ms | 0.8940 ms | ? | ? | 750.0000 | 750.0000 | 750.0000 | 11168428 B | + | | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Lzw** | **49.024 ms** | **35.9580 ms** | **1.9710 ms** | **1.00** | **0.00** | **800.0000** | **800.0000** | **800.0000** | **10673371 B** | + 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 411.728 ms | 47.6380 ms | 2.6112 ms | 8.41 | 0.39 | 1000.0000 | 1000.0000 | 1000.0000 | 23265464 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 47.288 ms | 1.4131 ms | 0.0775 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 10668688 B | + 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 201.643 ms | 5.6002 ms | 0.3070 ms | 4.26 | 0.00 | 333.3333 | 333.3333 | 333.3333 | 27451168 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 46.526 ms | 6.2383 ms | 0.3419 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 8001741 B | + 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 170.276 ms | 20.5515 ms | 1.1265 ms | 3.66 | 0.04 | 333.3333 | 333.3333 | 333.3333 | 27451445 B | + | | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **PackBits** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | + 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 28.948 ms | 7.0740 ms | 0.3877 ms | ? | ? | 500.0000 | 468.7500 | 468.7500 | 9943858 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | + 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 22.611 ms | 0.9267 ms | 0.0508 ms | ? | ? | 500.0000 | 468.7500 | 468.7500 | 9942792 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | + 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 23.465 ms | 4.7353 ms | 0.2596 ms | ? | ? | 531.2500 | 500.0000 | 500.0000 | 9942772 B | + | | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **CcittGroup3Fax** | **43.618 ms** | **6.0416 ms** | **0.3312 ms** | **1.00** | **0.00** | **-** | **-** | **-** | **1169683 B** | + 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 191.602 ms | 34.9864 ms | 1.9177 ms | 4.39 | 0.04 | 3333.3333 | 1333.3333 | 333.3333 | 24829048 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.258 ms | 3.5472 ms | 0.1944 ms | 1.00 | 0.00 | - | - | - | 1169200 B | + 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 177.930 ms | 50.1223 ms | 2.7474 ms | 4.11 | 0.04 | 3666.6667 | 2000.0000 | 666.6667 | 24772997 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.330 ms | 2.8194 ms | 0.1545 ms | 1.00 | 0.00 | - | - | - | 850189 B | + 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 168.846 ms | 19.1390 ms | 1.0491 ms | 3.90 | 0.01 | 3333.3333 | 1333.3333 | 333.3333 | 24774571 B | + | | | | | | | | | | | | | | + **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **ModifiedHuffman** | **17.106 ms** | **12.6692 ms** | **0.6944 ms** | **1.00** | **0.00** | **937.5000** | **937.5000** | **937.5000** | **11561706 B** | + 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 192.530 ms | 7.9946 ms | 0.4382 ms | 11.27 | 0.47 | 3333.3333 | 1333.3333 | 333.3333 | 24826163 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 16.988 ms | 2.7313 ms | 0.1497 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 11555088 B | + 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 180.265 ms | 78.0340 ms | 4.2773 ms | 10.61 | 0.18 | 3666.6667 | 2000.0000 | 666.6667 | 24769453 B | + | | | | | | | | | | | | | | + 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 15.989 ms | 2.7139 ms | 0.1488 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 8666467 B | + 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 181.295 ms | 231.7796 ms | 12.7046 ms | 11.34 | 0.90 | 3333.3333 | 1333.3333 | 333.3333 | 24770275 B | + +Benchmarks with issues: + EncodeTiff.'System.Drawing Tiff': Job-BXRYWG(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] + EncodeTiff.'System.Drawing Tiff': Job-YFKMTZ(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] + EncodeTiff.'System.Drawing Tiff': Job-ONTENJ(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] + EncodeTiff.'System.Drawing Tiff': Job-BXRYWG(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] + EncodeTiff.'System.Drawing Tiff': Job-YFKMTZ(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] + EncodeTiff.'System.Drawing Tiff': Job-ONTENJ(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-github.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-github.md new file mode 100644 index 0000000000..3dc7f0c2fa --- /dev/null +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-github.md @@ -0,0 +1,76 @@ +``` ini + +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 +Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + Job-BXRYWG : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT + Job-YFKMTZ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT + Job-ONTENJ : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT + +IterationCount=3 LaunchCount=1 WarmupCount=3 + +``` +| Method | Job | Runtime | TestImage | Compression | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|---------------------- |----------- |-------------- |-------------------------------------- |---------------- |-----------:|------------:|-----------:|------:|--------:|----------:|----------:|----------:|-----------:| +| **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **None** | **6.520 ms** | **2.1764 ms** | **0.1193 ms** | **1.00** | **0.00** | **984.3750** | **984.3750** | **984.3750** | **11570062 B** | +| 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.698 ms | 8.2629 ms | 0.4529 ms | 0.87 | 0.06 | 539.0625 | 500.0000 | 492.1875 | 9919288 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 6.851 ms | 1.4499 ms | 0.0795 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 11562768 B | +| 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 4.294 ms | 2.0150 ms | 0.1104 ms | 0.63 | 0.02 | 539.0625 | 500.0000 | 492.1875 | 9918144 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.835 ms | 1.7302 ms | 0.0948 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 8672224 B | +| 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.167 ms | 1.1793 ms | 0.0646 ms | 0.89 | 0.02 | 539.0625 | 500.0000 | 492.1875 | 9918112 B | +| | | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Deflate** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | +| 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 125.909 ms | 2.8957 ms | 0.1587 ms | ? | ? | 750.0000 | 750.0000 | 750.0000 | 11167960 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | +| 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 125.041 ms | 6.3920 ms | 0.3504 ms | ? | ? | 750.0000 | 750.0000 | 750.0000 | 11164792 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | +| 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 125.139 ms | 16.3106 ms | 0.8940 ms | ? | ? | 750.0000 | 750.0000 | 750.0000 | 11168428 B | +| | | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Lzw** | **49.024 ms** | **35.9580 ms** | **1.9710 ms** | **1.00** | **0.00** | **800.0000** | **800.0000** | **800.0000** | **10673371 B** | +| 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 411.728 ms | 47.6380 ms | 2.6112 ms | 8.41 | 0.39 | 1000.0000 | 1000.0000 | 1000.0000 | 23265464 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 47.288 ms | 1.4131 ms | 0.0775 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 10668688 B | +| 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 201.643 ms | 5.6002 ms | 0.3070 ms | 4.26 | 0.00 | 333.3333 | 333.3333 | 333.3333 | 27451168 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 46.526 ms | 6.2383 ms | 0.3419 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 8001741 B | +| 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 170.276 ms | 20.5515 ms | 1.1265 ms | 3.66 | 0.04 | 333.3333 | 333.3333 | 333.3333 | 27451445 B | +| | | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **PackBits** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | +| 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 28.948 ms | 7.0740 ms | 0.3877 ms | ? | ? | 500.0000 | 468.7500 | 468.7500 | 9943858 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | +| 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 22.611 ms | 0.9267 ms | 0.0508 ms | ? | ? | 500.0000 | 468.7500 | 468.7500 | 9942792 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | +| 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 23.465 ms | 4.7353 ms | 0.2596 ms | ? | ? | 531.2500 | 500.0000 | 500.0000 | 9942772 B | +| | | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **CcittGroup3Fax** | **43.618 ms** | **6.0416 ms** | **0.3312 ms** | **1.00** | **0.00** | **-** | **-** | **-** | **1169683 B** | +| 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 191.602 ms | 34.9864 ms | 1.9177 ms | 4.39 | 0.04 | 3333.3333 | 1333.3333 | 333.3333 | 24829048 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.258 ms | 3.5472 ms | 0.1944 ms | 1.00 | 0.00 | - | - | - | 1169200 B | +| 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 177.930 ms | 50.1223 ms | 2.7474 ms | 4.11 | 0.04 | 3666.6667 | 2000.0000 | 666.6667 | 24772997 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.330 ms | 2.8194 ms | 0.1545 ms | 1.00 | 0.00 | - | - | - | 850189 B | +| 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 168.846 ms | 19.1390 ms | 1.0491 ms | 3.90 | 0.01 | 3333.3333 | 1333.3333 | 333.3333 | 24774571 B | +| | | | | | | | | | | | | | | +| **'System.Drawing Tiff'** | **Job-BXRYWG** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **ModifiedHuffman** | **17.106 ms** | **12.6692 ms** | **0.6944 ms** | **1.00** | **0.00** | **937.5000** | **937.5000** | **937.5000** | **11561706 B** | +| 'ImageSharp Tiff' | Job-BXRYWG | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 192.530 ms | 7.9946 ms | 0.4382 ms | 11.27 | 0.47 | 3333.3333 | 1333.3333 | 333.3333 | 24826163 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 16.988 ms | 2.7313 ms | 0.1497 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 11555088 B | +| 'ImageSharp Tiff' | Job-YFKMTZ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 180.265 ms | 78.0340 ms | 4.2773 ms | 10.61 | 0.18 | 3666.6667 | 2000.0000 | 666.6667 | 24769453 B | +| | | | | | | | | | | | | | | +| 'System.Drawing Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 15.989 ms | 2.7139 ms | 0.1488 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 8666467 B | +| 'ImageSharp Tiff' | Job-ONTENJ | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 181.295 ms | 231.7796 ms | 12.7046 ms | 11.34 | 0.90 | 3333.3333 | 1333.3333 | 333.3333 | 24770275 B | + +Benchmarks with issues: + EncodeTiff.'System.Drawing Tiff': Job-BXRYWG(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] + EncodeTiff.'System.Drawing Tiff': Job-YFKMTZ(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] + EncodeTiff.'System.Drawing Tiff': Job-ONTENJ(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] + EncodeTiff.'System.Drawing Tiff': Job-BXRYWG(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] + EncodeTiff.'System.Drawing Tiff': Job-YFKMTZ(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] + EncodeTiff.'System.Drawing Tiff': Job-ONTENJ(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report.html b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report.html new file mode 100644 index 0000000000..1549909fd8 --- /dev/null +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report.html @@ -0,0 +1,68 @@ + + + + +SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-20210207-115408 + + + + +

+BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
+Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores
+.NET Core SDK=5.0.101
+  [Host]     : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
+  Job-BXRYWG : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT
+  Job-YFKMTZ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT
+  Job-ONTENJ : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
+
+
IterationCount=3  LaunchCount=1  WarmupCount=3  
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method JobRuntime TestImageCompressionMeanErrorStdDevRatioRatioSDGen 0Gen 1Gen 2Allocated
'System.Drawing Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffNone6.520 ms2.1764 ms0.1193 ms1.000.00984.3750984.3750984.375011570062 B
'ImageSharp Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffNone5.698 ms8.2629 ms0.4529 ms0.870.06539.0625500.0000492.18759919288 B
'System.Drawing Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffNone6.851 ms1.4499 ms0.0795 ms1.000.00984.3750984.3750984.375011562768 B
'ImageSharp Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffNone4.294 ms2.0150 ms0.1104 ms0.630.02539.0625500.0000492.18759918144 B
'System.Drawing Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffNone5.835 ms1.7302 ms0.0948 ms1.000.00984.3750984.3750984.37508672224 B
'ImageSharp Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffNone5.167 ms1.1793 ms0.0646 ms0.890.02539.0625500.0000492.18759918112 B
'System.Drawing Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffDeflateNANANA??----
'ImageSharp Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffDeflate125.909 ms2.8957 ms0.1587 ms??750.0000750.0000750.000011167960 B
'System.Drawing Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffDeflateNANANA??----
'ImageSharp Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffDeflate125.041 ms6.3920 ms0.3504 ms??750.0000750.0000750.000011164792 B
'System.Drawing Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffDeflateNANANA??----
'ImageSharp Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffDeflate125.139 ms16.3106 ms0.8940 ms??750.0000750.0000750.000011168428 B
'System.Drawing Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffLzw49.024 ms35.9580 ms1.9710 ms1.000.00800.0000800.0000800.000010673371 B
'ImageSharp Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffLzw411.728 ms47.6380 ms2.6112 ms8.410.391000.00001000.00001000.000023265464 B
'System.Drawing Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffLzw47.288 ms1.4131 ms0.0775 ms1.000.00818.1818818.1818818.181810668688 B
'ImageSharp Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffLzw201.643 ms5.6002 ms0.3070 ms4.260.00333.3333333.3333333.333327451168 B
'System.Drawing Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffLzw46.526 ms6.2383 ms0.3419 ms1.000.00818.1818818.1818818.18188001741 B
'ImageSharp Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffLzw170.276 ms20.5515 ms1.1265 ms3.660.04333.3333333.3333333.333327451445 B
'System.Drawing Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffPackBitsNANANA??----
'ImageSharp Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffPackBits28.948 ms7.0740 ms0.3877 ms??500.0000468.7500468.75009943858 B
'System.Drawing Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffPackBitsNANANA??----
'ImageSharp Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffPackBits22.611 ms0.9267 ms0.0508 ms??500.0000468.7500468.75009942792 B
'System.Drawing Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffPackBitsNANANA??----
'ImageSharp Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffPackBits23.465 ms4.7353 ms0.2596 ms??531.2500500.0000500.00009942772 B
'System.Drawing Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax43.618 ms6.0416 ms0.3312 ms1.000.00---1169683 B
'ImageSharp Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax191.602 ms34.9864 ms1.9177 ms4.390.043333.33331333.3333333.333324829048 B
'System.Drawing Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax43.258 ms3.5472 ms0.1944 ms1.000.00---1169200 B
'ImageSharp Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax177.930 ms50.1223 ms2.7474 ms4.110.043666.66672000.0000666.666724772997 B
'System.Drawing Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax43.330 ms2.8194 ms0.1545 ms1.000.00---850189 B
'ImageSharp Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax168.846 ms19.1390 ms1.0491 ms3.900.013333.33331333.3333333.333324774571 B
'System.Drawing Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman17.106 ms12.6692 ms0.6944 ms1.000.00937.5000937.5000937.500011561706 B
'ImageSharp Tiff'Job-BXRYWG.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman192.530 ms7.9946 ms0.4382 ms11.270.473333.33331333.3333333.333324826163 B
'System.Drawing Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman16.988 ms2.7313 ms0.1497 ms1.000.00937.5000937.5000937.500011555088 B
'ImageSharp Tiff'Job-YFKMTZ.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman180.265 ms78.0340 ms4.2773 ms10.610.183666.66672000.0000666.666724769453 B
'System.Drawing Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman15.989 ms2.7139 ms0.1488 ms1.000.00937.5000937.5000937.50008666467 B
'ImageSharp Tiff'Job-ONTENJ.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman181.295 ms231.7796 ms12.7046 ms11.340.903333.33331333.3333333.333324770275 B
+ + From 9e139882c4aaa26513e0685a3c986b3ef162a488 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sat, 6 Feb 2021 22:05:16 +0300 Subject: [PATCH 03/15] Support multi strip encoding for tiff. Improve performance and memory usage of decoders and encoders. # Conflicts: # tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs --- .../Formats/ImageExtensions.Save.cs | 1 - .../Tiff/Compression/BitWriterUtils.cs | 38 +-- .../Compressors/DeflateCompressor.cs | 59 +++++ .../Compression/Compressors/LzwCompressor.cs | 36 +++ .../Compression/Compressors/NoCompressor.cs | 28 +++ .../Compressors/PackBitsCompressor.cs | 39 +++ .../{T4BitWriter.cs => T4BitCompressor.cs} | 88 ++++--- .../Compression/Compressors/TiffLzwEncoder.cs | 52 ++-- .../Decompressors/DeflateTiffCompression.cs | 7 +- .../Decompressors/LzwTiffCompression.cs | 7 +- .../ModifiedHuffmanTiffCompression.cs | 15 +- .../Decompressors/NoneTiffCompression.cs | 12 +- .../Decompressors/PackBitsTiffCompression.cs | 20 +- .../Decompressors/T4TiffCompression.cs | 27 ++- .../FaxCompressionOptions.cs | 2 +- .../Tiff/Compression/HorizontalPredictor.cs | 56 +++-- .../Tiff/Compression/TiffBaseCompression.cs | 47 ++++ .../Tiff/Compression/TiffBaseCompressor.cs | 25 ++ ...eCompression.cs => TiffBaseDecompresor.cs} | 32 +-- .../Tiff/Compression/TiffCompressorFactory.cs | 61 +++++ .../TiffDecoderCompressionType.cs | 2 +- .../TiffDecompressorsFactory.cs | 27 ++- .../Formats/Tiff/ITiffEncoderOptions.cs | 10 + .../Formats/Tiff/TiffDecoderCore.cs | 6 +- .../Formats/Tiff/TiffDecoderOptionsParser.cs | 2 +- src/ImageSharp/Formats/Tiff/TiffEncoder.cs | 6 + .../Formats/Tiff/TiffEncoderCore.cs | 135 ++++++----- .../Tiff/TiffEncoderPixelStorageMethod.cs | 26 ++ .../Formats/Tiff/TiffThrowHelper.cs | 5 +- .../Tiff/Writers/TiffBaseColorWriter.cs | 103 ++++++-- .../Formats/Tiff/Writers/TiffBiColorWriter.cs | 225 +++++------------- .../Tiff/Writers/TiffColorWriterFactory.cs | 19 +- .../Tiff/Writers/TiffCompositeColorWriter.cs | 45 ++++ .../Formats/Tiff/Writers/TiffGrayWriter.cs | 162 +------------ .../Formats/Tiff/Writers/TiffPaletteWriter.cs | 212 +++-------------- .../Formats/Tiff/Writers/TiffRgbWriter.cs | 165 +------------ .../Formats/Tiff/Writers/TiffStreamWriter.cs | 1 - .../DeflateTiffCompressionTests.cs | 4 +- .../Compression/LzwTiffCompressionTests.cs | 13 +- .../Compression/NoneTiffCompressionTests.cs | 2 +- .../PackBitsTiffCompressionTests.cs | 3 +- .../Formats/Tiff/TiffEncoderHeaderTests.cs | 1 - .../Formats/Tiff/TiffEncoderTests.cs | 102 +++++++- .../Formats/Tiff/Utils/TiffWriterTests.cs | 2 - 44 files changed, 987 insertions(+), 943 deletions(-) create mode 100644 src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs create mode 100644 src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs create mode 100644 src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs create mode 100644 src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs rename src/ImageSharp/Formats/Tiff/Compression/Compressors/{T4BitWriter.cs => T4BitCompressor.cs} (88%) rename src/ImageSharp/Formats/Tiff/Compression/{Decompressors => }/FaxCompressionOptions.cs (98%) create mode 100644 src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs create mode 100644 src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs rename src/ImageSharp/Formats/Tiff/Compression/{Decompressors/TiffBaseCompression.cs => TiffBaseDecompresor.cs} (65%) create mode 100644 src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs rename src/ImageSharp/Formats/Tiff/Compression/{Decompressors => }/TiffDecoderCompressionType.cs (98%) rename src/ImageSharp/Formats/Tiff/Compression/{Decompressors => }/TiffDecompressorsFactory.cs (56%) create mode 100644 src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs create mode 100644 src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs diff --git a/src/ImageSharp/Formats/ImageExtensions.Save.cs b/src/ImageSharp/Formats/ImageExtensions.Save.cs index 07c6b37b84..6673803a48 100644 --- a/src/ImageSharp/Formats/ImageExtensions.Save.cs +++ b/src/ImageSharp/Formats/ImageExtensions.Save.cs @@ -13,7 +13,6 @@ using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Formats.Tga; -using SixLabors.ImageSharp.Formats.Tiff; namespace SixLabors.ImageSharp { diff --git a/src/ImageSharp/Formats/Tiff/Compression/BitWriterUtils.cs b/src/ImageSharp/Formats/Tiff/Compression/BitWriterUtils.cs index 9c857eccde..597a91b68c 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/BitWriterUtils.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/BitWriterUtils.cs @@ -14,34 +14,38 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression int startIdx = bufferPos + bitPos; int endIdx = (int)(startIdx + count); - for (int i = startIdx; i < endIdx; i++) + if (value == 1) { - if (value == 1) + for (int i = startIdx; i < endIdx; i++) { WriteBit(buffer, bufferPos, bitPos); + + bitPos++; + if (bitPos >= 8) + { + bitPos = 0; + bufferPos++; + } } - else + } + else + { + for (int i = startIdx; i < endIdx; i++) { WriteZeroBit(buffer, bufferPos, bitPos); - } - bitPos++; - if (bitPos >= 8) - { - bitPos = 0; - bufferPos++; + bitPos++; + if (bitPos >= 8) + { + bitPos = 0; + bufferPos++; + } } } } - public static void WriteBit(Span buffer, int bufferPos, int bitPos) - { - buffer[bufferPos] |= (byte)(1 << (7 - bitPos)); - } + public static void WriteBit(Span buffer, int bufferPos, int bitPos) => buffer[bufferPos] |= (byte)(1 << (7 - bitPos)); - public static void WriteZeroBit(Span buffer, int bufferPos, int bitPos) - { - buffer[bufferPos] = (byte)(buffer[bufferPos] & ~(1 << (7 - bitPos))); - } + public static void WriteZeroBit(Span buffer, int bufferPos, int bitPos) => buffer[bufferPos] = (byte)(buffer[bufferPos] & ~(1 << (7 - bitPos))); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs new file mode 100644 index 0000000000..f4b6c6ad7f --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs @@ -0,0 +1,59 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.IO; +using SixLabors.ImageSharp.Compression.Zlib; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors +{ + internal class DeflateCompressor : TiffBaseCompressor + { + private readonly DeflateCompressionLevel compressionLevel; + + private readonly MemoryStream memoryStream = new MemoryStream(); + + public DeflateCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor, DeflateCompressionLevel compressionLevel) + : base(output, allocator, width, bitsPerPixel, predictor) + => this.compressionLevel = compressionLevel; + + public override TiffEncoderCompression Method => TiffEncoderCompression.Deflate; + + public override void Initialize(int rowsPerStrip) + { + } + + public override void CompressStrip(Span rows, int height) + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + using var stream = new ZlibDeflateStream(this.Allocator, this.memoryStream, this.compressionLevel); + + if (this.Predictor == TiffPredictor.Horizontal) + { + HorizontalPredictor.ApplyHorizontalPrediction(rows, this.BytesPerRow, this.BitsPerPixel); + } + + stream.Write(rows); + + stream.Flush(); + //// stream.Dispose(); // todo: dispose write crc + + int size = (int)this.memoryStream.Position; + +#if !NETSTANDARD1_3 + byte[] buffer = this.memoryStream.GetBuffer(); + this.Output.Write(buffer, 0, size); +#else + this.memoryStream.SetLength(size); + this.memoryStream.Position = 0; + this.memoryStream.CopyTo(this.Output); +#endif + } + + protected override void Dispose(bool disposing) + { + } + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs new file mode 100644 index 0000000000..84dc95b5f9 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs @@ -0,0 +1,36 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.IO; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors +{ + internal class LzwCompressor : TiffBaseCompressor + { + private TiffLzwEncoder lzwEncoder; + + public LzwCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor) + : base(output, allocator, width, bitsPerPixel, predictor) + { + } + + public override TiffEncoderCompression Method => TiffEncoderCompression.Lzw; + + public override void Initialize(int rowsPerStrip) => this.lzwEncoder = new TiffLzwEncoder(this.Allocator); + + public override void CompressStrip(Span rows, int height) + { + if (this.Predictor == TiffPredictor.Horizontal) + { + HorizontalPredictor.ApplyHorizontalPrediction(rows, this.BytesPerRow, this.BitsPerPixel); + } + + this.lzwEncoder.Encode(rows, this.Output); + } + + protected override void Dispose(bool disposing) => this.lzwEncoder?.Dispose(); + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs new file mode 100644 index 0000000000..6c6b9ef343 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs @@ -0,0 +1,28 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.IO; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors +{ + internal class NoCompressor : TiffBaseCompressor + { + public NoCompressor(Stream output) + : base(output, default, default, default) + { + } + + public override TiffEncoderCompression Method => TiffEncoderCompression.None; + + public override void Initialize(int rowsPerStrip) + { + } + + public override void CompressStrip(Span rows, int height) => this.Output.Write(rows); + + protected override void Dispose(bool disposing) + { + } + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs new file mode 100644 index 0000000000..627ca6cbb2 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs @@ -0,0 +1,39 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.IO; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors +{ + internal class PackBitsCompressor : TiffBaseCompressor + { + private IManagedByteBuffer pixelData; + + public PackBitsCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel) + : base(output, allocator, width, bitsPerPixel) + { + } + + public override TiffEncoderCompression Method => TiffEncoderCompression.PackBits; + + public override void Initialize(int rowsPerStrip) + { + int additionalBytes = (this.BytesPerRow / 127) + 1; + this.pixelData = this.Allocator.AllocateManagedByteBuffer((this.BytesPerRow + additionalBytes) * rowsPerStrip); + } + + public override void CompressStrip(Span rows, int height) + { + this.pixelData.Clear(); + Span span = this.pixelData.GetSpan(); + int size = PackBitsWriter.PackBits(rows, span); + this.Output.Write(span.Slice(0, size)); + } + + protected override void Dispose(bool disposing) => this.pixelData?.Dispose(); + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitWriter.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs similarity index 88% rename from src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitWriter.cs rename to src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs index 99e2a148c8..f96fa071d0 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs @@ -5,16 +5,14 @@ using System; using System.Buffers; using System.Collections.Generic; using System.IO; - using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors { /// /// Bitwriter for writing compressed CCITT T4 1D data. /// - internal class T4BitWriter + internal class T4BitCompressor : TiffBaseCompressor { private const uint WhiteZeroRunTermCode = 0x35; @@ -176,49 +174,52 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors { 1408, 0x54 }, { 1472, 0x55 }, { 1536, 0x5A }, { 1600, 0x5B }, { 1664, 0x64 }, { 1728, 0x65 } }; - private readonly MemoryAllocator memoryAllocator; + /// + /// The modified huffman is basically the same as CCITT T4, but without EOL markers and padding at the end of the rows. + /// + private readonly bool useModifiedHuffman; - private readonly Configuration configuration; + private IMemoryOwner compressedDataBuffer; private int bytePosition; private byte bitPosition; /// - /// The modified huffman is basically the same as CCITT T4, but without EOL markers and padding at the end of the rows. - /// - private readonly bool useModifiedHuffman; - - /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The memory allocator. - /// The configuration. + /// The output. + /// The allocator. + /// The width. + /// The bits per pixel. /// Indicates if the modified huffman RLE should be used. - public T4BitWriter(MemoryAllocator memoryAllocator, Configuration configuration, bool useModifiedHuffman = false) + public T4BitCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, bool useModifiedHuffman = false) + : base(output, allocator, width, bitsPerPixel) { - this.memoryAllocator = memoryAllocator; - this.configuration = configuration; this.bytePosition = 0; this.bitPosition = 0; this.useModifiedHuffman = useModifiedHuffman; } - /// - /// Writes a image compressed with CCITT T4 to the stream. - /// - /// The pixel data. - /// The image to write to the stream. This has to be a bi-color image. - /// A span for converting a pixel row to gray. - /// The stream to write to. - /// The number of bytes written to the stream. - public int CompressImage(Image image, Span pixelRowAsGray, Stream stream) - where TPixel : unmanaged, IPixel + public override TiffEncoderCompression Method => this.useModifiedHuffman ? TiffEncoderCompression.ModifiedHuffman : TiffEncoderCompression.CcittGroup3Fax; + + public override void Initialize(int rowsPerStrip) { // This is too much memory allocated, but just 1 bit per pixel will not do, if the compression rate is not good. - int maxNeededBytes = image.Width * image.Height; - IMemoryOwner compressedDataBuffer = this.memoryAllocator.Allocate(maxNeededBytes, AllocationOptions.Clean); - Span compressedData = compressedDataBuffer.GetSpan(); + int maxNeededBytes = this.Width * rowsPerStrip; + this.compressedDataBuffer = this.Allocator.Allocate(maxNeededBytes); + } + + /// Writes a image compressed with CCITT T4 to the stream. + /// The pixels as 8-bit gray array. + /// The strip height. + public override void CompressStrip(Span pixelsAsGray, int height) + { + DebugGuard.Equals(pixelsAsGray.Length / height, this.Width); + DebugGuard.Equals(pixelsAsGray.Length % height, 0); + + this.compressedDataBuffer.Clear(); + Span compressedData = this.compressedDataBuffer.GetSpan(); this.bytePosition = 0; this.bitPosition = 0; @@ -229,36 +230,35 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors this.WriteCode(12, 1, compressedData); } - uint pixelsWritten = 0; - for (int y = 0; y < image.Height; y++) + for (int y = 0; y < height; y++) { bool isWhiteRun = true; bool isStartOrRow = true; - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8(this.configuration, pixelRow, pixelRowAsGray); int x = 0; - while (x < image.Width) + + Span row = pixelsAsGray.Slice(y * this.Width, this.Width); + while (x < this.Width) { uint runLength = 0; - for (int i = x; i < image.Width; i++) + for (int i = x; i < this.Width; i++) { - if (isWhiteRun && pixelRowAsGray[i].PackedValue != 255) + if (isWhiteRun && row[i] != 255) { break; } - if (isWhiteRun && pixelRowAsGray[i].PackedValue == 255) + if (isWhiteRun && row[i] == 255) { runLength++; continue; } - if (!isWhiteRun && pixelRowAsGray[i].PackedValue != 0) + if (!isWhiteRun && row[i] != 0) { break; } - if (!isWhiteRun && pixelRowAsGray[i].PackedValue == 0) + if (!isWhiteRun && row[i] == 0) { runLength++; } @@ -280,7 +280,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors code = this.GetTermCode(runLength, out codeLength, isWhiteRun); this.WriteCode(codeLength, code, compressedData); x += (int)runLength; - pixelsWritten += runLength; } else { @@ -288,10 +287,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors code = this.GetMakeupCode(runLength, out codeLength, isWhiteRun); this.WriteCode(codeLength, code, compressedData); x += (int)runLength; - pixelsWritten += runLength; // If we are at the end of the line with a makeup code, we need to write a final term code with a length of zero. - if (x == image.Width) + if (x == this.Width) { if (isWhiteRun) { @@ -315,11 +313,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors // Write the compressed data to the stream. int bytesToWrite = this.bitPosition != 0 ? this.bytePosition + 1 : this.bytePosition; - stream.Write(compressedData.Slice(0, bytesToWrite)); - - return bytesToWrite; + this.Output.Write(compressedData.Slice(0, bytesToWrite)); } + protected override void Dispose(bool disposing) => this.compressedDataBuffer?.Dispose(); + private void WriteEndOfLine(Span compressedData) { if (this.useModifiedHuffman) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs index db7d18a41a..f6a74c166a 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs @@ -7,7 +7,7 @@ using System.IO; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Memory; -namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors { /* This implementation is a port of a java tiff encoder by Harald Kuhr: https://github.com/haraldk/TwelveMonkeys @@ -71,8 +71,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils private static readonly int TableSize = 1 << MaxBits; - private readonly IMemoryOwner data; - // A child is made up of a parent (or prefix) code plus a suffix byte // and siblings are strings with a common parent(or prefix) and different suffix bytes. private readonly IMemoryOwner children; @@ -95,31 +93,27 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils /// /// Initializes a new instance of the class. /// - /// The data to compress. /// The memory allocator. - public TiffLzwEncoder(MemoryAllocator memoryAllocator, IMemoryOwner data) + public TiffLzwEncoder(MemoryAllocator memoryAllocator) { - this.data = data; - this.children = memoryAllocator.Allocate(TableSize, AllocationOptions.Clean); - this.siblings = memoryAllocator.Allocate(TableSize, AllocationOptions.Clean); - this.suffixes = memoryAllocator.Allocate(TableSize, AllocationOptions.Clean); - - this.parent = -1; - this.bitsPerCode = MinBits; - this.nextValidCode = EoiCode + 1; - this.maxCode = (1 << this.bitsPerCode) - 1; + this.children = memoryAllocator.Allocate(TableSize); + this.siblings = memoryAllocator.Allocate(TableSize); + this.suffixes = memoryAllocator.Allocate(TableSize); } /// /// Encodes and compresses the indexed pixels to the stream. /// + /// The data to compress. /// The stream to write to. - public void Encode(Stream stream) + public void Encode(Span data, Stream stream) { + this.Reset(); + Span childrenSpan = this.children.GetSpan(); Span suffixesSpan = this.suffixes.GetSpan(); Span siblingsSpan = this.siblings.GetSpan(); - int length = this.data.Length(); + int length = data.Length; if (length == 0) { @@ -130,12 +124,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils { // Init stream. this.WriteCode(stream, ClearCode); - this.parent = this.ReadNextByte() & 0xff; + this.parent = this.ReadNextByte(data); } - while (this.bufferPosition < this.data.Length()) + while (this.bufferPosition < data.Length) { - int value = this.ReadNextByte() & 0xff; + int value = this.ReadNextByte(data); int child = childrenSpan[this.parent]; if (child > 0) @@ -206,14 +200,24 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils this.suffixes.Dispose(); } - private byte ReadNextByte() + private void Reset() { - Span dataSpan = this.data.GetSpan(); - var nextByte = dataSpan[this.bufferPosition]; - this.bufferPosition++; - return nextByte; + this.children.Clear(); + this.siblings.Clear(); + this.suffixes.Clear(); + + this.parent = -1; + this.bitsPerCode = MinBits; + this.nextValidCode = EoiCode + 1; + this.maxCode = (1 << this.bitsPerCode) - 1; + + this.bits = 0; + this.bitPos = 0; + this.bufferPosition = 0; } + private byte ReadNextByte(Span data) => data[this.bufferPosition++]; + private void IncreaseCodeSizeOrResetIfNeeded(Stream stream) { if (this.nextValidCode > this.maxCode) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs index 8c0dbee95e..a53d69027d 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs @@ -6,7 +6,6 @@ using System.IO.Compression; using SixLabors.ImageSharp.Compression.Zlib; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; -using SixLabors.ImageSharp.Formats.Tiff.Compression; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -18,7 +17,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso /// /// Note that the 'OldDeflate' compression type is identical to the 'Deflate' compression type. /// - internal class DeflateTiffCompression : TiffBaseCompression + internal class DeflateTiffCompression : TiffBaseDecompresor { /// /// Initializes a new instance of the class. @@ -54,5 +53,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso HorizontalPredictor.Undo(buffer, this.Width, this.BitsPerPixel); } } + + protected override void Dispose(bool disposing) + { + } } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs index 98aecd1732..82640dfed3 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs @@ -4,7 +4,6 @@ using System; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; -using SixLabors.ImageSharp.Formats.Tiff.Compression; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -13,7 +12,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso /// /// Class to handle cases where TIFF image data is compressed using LZW compression. /// - internal class LzwTiffCompression : TiffBaseCompression + internal class LzwTiffCompression : TiffBaseDecompresor { /// /// Initializes a new instance of the class. @@ -38,5 +37,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso HorizontalPredictor.Undo(buffer, this.Width, this.BitsPerPixel); } } + + protected override void Dispose(bool disposing) + { + } } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs index 1664cbebb0..7a7cd20f78 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs @@ -14,6 +14,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso /// internal class ModifiedHuffmanTiffCompression : T4TiffCompression { + private readonly byte whiteValue; + + private readonly byte blackValue; + /// /// Initializes a new instance of the class. /// @@ -23,15 +27,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso public ModifiedHuffmanTiffCompression(MemoryAllocator allocator, TiffPhotometricInterpretation photometricInterpretation, int width) : base(allocator, FaxCompressionOptions.None, photometricInterpretation, width) { + bool isWhiteZero = photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero; + this.whiteValue = (byte)(isWhiteZero ? 0 : 1); + this.blackValue = (byte)(isWhiteZero ? 1 : 0); } /// protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer) { - bool isWhiteZero = this.PhotometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero; - byte whiteValue = (byte)(isWhiteZero ? 0 : 1); - byte blackValue = (byte)(isWhiteZero ? 1 : 0); - using var bitReader = new T4BitReader(stream, byteCount, this.Allocator, eolPadding: false, isModifiedHuffman: true); buffer.Clear(); @@ -45,13 +48,13 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso { if (bitReader.IsWhiteRun) { - BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, whiteValue); + BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.whiteValue); bitsWritten += bitReader.RunLength; pixelsWritten += bitReader.RunLength; } else { - BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, blackValue); + BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.blackValue); bitsWritten += bitReader.RunLength; pixelsWritten += bitReader.RunLength; } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs index f7271fd032..a30997debf 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs @@ -4,25 +4,27 @@ using System; using SixLabors.ImageSharp.IO; -using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors { /// /// Class to handle cases where TIFF image data is not compressed. /// - internal class NoneTiffCompression : TiffBaseCompression + internal class NoneTiffCompression : TiffBaseDecompresor { /// /// Initializes a new instance of the class. /// - /// The memoryAllocator to use for buffer allocations. - public NoneTiffCompression(MemoryAllocator memoryAllocator) - : base(memoryAllocator) + public NoneTiffCompression() + : base(default, default, default) { } /// protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer) => _ = stream.Read(buffer, 0, Math.Min(buffer.Length, byteCount)); + + protected override void Dispose(bool disposing) + { + } } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs index 9786ef5ff9..ab67d818d8 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs @@ -12,23 +12,33 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso /// /// Class to handle cases where TIFF image data is compressed using PackBits compression. /// - internal class PackBitsTiffCompression : TiffBaseCompression + internal class PackBitsTiffCompression : TiffBaseDecompresor { + private IMemoryOwner compressedDataMemory; + /// /// Initializes a new instance of the class. /// /// The memoryAllocator to use for buffer allocations. public PackBitsTiffCompression(MemoryAllocator memoryAllocator) - : base(memoryAllocator) + : base(memoryAllocator, default, default) { } /// protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer) { - using IMemoryOwner compressedDataMemory = this.Allocator.Allocate(byteCount); + if (this.compressedDataMemory == null) + { + this.compressedDataMemory = this.Allocator.Allocate(byteCount); + } + else if (this.compressedDataMemory.Length() < byteCount) + { + this.compressedDataMemory.Dispose(); + this.compressedDataMemory = this.Allocator.Allocate(byteCount); + } - Span compressedData = compressedDataMemory.GetSpan(); + Span compressedData = this.compressedDataMemory.GetSpan(); stream.Read(compressedData, 0, byteCount); int compressedOffset = 0; @@ -77,5 +87,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso destinationArray[i + destinationIndex] = value; } } + + protected override void Dispose(bool disposing) => this.compressedDataMemory?.Dispose(); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs index 005b5132a5..fe4641fb28 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs @@ -12,10 +12,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso /// /// Class to handle cases where TIFF image data is compressed using CCITT T4 compression. /// - internal class T4TiffCompression : TiffBaseCompression + internal class T4TiffCompression : TiffBaseDecompresor { private readonly FaxCompressionOptions faxCompressionOptions; + private readonly byte whiteValue; + + private readonly byte blackValue; + /// /// Initializes a new instance of the class. /// @@ -24,7 +28,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso /// The photometric interpretation. /// The image width. public T4TiffCompression(MemoryAllocator allocator, FaxCompressionOptions faxOptions, TiffPhotometricInterpretation photometricInterpretation, int width) - : base(allocator, photometricInterpretation, width) => this.faxCompressionOptions = faxOptions; + : base(allocator, width, default) + { + this.faxCompressionOptions = faxOptions; + + bool isWhiteZero = photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero; + this.whiteValue = (byte)(isWhiteZero ? 0 : 1); + this.blackValue = (byte)(isWhiteZero ? 1 : 0); + } /// protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer) @@ -34,10 +45,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso TiffThrowHelper.ThrowNotSupported("TIFF CCITT 2D compression is not yet supported"); } - bool isWhiteZero = this.PhotometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero; - byte whiteValue = (byte)(isWhiteZero ? 0 : 1); - byte blackValue = (byte)(isWhiteZero ? 1 : 0); - var eolPadding = this.faxCompressionOptions.HasFlag(FaxCompressionOptions.EolPadding); using var bitReader = new T4BitReader(stream, byteCount, this.Allocator, eolPadding); @@ -51,12 +58,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso { if (bitReader.IsWhiteRun) { - BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, whiteValue); + BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.whiteValue); bitsWritten += bitReader.RunLength; } else { - BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, blackValue); + BitWriterUtils.WriteBits(buffer, (int)bitsWritten, bitReader.RunLength, this.blackValue); bitsWritten += bitReader.RunLength; } } @@ -73,5 +80,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso } } } + + protected override void Dispose(bool disposing) + { + } } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/FaxCompressionOptions.cs b/src/ImageSharp/Formats/Tiff/Compression/FaxCompressionOptions.cs similarity index 98% rename from src/ImageSharp/Formats/Tiff/Compression/Decompressors/FaxCompressionOptions.cs rename to src/ImageSharp/Formats/Tiff/Compression/FaxCompressionOptions.cs index c98ad0387c..d5171db657 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/FaxCompressionOptions.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/FaxCompressionOptions.cs @@ -3,7 +3,7 @@ using System; -namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { /// /// Fax compression options, see TIFF spec page 51f (T4Options). diff --git a/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs b/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs index 10ac39747d..0e394d26a5 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; using SixLabors.ImageSharp.PixelFormats; -namespace SixLabors.ImageSharp.Formats.Tiff.Compression +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { /// /// Methods for undoing the horizontal prediction used in combination with deflate and LZW compressed TIFF images. @@ -32,38 +32,64 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression } } + public static void ApplyHorizontalPrediction(Span rows, int width, int bitsPerPixel) + { + if (bitsPerPixel == 8) + { + ApplyHorizontalPrediction8Bit(rows, width); + } + else if (bitsPerPixel == 24) + { + ApplyHorizontalPrediction24Bit(rows, width); + } + } + /// /// Applies a horizontal predictor to the rgb row. /// Make use of the fact that many continuous-tone images rarely vary much in pixel value from one pixel to the next. /// In such images, if we replace the pixel values by differences between consecutive pixels, many of the differences should be 0, plus /// or minus 1, and so on.This reduces the apparent information content and allows LZW to encode the data more compactly. /// - /// The rgb pixel row. + /// The rgb pixel rows. + /// The width. [MethodImpl(InliningOptions.ShortMethod)] - public static void ApplyHorizontalPrediction24Bit(Span rowSpan) + private static void ApplyHorizontalPrediction24Bit(Span rows, int width) { - Span rowRgb = MemoryMarshal.Cast(rowSpan); - - for (int x = rowRgb.Length - 1; x >= 1; x--) + DebugGuard.Equals(rows.Length % width, 0); + int height = rows.Length / width; + for (int y = 0; y < height; y++) { - byte r = (byte)(rowRgb[x].R - rowRgb[x - 1].R); - byte g = (byte)(rowRgb[x].G - rowRgb[x - 1].G); - byte b = (byte)(rowRgb[x].B - rowRgb[x - 1].B); - var rgb = new Rgb24(r, g, b); - rowRgb[x].FromRgb24(rgb); + Span rowSpan = rows.Slice(y * width, width); + Span rowRgb = MemoryMarshal.Cast(rowSpan); + + for (int x = rowRgb.Length - 1; x >= 1; x--) + { + byte r = (byte)(rowRgb[x].R - rowRgb[x - 1].R); + byte g = (byte)(rowRgb[x].G - rowRgb[x - 1].G); + byte b = (byte)(rowRgb[x].B - rowRgb[x - 1].B); + var rgb = new Rgb24(r, g, b); + rowRgb[x].FromRgb24(rgb); + } } } /// /// Applies a horizontal predictor to a gray pixel row. /// - /// The gray pixel row. + /// The gray pixel rows. + /// The width. [MethodImpl(InliningOptions.ShortMethod)] - public static void ApplyHorizontalPrediction8Bit(Span rowSpan) + private static void ApplyHorizontalPrediction8Bit(Span rows, int width) { - for (int x = rowSpan.Length - 1; x >= 1; x--) + DebugGuard.Equals(rows.Length % width, 0); + int height = rows.Length / width; + for (int y = 0; y < height; y++) { - rowSpan[x] -= rowSpan[x - 1]; + Span rowSpan = rows.Slice(y * width, width); + for (int x = rowSpan.Length - 1; x >= 1; x--) + { + rowSpan[x] -= rowSpan[x - 1]; + } } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs new file mode 100644 index 0000000000..e47b65c991 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs @@ -0,0 +1,47 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression +{ + internal abstract class TiffBaseCompression : IDisposable + { + private bool isDisposed; + + protected TiffBaseCompression(MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor = TiffPredictor.None) + { + this.Allocator = allocator; + this.Width = width; + this.BitsPerPixel = bitsPerPixel; + this.Predictor = predictor; + + this.BytesPerRow = ((width * bitsPerPixel) + 7) / 8; + } + + public int Width { get; } + + public int BitsPerPixel { get; } + + public int BytesPerRow { get; } + + public TiffPredictor Predictor { get; } + + protected MemoryAllocator Allocator { get; } + + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + this.isDisposed = true; + this.Dispose(true); + } + + protected abstract void Dispose(bool disposing); + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs new file mode 100644 index 0000000000..71190c7c45 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs @@ -0,0 +1,25 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.IO; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression +{ + internal abstract class TiffBaseCompressor : TiffBaseCompression + { + protected TiffBaseCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor = TiffPredictor.None) + : base(allocator, width, bitsPerPixel, predictor) + => this.Output = output; + + public abstract TiffEncoderCompression Method { get; } + + public Stream Output { get; } + + public abstract void Initialize(int rowsPerStrip); + + public abstract void CompressStrip(Span rows, int height); + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffBaseCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseDecompresor.cs similarity index 65% rename from src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffBaseCompression.cs rename to src/ImageSharp/Formats/Tiff/Compression/TiffBaseDecompresor.cs index 7262b483b0..5f981911df 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffBaseCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseDecompresor.cs @@ -8,40 +8,18 @@ using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; -namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { /// - /// Base tiff decompressor class. + /// The base tiff decompressor class. /// - internal abstract class TiffBaseCompression + internal abstract class TiffBaseDecompresor : TiffBaseCompression { - protected TiffBaseCompression(MemoryAllocator allocator) => this.Allocator = allocator; - - protected TiffBaseCompression(MemoryAllocator allocator, TiffPhotometricInterpretation photometricInterpretation, int width) - : this(allocator) + protected TiffBaseDecompresor(MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor = TiffPredictor.None) + : base(allocator, width, bitsPerPixel, predictor) { - this.PhotometricInterpretation = photometricInterpretation; - this.Width = width; } - protected TiffBaseCompression(MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor) - : this(allocator) - { - this.Width = width; - this.BitsPerPixel = bitsPerPixel; - this.Predictor = predictor; - } - - protected MemoryAllocator Allocator { get; } - - protected TiffPhotometricInterpretation PhotometricInterpretation { get; } - - protected int Width { get; } - - protected int BitsPerPixel { get; } - - protected TiffPredictor Predictor { get; } - /// /// Decompresses image data into the supplied buffer. /// diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs new file mode 100644 index 0000000000..d964fbb142 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs @@ -0,0 +1,61 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Buffers; +using System.IO; +using SixLabors.ImageSharp.Compression.Zlib; +using SixLabors.ImageSharp.Formats.Experimental.Tiff; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; +using SixLabors.ImageSharp.Memory; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression +{ + internal static class TiffCompressorFactory + { + public static TiffBaseCompressor Create( + TiffEncoderCompression method, + Stream output, + MemoryAllocator allocator, + int width, + int bitsPerPixel, + DeflateCompressionLevel compressionLevel, + TiffPredictor predictor) + { + switch (method) + { + case TiffEncoderCompression.None: + DebugGuard.Equals(compressionLevel, default(DeflateCompressionLevel)); + DebugGuard.Equals(predictor, TiffPredictor.None); + + return new NoCompressor(output); + + case TiffEncoderCompression.PackBits: + DebugGuard.Equals(compressionLevel, default(DeflateCompressionLevel)); + DebugGuard.Equals(predictor, TiffPredictor.None); + return new PackBitsCompressor(output, allocator, width, bitsPerPixel); + + case TiffEncoderCompression.Deflate: + return new DeflateCompressor(output, allocator, width, bitsPerPixel, predictor, compressionLevel); + + case TiffEncoderCompression.Lzw: + DebugGuard.Equals(compressionLevel, default(DeflateCompressionLevel)); + return new LzwCompressor(output, allocator, width, bitsPerPixel, predictor); + + case TiffEncoderCompression.CcittGroup3Fax: + DebugGuard.Equals(compressionLevel, default(DeflateCompressionLevel)); + DebugGuard.Equals(predictor, TiffPredictor.None); + return new T4BitCompressor(output, allocator, width, bitsPerPixel, false); + + case TiffEncoderCompression.ModifiedHuffman: + DebugGuard.Equals(compressionLevel, default(DeflateCompressionLevel)); + DebugGuard.Equals(predictor, TiffPredictor.None); + return new T4BitCompressor(output, allocator, width, bitsPerPixel, true); + + default: + throw TiffThrowHelper.NotSupportedCompressor(nameof(method)); + } + } + } +} diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffDecoderCompressionType.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffDecoderCompressionType.cs similarity index 98% rename from src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffDecoderCompressionType.cs rename to src/ImageSharp/Formats/Tiff/Compression/TiffDecoderCompressionType.cs index 8ec11c3605..247d91e63e 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffDecoderCompressionType.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffDecoderCompressionType.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { /// /// Provides enumeration of the various TIFF compression types the decoder can handle. diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffDecompressorsFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs similarity index 56% rename from src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffDecompressorsFactory.cs rename to src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs index 2f78405bb7..e219f0b937 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/TiffDecompressorsFactory.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs @@ -1,15 +1,16 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Memory; -namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { internal static class TiffDecompressorsFactory { - public static TiffBaseCompression Create( - TiffDecoderCompressionType compressionType, + public static TiffBaseDecompresor Create( + TiffDecoderCompressionType method, MemoryAllocator allocator, TiffPhotometricInterpretation photometricInterpretation, int width, @@ -17,32 +18,38 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso TiffPredictor predictor, FaxCompressionOptions faxOptions) { - switch (compressionType) + switch (method) { case TiffDecoderCompressionType.None: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor"); - return new NoneTiffCompression(allocator); + DebugGuard.Equals(predictor, TiffPredictor.None); + DebugGuard.Equals(faxOptions, FaxCompressionOptions.None); + return new NoneTiffCompression(); case TiffDecoderCompressionType.PackBits: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor"); + DebugGuard.Equals(predictor, TiffPredictor.None); + DebugGuard.Equals(faxOptions, FaxCompressionOptions.None); return new PackBitsTiffCompression(allocator); case TiffDecoderCompressionType.Deflate: + DebugGuard.Equals(faxOptions, FaxCompressionOptions.None); return new DeflateTiffCompression(allocator, width, bitsPerPixel, predictor); case TiffDecoderCompressionType.Lzw: + DebugGuard.Equals(faxOptions, FaxCompressionOptions.None); return new LzwTiffCompression(allocator, width, bitsPerPixel, predictor); case TiffDecoderCompressionType.T4: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor"); + DebugGuard.Equals(predictor, TiffPredictor.None); + DebugGuard.Equals(faxOptions, FaxCompressionOptions.None); return new T4TiffCompression(allocator, faxOptions, photometricInterpretation, width); case TiffDecoderCompressionType.HuffmanRle: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "predictor"); + DebugGuard.Equals(predictor, TiffPredictor.None); + DebugGuard.Equals(faxOptions, FaxCompressionOptions.None); return new ModifiedHuffmanTiffCompression(allocator, photometricInterpretation, width); default: - throw TiffThrowHelper.NotSupportedCompression(nameof(compressionType)); + throw TiffThrowHelper.NotSupportedDecompressor(nameof(method)); } } } diff --git a/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs b/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs index d9ede337ad..8d0a15ffe6 100644 --- a/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs +++ b/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs @@ -37,5 +37,15 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// Gets the quantizer for creating a color palette image. /// IQuantizer Quantizer { get; } + + /// + /// Gets the pixel storage method. + /// + TiffEncoderPixelStorageMethod PixelStorageMethod { get; } + + /// + /// Gets the maximum size of strip (bytes). + /// + int MaxStripBytes { get; } } } diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 26c4d0038c..fe81d2edb3 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Threading; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -249,7 +249,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff stripBuffers[stripIndex] = this.memoryAllocator.AllocateManagedByteBuffer(uncompressedStripSize); } - TiffBaseCompression decompressor = TiffDecompressorsFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, frame.Width, bitsPerPixel, this.Predictor, this.FaxCompressionOptions); + using TiffBaseDecompresor decompressor = TiffDecompressorsFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, frame.Width, bitsPerPixel, this.Predictor, this.FaxCompressionOptions); RgbPlanarTiffColor colorDecoder = TiffColorDecoderFactory.CreatePlanar(this.ColorType, this.BitsPerSample, this.ColorMap); @@ -292,7 +292,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff Buffer2D pixels = frame.PixelBuffer; - TiffBaseCompression decompressor = TiffDecompressorsFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, frame.Width, bitsPerPixel, this.Predictor, this.FaxCompressionOptions); + using TiffBaseDecompresor decompressor = TiffDecompressorsFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, frame.Width, bitsPerPixel, this.Predictor, this.FaxCompressionOptions); TiffBaseColorDecoder colorDecoder = TiffColorDecoderFactory.Create(this.ColorType, this.BitsPerSample, this.ColorMap); diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs index 625af123df..2c632b36e4 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Metadata.Profiles.Exif; diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoder.cs b/src/ImageSharp/Formats/Tiff/TiffEncoder.cs index 0f333679e9..86091a5c48 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoder.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoder.cs @@ -32,6 +32,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// public IQuantizer Quantizer { get; set; } + /// + public TiffEncoderPixelStorageMethod PixelStorageMethod { get; set; } + + /// + public int MaxStripBytes { get; set; } + /// public void Encode(Image image, Stream stream) where TPixel : unmanaged, IPixel diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index 063da629fc..f378e2fe8e 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -8,6 +8,7 @@ using System.Threading; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Compression.Zlib; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers; using SixLabors.ImageSharp.Memory; @@ -30,6 +31,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff ? TiffConstants.ByteOrderLittleEndianShort : TiffConstants.ByteOrderBigEndianShort; + private const int DefaultStripSize = 8 * 1024; + /// /// Used for allocating memory during processing operations. /// @@ -43,7 +46,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// /// The color depth, in number of bits per pixel. /// - private TiffBitsPerPixel? bitsPerPixel; + private TiffBitsPerPixel bitsPerPixel; /// /// The quantizer for creating color palette image. @@ -55,6 +58,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// private readonly DeflateCompressionLevel compressionLevel; + private readonly TiffEncoderPixelStorageMethod storageMode; + + private readonly int maxStripBytes; + /// /// Initializes a new instance of the class. /// @@ -68,6 +75,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff this.quantizer = options.Quantizer ?? KnownQuantizers.Octree; this.UseHorizontalPredictor = options.UseHorizontalPredictor; this.compressionLevel = options.CompressionLevel; + this.storageMode = options.PixelStorageMethod; + this.maxStripBytes = options.MaxStripBytes; } /// @@ -105,26 +114,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff Guard.NotNull(stream, nameof(stream)); this.configuration = image.GetConfiguration(); - ImageMetadata metadata = image.Metadata; - TiffMetadata tiffMetadata = metadata.GetTiffMetadata(); - this.bitsPerPixel ??= tiffMetadata.BitsPerPixel; - if (this.Mode == TiffEncodingMode.Default) - { - // Preserve input bits per pixel, if no mode was specified. - if (this.bitsPerPixel == TiffBitsPerPixel.Pixel8) - { - this.Mode = TiffEncodingMode.Gray; - } - else if (this.bitsPerPixel == TiffBitsPerPixel.Pixel1) - { - this.Mode = TiffEncodingMode.BiColor; - } - else - { - this.Mode = TiffEncodingMode.Rgb; - } - } + this.SetMode(image); this.SetPhotometricInterpretation(); using (var writer = new TiffStreamWriter(stream)) @@ -132,7 +123,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff long firstIfdMarker = this.WriteHeader(writer); // TODO: multiframing is not support - long nextIfdMarker = this.WriteImage(writer, image, firstIfdMarker); + this.WriteImage(writer, image, firstIfdMarker); } } @@ -159,8 +150,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// The to write data to. /// The to encode from. /// The marker to write this IFD offset. - /// The marker to write the next IFD offset (if present). - public long WriteImage(TiffStreamWriter writer, Image image, long ifdOffset) + private void WriteImage(TiffStreamWriter writer, Image image, long ifdOffset) where TPixel : unmanaged, IPixel { var entriesCollector = new TiffEncoderEntriesCollector(); @@ -168,18 +158,43 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff // Write the image bytes to the steam. var imageDataStart = (uint)writer.Position; - TiffBaseColorWriter colorWriter = TiffColorWriterFactory.Create(this.Mode, writer, this.memoryAllocator, this.configuration, entriesCollector); + using TiffBaseCompressor compressor = TiffCompressorFactory.Create( + this.CompressionType, + writer.BaseStream, + this.memoryAllocator, + image.Width, + (int)this.bitsPerPixel, + this.compressionLevel, + this.UseHorizontalPredictor ? TiffPredictor.Horizontal : TiffPredictor.None); + + using TiffBaseColorWriter colorWriter = TiffColorWriterFactory.Create(this.Mode, image.Frames.RootFrame, this.quantizer, this.memoryAllocator, this.configuration, entriesCollector); + + int rowsPerStrip = this.CalcRowsPerStrip(image.Frames.RootFrame, colorWriter.BytesPerRow); - int imageDataBytes = colorWriter.Write(image, this.quantizer, this.CompressionType, this.compressionLevel, this.UseHorizontalPredictor); + colorWriter.Write(compressor, rowsPerStrip); - this.AddStripTags(image, entriesCollector, imageDataStart, imageDataBytes); entriesCollector.ProcessImageFormat(this); entriesCollector.ProcessGeneral(image); writer.WriteMarker(ifdOffset, (uint)writer.Position); long nextIfdMarker = this.WriteIfd(writer, entriesCollector.Entries); + } + + private int CalcRowsPerStrip(ImageFrame image, int bytesPerRow) + { + switch (this.storageMode) + { + default: + case TiffEncoderPixelStorageMethod.Auto: + case TiffEncoderPixelStorageMethod.MultiStrip: + int sz = this.maxStripBytes > 0 ? this.maxStripBytes : DefaultStripSize; + int height = sz / bytesPerRow; + + return height > 0 ? (height < image.Height ? height : image.Height) : 1; - return nextIfdMarker + imageDataBytes; + case TiffEncoderPixelStorageMethod.SingleStrip: + return image.Height; + } } /// @@ -188,7 +203,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// The to write data to. /// The IFD entries to write to the file. /// The marker to write the next IFD offset (if present). - public long WriteIfd(TiffStreamWriter writer, List entries) + private long WriteIfd(TiffStreamWriter writer, List entries) { if (entries.Count == 0) { @@ -239,37 +254,51 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff return nextIfdMarker; } - /// - /// Adds image format information to the specified IFD. - /// - /// The pixel format. - /// The to encode from. - /// The entries collector. - /// The start of the image data in the stream. - /// The image data in bytes to write. - public void AddStripTags(Image image, TiffEncoderEntriesCollector entriesCollector, uint imageDataStartOffset, int imageDataBytes) - where TPixel : unmanaged, IPixel + private void SetMode(Image image) { - var stripOffsets = new ExifLongArray(ExifTagValue.StripOffsets) + if (this.CompressionType == TiffEncoderCompression.CcittGroup3Fax || this.CompressionType == TiffEncoderCompression.ModifiedHuffman) { - // TODO: we only write one image strip for the start. - Value = new[] { imageDataStartOffset } - }; + this.Mode = TiffEncodingMode.BiColor; + this.bitsPerPixel = TiffBitsPerPixel.Pixel1; + return; + } - var rowsPerStrip = new ExifLong(ExifTagValue.RowsPerStrip) + if (this.Mode == TiffEncodingMode.Default) { - // All rows in one strip. - Value = (uint)image.Height - }; + // Preserve input bits per pixel, if no mode was specified. + TiffMetadata tiffMetadata = image.Metadata.GetTiffMetadata(); + switch (tiffMetadata.BitsPerPixel) + { + case TiffBitsPerPixel.Pixel1: + this.Mode = TiffEncodingMode.BiColor; + break; + case TiffBitsPerPixel.Pixel8: + // todo: can gray or palette + this.Mode = TiffEncodingMode.Gray; + break; + default: + this.Mode = TiffEncodingMode.Rgb; + break; + } + } - var stripByteCounts = new ExifLongArray(ExifTagValue.StripByteCounts) + switch (this.Mode) { - Value = new[] { (uint)imageDataBytes } - }; - - entriesCollector.Add(stripOffsets); - entriesCollector.Add(rowsPerStrip); - entriesCollector.Add(stripByteCounts); + case TiffEncodingMode.BiColor: + this.bitsPerPixel = TiffBitsPerPixel.Pixel1; + break; + case TiffEncodingMode.ColorPalette: + case TiffEncodingMode.Gray: + this.bitsPerPixel = TiffBitsPerPixel.Pixel8; + break; + case TiffEncodingMode.Rgb: + this.bitsPerPixel = TiffBitsPerPixel.Pixel24; + break; + default: + this.Mode = TiffEncodingMode.Rgb; + this.bitsPerPixel = TiffBitsPerPixel.Pixel24; + break; + } } private void SetPhotometricInterpretation() diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs new file mode 100644 index 0000000000..e1e12c08d0 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs @@ -0,0 +1,26 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff +{ + /// + /// The tiff encoder pixel storage method. + /// + public enum TiffEncoderPixelStorageMethod + { + /// + /// The auto mode. + /// + Auto, + + /// + /// The single strip mode. + /// + SingleStrip, + + /// + /// The multi strip mode. + /// + MultiStrip, + } +} diff --git a/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs b/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs index d853836b55..db91fcbcb4 100644 --- a/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs +++ b/src/ImageSharp/Formats/Tiff/TiffThrowHelper.cs @@ -19,7 +19,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff public static void ThrowImageFormatException(string errorMessage) => throw new ImageFormatException(errorMessage); [MethodImpl(InliningOptions.ColdPath)] - public static Exception NotSupportedCompression(string compressionType) => throw new NotSupportedException($"Not supported compression: {compressionType}"); + public static Exception NotSupportedDecompressor(string compressionType) => throw new NotSupportedException($"Not supported decoder compression method: {compressionType}"); + + [MethodImpl(InliningOptions.ColdPath)] + public static Exception NotSupportedCompressor(string compressionType) => throw new NotSupportedException($"Not supported encoder compression method: {compressionType}"); [MethodImpl(InliningOptions.ColdPath)] public static Exception InvalidColorType(string colorType) => throw new NotSupportedException($"Invalid color type: {colorType}"); diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs index 23b4e329df..191c051d69 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs @@ -2,35 +2,33 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.IO; -using SixLabors.ImageSharp.Compression.Zlib; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { - /// - /// Utility class for writing TIFF data to a . - /// - internal abstract class TiffBaseColorWriter + internal abstract class TiffBaseColorWriter : IDisposable + where TPixel : unmanaged, IPixel { - /// - /// Initializes a new instance of the class. - /// - /// The output stream. - /// The memory allocator. - /// The configuration. - /// The entries collector. - protected TiffBaseColorWriter(TiffStreamWriter output, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + private bool isDisposed; + + protected TiffBaseColorWriter(ImageFrame image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) { - this.Output = output; + this.Image = image; this.MemoryAllocator = memoryAllocator; this.Configuration = configuration; this.EntriesCollector = entriesCollector; + + this.BytesPerRow = ((image.Width * this.BitsPerPixel) + 7) / 8; } - protected TiffStreamWriter Output { get; } + public abstract int BitsPerPixel { get; } + + public int BytesPerRow { get; } + + protected ImageFrame Image { get; } protected MemoryAllocator MemoryAllocator { get; } @@ -38,7 +36,74 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers protected TiffEncoderEntriesCollector EntriesCollector { get; } - public abstract int Write(Image image, IQuantizer quantizer, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) - where TPixel : unmanaged, IPixel; + public virtual void Write(TiffBaseCompressor compressor, int rowsPerStrip) + { + DebugGuard.Equals(this.BytesPerRow, compressor.BytesPerRow); + int stripsCount = (this.Image.Height + rowsPerStrip - 1) / rowsPerStrip; + + uint[] stripOffsets = new uint[stripsCount]; + uint[] stripByteCounts = new uint[stripsCount]; + + int stripIndex = 0; + compressor.Initialize(rowsPerStrip); + for (int y = 0; y < this.Image.Height; y += rowsPerStrip) + { + long offset = compressor.Output.Position; + + int height = Math.Min(rowsPerStrip, this.Image.Height - y); + this.EncodeStrip(y, height, compressor); + + long endOffset = compressor.Output.Position; + stripOffsets[stripIndex] = (uint)offset; + stripByteCounts[stripIndex] = (uint)(endOffset - offset); + stripIndex++; + } + + DebugGuard.Equals(stripIndex, stripsCount); + this.AddStripTags(rowsPerStrip, stripOffsets, stripByteCounts); + } + + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + this.isDisposed = true; + this.Dispose(true); + } + + protected static Span GetStripPixels(Buffer2D buffer2D, int y, int height) + where T : struct + => buffer2D.GetSingleSpan().Slice(y * buffer2D.Width, height * buffer2D.Width); + + protected abstract void EncodeStrip(int y, int height, TiffBaseCompressor compressor); + + /// + /// Adds image format information to the specified IFD. + /// + /// The rows per strip. + /// The strip offsets. + /// The strip byte counts. + private void AddStripTags(int rowsPerStrip, uint[] stripOffsets, uint[] stripByteCounts) + { + this.EntriesCollector.Add(new ExifLong(ExifTagValue.RowsPerStrip) + { + Value = (uint)rowsPerStrip + }); + + this.EntriesCollector.Add(new ExifLongArray(ExifTagValue.StripOffsets) + { + Value = stripOffsets + }); + + this.EntriesCollector.Add(new ExifLongArray(ExifTagValue.StripByteCounts) + { + Value = stripByteCounts + }); + } + + protected abstract void Dispose(bool disposing); } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs index 24c2f08daf..76d5cbaa04 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs @@ -3,208 +3,97 @@ using System; using System.Buffers; -using System.IO; - -using SixLabors.ImageSharp.Compression.Zlib; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Dithering; -using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { - /// - /// Utility class for writing TIFF data to a . - /// - internal class TiffBiColorWriter : TiffBaseColorWriter + internal class TiffBiColorWriter : TiffBaseColorWriter + where TPixel : unmanaged, IPixel { - public TiffBiColorWriter(TiffStreamWriter output, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) - : base(output, memoryAllocator, configuration, entriesCollector) - { - } + private readonly Image imageBlackWhite; - /// - /// Writes the image data as 1 bit black and white to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// The quantizer. - /// The compression to use. - /// The compression level for deflate compression. - /// if set to true [use horizontal predictor]. - /// - /// The number of bytes written. - /// - public override int Write(Image image, IQuantizer quantizer, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) - { - int padding = image.Width % 8 == 0 ? 0 : 1; - int bytesPerRow = (image.Width / 8) + padding; - using IMemoryOwner pixelRowAsGray = this.MemoryAllocator.Allocate(image.Width); - using IManagedByteBuffer row = this.MemoryAllocator.AllocateManagedByteBuffer(bytesPerRow, AllocationOptions.Clean); - Span outputRow = row.GetSpan(); - Span pixelRowAsGraySpan = pixelRowAsGray.GetSpan(); + private IMemoryOwner pixelsAsGray; + + private IMemoryOwner bitStrip; + public TiffBiColorWriter(ImageFrame image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + : base(image, memoryAllocator, configuration, entriesCollector) + { // Convert image to black and white. // TODO: Should we allow to skip this by the user, if its known to be black and white already? - using Image imageBlackWhite = image.Clone(); - imageBlackWhite.Mutate(img => img.BinaryDither(default(ErrorDither))); - - if (compression == TiffEncoderCompression.Deflate) - { - return this.WriteBiColorDeflate(imageBlackWhite, pixelRowAsGraySpan, outputRow, compressionLevel); - } + this.imageBlackWhite = new Image(configuration, new ImageMetadata(), new[] { image.Clone() }); + this.imageBlackWhite.Mutate(img => img.BinaryDither(default(ErrorDither))); + } - if (compression == TiffEncoderCompression.PackBits) - { - return this.WriteBiColorPackBits(imageBlackWhite, pixelRowAsGraySpan, outputRow); - } + public override int BitsPerPixel => 1; - if (compression == TiffEncoderCompression.CcittGroup3Fax) + protected override void EncodeStrip(int y, int height, TiffBaseCompressor compressor) + { + if (this.pixelsAsGray == null) { - var bitWriter = new T4BitWriter(this.MemoryAllocator, this.Configuration); - return bitWriter.CompressImage(imageBlackWhite, pixelRowAsGraySpan, this.Output.BaseStream); + this.pixelsAsGray = this.MemoryAllocator.Allocate(height * this.Image.Width); } - if (compression == TiffEncoderCompression.ModifiedHuffman) - { - var bitWriter = new T4BitWriter(this.MemoryAllocator, this.Configuration, useModifiedHuffman: true); - return bitWriter.CompressImage(imageBlackWhite, pixelRowAsGraySpan, this.Output.BaseStream); - } + this.pixelsAsGray.Clear(); - // Write image uncompressed. - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - int bitIndex = 0; - int byteIndex = 0; - Span pixelRow = imageBlackWhite.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8(this.Configuration, pixelRow, pixelRowAsGraySpan); - for (int x = 0; x < pixelRow.Length; x++) - { - int shift = 7 - bitIndex; - if (pixelRowAsGraySpan[x].PackedValue == 255) - { - outputRow[byteIndex] |= (byte)(1 << shift); - } + Span pixelAsGraySpan = this.pixelsAsGray.Slice(0, height * this.Image.Width); - bitIndex++; - if (bitIndex == 8) - { - byteIndex++; - bitIndex = 0; - } - } + Span pixels = GetStripPixels(this.imageBlackWhite.GetRootFramePixelBuffer(), y, height); - this.Output.Write(outputRow); - bytesWritten += outputRow.Length; + PixelOperations.Instance.ToL8Bytes(this.Configuration, pixels, pixelAsGraySpan, pixels.Length); - outputRow.Clear(); + if (compressor.Method == TiffEncoderCompression.CcittGroup3Fax || compressor.Method == TiffEncoderCompression.ModifiedHuffman) + { + compressor.CompressStrip(pixelAsGraySpan, height); } - - return bytesWritten; - } - - /// - /// Writes the image data as 1 bit black and white with deflate compression to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// A span for converting a pixel row to gray. - /// A span which will be used to store the output pixels. - /// The compression level for deflate compression. - /// The number of bytes written. - public int WriteBiColorDeflate(Image image, Span pixelRowAsGraySpan, Span outputRow, DeflateCompressionLevel compressionLevel) - where TPixel : unmanaged, IPixel - { - using var memoryStream = new MemoryStream(); - using var deflateStream = new ZlibDeflateStream(this.MemoryAllocator, memoryStream, compressionLevel); - - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) + else { - int bitIndex = 0; - int byteIndex = 0; - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8(this.Configuration, pixelRow, pixelRowAsGraySpan); - for (int x = 0; x < pixelRow.Length; x++) + if (this.bitStrip == null) { - int shift = 7 - bitIndex; - if (pixelRowAsGraySpan[x].PackedValue == 255) - { - outputRow[byteIndex] |= (byte)(1 << shift); - } - - bitIndex++; - if (bitIndex == 8) - { - byteIndex++; - bitIndex = 0; - } + int bytesPerRow = this.BytesPerRow * height; + this.bitStrip = this.MemoryAllocator.AllocateManagedByteBuffer(bytesPerRow); } - deflateStream.Write(outputRow); - - outputRow.Clear(); - } + this.bitStrip.Clear(); + Span rows = this.bitStrip.GetSpan(); - deflateStream.Flush(); - byte[] buffer = memoryStream.ToArray(); - this.Output.Write(buffer); - bytesWritten += buffer.Length; - - return bytesWritten; - } - - /// - /// Writes the image data as 1 bit black and white with pack bits compression to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// A span for converting a pixel row to gray. - /// A span which will be used to store the output pixels. - /// The number of bytes written. - public int WriteBiColorPackBits(Image image, Span pixelRowAsGraySpan, Span outputRow) - 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) + 2; - int compressedRowBytes = (image.Width / 8) + additionalBytes; - using IManagedByteBuffer compressedRow = this.MemoryAllocator.AllocateManagedByteBuffer(compressedRowBytes, AllocationOptions.Clean); - Span compressedRowSpan = compressedRow.GetSpan(); - - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - int bitIndex = 0; - int byteIndex = 0; - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8(this.Configuration, pixelRow, pixelRowAsGraySpan); - for (int x = 0; x < pixelRow.Length; x++) + int xx = 0; + for (int s = 0; s < height; s++) { - int shift = 7 - bitIndex; - if (pixelRowAsGraySpan[x].PackedValue == 255) + int bitIndex = 0; + int byteIndex = 0; + Span outputRow = rows.Slice(s * this.BytesPerRow); + for (int x = 0; x < this.Image.Width; x++) { - outputRow[byteIndex] |= (byte)(1 << shift); - } - - bitIndex++; - if (bitIndex == 8) - { - byteIndex++; - bitIndex = 0; + int shift = 7 - bitIndex; + if (pixelAsGraySpan[xx++] == 255) + { + outputRow[byteIndex] |= (byte)(1 << shift); + } + + bitIndex++; + if (bitIndex == 8) + { + byteIndex++; + bitIndex = 0; + } } } - var size = PackBitsWriter.PackBits(outputRow, compressedRowSpan); - this.Output.Write(compressedRowSpan.Slice(0, size)); - bytesWritten += size; - - outputRow.Clear(); + compressor.CompressStrip(rows, height); } + } - return bytesWritten; + protected override void Dispose(bool disposing) + { + this.imageBlackWhite?.Dispose(); + this.pixelsAsGray?.Dispose(); + this.bitStrip?.Dispose(); } } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffColorWriterFactory.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffColorWriterFactory.cs index 6c378f28dc..10bb9b96ed 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffColorWriterFactory.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffColorWriterFactory.cs @@ -2,23 +2,32 @@ // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { internal static class TiffColorWriterFactory { - public static TiffBaseColorWriter Create(TiffEncodingMode mode, TiffStreamWriter output, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + public static TiffBaseColorWriter Create( + TiffEncodingMode mode, + ImageFrame image, + IQuantizer quantizer, + MemoryAllocator memoryAllocator, + Configuration configuration, + TiffEncoderEntriesCollector entriesCollector) + where TPixel : unmanaged, IPixel { switch (mode) { case TiffEncodingMode.ColorPalette: - return new TiffPaletteWriter(output, memoryAllocator, configuration, entriesCollector); + return new TiffPaletteWriter(image, quantizer, memoryAllocator, configuration, entriesCollector); case TiffEncodingMode.Gray: - return new TiffGrayWriter(output, memoryAllocator, configuration, entriesCollector); + return new TiffGrayWriter(image, memoryAllocator, configuration, entriesCollector); case TiffEncodingMode.BiColor: - return new TiffBiColorWriter(output, memoryAllocator, configuration, entriesCollector); + return new TiffBiColorWriter(image, memoryAllocator, configuration, entriesCollector); default: - return new TiffRgbWriter(output, memoryAllocator, configuration, entriesCollector); + return new TiffRgbWriter(image, memoryAllocator, configuration, entriesCollector); } } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs new file mode 100644 index 0000000000..1b2bd4ab68 --- /dev/null +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs @@ -0,0 +1,45 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers +{ + /// + /// The base class for composite color types: 8-bit gray, 24-bit RGB (4-bit gray, 16-bit (565/555) RGB, 32-bit RGB, CMYK, YCbCr). + /// + internal abstract class TiffCompositeColorWriter : TiffBaseColorWriter + where TPixel : unmanaged, IPixel + { + private IManagedByteBuffer rowBuffer; + + public TiffCompositeColorWriter(ImageFrame image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + : base(image, memoryAllocator, configuration, entriesCollector) + { + } + + protected override void EncodeStrip(int y, int height, TiffBaseCompressor compressor) + { + if (this.rowBuffer == null) + { + this.rowBuffer = this.MemoryAllocator.AllocateManagedByteBuffer(this.BytesPerRow * height); + } + + this.rowBuffer.Clear(); + + Span rowSpan = this.rowBuffer.GetSpan().Slice(0, this.BytesPerRow * height); + + Span pixels = GetStripPixels(this.Image.PixelBuffer, y, height); + + this.EncodePixels(pixels, rowSpan); + compressor.CompressStrip(rowSpan, height); + } + + protected abstract void EncodePixels(Span pixels, Span buffer); + + protected override void Dispose(bool disposing) => this.rowBuffer?.Dispose(); + } +} diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs index 7161254f83..f2b06d8720 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs @@ -2,172 +2,22 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Buffers; using System.IO; - -using SixLabors.ImageSharp.Compression.Zlib; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; -using SixLabors.ImageSharp.Formats.Tiff.Compression; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { - /// - /// Utility class for writing TIFF data to a . - /// - internal class TiffGrayWriter : TiffBaseColorWriter + internal class TiffGrayWriter : TiffCompositeColorWriter + where TPixel : unmanaged, IPixel { - public TiffGrayWriter(TiffStreamWriter output, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) - : base(output, memoryAllocator, configuration, entriesCollector) - { - } - - /// - /// Writes the image data as 8 bit gray to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// The quantizer. - /// The compression to use. - /// The compression level for deflate compression. - /// Indicates if horizontal prediction should be used. Should only be used with deflate or lzw compression. - /// - /// The number of bytes written. - /// - public override int Write(Image image, IQuantizer quantizer, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) + public TiffGrayWriter(ImageFrame image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + : base(image, memoryAllocator, configuration, entriesCollector) { - using IManagedByteBuffer row = this.MemoryAllocator.AllocateManagedByteBuffer(image.Width); - Span rowSpan = row.GetSpan(); - - if (compression == TiffEncoderCompression.Deflate) - { - return this.WriteGrayDeflateCompressed(image, rowSpan, compressionLevel, useHorizontalPredictor); - } - - if (compression == TiffEncoderCompression.Lzw) - { - return this.WriteGrayLzwCompressed(image, rowSpan, useHorizontalPredictor); - } - - if (compression == TiffEncoderCompression.PackBits) - { - return this.WriteGrayPackBitsCompressed(image, rowSpan); - } - - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - this.Output.Write(rowSpan); - bytesWritten += rowSpan.Length; - } - - return bytesWritten; } - /// - /// Writes the image data as 8 bit gray with deflate compression to the stream. - /// - /// The image to write to the stream. - /// A span of a row of pixels. - /// The compression level for deflate compression. - /// Indicates if horizontal prediction should be used. - /// The number of bytes written. - private int WriteGrayDeflateCompressed(Image image, Span rowSpan, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) - where TPixel : unmanaged, IPixel - { - int bytesWritten = 0; - using var memoryStream = new MemoryStream(); - using var deflateStream = new ZlibDeflateStream(this.MemoryAllocator, memoryStream, compressionLevel); - - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - - if (useHorizontalPredictor) - { - HorizontalPredictor.ApplyHorizontalPrediction8Bit(rowSpan); - } - - deflateStream.Write(rowSpan); - } - - deflateStream.Flush(); + public override int BitsPerPixel => 8; - byte[] buffer = memoryStream.ToArray(); - this.Output.Write(buffer); - bytesWritten += buffer.Length; - return bytesWritten; - } - - /// - /// Writes the image data as 8 bit gray with lzw compression to the stream. - /// - /// The image to write to the stream. - /// A span of a row of pixels. - /// Indicates if horizontal prediction should be used. - /// The number of bytes written. - private int WriteGrayLzwCompressed(Image image, Span rowSpan, bool useHorizontalPredictor) - where TPixel : unmanaged, IPixel - { - int bytesWritten = 0; - using var memoryStream = new MemoryStream(); - - IMemoryOwner pixelData = this.MemoryAllocator.Allocate(image.Width * image.Height); - Span pixels = pixelData.GetSpan(); - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - if (useHorizontalPredictor) - { - HorizontalPredictor.ApplyHorizontalPrediction8Bit(rowSpan); - } - - rowSpan.CopyTo(pixels.Slice(y * image.Width)); - } - - using var lzwEncoder = new TiffLzwEncoder(this.MemoryAllocator, pixelData); - lzwEncoder.Encode(memoryStream); - - byte[] buffer = memoryStream.ToArray(); - this.Output.Write(buffer); - bytesWritten += buffer.Length; - return bytesWritten; - } - - /// - /// Writes the image data as 8 bit gray to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// A span of a row of pixels. - /// The number of bytes written. - private int WriteGrayPackBitsCompressed(Image image, Span rowSpan) - 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 bytes. - int additionalBytes = (image.Width / 127) + 1; - using IManagedByteBuffer compressedRow = this.MemoryAllocator.AllocateManagedByteBuffer(image.Width + additionalBytes, AllocationOptions.Clean); - Span compressedRowSpan = compressedRow.GetSpan(); - - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToL8Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - int size = PackBitsWriter.PackBits(rowSpan, compressedRowSpan); - this.Output.Write(compressedRow.Slice(0, size)); - bytesWritten += size; - compressedRowSpan.Clear(); - } - - return bytesWritten; - } + protected override void EncodePixels(Span pixels, Span buffer) => PixelOperations.Instance.ToL8Bytes(this.Configuration, pixels, buffer, pixels.Length); } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs index 55a2efc9a9..2866637062 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs @@ -3,13 +3,9 @@ using System; using System.Buffers; -using System.IO; using System.Runtime.InteropServices; - -using SixLabors.ImageSharp.Compression.Zlib; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; -using SixLabors.ImageSharp.Formats.Tiff.Compression; +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; @@ -17,44 +13,37 @@ using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { - /// - /// Utility class for writing TIFF data to a . - /// - internal class TiffPaletteWriter : TiffBaseColorWriter + internal class TiffPaletteWriter : TiffBaseColorWriter + where TPixel : unmanaged, IPixel { - /// - /// Initializes a new instance of the class. - /// - /// The output stream. - /// The memory allocator. - /// The configuration. - /// The entries collector. - public TiffPaletteWriter(TiffStreamWriter output, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) - : base(output, memoryAllocator, configuration, entriesCollector) + private const int ColorsPerChannel = 256; + private const int ColorPaletteSize = ColorsPerChannel * 3; + private const int ColorPaletteBytes = ColorPaletteSize * 2; + + private readonly IndexedImageFrame quantized; + + public TiffPaletteWriter(ImageFrame image, IQuantizer quantizer, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + : base(image, memoryAllocator, configuration, entriesCollector) { + using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.Configuration); + this.quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image, image.Bounds()); + + this.AddTag(this.quantized); } - /// - /// Writes the image data as indices into a color map to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// The quantizer to use. - /// The compression to use. - /// The compression level for deflate compression. - /// Indicates if horizontal prediction should be used. Should only be used in combination with deflate or LZW compression. - /// - /// The number of bytes written. - /// - public override int Write(Image image, IQuantizer quantizer, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) + public override int BitsPerPixel => 8; + + protected override void EncodeStrip(int y, int height, TiffBaseCompressor compressor) { - int colorsPerChannel = 256; - int colorPaletteSize = colorsPerChannel * 3; - int colorPaletteBytes = colorPaletteSize * 2; - using IManagedByteBuffer row = this.MemoryAllocator.AllocateManagedByteBuffer(image.Width); - using IQuantizer frameQuantizer = quantizer.CreatePixelSpecificQuantizer(this.Configuration); - using IndexedImageFrame quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image.Frames.RootFrame, image.Bounds()); - using IMemoryOwner colorPaletteBuffer = this.MemoryAllocator.AllocateManagedByteBuffer(colorPaletteBytes); + Span pixels = GetStripPixels(((IPixelSource)this.quantized).PixelBuffer, y, height); + compressor.CompressStrip(pixels, height); + } + + protected override void Dispose(bool disposing) => this.quantized?.Dispose(); + + private void AddTag(IndexedImageFrame quantized) + { + using IMemoryOwner colorPaletteBuffer = this.MemoryAllocator.AllocateManagedByteBuffer(ColorPaletteBytes); Span colorPalette = colorPaletteBuffer.GetSpan(); ReadOnlySpan quantizedColors = quantized.Palette.Span; @@ -65,11 +54,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers PixelOperations.Instance.ToRgb48(this.Configuration, quantizedColors, quantizedColorRgb48); // It can happen that the quantized colors are less than the expected 256 per channel. - var diffToMaxColors = colorsPerChannel - quantizedColors.Length; + var diffToMaxColors = ColorsPerChannel - quantizedColors.Length; // In a TIFF ColorMap, all the Red values come first, followed by the Green values, // then the Blue values. Convert the quantized palette to this format. - var palette = new ushort[colorPaletteSize]; + var palette = new ushort[ColorPaletteSize]; int paletteIdx = 0; for (int i = 0; i < quantizedColors.Length; i++) { @@ -96,147 +85,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers }; this.EntriesCollector.Add(colorMap); - - if (compression == TiffEncoderCompression.Deflate) - { - return this.WriteDeflateCompressedPalettedRgb(image, quantized, compressionLevel, useHorizontalPredictor); - } - - if (compression == TiffEncoderCompression.Lzw) - { - return this.WriteLzwCompressedPalettedRgb(image, quantized, useHorizontalPredictor); - } - - if (compression == TiffEncoderCompression.PackBits) - { - return this.WritePackBitsCompressedPalettedRgb(image, quantized); - } - - // No compression. - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - ReadOnlySpan pixelSpan = quantized.GetPixelRowSpan(y); - this.Output.Write(pixelSpan); - bytesWritten += pixelSpan.Length; - } - - return bytesWritten; - } - - /// - /// Writes the image data as indices into a color map compressed with deflate compression to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// The quantized frame. - /// The compression level for deflate compression. - /// Indicates if horizontal prediction should be used. - /// The number of bytes written. - private int WriteDeflateCompressedPalettedRgb(Image image, IndexedImageFrame quantized, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) - where TPixel : unmanaged, IPixel - { - using IManagedByteBuffer tmpBuffer = this.MemoryAllocator.AllocateManagedByteBuffer(image.Width); - using var memoryStream = new MemoryStream(); - using var deflateStream = new ZlibDeflateStream(this.MemoryAllocator, memoryStream, compressionLevel); - - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - ReadOnlySpan pixelRow = quantized.GetPixelRowSpan(y); - if (useHorizontalPredictor) - { - // We need a writable Span here. - Span pixelRowCopy = tmpBuffer.GetSpan(); - pixelRow.CopyTo(pixelRowCopy); - HorizontalPredictor.ApplyHorizontalPrediction8Bit(pixelRowCopy); - deflateStream.Write(pixelRowCopy); - } - else - { - deflateStream.Write(pixelRow); - } - } - - deflateStream.Flush(); - byte[] buffer = memoryStream.ToArray(); - this.Output.Write(buffer); - bytesWritten += buffer.Length; - - return bytesWritten; - } - - /// - /// Writes the image data as indices into a color map compressed with lzw compression to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// The quantized frame. - /// Indicates if horizontal prediction should be used. - /// The number of bytes written. - private int WriteLzwCompressedPalettedRgb(Image image, IndexedImageFrame quantized, bool useHorizontalPredictor) - where TPixel : unmanaged, IPixel - { - IMemoryOwner pixelData = this.MemoryAllocator.Allocate(image.Width * image.Height); - using IManagedByteBuffer tmpBuffer = this.MemoryAllocator.AllocateManagedByteBuffer(image.Width); - using var memoryStream = new MemoryStream(); - - int bytesWritten = 0; - Span pixels = pixelData.GetSpan(); - for (int y = 0; y < image.Height; y++) - { - ReadOnlySpan indexedPixelRow = quantized.GetPixelRowSpan(y); - - if (useHorizontalPredictor) - { - // We need a writable Span here. - Span pixelRowCopy = tmpBuffer.GetSpan(); - indexedPixelRow.CopyTo(pixelRowCopy); - HorizontalPredictor.ApplyHorizontalPrediction8Bit(pixelRowCopy); - pixelRowCopy.CopyTo(pixels.Slice(y * image.Width)); - } - else - { - indexedPixelRow.CopyTo(pixels.Slice(y * image.Width)); - } - } - - using var lzwEncoder = new TiffLzwEncoder(this.MemoryAllocator, pixelData); - lzwEncoder.Encode(memoryStream); - - byte[] buffer = memoryStream.ToArray(); - this.Output.Write(buffer); - bytesWritten += buffer.Length; - - return bytesWritten; - } - - /// - /// Writes the image data as indices into a color map compressed with deflate compression to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// The quantized frame. - /// The number of bytes written. - private int WritePackBitsCompressedPalettedRgb(Image image, IndexedImageFrame quantized) - 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 bytes. - int additionalBytes = (image.Width * 3 / 127) + 1; - using IManagedByteBuffer compressedRow = this.MemoryAllocator.AllocateManagedByteBuffer((image.Width * 3) + additionalBytes, AllocationOptions.Clean); - Span compressedRowSpan = compressedRow.GetSpan(); - - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - ReadOnlySpan pixelSpan = quantized.GetPixelRowSpan(y); - - int size = PackBitsWriter.PackBits(pixelSpan, compressedRowSpan); - this.Output.Write(compressedRowSpan.Slice(0, size)); - bytesWritten += size; - } - - return bytesWritten; } } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs index 26f2d82d86..174a677279 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs @@ -2,175 +2,22 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Buffers; using System.IO; - -using SixLabors.ImageSharp.Compression.Zlib; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; -using SixLabors.ImageSharp.Formats.Tiff.Compression; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing.Processors.Quantization; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { - /// - /// Utility class for writing TIFF data to a . - /// - internal class TiffRgbWriter : TiffBaseColorWriter + internal class TiffRgbWriter : TiffCompositeColorWriter + where TPixel : unmanaged, IPixel { - public TiffRgbWriter(TiffStreamWriter output, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) - : base(output, memoryAllocator, configuration, entriesCollector) - { - } - - /// - /// Writes the image data as RGB to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// The quantizer. - /// The compression to use. - /// The compression level for deflate compression. - /// Indicates if horizontal prediction should be used. Should only be used with deflate compression. - /// - /// The number of bytes written. - /// - public override int Write(Image image, IQuantizer quantizer, TiffEncoderCompression compression, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) + public TiffRgbWriter(ImageFrame image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + : base(image, memoryAllocator, configuration, entriesCollector) { - using IManagedByteBuffer row = this.MemoryAllocator.AllocateManagedByteBuffer(image.Width * 3); - Span rowSpan = row.GetSpan(); - if (compression == TiffEncoderCompression.Deflate) - { - return this.WriteDeflateCompressedRgb(image, rowSpan, compressionLevel, useHorizontalPredictor); - } - - if (compression == TiffEncoderCompression.Lzw) - { - return this.WriteLzwCompressedRgb(image, rowSpan, useHorizontalPredictor); - } - - if (compression == TiffEncoderCompression.PackBits) - { - return this.WriteRgbPackBitsCompressed(image, rowSpan); - } - - // No compression. - int bytesWritten = 0; - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgb24Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - this.Output.Write(rowSpan); - bytesWritten += rowSpan.Length; - } - - return bytesWritten; } - /// - /// Writes the image data as RGB compressed with zlib to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// A Span for a pixel row. - /// The compression level for deflate compression. - /// Indicates if horizontal prediction should be used. Should only be used with deflate compression. - /// The number of bytes written. - private int WriteDeflateCompressedRgb(Image image, Span rowSpan, DeflateCompressionLevel compressionLevel, bool useHorizontalPredictor) - where TPixel : unmanaged, IPixel - { - int bytesWritten = 0; - using var memoryStream = new MemoryStream(); - using var deflateStream = new ZlibDeflateStream(this.MemoryAllocator, memoryStream, compressionLevel); - - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgb24Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - - if (useHorizontalPredictor) - { - HorizontalPredictor.ApplyHorizontalPrediction24Bit(rowSpan); - } + public override int BitsPerPixel => 24; - deflateStream.Write(rowSpan); - } - - deflateStream.Flush(); - - byte[] buffer = memoryStream.ToArray(); - this.Output.Write(buffer); - bytesWritten += buffer.Length; - return bytesWritten; - } - - /// - /// Writes the image data as RGB compressed with lzw to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// A Span for a pixel row. - /// Indicates if horizontal prediction should be used. - /// The number of bytes written. - private int WriteLzwCompressedRgb(Image image, Span rowSpan, bool useHorizontalPredictor) - where TPixel : unmanaged, IPixel - { - int bytesWritten = 0; - using var memoryStream = new MemoryStream(); - - IMemoryOwner pixelData = this.MemoryAllocator.Allocate(image.Width * image.Height * 3); - Span pixels = pixelData.GetSpan(); - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgb24Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - - if (useHorizontalPredictor) - { - HorizontalPredictor.ApplyHorizontalPrediction24Bit(rowSpan); - } - - rowSpan.CopyTo(pixels.Slice(y * image.Width * 3)); - } - - using var lzwEncoder = new TiffLzwEncoder(this.MemoryAllocator, pixelData); - lzwEncoder.Encode(memoryStream); - - byte[] buffer = memoryStream.ToArray(); - this.Output.Write(buffer); - bytesWritten += buffer.Length; - return bytesWritten; - } - - /// - /// Writes the image data as RGB with packed bits compression to the stream. - /// - /// The pixel data. - /// The image to write to the stream. - /// A Span for a pixel row. - /// The number of bytes written. - private int WriteRgbPackBitsCompressed(Image image, Span rowSpan) - 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 bytes. - int additionalBytes = (image.Width * 3 / 127) + 1; - using IManagedByteBuffer compressedRow = this.MemoryAllocator.AllocateManagedByteBuffer((image.Width * 3) + additionalBytes, AllocationOptions.Clean); - Span compressedRowSpan = compressedRow.GetSpan(); - int bytesWritten = 0; - - for (int y = 0; y < image.Height; y++) - { - Span pixelRow = image.GetPixelRowSpan(y); - PixelOperations.Instance.ToRgb24Bytes(this.Configuration, pixelRow, rowSpan, pixelRow.Length); - int size = PackBitsWriter.PackBits(rowSpan, compressedRowSpan); - this.Output.Write(compressedRow.Slice(0, size)); - bytesWritten += size; - compressedRowSpan.Clear(); - } - - return bytesWritten; - } + protected override void EncodePixels(Span pixels, Span buffer) => PixelOperations.Instance.ToRgb24Bytes(this.Configuration, pixels, buffer, pixels.Length); } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs index 5b971962a4..b7749e0f6f 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs index f1de0c9715..cdf0f68f64 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs @@ -26,7 +26,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression { var buffer = new byte[data.Length]; - new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, 0, (uint)stream.Length, buffer); + using var decompressor = new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None); + + decompressor.Decompress(stream, 0, (uint)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 94835962da..fcce507d8d 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs @@ -1,13 +1,11 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System; using System.IO; +using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompressors; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; using SixLabors.ImageSharp.IO; -using SixLabors.ImageSharp.Memory; using Xunit; namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression @@ -39,7 +37,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression using BufferedReadStream stream = CreateCompressedStream(data); var buffer = new byte[data.Length]; - new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None).Decompress(stream, 0, (uint)stream.Length, buffer); + using var decompressor = new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None); + decompressor.Decompress(stream, 0, (uint)stream.Length, buffer); Assert.Equal(data, buffer); } @@ -47,12 +46,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression private static BufferedReadStream CreateCompressedStream(byte[] inputData) { Stream compressedStream = new MemoryStream(); - using System.Buffers.IMemoryOwner data = Configuration.Default.MemoryAllocator.Allocate(inputData.Length); - inputData.AsSpan().CopyTo(data.GetSpan()); - using (var encoder = new TiffLzwEncoder(Configuration.Default.MemoryAllocator, data)) + using (var encoder = new TiffLzwEncoder(Configuration.Default.MemoryAllocator)) { - encoder.Encode(compressedStream); + encoder.Encode(inputData, compressedStream); } compressedStream.Seek(0, SeekOrigin.Begin); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs index b366694578..466027bee4 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression var stream = new BufferedReadStream(Configuration.Default, new MemoryStream(inputData)); var buffer = new byte[expectedResult.Length]; - new NoneTiffCompression(null).Decompress(stream, 0, byteCount, buffer); + new NoneTiffCompression().Decompress(stream, 0, byteCount, buffer); Assert.Equal(expectedResult, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs index 6fcaa24d26..a211bde535 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs @@ -29,7 +29,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression var stream = new BufferedReadStream(Configuration.Default, new MemoryStream(inputData)); var buffer = new byte[expectedResult.Length]; - new PackBitsTiffCompression(new ArrayPoolMemoryAllocator()).Decompress(stream, 0, (uint)inputData.Length, buffer); + using var decompressor = new PackBitsTiffCompression(new ArrayPoolMemoryAllocator()); + decompressor.Decompress(stream, 0, (uint)inputData.Length, buffer); Assert.Equal(expectedResult, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs index d7c066ec2f..107fd6079a 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs @@ -4,7 +4,6 @@ using System.IO; using SixLabors.ImageSharp.Formats.Experimental.Tiff; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers; using SixLabors.ImageSharp.Memory; diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index 7eaf735c97..a79d84e109 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncoderCompression.ModifiedHuffman, TiffCompression.Ccitt1D)] [WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffEncoderCompression.CcittGroup3Fax, TiffCompression.CcittGroup3Fax)] [WithFile(PaletteDeflateMultistrip, PixelTypes.L8, TiffEncoderCompression.ModifiedHuffman, TiffCompression.Ccitt1D)] - public void TiffEncoder_CorrectBiMode_Bug(TestImageProvider provider, TiffEncoderCompression compression, TiffCompression expectedCompression) + public void TiffEncoder_CorrectBiMode(TestImageProvider provider, TiffEncoderCompression compression, TiffCompression expectedCompression) where TPixel : unmanaged, IPixel { // arrange @@ -111,17 +111,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff using var output = Image.Load(this.configuration, memStream); TiffMetadata meta = output.Metadata.GetTiffMetadata(); - // This is bug! - // BitsPerPixel must be 1, and compression must be eqals which was setted in encoder - Assert.NotEqual(TiffBitsPerPixel.Pixel1, meta.BitsPerPixel); - Assert.NotEqual(expectedCompression, meta.Compression); - - Assert.Equal(input.Metadata.GetTiffMetadata().BitsPerPixel, meta.BitsPerPixel); - Assert.Equal(TiffCompression.None, meta.Compression); - - // expected values - //// Assert.Equal(TiffBitsPerPixel.Pixel1, meta.BitsPerPixel); - //// Assert.Equal(expectedCompression, meta.Compression); + Assert.Equal(TiffBitsPerPixel.Pixel1, meta.BitsPerPixel); + Assert.Equal(expectedCompression, meta.Compression); } [Theory] @@ -286,6 +277,62 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public void TiffEncoder_EncodeBiColor_WithModifiedHuffmanCompression_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Pixel1, TiffEncodingMode.BiColor, TiffEncoderCompression.ModifiedHuffman); + [Theory] + [WithFile(Calliphora_BiColorUncompressed, PixelTypes.L8, TiffEncodingMode.BiColor, TiffEncoderPixelStorageMethod.SingleStrip)] + [WithFile(Calliphora_BiColorUncompressed, PixelTypes.L8, TiffEncodingMode.BiColor, TiffEncoderPixelStorageMethod.MultiStrip, 9 * 1024)] + [WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffEncodingMode.Gray, TiffEncoderPixelStorageMethod.SingleStrip)] + [WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffEncodingMode.Gray, TiffEncoderPixelStorageMethod.MultiStrip, 16 * 1024)] + [WithFile(PaletteDeflateMultistrip, PixelTypes.L8, TiffEncodingMode.ColorPalette, TiffEncoderPixelStorageMethod.SingleStrip)] + [WithFile(PaletteDeflateMultistrip, PixelTypes.L8, TiffEncodingMode.ColorPalette, TiffEncoderPixelStorageMethod.MultiStrip, 32 * 1024)] + [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncodingMode.Rgb, TiffEncoderPixelStorageMethod.SingleStrip)] + [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncodingMode.Rgb, TiffEncoderPixelStorageMethod.MultiStrip, 64 * 1024)] + public void TiffEncoder_StorageMethods(TestImageProvider provider, TiffEncodingMode mode, TiffEncoderPixelStorageMethod storageMethod, int maxSize = 0) + where TPixel : unmanaged, IPixel + { + // arrange + var tiffEncoder = new TiffEncoder() { PixelStorageMethod = storageMethod, MaxStripBytes = maxSize }; + using Image input = provider.GetImage(); + using var memStream = new MemoryStream(); + + TiffFrameMetadata inputMeta = input.Frames.RootFrame.Metadata.GetTiffMetadata(); + + // act + input.Save(memStream, tiffEncoder); + + // assert + memStream.Position = 0; + using var output = Image.Load(this.configuration, memStream); + TiffFrameMetadata meta = output.Frames.RootFrame.Metadata.GetTiffMetadata(); + + if (storageMethod == TiffEncoderPixelStorageMethod.SingleStrip) + { + Assert.Equal(output.Height, (int)meta.RowsPerStrip); + Assert.Equal(1, meta.StripOffsets.Length); + Assert.Equal(1, meta.StripByteCounts.Length); + } + else + { + Assert.True(output.Height > (int)meta.RowsPerStrip); + Assert.True(meta.StripOffsets.Length > 1); + Assert.True(meta.StripByteCounts.Length > 1); + + foreach (Number sz in meta.StripByteCounts) + { + Assert.True((int)sz <= maxSize); + } + } + + // compare with reference + TestTiffEncoderCore( + provider, + (TiffBitsPerPixel)inputMeta.BitsPerPixel, + mode, + Convert(inputMeta.Compression), + maxStripSize: maxSize, + storageMethod: storageMethod + ); + } + private static void TestTiffEncoderCore( TestImageProvider provider, TiffBitsPerPixel bitsPerPixel, @@ -293,14 +340,43 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff TiffEncoderCompression compression = TiffEncoderCompression.None, bool usePredictor = false, bool useExactComparer = true, + int maxStripSize = 0, + TiffEncoderPixelStorageMethod? storageMethod = null, float compareTolerance = 0.01f) where TPixel : unmanaged, IPixel { using Image image = provider.GetImage(); - var encoder = new TiffEncoder { Mode = mode, Compression = compression, UseHorizontalPredictor = usePredictor }; + var encoder = new TiffEncoder + { + Mode = mode, + Compression = compression, + UseHorizontalPredictor = usePredictor, + PixelStorageMethod = storageMethod ?? TiffEncoderPixelStorageMethod.Auto, + MaxStripBytes = maxStripSize + }; // Does DebugSave & load reference CompareToReferenceInput(): image.VerifyEncoder(provider, "tiff", bitsPerPixel, encoder, useExactComparer ? ImageComparer.Exact : ImageComparer.Tolerant(compareTolerance), referenceDecoder: ReferenceDecoder); } + + private static TiffEncoderCompression Convert(TiffCompression compression) + { + switch (compression) + { + default: + case TiffCompression.None: + return TiffEncoderCompression.None; + case TiffCompression.Deflate: + return TiffEncoderCompression.Deflate; + case TiffCompression.Lzw: + return TiffEncoderCompression.Lzw; + case TiffCompression.PackBits: + return TiffEncoderCompression.PackBits; + case TiffCompression.CcittGroup3Fax: + return TiffEncoderCompression.CcittGroup3Fax; + case TiffCompression.CcittGroup4Fax: + return TiffEncoderCompression.ModifiedHuffman; + } + } } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs index 8d86482ecc..7ea2e4cc4a 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Utils; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers; using SixLabors.ImageSharp.Memory; From 74dacb66018db765274661f4ca7902d90af634da Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sat, 6 Feb 2021 23:14:38 +0300 Subject: [PATCH 04/15] Report palette lzw bug --- .../Formats/Tiff/TiffEncoderTests.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index a79d84e109..774454259d 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -210,7 +210,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public void TiffEncoder_EncodeColorPalette_WithLzwCompression_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel { - var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw }; + var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, PixelStorageMethod = TiffEncoderPixelStorageMethod.SingleStrip }; this.TiffEncoderPaletteTest(provider, encoder); } @@ -220,11 +220,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel { - var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, UseHorizontalPredictor = true }; + var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, UseHorizontalPredictor = true, PixelStorageMethod = TiffEncoderPixelStorageMethod.SingleStrip }; this.TiffEncoderPaletteTest(provider, encoder); } + [Theory] + [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Bug(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, PixelStorageMethod = TiffEncoderPixelStorageMethod.MultiStrip, UseHorizontalPredictor = true }; + + Assert.Throws(() => this.TiffEncoderPaletteTest(provider, encoder)); + } + [Theory] [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] public void TiffEncoder_EncodeColorPalette_WithPackBitsCompression_Works(TestImageProvider provider) From ace0d184b0c01558834a8e0546291e789c9aa1f4 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sun, 7 Feb 2021 12:16:27 +0300 Subject: [PATCH 05/15] Update benchmark results --- ...hmarks.Codecs.DecodeTiff-report-default.md | 102 +++++++------- ...chmarks.Codecs.DecodeTiff-report-github.md | 102 +++++++------- ...p.Benchmarks.Codecs.DecodeTiff-report.html | 104 +++++++------- ...hmarks.Codecs.EncodeTiff-report-default.md | 128 +++++++++--------- ...chmarks.Codecs.EncodeTiff-report-github.md | 128 +++++++++--------- ...p.Benchmarks.Codecs.EncodeTiff-report.html | 80 +++++------ 6 files changed, 322 insertions(+), 322 deletions(-) diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md index 6b35c6fe83..78128aff53 100644 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-default.md @@ -3,83 +3,83 @@ BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.101 [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT - Job-EMDSBW : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT - Job-KCUIVJ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT - Job-NIWDJE : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT + Job-MVPLTM : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT + Job-ZMKWLH : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT + Job-DYSEOC : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT InvocationCount=1 IterationCount=3 LaunchCount=1 UnrollFactor=1 WarmupCount=3 Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | ---------------------- |----------- |-------------- |----------------------------------------------- |------------:|--------------:|-------------:|------:|--------:|------:|------:|------:|----------:| - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_grayscale_uncompressed.tiff** | **1,107.9 μs** | **260.10 μs** | **14.26 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **974848 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_grayscale_uncompressed.tiff | 29,794.8 μs | 3,103.68 μs | 170.12 μs | 26.90 | 0.49 | - | - | - | 32768 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_grayscale_uncompressed.tiff** | **1,513.5 μs** | **6,982.54 μs** | **382.74 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **974848 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_grayscale_uncompressed.tiff | 29,504.9 μs | 2,030.88 μs | 111.32 μs | 20.46 | 5.74 | - | - | - | 32768 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 1,020.4 μs | 641.11 μs | 35.14 μs | 1.00 | 0.00 | - | - | - | 968832 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 12,593.4 μs | 4,807.87 μs | 263.54 μs | 12.36 | 0.67 | - | - | - | 29976 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 1,441.5 μs | 5,692.62 μs | 312.03 μs | 1.00 | 0.00 | - | - | - | 968832 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 12,512.9 μs | 669.83 μs | 36.72 μs | 8.98 | 2.11 | - | - | - | 30072 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 987.2 μs | 2,211.93 μs | 121.24 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 44,255.5 μs | 13,031.10 μs | 714.28 μs | 45.23 | 4.88 | - | - | - | 29896 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 989.7 μs | 1,621.23 μs | 88.87 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 44,038.5 μs | 7,702.48 μs | 422.20 μs | 44.75 | 4.23 | - | - | - | 29992 B | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_deflate_predictor.tiff** | **16,118.9 μs** | **2,095.51 μs** | **114.86 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **1483440 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 25,967.5 μs | 4,545.04 μs | 249.13 μs | 1.61 | 0.01 | - | - | - | 848240 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_deflate_predictor.tiff** | **16,368.6 μs** | **3,342.63 μs** | **183.22 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **1483440 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 27,334.9 μs | 5,327.53 μs | 292.02 μs | 1.67 | 0.04 | - | - | - | 848240 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,465.6 μs | 7,761.65 μs | 425.44 μs | 1.00 | 0.00 | - | - | - | 1480344 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,536.9 μs | 3,415.62 μs | 187.22 μs | 1.13 | 0.02 | - | - | - | 68176 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,192.2 μs | 4,200.11 μs | 230.22 μs | 1.00 | 0.00 | - | - | - | 1480344 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,448.9 μs | 3,957.52 μs | 216.93 μs | 1.14 | 0.00 | - | - | - | 68224 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,216.2 μs | 3,288.12 μs | 180.23 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 20,740.6 μs | 54,608.55 μs | 2,993.28 μs | 1.28 | 0.17 | - | - | - | 65120 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 15,936.7 μs | 3,145.57 μs | 172.42 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,973.7 μs | 16,625.54 μs | 911.30 μs | 1.19 | 0.06 | - | - | - | 65168 B | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_lzw_predictor.tiff** | **83,012.1 μs** | **14,786.35 μs** | **810.49 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2545736 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 64,895.5 μs | 11,397.89 μs | 624.76 μs | 0.78 | 0.01 | - | - | - | 24576 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_lzw_predictor.tiff** | **81,687.4 μs** | **6,229.79 μs** | **341.48 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2545736 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 67,259.5 μs | 4,315.22 μs | 236.53 μs | 0.82 | 0.01 | - | - | - | 24576 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 82,854.1 μs | 45,495.28 μs | 2,493.75 μs | 1.00 | 0.00 | - | - | - | 2541376 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 44,307.1 μs | 15,595.85 μs | 854.86 μs | 0.53 | 0.01 | - | - | - | 23832 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 81,554.2 μs | 9,082.88 μs | 497.86 μs | 1.00 | 0.00 | - | - | - | 2541376 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 43,966.2 μs | 3,806.49 μs | 208.65 μs | 0.54 | 0.00 | - | - | - | 23880 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 83,297.5 μs | 15,796.71 μs | 865.87 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 59,464.0 μs | 13,870.15 μs | 760.27 μs | 0.71 | 0.01 | - | - | - | 23760 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 80,333.6 μs | 24,190.59 μs | 1,325.97 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 54,418.0 μs | 122,629.27 μs | 6,721.72 μs | 0.68 | 0.09 | - | - | - | 23848 B | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_packbits.tiff** | **3,707.2 μs** | **6,293.27 μs** | **344.96 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2916008 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_packbits.tiff | 7,526.9 μs | 5,965.86 μs | 327.01 μs | 2.04 | 0.24 | - | - | - | 81920 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_packbits.tiff** | **3,554.1 μs** | **2,577.75 μs** | **141.30 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2916000 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_packbits.tiff | 7,231.9 μs | 3,934.62 μs | 215.67 μs | 2.04 | 0.08 | - | - | - | 57344 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,037.7 μs | 9,243.97 μs | 506.69 μs | 1.00 | 0.00 | - | - | - | 2903544 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,395.7 μs | 1,394.13 μs | 76.42 μs | 1.10 | 0.15 | - | - | - | 80256 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,815.4 μs | 11,074.41 μs | 607.03 μs | 1.00 | 0.00 | - | - | - | 2903544 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,415.6 μs | 7,272.82 μs | 398.65 μs | 1.17 | 0.08 | - | - | - | 51920 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,456.3 μs | 4,443.73 μs | 243.58 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,542.9 μs | 3,820.61 μs | 209.42 μs | 1.32 | 0.13 | - | - | - | 80184 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,297.6 μs | 5,129.08 μs | 281.14 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,421.7 μs | 3,349.14 μs | 183.58 μs | 1.34 | 0.07 | - | - | - | 51848 B | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_palette_lzw_predictor.tiff** | **60,298.5 μs** | **24,263.76 μs** | **1,329.98 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **827416 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 76,021.3 μs | 4,206.79 μs | 230.59 μs | 1.26 | 0.02 | - | - | - | 49152 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_palette_lzw_predictor.tiff** | **60,458.2 μs** | **21,405.09 μs** | **1,173.29 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **827416 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 76,324.5 μs | 12,909.45 μs | 707.61 μs | 1.26 | 0.04 | - | - | - | 49152 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 59,122.1 μs | 9,681.07 μs | 530.65 μs | 1.00 | 0.00 | - | - | - | 825648 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 45,789.3 μs | 7,453.72 μs | 408.56 μs | 0.77 | 0.00 | - | - | - | 45936 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 61,210.5 μs | 17,165.24 μs | 940.88 μs | 1.00 | 0.00 | - | - | - | 825648 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 46,951.4 μs | 1,602.53 μs | 87.84 μs | 0.77 | 0.01 | - | - | - | 45984 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 61,361.5 μs | 25,759.90 μs | 1,411.99 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 68,134.6 μs | 303,212.80 μs | 16,620.12 μs | 1.11 | 0.25 | - | - | - | 45864 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 59,056.7 μs | 6,187.79 μs | 339.17 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 66,042.9 μs | 291,880.02 μs | 15,998.93 μs | 1.12 | 0.27 | - | - | - | 45912 B | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **3,431.7 μs** | **7,649.10 μs** | **419.27 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2915944 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | 6,382.4 μs | 2,573.27 μs | 141.05 μs | 1.87 | 0.18 | - | - | - | 57344 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **3,385.5 μs** | **6,266.60 μs** | **343.49 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2915968 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | 7,584.8 μs | 358.27 μs | 19.64 μs | 2.25 | 0.21 | - | - | - | 57344 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,636.1 μs | 8,607.66 μs | 471.81 μs | 1.00 | 0.00 | - | - | - | 2905840 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,018.7 μs | 1,662.68 μs | 91.14 μs | 1.12 | 0.16 | - | - | - | 51472 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,405.8 μs | 4,765.81 μs | 261.23 μs | 1.00 | 0.00 | - | - | - | 2905840 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,930.3 μs | 3,250.19 μs | 178.15 μs | 1.16 | 0.05 | - | - | - | 51568 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 2,970.8 μs | 5,028.62 μs | 275.64 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,009.6 μs | 3,007.19 μs | 164.83 μs | 1.36 | 0.17 | - | - | - | 51400 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,087.8 μs | 5,556.58 μs | 304.58 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,909.1 μs | 2,519.27 μs | 138.09 μs | 1.27 | 0.14 | - | - | - | 51496 B | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/ccitt_fax3_all_terminating_codes.tiff** | **178.4 μs** | **375.89 μs** | **20.60 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 634.5 μs | 251.14 μs | 13.77 μs | 3.58 | 0.37 | - | - | - | 24576 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/ccitt_fax3_all_terminating_codes.tiff** | **151.9 μs** | **73.26 μs** | **4.02 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 648.7 μs | 165.54 μs | 9.07 μs | 4.27 | 0.08 | - | - | - | 24576 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 171.7 μs | 606.95 μs | 33.27 μs | 1.00 | 0.00 | - | - | - | 2032 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 421.0 μs | 31.60 μs | 1.73 μs | 2.51 | 0.49 | - | - | - | 17848 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 160.6 μs | 80.44 μs | 4.41 μs | 1.00 | 0.00 | - | - | - | 2032 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 427.7 μs | 431.89 μs | 23.67 μs | 2.66 | 0.17 | - | - | - | 17952 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 137.2 μs | 78.18 μs | 4.29 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 888.5 μs | 495.11 μs | 27.14 μs | 6.47 | 0.05 | - | - | - | 17768 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 230.1 μs | 952.83 μs | 52.23 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 945.4 μs | 511.67 μs | 28.05 μs | 4.26 | 1.00 | - | - | - | 17872 B | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/huffman_rle_all_makeup_codes.tiff** | **189.8 μs** | **818.95 μs** | **44.89 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | - 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/huffman_rle_all_makeup_codes.tiff | 9,137.1 μs | 1,178.82 μs | 64.62 μs | 49.85 | 10.86 | - | - | - | 24576 B | + **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/huffman_rle_all_makeup_codes.tiff** | **188.4 μs** | **609.38 μs** | **33.40 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | + 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/huffman_rle_all_makeup_codes.tiff | 8,870.6 μs | 2,847.17 μs | 156.06 μs | 48.06 | 8.32 | - | - | - | 24576 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 298.5 μs | 1,361.33 μs | 74.62 μs | 1.00 | 0.00 | - | - | - | 2088 B | - 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 5,717.5 μs | 2,533.21 μs | 138.85 μs | 19.89 | 4.51 | - | - | - | 18328 B | + 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 222.0 μs | 620.73 μs | 34.02 μs | 1.00 | 0.00 | - | - | - | 2088 B | + 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 5,660.9 μs | 3,414.81 μs | 187.18 μs | 25.92 | 4.17 | - | - | - | 18432 B | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 159.5 μs | 140.52 μs | 7.70 μs | 1.00 | 0.00 | - | - | - | 176 B | - 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 15,047.7 μs | 2,686.03 μs | 147.23 μs | 94.47 | 4.56 | - | - | - | 18248 B | + 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 176.5 μs | 227.25 μs | 12.46 μs | 1.00 | 0.00 | - | - | - | 176 B | + 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 14,251.6 μs | 597.28 μs | 32.74 μs | 81.00 | 5.71 | - | - | - | 18352 B | diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md index a07b5d1f86..a424669072 100644 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report-github.md @@ -4,9 +4,9 @@ BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.101 [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT - Job-EMDSBW : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT - Job-KCUIVJ : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT - Job-NIWDJE : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT + Job-MVPLTM : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT + Job-ZMKWLH : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT + Job-DYSEOC : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT InvocationCount=1 IterationCount=3 LaunchCount=1 UnrollFactor=1 WarmupCount=3 @@ -14,74 +14,74 @@ UnrollFactor=1 WarmupCount=3 ``` | Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | |---------------------- |----------- |-------------- |----------------------------------------------- |------------:|--------------:|-------------:|------:|--------:|------:|------:|------:|----------:| -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_grayscale_uncompressed.tiff** | **1,107.9 μs** | **260.10 μs** | **14.26 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **974848 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_grayscale_uncompressed.tiff | 29,794.8 μs | 3,103.68 μs | 170.12 μs | 26.90 | 0.49 | - | - | - | 32768 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_grayscale_uncompressed.tiff** | **1,513.5 μs** | **6,982.54 μs** | **382.74 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **974848 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_grayscale_uncompressed.tiff | 29,504.9 μs | 2,030.88 μs | 111.32 μs | 20.46 | 5.74 | - | - | - | 32768 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 1,020.4 μs | 641.11 μs | 35.14 μs | 1.00 | 0.00 | - | - | - | 968832 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 12,593.4 μs | 4,807.87 μs | 263.54 μs | 12.36 | 0.67 | - | - | - | 29976 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 1,441.5 μs | 5,692.62 μs | 312.03 μs | 1.00 | 0.00 | - | - | - | 968832 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 12,512.9 μs | 669.83 μs | 36.72 μs | 8.98 | 2.11 | - | - | - | 30072 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 987.2 μs | 2,211.93 μs | 121.24 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 44,255.5 μs | 13,031.10 μs | 714.28 μs | 45.23 | 4.88 | - | - | - | 29896 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 989.7 μs | 1,621.23 μs | 88.87 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_grayscale_uncompressed.tiff | 44,038.5 μs | 7,702.48 μs | 422.20 μs | 44.75 | 4.23 | - | - | - | 29992 B | | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_deflate_predictor.tiff** | **16,118.9 μs** | **2,095.51 μs** | **114.86 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **1483440 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 25,967.5 μs | 4,545.04 μs | 249.13 μs | 1.61 | 0.01 | - | - | - | 848240 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_deflate_predictor.tiff** | **16,368.6 μs** | **3,342.63 μs** | **183.22 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **1483440 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 27,334.9 μs | 5,327.53 μs | 292.02 μs | 1.67 | 0.04 | - | - | - | 848240 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,465.6 μs | 7,761.65 μs | 425.44 μs | 1.00 | 0.00 | - | - | - | 1480344 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,536.9 μs | 3,415.62 μs | 187.22 μs | 1.13 | 0.02 | - | - | - | 68176 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,192.2 μs | 4,200.11 μs | 230.22 μs | 1.00 | 0.00 | - | - | - | 1480344 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,448.9 μs | 3,957.52 μs | 216.93 μs | 1.14 | 0.00 | - | - | - | 68224 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 16,216.2 μs | 3,288.12 μs | 180.23 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 20,740.6 μs | 54,608.55 μs | 2,993.28 μs | 1.28 | 0.17 | - | - | - | 65120 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 15,936.7 μs | 3,145.57 μs | 172.42 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_deflate_predictor.tiff | 18,973.7 μs | 16,625.54 μs | 911.30 μs | 1.19 | 0.06 | - | - | - | 65168 B | | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_lzw_predictor.tiff** | **83,012.1 μs** | **14,786.35 μs** | **810.49 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2545736 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 64,895.5 μs | 11,397.89 μs | 624.76 μs | 0.78 | 0.01 | - | - | - | 24576 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_lzw_predictor.tiff** | **81,687.4 μs** | **6,229.79 μs** | **341.48 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2545736 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 67,259.5 μs | 4,315.22 μs | 236.53 μs | 0.82 | 0.01 | - | - | - | 24576 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 82,854.1 μs | 45,495.28 μs | 2,493.75 μs | 1.00 | 0.00 | - | - | - | 2541376 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 44,307.1 μs | 15,595.85 μs | 854.86 μs | 0.53 | 0.01 | - | - | - | 23832 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 81,554.2 μs | 9,082.88 μs | 497.86 μs | 1.00 | 0.00 | - | - | - | 2541376 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 43,966.2 μs | 3,806.49 μs | 208.65 μs | 0.54 | 0.00 | - | - | - | 23880 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 83,297.5 μs | 15,796.71 μs | 865.87 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 59,464.0 μs | 13,870.15 μs | 760.27 μs | 0.71 | 0.01 | - | - | - | 23760 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 80,333.6 μs | 24,190.59 μs | 1,325.97 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_lzw_predictor.tiff | 54,418.0 μs | 122,629.27 μs | 6,721.72 μs | 0.68 | 0.09 | - | - | - | 23848 B | | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_packbits.tiff** | **3,707.2 μs** | **6,293.27 μs** | **344.96 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2916008 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_packbits.tiff | 7,526.9 μs | 5,965.86 μs | 327.01 μs | 2.04 | 0.24 | - | - | - | 81920 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_packbits.tiff** | **3,554.1 μs** | **2,577.75 μs** | **141.30 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2916000 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_packbits.tiff | 7,231.9 μs | 3,934.62 μs | 215.67 μs | 2.04 | 0.08 | - | - | - | 57344 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,037.7 μs | 9,243.97 μs | 506.69 μs | 1.00 | 0.00 | - | - | - | 2903544 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,395.7 μs | 1,394.13 μs | 76.42 μs | 1.10 | 0.15 | - | - | - | 80256 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,815.4 μs | 11,074.41 μs | 607.03 μs | 1.00 | 0.00 | - | - | - | 2903544 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,415.6 μs | 7,272.82 μs | 398.65 μs | 1.17 | 0.08 | - | - | - | 51920 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,456.3 μs | 4,443.73 μs | 243.58 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,542.9 μs | 3,820.61 μs | 209.42 μs | 1.32 | 0.13 | - | - | - | 80184 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 3,297.6 μs | 5,129.08 μs | 281.14 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_packbits.tiff | 4,421.7 μs | 3,349.14 μs | 183.58 μs | 1.34 | 0.07 | - | - | - | 51848 B | | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_palette_lzw_predictor.tiff** | **60,298.5 μs** | **24,263.76 μs** | **1,329.98 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **827416 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 76,021.3 μs | 4,206.79 μs | 230.59 μs | 1.26 | 0.02 | - | - | - | 49152 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_palette_lzw_predictor.tiff** | **60,458.2 μs** | **21,405.09 μs** | **1,173.29 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **827416 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 76,324.5 μs | 12,909.45 μs | 707.61 μs | 1.26 | 0.04 | - | - | - | 49152 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 59,122.1 μs | 9,681.07 μs | 530.65 μs | 1.00 | 0.00 | - | - | - | 825648 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 45,789.3 μs | 7,453.72 μs | 408.56 μs | 0.77 | 0.00 | - | - | - | 45936 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 61,210.5 μs | 17,165.24 μs | 940.88 μs | 1.00 | 0.00 | - | - | - | 825648 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 46,951.4 μs | 1,602.53 μs | 87.84 μs | 0.77 | 0.01 | - | - | - | 45984 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 61,361.5 μs | 25,759.90 μs | 1,411.99 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 68,134.6 μs | 303,212.80 μs | 16,620.12 μs | 1.11 | 0.25 | - | - | - | 45864 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 59,056.7 μs | 6,187.79 μs | 339.17 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_palette_lzw_predictor.tiff | 66,042.9 μs | 291,880.02 μs | 15,998.93 μs | 1.12 | 0.27 | - | - | - | 45912 B | | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **3,431.7 μs** | **7,649.10 μs** | **419.27 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2915944 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | 6,382.4 μs | 2,573.27 μs | 141.05 μs | 1.87 | 0.18 | - | - | - | 57344 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **3,385.5 μs** | **6,266.60 μs** | **343.49 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **2915968 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | 7,584.8 μs | 358.27 μs | 19.64 μs | 2.25 | 0.21 | - | - | - | 57344 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,636.1 μs | 8,607.66 μs | 471.81 μs | 1.00 | 0.00 | - | - | - | 2905840 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,018.7 μs | 1,662.68 μs | 91.14 μs | 1.12 | 0.16 | - | - | - | 51472 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,405.8 μs | 4,765.81 μs | 261.23 μs | 1.00 | 0.00 | - | - | - | 2905840 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,930.3 μs | 3,250.19 μs | 178.15 μs | 1.16 | 0.05 | - | - | - | 51568 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 2,970.8 μs | 5,028.62 μs | 275.64 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 4,009.6 μs | 3,007.19 μs | 164.83 μs | 1.36 | 0.17 | - | - | - | 51400 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,087.8 μs | 5,556.58 μs | 304.58 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | 3,909.1 μs | 2,519.27 μs | 138.09 μs | 1.27 | 0.14 | - | - | - | 51496 B | | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/ccitt_fax3_all_terminating_codes.tiff** | **178.4 μs** | **375.89 μs** | **20.60 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 634.5 μs | 251.14 μs | 13.77 μs | 3.58 | 0.37 | - | - | - | 24576 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/ccitt_fax3_all_terminating_codes.tiff** | **151.9 μs** | **73.26 μs** | **4.02 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 648.7 μs | 165.54 μs | 9.07 μs | 4.27 | 0.08 | - | - | - | 24576 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 171.7 μs | 606.95 μs | 33.27 μs | 1.00 | 0.00 | - | - | - | 2032 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 421.0 μs | 31.60 μs | 1.73 μs | 2.51 | 0.49 | - | - | - | 17848 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 160.6 μs | 80.44 μs | 4.41 μs | 1.00 | 0.00 | - | - | - | 2032 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 427.7 μs | 431.89 μs | 23.67 μs | 2.66 | 0.17 | - | - | - | 17952 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 137.2 μs | 78.18 μs | 4.29 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 888.5 μs | 495.11 μs | 27.14 μs | 6.47 | 0.05 | - | - | - | 17768 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 230.1 μs | 952.83 μs | 52.23 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/ccitt_fax3_all_terminating_codes.tiff | 945.4 μs | 511.67 μs | 28.05 μs | 4.26 | 1.00 | - | - | - | 17872 B | | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-EMDSBW** | **.NET 4.7.2** | **Tiff/huffman_rle_all_makeup_codes.tiff** | **189.8 μs** | **818.95 μs** | **44.89 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | -| 'ImageSharp Tiff' | Job-EMDSBW | .NET 4.7.2 | Tiff/huffman_rle_all_makeup_codes.tiff | 9,137.1 μs | 1,178.82 μs | 64.62 μs | 49.85 | 10.86 | - | - | - | 24576 B | +| **'System.Drawing Tiff'** | **Job-MVPLTM** | **.NET 4.7.2** | **Tiff/huffman_rle_all_makeup_codes.tiff** | **188.4 μs** | **609.38 μs** | **33.40 μs** | **1.00** | **0.00** | **-** | **-** | **-** | **8192 B** | +| 'ImageSharp Tiff' | Job-MVPLTM | .NET 4.7.2 | Tiff/huffman_rle_all_makeup_codes.tiff | 8,870.6 μs | 2,847.17 μs | 156.06 μs | 48.06 | 8.32 | - | - | - | 24576 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 298.5 μs | 1,361.33 μs | 74.62 μs | 1.00 | 0.00 | - | - | - | 2088 B | -| 'ImageSharp Tiff' | Job-KCUIVJ | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 5,717.5 μs | 2,533.21 μs | 138.85 μs | 19.89 | 4.51 | - | - | - | 18328 B | +| 'System.Drawing Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 222.0 μs | 620.73 μs | 34.02 μs | 1.00 | 0.00 | - | - | - | 2088 B | +| 'ImageSharp Tiff' | Job-ZMKWLH | .NET Core 2.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 5,660.9 μs | 3,414.81 μs | 187.18 μs | 25.92 | 4.17 | - | - | - | 18432 B | | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 159.5 μs | 140.52 μs | 7.70 μs | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-NIWDJE | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 15,047.7 μs | 2,686.03 μs | 147.23 μs | 94.47 | 4.56 | - | - | - | 18248 B | +| 'System.Drawing Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 176.5 μs | 227.25 μs | 12.46 μs | 1.00 | 0.00 | - | - | - | 176 B | +| 'ImageSharp Tiff' | Job-DYSEOC | .NET Core 3.1 | Tiff/huffman_rle_all_makeup_codes.tiff | 14,251.6 μs | 597.28 μs | 32.74 μs | 81.00 | 5.71 | - | - | - | 18352 B | diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html index 86292073ba..c29e35d579 100644 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html +++ b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-report.html @@ -2,7 +2,7 @@ -SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-20210207-115335 +SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiff-20210207-174953 - - -

-BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
-Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores
-.NET Core SDK=5.0.101
-  [Host]     : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
-  Job-MVPLTM : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT
-  Job-ZMKWLH : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT
-  Job-DYSEOC : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
-
-
InvocationCount=1  IterationCount=3  LaunchCount=1  
-UnrollFactor=1  WarmupCount=3  
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method JobRuntime TestImage Mean ErrorStdDevRatioRatioSDGen 0Gen 1Gen 2Allocated
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_grayscale_uncompressed.tiff1,513.5 μs6,982.54 μs382.74 μs1.000.00---974848 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_grayscale_uncompressed.tiff29,504.9 μs2,030.88 μs111.32 μs20.465.74---32768 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_grayscale_uncompressed.tiff1,441.5 μs5,692.62 μs312.03 μs1.000.00---968832 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_grayscale_uncompressed.tiff12,512.9 μs669.83 μs36.72 μs8.982.11---30072 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_grayscale_uncompressed.tiff989.7 μs1,621.23 μs88.87 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_grayscale_uncompressed.tiff44,038.5 μs7,702.48 μs422.20 μs44.754.23---29992 B
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_deflate_predictor.tiff16,368.6 μs3,342.63 μs183.22 μs1.000.00---1483440 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_deflate_predictor.tiff27,334.9 μs5,327.53 μs292.02 μs1.670.04---848240 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_deflate_predictor.tiff16,192.2 μs4,200.11 μs230.22 μs1.000.00---1480344 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_deflate_predictor.tiff18,448.9 μs3,957.52 μs216.93 μs1.140.00---68224 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_deflate_predictor.tiff15,936.7 μs3,145.57 μs172.42 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_deflate_predictor.tiff18,973.7 μs16,625.54 μs911.30 μs1.190.06---65168 B
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_lzw_predictor.tiff81,687.4 μs6,229.79 μs341.48 μs1.000.00---2545736 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_lzw_predictor.tiff67,259.5 μs4,315.22 μs236.53 μs0.820.01---24576 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_lzw_predictor.tiff81,554.2 μs9,082.88 μs497.86 μs1.000.00---2541376 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_lzw_predictor.tiff43,966.2 μs3,806.49 μs208.65 μs0.540.00---23880 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_lzw_predictor.tiff80,333.6 μs24,190.59 μs1,325.97 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_lzw_predictor.tiff54,418.0 μs122,629.27 μs6,721.72 μs0.680.09---23848 B
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_packbits.tiff3,554.1 μs2,577.75 μs141.30 μs1.000.00---2916000 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_packbits.tiff7,231.9 μs3,934.62 μs215.67 μs2.040.08---57344 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_packbits.tiff3,815.4 μs11,074.41 μs607.03 μs1.000.00---2903544 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_packbits.tiff4,415.6 μs7,272.82 μs398.65 μs1.170.08---51920 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_packbits.tiff3,297.6 μs5,129.08 μs281.14 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_packbits.tiff4,421.7 μs3,349.14 μs183.58 μs1.340.07---51848 B
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_palette_lzw_predictor.tiff60,458.2 μs21,405.09 μs1,173.29 μs1.000.00---827416 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_palette_lzw_predictor.tiff76,324.5 μs12,909.45 μs707.61 μs1.260.04---49152 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff61,210.5 μs17,165.24 μs940.88 μs1.000.00---825648 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff46,951.4 μs1,602.53 μs87.84 μs0.770.01---45984 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff59,056.7 μs6,187.79 μs339.17 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_palette_lzw_predictor.tiff66,042.9 μs291,880.02 μs15,998.93 μs1.120.27---45912 B
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiff3,385.5 μs6,266.60 μs343.49 μs1.000.00---2915968 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiff7,584.8 μs358.27 μs19.64 μs2.250.21---57344 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiff3,405.8 μs4,765.81 μs261.23 μs1.000.00---2905840 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiff3,930.3 μs3,250.19 μs178.15 μs1.160.05---51568 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiff3,087.8 μs5,556.58 μs304.58 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiff3,909.1 μs2,519.27 μs138.09 μs1.270.14---51496 B
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/ccitt_fax3_all_terminating_codes.tiff151.9 μs73.26 μs4.02 μs1.000.00---8192 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/ccitt_fax3_all_terminating_codes.tiff648.7 μs165.54 μs9.07 μs4.270.08---24576 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/ccitt_fax3_all_terminating_codes.tiff160.6 μs80.44 μs4.41 μs1.000.00---2032 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/ccitt_fax3_all_terminating_codes.tiff427.7 μs431.89 μs23.67 μs2.660.17---17952 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/ccitt_fax3_all_terminating_codes.tiff230.1 μs952.83 μs52.23 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/ccitt_fax3_all_terminating_codes.tiff945.4 μs511.67 μs28.05 μs4.261.00---17872 B
'System.Drawing Tiff'Job-MVPLTM.NET 4.7.2Tiff/huffman_rle_all_makeup_codes.tiff188.4 μs609.38 μs33.40 μs1.000.00---8192 B
'ImageSharp Tiff'Job-MVPLTM.NET 4.7.2Tiff/huffman_rle_all_makeup_codes.tiff8,870.6 μs2,847.17 μs156.06 μs48.068.32---24576 B
'System.Drawing Tiff'Job-ZMKWLH.NET Core 2.1Tiff/huffman_rle_all_makeup_codes.tiff222.0 μs620.73 μs34.02 μs1.000.00---2088 B
'ImageSharp Tiff'Job-ZMKWLH.NET Core 2.1Tiff/huffman_rle_all_makeup_codes.tiff5,660.9 μs3,414.81 μs187.18 μs25.924.17---18432 B
'System.Drawing Tiff'Job-DYSEOC.NET Core 3.1Tiff/huffman_rle_all_makeup_codes.tiff176.5 μs227.25 μs12.46 μs1.000.00---176 B
'ImageSharp Tiff'Job-DYSEOC.NET Core 3.1Tiff/huffman_rle_all_makeup_codes.tiff14,251.6 μs597.28 μs32.74 μs81.005.71---18352 B
- - diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiffBig-report-github.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiffBig-report-github.md deleted file mode 100644 index 366c1480ab..0000000000 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiffBig-report-github.md +++ /dev/null @@ -1,87 +0,0 @@ -``` ini - -BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 -Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=5.0.100 - [Host] : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT - Job-KSIANY : .NET Framework 4.8 (4.8.4250.0), X64 RyuJIT - Job-VMCLSF : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT - Job-UHENIY : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT - -InvocationCount=1 IterationCount=5 LaunchCount=1 -UnrollFactor=1 WarmupCount=3 - -``` -| Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | -|---------------------- |----------- |-------------- |----------------------------------- |-----------:|----------:|----------:|------:|--------:|-----------:|----------:|----------:|------------:| -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_bw_Fax3.tiff** | **491.6 ms** | **20.40 ms** | **5.30 ms** | **1.00** | **0.00** | **1000.0000** | **-** | **-** | **5768128 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_bw_Fax3.tiff | 6,970.2 ms | 70.64 ms | 10.93 ms | 14.23 | 0.12 | 1000.0000 | 1000.0000 | 1000.0000 | 241518600 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Fax3.tiff | 486.2 ms | 23.15 ms | 3.58 ms | 1.00 | 0.00 | 1000.0000 | - | - | 5751016 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Fax3.tiff | 4,150.2 ms | 322.16 ms | 83.66 ms | 8.47 | 0.16 | - | - | - | 235961088 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Fax3.tiff | 490.1 ms | 12.76 ms | 3.31 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Fax3.tiff | 3,582.9 ms | 61.89 ms | 16.07 ms | 7.31 | 0.06 | - | - | - | 235961496 B | -| | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_bw_Rle.tiff** | **499.1 ms** | **26.71 ms** | **6.94 ms** | **1.00** | **0.00** | **1000.0000** | **-** | **-** | **8494472 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_bw_Rle.tiff | 7,290.4 ms | 938.28 ms | 243.67 ms | 14.61 | 0.33 | 1000.0000 | 1000.0000 | 1000.0000 | 237020384 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Rle.tiff | 490.6 ms | 30.19 ms | 4.67 ms | 1.00 | 0.00 | 1000.0000 | - | - | 8475688 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_bw_Rle.tiff | 4,230.2 ms | 35.59 ms | 5.51 ms | 8.62 | 0.08 | - | - | - | 235961944 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Rle.tiff | 487.6 ms | 12.07 ms | 1.87 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_bw_Rle.tiff | 3,647.4 ms | 42.62 ms | 11.07 ms | 7.48 | 0.04 | - | - | - | 235962184 B | -| | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_grayscale_uncompressed.tiff** | **606.7 ms** | **20.45 ms** | **5.31 ms** | **1.00** | **0.00** | **18000.0000** | **-** | **-** | **90301696 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_grayscale_uncompressed.tiff | 1,852.9 ms | 6.74 ms | 1.75 ms | 3.05 | 0.03 | - | - | - | 235970584 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_grayscale_uncompressed.tiff | 606.6 ms | 36.58 ms | 9.50 ms | 1.00 | 0.00 | 18000.0000 | - | - | 90104048 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_grayscale_uncompressed.tiff | 764.3 ms | 15.69 ms | 4.08 ms | 1.26 | 0.02 | - | - | - | 235965376 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_grayscale_uncompressed.tiff | 569.6 ms | 17.44 ms | 4.53 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_grayscale_uncompressed.tiff | 655.2 ms | 17.48 ms | 4.54 ms | 1.15 | 0.01 | - | - | - | 235965488 B | -| | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_palette_uncompressed.tiff** | **578.0 ms** | **22.32 ms** | **5.80 ms** | **1.00** | **0.00** | **18000.0000** | **-** | **-** | **90301696 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_palette_uncompressed.tiff | 3,336.9 ms | 21.42 ms | 5.56 ms | 5.77 | 0.07 | - | - | - | 236003608 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_palette_uncompressed.tiff | 601.9 ms | 40.85 ms | 6.32 ms | 1.00 | 0.00 | 18000.0000 | - | - | 90107368 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_palette_uncompressed.tiff | 1,971.9 ms | 15.69 ms | 4.07 ms | 3.28 | 0.04 | - | - | - | 235996096 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_palette_uncompressed.tiff | 566.1 ms | 28.06 ms | 4.34 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_palette_uncompressed.tiff | 1,664.1 ms | 11.59 ms | 1.79 ms | 2.94 | 0.02 | - | - | - | 235996208 B | -| | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_deflate.tiff** | **357.4 ms** | **15.54 ms** | **2.40 ms** | **1.00** | **0.00** | **3000.0000** | **-** | **-** | **9662560 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_deflate.tiff | 776.1 ms | 14.51 ms | 3.77 ms | 2.17 | 0.01 | 22000.0000 | 1000.0000 | 1000.0000 | 303476856 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_deflate.tiff | 359.7 ms | 12.29 ms | 3.19 ms | 1.00 | 0.00 | 3000.0000 | - | - | 9629400 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_deflate.tiff | 554.5 ms | 16.78 ms | 4.36 ms | 1.54 | 0.02 | 2000.0000 | 1000.0000 | 1000.0000 | 239716144 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_deflate.tiff | 353.2 ms | 7.22 ms | 1.12 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_deflate.tiff | 557.1 ms | 10.79 ms | 2.80 ms | 1.58 | 0.00 | 2000.0000 | 1000.0000 | 1000.0000 | 239470552 B | -| | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_lzw.tiff** | **511.0 ms** | **6.43 ms** | **1.67 ms** | **1.00** | **0.00** | **3000.0000** | **-** | **-** | **11600840 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_lzw.tiff | 2,691.6 ms | 16.81 ms | 2.60 ms | 5.27 | 0.02 | - | - | - | 236044312 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_lzw.tiff | 511.4 ms | 11.44 ms | 1.77 ms | 1.00 | 0.00 | 3000.0000 | - | - | 11569776 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_lzw.tiff | 1,654.1 ms | 12.42 ms | 1.92 ms | 3.23 | 0.01 | - | - | - | 236041592 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_lzw.tiff | 507.7 ms | 8.89 ms | 2.31 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_lzw.tiff | 1,689.5 ms | 40.41 ms | 6.25 ms | 3.33 | 0.03 | - | - | - | 236041656 B | -| | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_packbits.tiff** | **776.8 ms** | **31.69 ms** | **8.23 ms** | **1.00** | **0.00** | **56000.0000** | **-** | **-** | **304057016 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_packbits.tiff | 531.2 ms | 23.17 ms | 6.02 ms | 0.68 | 0.01 | - | - | - | 236003352 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_packbits.tiff | 764.2 ms | 41.43 ms | 6.41 ms | 1.00 | 0.00 | 56000.0000 | - | - | 303861120 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_packbits.tiff | 300.0 ms | 4.39 ms | 0.68 ms | 0.39 | 0.00 | - | - | - | 235998408 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_packbits.tiff | 659.1 ms | 34.59 ms | 8.98 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_packbits.tiff | 297.5 ms | 21.13 ms | 5.49 ms | 0.45 | 0.00 | - | - | - | 235998520 B | -| | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KSIANY** | **.NET 4.7.2** | **medium_rgb_uncompressed.tiff** | **742.5 ms** | **50.45 ms** | **13.10 ms** | **1.00** | **0.00** | **55000.0000** | **-** | **-** | **302644272 B** | -| 'ImageSharp Tiff' | Job-KSIANY | .NET 4.7.2 | medium_rgb_uncompressed.tiff | 414.3 ms | 15.37 ms | 3.99 ms | 0.56 | 0.01 | - | - | - | 235986968 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_uncompressed.tiff | 750.2 ms | 74.13 ms | 19.25 ms | 1.00 | 0.00 | 55000.0000 | - | - | 302448096 B | -| 'ImageSharp Tiff' | Job-VMCLSF | .NET Core 2.1 | medium_rgb_uncompressed.tiff | 283.6 ms | 21.56 ms | 5.60 ms | 0.38 | 0.01 | - | - | - | 235981128 B | -| | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_uncompressed.tiff | 662.6 ms | 49.79 ms | 12.93 ms | 1.00 | 0.00 | - | - | - | 176 B | -| 'ImageSharp Tiff' | Job-UHENIY | .NET Core 3.1 | medium_rgb_uncompressed.tiff | 278.6 ms | 9.48 ms | 2.46 ms | 0.42 | 0.01 | - | - | - | 235981352 B | diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiffBig-report.html b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiffBig-report.html deleted file mode 100644 index 10fd01fd45..0000000000 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiffBig-report.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -SixLabors.ImageSharp.Benchmarks.Codecs.DecodeTiffBig-20201209-175548 - - - - -

-BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
-Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores
-.NET Core SDK=5.0.100
-  [Host]     : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
-  Job-KSIANY : .NET Framework 4.8 (4.8.4250.0), X64 RyuJIT
-  Job-VMCLSF : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT
-  Job-UHENIY : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT
-
-
InvocationCount=1  IterationCount=5  LaunchCount=1  
-UnrollFactor=1  WarmupCount=3  
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method JobRuntime TestImageMeanErrorStdDevRatioRatioSDGen 0Gen 1Gen 2Allocated
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_bw_Fax3.tiff491.6 ms20.40 ms5.30 ms1.000.001000.0000--5768128 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_bw_Fax3.tiff6,970.2 ms70.64 ms10.93 ms14.230.121000.00001000.00001000.0000241518600 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_bw_Fax3.tiff486.2 ms23.15 ms3.58 ms1.000.001000.0000--5751016 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_bw_Fax3.tiff4,150.2 ms322.16 ms83.66 ms8.470.16---235961088 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_bw_Fax3.tiff490.1 ms12.76 ms3.31 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_bw_Fax3.tiff3,582.9 ms61.89 ms16.07 ms7.310.06---235961496 B
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_bw_Rle.tiff499.1 ms26.71 ms6.94 ms1.000.001000.0000--8494472 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_bw_Rle.tiff7,290.4 ms938.28 ms243.67 ms14.610.331000.00001000.00001000.0000237020384 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_bw_Rle.tiff490.6 ms30.19 ms4.67 ms1.000.001000.0000--8475688 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_bw_Rle.tiff4,230.2 ms35.59 ms5.51 ms8.620.08---235961944 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_bw_Rle.tiff487.6 ms12.07 ms1.87 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_bw_Rle.tiff3,647.4 ms42.62 ms11.07 ms7.480.04---235962184 B
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_grayscale_uncompressed.tiff606.7 ms20.45 ms5.31 ms1.000.0018000.0000--90301696 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_grayscale_uncompressed.tiff1,852.9 ms6.74 ms1.75 ms3.050.03---235970584 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_grayscale_uncompressed.tiff606.6 ms36.58 ms9.50 ms1.000.0018000.0000--90104048 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_grayscale_uncompressed.tiff764.3 ms15.69 ms4.08 ms1.260.02---235965376 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_grayscale_uncompressed.tiff569.6 ms17.44 ms4.53 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_grayscale_uncompressed.tiff655.2 ms17.48 ms4.54 ms1.150.01---235965488 B
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_palette_uncompressed.tiff578.0 ms22.32 ms5.80 ms1.000.0018000.0000--90301696 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_palette_uncompressed.tiff3,336.9 ms21.42 ms5.56 ms5.770.07---236003608 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_palette_uncompressed.tiff601.9 ms40.85 ms6.32 ms1.000.0018000.0000--90107368 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_palette_uncompressed.tiff1,971.9 ms15.69 ms4.07 ms3.280.04---235996096 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_palette_uncompressed.tiff566.1 ms28.06 ms4.34 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_palette_uncompressed.tiff1,664.1 ms11.59 ms1.79 ms2.940.02---235996208 B
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_rgb_deflate.tiff357.4 ms15.54 ms2.40 ms1.000.003000.0000--9662560 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_rgb_deflate.tiff776.1 ms14.51 ms3.77 ms2.170.0122000.00001000.00001000.0000303476856 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_deflate.tiff359.7 ms12.29 ms3.19 ms1.000.003000.0000--9629400 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_deflate.tiff554.5 ms16.78 ms4.36 ms1.540.022000.00001000.00001000.0000239716144 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_rgb_deflate.tiff353.2 ms7.22 ms1.12 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_rgb_deflate.tiff557.1 ms10.79 ms2.80 ms1.580.002000.00001000.00001000.0000239470552 B
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_rgb_lzw.tiff511.0 ms6.43 ms1.67 ms1.000.003000.0000--11600840 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_rgb_lzw.tiff2,691.6 ms16.81 ms2.60 ms5.270.02---236044312 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_lzw.tiff511.4 ms11.44 ms1.77 ms1.000.003000.0000--11569776 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_lzw.tiff1,654.1 ms12.42 ms1.92 ms3.230.01---236041592 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_rgb_lzw.tiff507.7 ms8.89 ms2.31 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_rgb_lzw.tiff1,689.5 ms40.41 ms6.25 ms3.330.03---236041656 B
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_rgb_packbits.tiff776.8 ms31.69 ms8.23 ms1.000.0056000.0000--304057016 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_rgb_packbits.tiff531.2 ms23.17 ms6.02 ms0.680.01---236003352 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_packbits.tiff764.2 ms41.43 ms6.41 ms1.000.0056000.0000--303861120 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_packbits.tiff300.0 ms4.39 ms0.68 ms0.390.00---235998408 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_rgb_packbits.tiff659.1 ms34.59 ms8.98 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_rgb_packbits.tiff297.5 ms21.13 ms5.49 ms0.450.00---235998520 B
'System.Drawing Tiff'Job-KSIANY.NET 4.7.2medium_rgb_uncompressed.tiff742.5 ms50.45 ms13.10 ms1.000.0055000.0000--302644272 B
'ImageSharp Tiff'Job-KSIANY.NET 4.7.2medium_rgb_uncompressed.tiff414.3 ms15.37 ms3.99 ms0.560.01---235986968 B
'System.Drawing Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_uncompressed.tiff750.2 ms74.13 ms19.25 ms1.000.0055000.0000--302448096 B
'ImageSharp Tiff'Job-VMCLSF.NET Core 2.1medium_rgb_uncompressed.tiff283.6 ms21.56 ms5.60 ms0.380.01---235981128 B
'System.Drawing Tiff'Job-UHENIY.NET Core 3.1medium_rgb_uncompressed.tiff662.6 ms49.79 ms12.93 ms1.000.00---176 B
'ImageSharp Tiff'Job-UHENIY.NET Core 3.1medium_rgb_uncompressed.tiff278.6 ms9.48 ms2.46 ms0.420.01---235981352 B
- - diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-default.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-default.md deleted file mode 100644 index 886e2bb3e8..0000000000 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-default.md +++ /dev/null @@ -1,74 +0,0 @@ - -BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 -Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=5.0.101 - [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT - Job-KBSVFT : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT - Job-SLIUCH : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT - Job-EFFLUU : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT - -IterationCount=3 LaunchCount=1 WarmupCount=3 - - Method | Job | Runtime | TestImage | Compression | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | ----------------------- |----------- |-------------- |-------------------------------------- |---------------- |-----------:|------------:|----------:|------:|--------:|----------:|----------:|---------:|-----------:| - **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **None** | **6.614 ms** | **0.2900 ms** | **0.0159 ms** | **1.00** | **0.00** | **984.3750** | **984.3750** | **984.3750** | **11570062 B** | - 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 4.844 ms | 0.8879 ms | 0.0487 ms | 0.73 | 0.01 | 375.0000 | 335.9375 | 335.9375 | 7445922 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 6.953 ms | 0.2917 ms | 0.0160 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 11562768 B | - 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 3.189 ms | 15.5206 ms | 0.8507 ms | 0.46 | 0.12 | 925.7813 | 886.7188 | 882.8125 | 7444718 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.884 ms | 0.7275 ms | 0.0399 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 8672224 B | - 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 3.342 ms | 18.8082 ms | 1.0309 ms | 0.57 | 0.18 | 796.8750 | 765.6250 | 757.8125 | 7444631 B | - | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Deflate** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | - 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 87.815 ms | 11.2070 ms | 0.6143 ms | ? | ? | 833.3333 | 333.3333 | 333.3333 | 6617521 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | - 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 84.005 ms | 3.1221 ms | 0.1711 ms | ? | ? | 1000.0000 | 500.0000 | 500.0000 | 6605507 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | - 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 81.102 ms | 6.5299 ms | 0.3579 ms | ? | ? | 1000.0000 | 428.5714 | 428.5714 | 6604792 B | - | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Lzw** | **47.121 ms** | **7.2057 ms** | **0.3950 ms** | **1.00** | **0.00** | **818.1818** | **818.1818** | **818.1818** | **10673499 B** | - 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 125.569 ms | 5.9762 ms | 0.3276 ms | 2.66 | 0.03 | 500.0000 | 500.0000 | 500.0000 | 8423760 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 47.311 ms | 4.2582 ms | 0.2334 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 10668688 B | - 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 96.217 ms | 10.7439 ms | 0.5889 ms | 2.03 | 0.02 | 333.3333 | 333.3333 | 333.3333 | 8422488 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 46.347 ms | 3.7463 ms | 0.2053 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 8001750 B | - 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 93.635 ms | 11.9328 ms | 0.6541 ms | 2.02 | 0.01 | 333.3333 | 333.3333 | 333.3333 | 8422504 B | - | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **PackBits** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | - 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 27.449 ms | 2.1924 ms | 0.1202 ms | ? | ? | 375.0000 | 343.7500 | 343.7500 | 7453052 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | - 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 19.935 ms | 1.6746 ms | 0.0918 ms | ? | ? | 375.0000 | 343.7500 | 343.7500 | 7451912 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | - 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 19.664 ms | 9.2973 ms | 0.5096 ms | ? | ? | 375.0000 | 343.7500 | 343.7500 | 7451974 B | - | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **CcittGroup3Fax** | **43.335 ms** | **2.7418 ms** | **0.1503 ms** | **1.00** | **0.00** | **-** | **-** | **-** | **1169683 B** | - 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 191.413 ms | 55.3579 ms | 3.0344 ms | 4.42 | 0.07 | 3333.3333 | 1333.3333 | 333.3333 | 22714336 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.559 ms | 4.3644 ms | 0.2392 ms | 1.00 | 0.00 | - | - | - | 1169200 B | - 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 180.059 ms | 38.0202 ms | 2.0840 ms | 4.13 | 0.03 | 3666.6667 | 2000.0000 | 666.6667 | 22658509 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.437 ms | 3.9436 ms | 0.2162 ms | 1.00 | 0.00 | - | - | - | 850187 B | - 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 171.370 ms | 129.4719 ms | 7.0968 ms | 3.94 | 0.14 | 3333.3333 | 1333.3333 | 333.3333 | 22658261 B | - | | | | | | | | | | | | | | - **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **ModifiedHuffman** | **17.099 ms** | **9.2464 ms** | **0.5068 ms** | **1.00** | **0.00** | **937.5000** | **937.5000** | **937.5000** | **11561706 B** | - 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 191.066 ms | 16.8580 ms | 0.9240 ms | 11.18 | 0.36 | 3333.3333 | 1333.3333 | 333.3333 | 22710384 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 17.035 ms | 1.8390 ms | 0.1008 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 11555088 B | - 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 177.379 ms | 33.9255 ms | 1.8596 ms | 10.41 | 0.06 | 3666.6667 | 2000.0000 | 666.6667 | 22656395 B | - | | | | | | | | | | | | | | - 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 15.948 ms | 3.3609 ms | 0.1842 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 8666468 B | - 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 167.231 ms | 21.2228 ms | 1.1633 ms | 10.49 | 0.09 | 3333.3333 | 1333.3333 | 333.3333 | 22659275 B | - -Benchmarks with issues: - EncodeTiff.'System.Drawing Tiff': Job-KBSVFT(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] - EncodeTiff.'System.Drawing Tiff': Job-SLIUCH(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] - EncodeTiff.'System.Drawing Tiff': Job-EFFLUU(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] - EncodeTiff.'System.Drawing Tiff': Job-KBSVFT(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] - EncodeTiff.'System.Drawing Tiff': Job-SLIUCH(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] - EncodeTiff.'System.Drawing Tiff': Job-EFFLUU(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-github.md b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-github.md deleted file mode 100644 index ac9aebf617..0000000000 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report-github.md +++ /dev/null @@ -1,76 +0,0 @@ -``` ini - -BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 -Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=5.0.101 - [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT - Job-KBSVFT : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT - Job-SLIUCH : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT - Job-EFFLUU : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT - -IterationCount=3 LaunchCount=1 WarmupCount=3 - -``` -| Method | Job | Runtime | TestImage | Compression | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | -|---------------------- |----------- |-------------- |-------------------------------------- |---------------- |-----------:|------------:|----------:|------:|--------:|----------:|----------:|---------:|-----------:| -| **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **None** | **6.614 ms** | **0.2900 ms** | **0.0159 ms** | **1.00** | **0.00** | **984.3750** | **984.3750** | **984.3750** | **11570062 B** | -| 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 4.844 ms | 0.8879 ms | 0.0487 ms | 0.73 | 0.01 | 375.0000 | 335.9375 | 335.9375 | 7445922 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 6.953 ms | 0.2917 ms | 0.0160 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 11562768 B | -| 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 3.189 ms | 15.5206 ms | 0.8507 ms | 0.46 | 0.12 | 925.7813 | 886.7188 | 882.8125 | 7444718 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 5.884 ms | 0.7275 ms | 0.0399 ms | 1.00 | 0.00 | 984.3750 | 984.3750 | 984.3750 | 8672224 B | -| 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | None | 3.342 ms | 18.8082 ms | 1.0309 ms | 0.57 | 0.18 | 796.8750 | 765.6250 | 757.8125 | 7444631 B | -| | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Deflate** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | -| 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 87.815 ms | 11.2070 ms | 0.6143 ms | ? | ? | 833.3333 | 333.3333 | 333.3333 | 6617521 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | -| 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 84.005 ms | 3.1221 ms | 0.1711 ms | ? | ? | 1000.0000 | 500.0000 | 500.0000 | 6605507 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | NA | NA | NA | ? | ? | - | - | - | - | -| 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Deflate | 81.102 ms | 6.5299 ms | 0.3579 ms | ? | ? | 1000.0000 | 428.5714 | 428.5714 | 6604792 B | -| | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **Lzw** | **47.121 ms** | **7.2057 ms** | **0.3950 ms** | **1.00** | **0.00** | **818.1818** | **818.1818** | **818.1818** | **10673499 B** | -| 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 125.569 ms | 5.9762 ms | 0.3276 ms | 2.66 | 0.03 | 500.0000 | 500.0000 | 500.0000 | 8423760 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 47.311 ms | 4.2582 ms | 0.2334 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 10668688 B | -| 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 96.217 ms | 10.7439 ms | 0.5889 ms | 2.03 | 0.02 | 333.3333 | 333.3333 | 333.3333 | 8422488 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 46.347 ms | 3.7463 ms | 0.2053 ms | 1.00 | 0.00 | 818.1818 | 818.1818 | 818.1818 | 8001750 B | -| 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | Lzw | 93.635 ms | 11.9328 ms | 0.6541 ms | 2.02 | 0.01 | 333.3333 | 333.3333 | 333.3333 | 8422504 B | -| | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **PackBits** | **NA** | **NA** | **NA** | **?** | **?** | **-** | **-** | **-** | **-** | -| 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 27.449 ms | 2.1924 ms | 0.1202 ms | ? | ? | 375.0000 | 343.7500 | 343.7500 | 7453052 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | -| 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 19.935 ms | 1.6746 ms | 0.0918 ms | ? | ? | 375.0000 | 343.7500 | 343.7500 | 7451912 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | NA | NA | NA | ? | ? | - | - | - | - | -| 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | PackBits | 19.664 ms | 9.2973 ms | 0.5096 ms | ? | ? | 375.0000 | 343.7500 | 343.7500 | 7451974 B | -| | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **CcittGroup3Fax** | **43.335 ms** | **2.7418 ms** | **0.1503 ms** | **1.00** | **0.00** | **-** | **-** | **-** | **1169683 B** | -| 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 191.413 ms | 55.3579 ms | 3.0344 ms | 4.42 | 0.07 | 3333.3333 | 1333.3333 | 333.3333 | 22714336 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.559 ms | 4.3644 ms | 0.2392 ms | 1.00 | 0.00 | - | - | - | 1169200 B | -| 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 180.059 ms | 38.0202 ms | 2.0840 ms | 4.13 | 0.03 | 3666.6667 | 2000.0000 | 666.6667 | 22658509 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 43.437 ms | 3.9436 ms | 0.2162 ms | 1.00 | 0.00 | - | - | - | 850187 B | -| 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | CcittGroup3Fax | 171.370 ms | 129.4719 ms | 7.0968 ms | 3.94 | 0.14 | 3333.3333 | 1333.3333 | 333.3333 | 22658261 B | -| | | | | | | | | | | | | | | -| **'System.Drawing Tiff'** | **Job-KBSVFT** | **.NET 4.7.2** | **Tiff/Calliphora_rgb_uncompressed.tiff** | **ModifiedHuffman** | **17.099 ms** | **9.2464 ms** | **0.5068 ms** | **1.00** | **0.00** | **937.5000** | **937.5000** | **937.5000** | **11561706 B** | -| 'ImageSharp Tiff' | Job-KBSVFT | .NET 4.7.2 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 191.066 ms | 16.8580 ms | 0.9240 ms | 11.18 | 0.36 | 3333.3333 | 1333.3333 | 333.3333 | 22710384 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 17.035 ms | 1.8390 ms | 0.1008 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 11555088 B | -| 'ImageSharp Tiff' | Job-SLIUCH | .NET Core 2.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 177.379 ms | 33.9255 ms | 1.8596 ms | 10.41 | 0.06 | 3666.6667 | 2000.0000 | 666.6667 | 22656395 B | -| | | | | | | | | | | | | | | -| 'System.Drawing Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 15.948 ms | 3.3609 ms | 0.1842 ms | 1.00 | 0.00 | 937.5000 | 937.5000 | 937.5000 | 8666468 B | -| 'ImageSharp Tiff' | Job-EFFLUU | .NET Core 3.1 | Tiff/Calliphora_rgb_uncompressed.tiff | ModifiedHuffman | 167.231 ms | 21.2228 ms | 1.1633 ms | 10.49 | 0.09 | 3333.3333 | 1333.3333 | 333.3333 | 22659275 B | - -Benchmarks with issues: - EncodeTiff.'System.Drawing Tiff': Job-KBSVFT(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] - EncodeTiff.'System.Drawing Tiff': Job-SLIUCH(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] - EncodeTiff.'System.Drawing Tiff': Job-EFFLUU(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=Deflate] - EncodeTiff.'System.Drawing Tiff': Job-KBSVFT(Runtime=.NET 4.7.2, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] - EncodeTiff.'System.Drawing Tiff': Job-SLIUCH(Runtime=.NET Core 2.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] - EncodeTiff.'System.Drawing Tiff': Job-EFFLUU(Runtime=.NET Core 3.1, IterationCount=3, LaunchCount=1, WarmupCount=3) [TestImage=Tiff/Calliphora_rgb_uncompressed.tiff, Compression=PackBits] diff --git a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report.html b/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report.html deleted file mode 100644 index 6609649553..0000000000 --- a/tests/Images/Input/Tiff/Benchmarks/SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-report.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - -SixLabors.ImageSharp.Benchmarks.Codecs.EncodeTiff-20210207-120859 - - - - -

-BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
-Intel Core i7-3610QM CPU 2.30GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores
-.NET Core SDK=5.0.101
-  [Host]     : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
-  Job-KBSVFT : .NET Framework 4.8 (4.8.4300.0), X64 RyuJIT
-  Job-SLIUCH : .NET Core 2.1.23 (CoreCLR 4.6.29321.03, CoreFX 4.6.29321.01), X64 RyuJIT
-  Job-EFFLUU : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT
-
-
IterationCount=3  LaunchCount=1  WarmupCount=3  
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method JobRuntime TestImageCompressionMeanErrorStdDevRatioRatioSDGen 0Gen 1Gen 2Allocated
'System.Drawing Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffNone6.614 ms0.2900 ms0.0159 ms1.000.00984.3750984.3750984.375011570062 B
'ImageSharp Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffNone4.844 ms0.8879 ms0.0487 ms0.730.01375.0000335.9375335.93757445922 B
'System.Drawing Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffNone6.953 ms0.2917 ms0.0160 ms1.000.00984.3750984.3750984.375011562768 B
'ImageSharp Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffNone3.189 ms15.5206 ms0.8507 ms0.460.12925.7813886.7188882.81257444718 B
'System.Drawing Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffNone5.884 ms0.7275 ms0.0399 ms1.000.00984.3750984.3750984.37508672224 B
'ImageSharp Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffNone3.342 ms18.8082 ms1.0309 ms0.570.18796.8750765.6250757.81257444631 B
'System.Drawing Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffDeflateNANANA??----
'ImageSharp Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffDeflate87.815 ms11.2070 ms0.6143 ms??833.3333333.3333333.33336617521 B
'System.Drawing Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffDeflateNANANA??----
'ImageSharp Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffDeflate84.005 ms3.1221 ms0.1711 ms??1000.0000500.0000500.00006605507 B
'System.Drawing Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffDeflateNANANA??----
'ImageSharp Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffDeflate81.102 ms6.5299 ms0.3579 ms??1000.0000428.5714428.57146604792 B
'System.Drawing Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffLzw47.121 ms7.2057 ms0.3950 ms1.000.00818.1818818.1818818.181810673499 B
'ImageSharp Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffLzw125.569 ms5.9762 ms0.3276 ms2.660.03500.0000500.0000500.00008423760 B
'System.Drawing Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffLzw47.311 ms4.2582 ms0.2334 ms1.000.00818.1818818.1818818.181810668688 B
'ImageSharp Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffLzw96.217 ms10.7439 ms0.5889 ms2.030.02333.3333333.3333333.33338422488 B
'System.Drawing Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffLzw46.347 ms3.7463 ms0.2053 ms1.000.00818.1818818.1818818.18188001750 B
'ImageSharp Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffLzw93.635 ms11.9328 ms0.6541 ms2.020.01333.3333333.3333333.33338422504 B
'System.Drawing Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffPackBitsNANANA??----
'ImageSharp Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffPackBits27.449 ms2.1924 ms0.1202 ms??375.0000343.7500343.75007453052 B
'System.Drawing Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffPackBitsNANANA??----
'ImageSharp Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffPackBits19.935 ms1.6746 ms0.0918 ms??375.0000343.7500343.75007451912 B
'System.Drawing Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffPackBitsNANANA??----
'ImageSharp Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffPackBits19.664 ms9.2973 ms0.5096 ms??375.0000343.7500343.75007451974 B
'System.Drawing Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax43.335 ms2.7418 ms0.1503 ms1.000.00---1169683 B
'ImageSharp Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax191.413 ms55.3579 ms3.0344 ms4.420.073333.33331333.3333333.333322714336 B
'System.Drawing Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax43.559 ms4.3644 ms0.2392 ms1.000.00---1169200 B
'ImageSharp Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax180.059 ms38.0202 ms2.0840 ms4.130.033666.66672000.0000666.666722658509 B
'System.Drawing Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax43.437 ms3.9436 ms0.2162 ms1.000.00---850187 B
'ImageSharp Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffCcittGroup3Fax171.370 ms129.4719 ms7.0968 ms3.940.143333.33331333.3333333.333322658261 B
'System.Drawing Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman17.099 ms9.2464 ms0.5068 ms1.000.00937.5000937.5000937.500011561706 B
'ImageSharp Tiff'Job-KBSVFT.NET 4.7.2Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman191.066 ms16.8580 ms0.9240 ms11.180.363333.33331333.3333333.333322710384 B
'System.Drawing Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman17.035 ms1.8390 ms0.1008 ms1.000.00937.5000937.5000937.500011555088 B
'ImageSharp Tiff'Job-SLIUCH.NET Core 2.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman177.379 ms33.9255 ms1.8596 ms10.410.063666.66672000.0000666.666722656395 B
'System.Drawing Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman15.948 ms3.3609 ms0.1842 ms1.000.00937.5000937.5000937.50008666468 B
'ImageSharp Tiff'Job-EFFLUU.NET Core 3.1Tiff/Calliphora_rgb_uncompressed.tiffModifiedHuffman167.231 ms21.2228 ms1.1633 ms10.490.093333.33331333.3333333.333322659275 B
- - From 729220647ec927e39adb3356fb55bf0460a29bf7 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Mon, 8 Feb 2021 08:41:02 +0300 Subject: [PATCH 08/15] Update readme --- src/ImageSharp/Formats/Tiff/README.md | 14 +++++++------- .../Formats/Tiff/TiffDecoderOptionsParser.cs | 5 +++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/README.md b/src/ImageSharp/Formats/Tiff/README.md index 32c2b1d400..565ecb6cd8 100644 --- a/src/ImageSharp/Formats/Tiff/README.md +++ b/src/ImageSharp/Formats/Tiff/README.md @@ -79,19 +79,19 @@ |CellWidth | | | | |CellLength | | | | |FillOrder | | - | Ignore. In practice is very uncommon, and is not recommended. | -|ImageDescription | | Y | | -|Make | | Y | | -|Model | | Y | | +|ImageDescription | Y | Y | | +|Make | Y | Y | | +|Model | Y | Y | | |StripOffsets | Y | Y | | |Orientation | | - | Ignore. Many readers ignore this tag. | |SamplesPerPixel | Y | - | Currently ignored, as can be inferred from count of BitsPerSample | -|RowsPerStrip | | Y | | +|RowsPerStrip | Y | Y | | |StripByteCounts | Y | Y | | |MinSampleValue | | | | |MaxSampleValue | | | | |XResolution | Y | Y | | |YResolution | Y | Y | | -|PlanarConfiguration | | Y | | +|PlanarConfiguration | | Y | Encoding support only chunky. | |FreeOffsets | | | | |FreeByteCounts | | | | |GrayResponseUnit | | | | @@ -110,7 +110,7 @@ | |Encoder|Decoder|Comments | |---------------------------|:-----:|:-----:|--------------------------| |NewSubfileType | | | | -|DocumentName | | | | +|DocumentName | Y | Y | | |PageName | | | | |XPosition | | | | |YPosition | | | | @@ -166,7 +166,7 @@ |YCbCrSubSampling | | | | |YCbCrPositioning | | | | |ReferenceBlackWhite | | | | -|StripRowCounts | | - | | +|StripRowCounts | - | - | See RFC 2301 (File Format for Internet Fax). | |XMP | Y | Y | | |ImageID | | | | |ImageLayer | | | | diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs index 2c632b36e4..123b8494eb 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs @@ -50,6 +50,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff } } + if (entries.ExifProfile.GetValue(ExifTag.StripRowCounts) != null) + { + TiffThrowHelper.ThrowNotSupported("Variable-sized strips are not supported."); + } + options.PlanarConfiguration = entries.PlanarConfiguration; options.Predictor = entries.Predictor; options.PhotometricInterpretation = entries.PhotometricInterpretation; From 7c97634bcbd5812b514e39a325f548a2fc131ebf Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 12 Feb 2021 12:54:16 +0100 Subject: [PATCH 09/15] Change BinaryDither to FloydSteinberg --- src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs index 76d5cbaa04..5db0eff733 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs @@ -3,12 +3,12 @@ using System; using System.Buffers; + using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; -using SixLabors.ImageSharp.Processing.Processors.Dithering; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { @@ -27,11 +27,13 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers // Convert image to black and white. // TODO: Should we allow to skip this by the user, if its known to be black and white already? this.imageBlackWhite = new Image(configuration, new ImageMetadata(), new[] { image.Clone() }); - this.imageBlackWhite.Mutate(img => img.BinaryDither(default(ErrorDither))); + this.imageBlackWhite.Mutate(img => img.BinaryDither(KnownDitherings.FloydSteinberg)); } + /// public override int BitsPerPixel => 1; + /// protected override void EncodeStrip(int y, int height, TiffBaseCompressor compressor) { if (this.pixelsAsGray == null) @@ -89,6 +91,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers } } + /// protected override void Dispose(bool disposing) { this.imageBlackWhite?.Dispose(); From 3b4bc1de2384239add75ae5ad33b2ee068ba79f1 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sat, 13 Feb 2021 12:47:29 +0300 Subject: [PATCH 10/15] Remove TiffEncoderPixelStorageMethod, add CRC writing for deflate. Correct tests. --- .../Compressors/DeflateCompressor.cs | 2 +- .../Formats/Tiff/ITiffEncoderOptions.cs | 5 - src/ImageSharp/Formats/Tiff/TiffEncoder.cs | 5 +- .../Formats/Tiff/TiffEncoderCore.cs | 35 +++-- .../Tiff/TiffEncoderPixelStorageMethod.cs | 26 ---- .../Formats/Tiff/TiffEncoderTests.cs | 122 ++++++++++-------- 6 files changed, 86 insertions(+), 109 deletions(-) delete mode 100644 src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs index f4b6c6ad7f..64d3b1ea31 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs @@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors stream.Write(rows); stream.Flush(); - //// stream.Dispose(); // todo: dispose write crc + stream.Dispose(); int size = (int)this.memoryStream.Position; diff --git a/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs b/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs index 8d0a15ffe6..03a8328eca 100644 --- a/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs +++ b/src/ImageSharp/Formats/Tiff/ITiffEncoderOptions.cs @@ -38,11 +38,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff ///
IQuantizer Quantizer { get; } - /// - /// Gets the pixel storage method. - /// - TiffEncoderPixelStorageMethod PixelStorageMethod { get; } - /// /// Gets the maximum size of strip (bytes). /// diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoder.cs b/src/ImageSharp/Formats/Tiff/TiffEncoder.cs index 86091a5c48..5f747a6851 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoder.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoder.cs @@ -33,10 +33,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff public IQuantizer Quantizer { get; set; } /// - public TiffEncoderPixelStorageMethod PixelStorageMethod { get; set; } - - /// - public int MaxStripBytes { get; set; } + public int MaxStripBytes { get; set; } = TiffEncoderCore.DefaultStripSize; /// public void Encode(Image image, Stream stream) diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index f378e2fe8e..ec9c761aa4 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -25,14 +25,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff ///
internal sealed class TiffEncoderCore : IImageEncoderInternals { + public const int DefaultStripSize = 8 * 1024; + public static readonly ByteOrder ByteOrder = BitConverter.IsLittleEndian ? ByteOrder.LittleEndian : ByteOrder.BigEndian; private static readonly ushort ByteOrderMarker = BitConverter.IsLittleEndian ? TiffConstants.ByteOrderLittleEndianShort : TiffConstants.ByteOrderBigEndianShort; - private const int DefaultStripSize = 8 * 1024; - /// /// Used for allocating memory during processing operations. /// @@ -58,8 +58,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff ///
private readonly DeflateCompressionLevel compressionLevel; - private readonly TiffEncoderPixelStorageMethod storageMode; - private readonly int maxStripBytes; /// @@ -75,7 +73,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff this.quantizer = options.Quantizer ?? KnownQuantizers.Octree; this.UseHorizontalPredictor = options.UseHorizontalPredictor; this.compressionLevel = options.CompressionLevel; - this.storageMode = options.PixelStorageMethod; this.maxStripBytes = options.MaxStripBytes; } @@ -182,19 +179,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff private int CalcRowsPerStrip(ImageFrame image, int bytesPerRow) { - switch (this.storageMode) - { - default: - case TiffEncoderPixelStorageMethod.Auto: - case TiffEncoderPixelStorageMethod.MultiStrip: - int sz = this.maxStripBytes > 0 ? this.maxStripBytes : DefaultStripSize; - int height = sz / bytesPerRow; - - return height > 0 ? (height < image.Height ? height : image.Height) : 1; + int sz = this.maxStripBytes > 0 ? this.maxStripBytes : DefaultStripSize; + int height = sz / bytesPerRow; - case TiffEncoderPixelStorageMethod.SingleStrip: - return image.Height; - } + return height > 0 ? (height < image.Height ? height : image.Height) : 1; } /// @@ -258,9 +246,16 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff { if (this.CompressionType == TiffEncoderCompression.CcittGroup3Fax || this.CompressionType == TiffEncoderCompression.ModifiedHuffman) { - this.Mode = TiffEncodingMode.BiColor; - this.bitsPerPixel = TiffBitsPerPixel.Pixel1; - return; + if (this.Mode == TiffEncodingMode.Default) + { + this.Mode = TiffEncodingMode.BiColor; + this.bitsPerPixel = TiffBitsPerPixel.Pixel1; + return; + } + else if (this.Mode != TiffEncodingMode.BiColor) + { + TiffThrowHelper.ThrowImageFormatException($"The {this.CompressionType} compression and {this.Mode} aren't compatible. Please use {this.CompressionType} only with {TiffEncodingMode.BiColor} or {TiffEncodingMode.Default} mode."); + } } if (this.Mode == TiffEncodingMode.Default) diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs deleted file mode 100644 index e1e12c08d0..0000000000 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderPixelStorageMethod.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. - -namespace SixLabors.ImageSharp.Formats.Experimental.Tiff -{ - /// - /// The tiff encoder pixel storage method. - /// - public enum TiffEncoderPixelStorageMethod - { - /// - /// The auto mode. - /// - Auto, - - /// - /// The single strip mode. - /// - SingleStrip, - - /// - /// The multi strip mode. - /// - MultiStrip, - } -} diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index 774454259d..b9368e4ca6 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using System; using System.IO; using SixLabors.ImageSharp.Formats; @@ -21,12 +22,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff { private static readonly IImageDecoder ReferenceDecoder = new MagickReferenceDecoder(); - private readonly Configuration configuration; + private static readonly Configuration Configuration; - public TiffEncoderTests() + static TiffEncoderTests() { - this.configuration = new Configuration(); - this.configuration.AddTiff(); + Configuration = new Configuration(); + Configuration.AddTiff(); } [Theory] @@ -62,7 +63,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff // assert memStream.Position = 0; - using var output = Image.Load(this.configuration, memStream); + using var output = Image.Load(Configuration, memStream); TiffMetadata meta = output.Metadata.GetTiffMetadata(); Assert.Equal(expectedBitsPerPixel, meta.BitsPerPixel); Assert.Equal(expectedCompression, meta.Compression); @@ -85,7 +86,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff // assert memStream.Position = 0; - using var output = Image.Load(this.configuration, memStream); + using var output = Image.Load(Configuration, memStream); TiffMetadata meta = output.Metadata.GetTiffMetadata(); Assert.Equal(expectedBitsPerPixel, meta.BitsPerPixel); } @@ -108,13 +109,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff // assert memStream.Position = 0; - using var output = Image.Load(this.configuration, memStream); + using var output = Image.Load(Configuration, memStream); TiffMetadata meta = output.Metadata.GetTiffMetadata(); Assert.Equal(TiffBitsPerPixel.Pixel1, meta.BitsPerPixel); Assert.Equal(expectedCompression, meta.Compression); } + [Theory] + [InlineData(TiffEncodingMode.ColorPalette, TiffEncoderCompression.CcittGroup3Fax)] + [InlineData(TiffEncodingMode.ColorPalette, TiffEncoderCompression.ModifiedHuffman)] + [InlineData(TiffEncodingMode.Gray, TiffEncoderCompression.ModifiedHuffman)] + [InlineData(TiffEncodingMode.Rgb, TiffEncoderCompression.ModifiedHuffman)] + public void TiffEncoder_IncompatibilityOptions(TiffEncodingMode mode, TiffEncoderCompression compression) + where TPixel : unmanaged, IPixel + { + // arrange + using var input = new Image(10, 10); + var encoder = new TiffEncoder() { Mode = mode, Compression = compression }; + using var memStream = new MemoryStream(); + + // act + Assert.Throws(() => input.Save(memStream, encoder)); + } + [Theory] [WithFile(Calliphora_RgbUncompressed, PixelTypes.Rgba32)] public void TiffEncoder_EncodeRgb_Works(TestImageProvider provider) @@ -207,30 +225,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [Theory] [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] - public void TiffEncoder_EncodeColorPalette_WithLzwCompression_Works(TestImageProvider provider) - where TPixel : unmanaged, IPixel - { - var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, PixelStorageMethod = TiffEncoderPixelStorageMethod.SingleStrip }; - - this.TiffEncoderPaletteTest(provider, encoder); - } - - [Theory] - [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] - public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Works(TestImageProvider provider) + public void TiffEncoder_EncodeColorPalette_WithLzwCompression_Works_Bug(TestImageProvider provider) where TPixel : unmanaged, IPixel { - var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, UseHorizontalPredictor = true, PixelStorageMethod = TiffEncoderPixelStorageMethod.SingleStrip }; + var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw }; this.TiffEncoderPaletteTest(provider, encoder); } [Theory] [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] - public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Bug(TestImageProvider provider) + public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Works_Bug(TestImageProvider provider) where TPixel : unmanaged, IPixel { - var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, PixelStorageMethod = TiffEncoderPixelStorageMethod.MultiStrip, UseHorizontalPredictor = true }; + var encoder = new TiffEncoder { Mode = TiffEncodingMode.ColorPalette, Compression = TiffEncoderCompression.Lzw, UseHorizontalPredictor = true }; Assert.Throws(() => this.TiffEncoderPaletteTest(provider, encoder)); } @@ -257,7 +265,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff image.Save(memStream, encoder); memStream.Position = 0; - using var encodedImage = (Image)Image.Load(this.configuration, memStream); + using var encodedImage = (Image)Image.Load(Configuration, memStream); var encodedImagePath = provider.Utility.SaveTestOutputFile(encodedImage, "tiff", encoder); TiffTestUtils.CompareWithReferenceDecoder(encodedImagePath, encodedImage); } @@ -288,22 +296,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Pixel1, TiffEncodingMode.BiColor, TiffEncoderCompression.ModifiedHuffman); [Theory] - [WithFile(Calliphora_BiColorUncompressed, PixelTypes.L8, TiffEncodingMode.BiColor, TiffEncoderPixelStorageMethod.SingleStrip)] - [WithFile(Calliphora_BiColorUncompressed, PixelTypes.L8, TiffEncodingMode.BiColor, TiffEncoderPixelStorageMethod.MultiStrip, 9 * 1024)] - [WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffEncodingMode.Gray, TiffEncoderPixelStorageMethod.SingleStrip)] - [WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffEncodingMode.Gray, TiffEncoderPixelStorageMethod.MultiStrip, 16 * 1024)] - [WithFile(PaletteDeflateMultistrip, PixelTypes.L8, TiffEncodingMode.ColorPalette, TiffEncoderPixelStorageMethod.SingleStrip)] - [WithFile(PaletteDeflateMultistrip, PixelTypes.L8, TiffEncodingMode.ColorPalette, TiffEncoderPixelStorageMethod.MultiStrip, 32 * 1024)] - [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncodingMode.Rgb, TiffEncoderPixelStorageMethod.SingleStrip)] - [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncodingMode.Rgb, TiffEncoderPixelStorageMethod.MultiStrip, 64 * 1024)] - public void TiffEncoder_StorageMethods(TestImageProvider provider, TiffEncodingMode mode, TiffEncoderPixelStorageMethod storageMethod, int maxSize = 0) + [WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffEncodingMode.Gray, TiffEncoderCompression.PackBits, 16 * 1024)] + [WithFile(PaletteDeflateMultistrip, PixelTypes.L8, TiffEncodingMode.ColorPalette, TiffEncoderCompression.Lzw, 32 * 1024)] + [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncodingMode.Rgb, TiffEncoderCompression.Deflate, 64 * 1024)] + [WithFile(RgbUncompressed, PixelTypes.Rgb24, TiffEncodingMode.Rgb, TiffEncoderCompression.None, 10 * 1024)] + [WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffEncodingMode.Rgb, TiffEncoderCompression.None, 30 * 1024)] + [WithFile(RgbUncompressed, PixelTypes.Rgb48, TiffEncodingMode.Rgb, TiffEncoderCompression.None, 70 * 1024)] + public void TiffEncoder_StripLength(TestImageProvider provider, TiffEncodingMode mode, TiffEncoderCompression compression, int maxSize) + where TPixel : unmanaged, IPixel => + TestStripLength(provider, mode, compression, maxSize); + + [Theory] + [WithFile(Calliphora_BiColorUncompressed, PixelTypes.L8, TiffEncodingMode.BiColor, TiffEncoderCompression.CcittGroup3Fax, 9 * 1024)] + public void TiffEncoder_StripLength_OutOfBounds(TestImageProvider provider, TiffEncodingMode mode, TiffEncoderCompression compression, int maxSize) + where TPixel : unmanaged, IPixel => + //// CcittGroup3Fax compressed data length can be larger than the original length + Assert.Throws(() => TestStripLength(provider, mode, compression, maxSize)); + + private static void TestStripLength(TestImageProvider provider, TiffEncodingMode mode, TiffEncoderCompression compression, int maxSize) where TPixel : unmanaged, IPixel { // arrange - var tiffEncoder = new TiffEncoder() { PixelStorageMethod = storageMethod, MaxStripBytes = maxSize }; - using Image input = provider.GetImage(); + var tiffEncoder = new TiffEncoder() { Mode = mode, Compression = compression, MaxStripBytes = maxSize }; + Image input = provider.GetImage(); using var memStream = new MemoryStream(); - TiffFrameMetadata inputMeta = input.Frames.RootFrame.Metadata.GetTiffMetadata(); // act @@ -311,24 +327,28 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff // assert memStream.Position = 0; - using var output = Image.Load(this.configuration, memStream); + var output = Image.Load(Configuration, memStream); TiffFrameMetadata meta = output.Frames.RootFrame.Metadata.GetTiffMetadata(); - if (storageMethod == TiffEncoderPixelStorageMethod.SingleStrip) + Assert.True(output.Height > (int)meta.RowsPerStrip); + Assert.True(meta.StripOffsets.Length > 1); + Assert.True(meta.StripByteCounts.Length > 1); + + foreach (Number sz in meta.StripByteCounts) { - Assert.Equal(output.Height, (int)meta.RowsPerStrip); - Assert.Equal(1, meta.StripOffsets.Length); - Assert.Equal(1, meta.StripByteCounts.Length); + Assert.True((uint)sz <= maxSize); } - else - { - Assert.True(output.Height > (int)meta.RowsPerStrip); - Assert.True(meta.StripOffsets.Length > 1); - Assert.True(meta.StripByteCounts.Length > 1); - foreach (Number sz in meta.StripByteCounts) + // for uncompressed more accurate test + if (compression == TiffEncoderCompression.None) + { + for (int i = 0; i < meta.StripByteCounts.Length - 1; i++) { - Assert.True((int)sz <= maxSize); + // the difference must be less than one row + int stripBytes = (int)meta.StripByteCounts[i]; + var widthBytes = (meta.BitsPerPixel + 7) / 8 * (int)meta.Width; + + Assert.True((maxSize - stripBytes) < widthBytes); } } @@ -338,9 +358,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff (TiffBitsPerPixel)inputMeta.BitsPerPixel, mode, Convert(inputMeta.Compression), - maxStripSize: maxSize, - storageMethod: storageMethod - ); + maxStripSize: maxSize); } private static void TestTiffEncoderCore( @@ -351,7 +369,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff bool usePredictor = false, bool useExactComparer = true, int maxStripSize = 0, - TiffEncoderPixelStorageMethod? storageMethod = null, float compareTolerance = 0.01f) where TPixel : unmanaged, IPixel { @@ -361,7 +378,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Mode = mode, Compression = compression, UseHorizontalPredictor = usePredictor, - PixelStorageMethod = storageMethod ?? TiffEncoderPixelStorageMethod.Auto, MaxStripBytes = maxStripSize }; @@ -382,10 +398,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff return TiffEncoderCompression.Lzw; case TiffCompression.PackBits: return TiffEncoderCompression.PackBits; + case TiffCompression.Ccitt1D: + return TiffEncoderCompression.ModifiedHuffman; case TiffCompression.CcittGroup3Fax: return TiffEncoderCompression.CcittGroup3Fax; - case TiffCompression.CcittGroup4Fax: - return TiffEncoderCompression.ModifiedHuffman; } } } From 4b210bbfe01ea14673b7785a2c6366c64f0bd4a7 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sun, 14 Feb 2021 18:03:15 +0300 Subject: [PATCH 11/15] Rename tests --- tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index 6efe92b232..c2dccd2a74 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -213,13 +213,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [Theory] [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] - public void TiffEncoder_EncodeColorPalette_WithLzwCompression_Works_Bug(TestImageProvider provider) + public void TiffEncoder_EncodeColorPalette_WithLzwCompression_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Pixel24, TiffEncodingMode.ColorPalette, TiffEncoderCompression.Lzw, useExactComparer: false, compareTolerance: 0.001f); [Theory] [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] - public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Works_Bug(TestImageProvider provider) + public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Pixel24, TiffEncodingMode.ColorPalette, TiffEncoderCompression.Lzw, usePredictor: true, useExactComparer: false, compareTolerance: 0.001f); From 8cc2ce38f81faa0c33a0b1e34cc72dd4cf3cdfc2 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sun, 14 Feb 2021 19:22:47 +0300 Subject: [PATCH 12/15] Correct test --- tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index c2dccd2a74..0041d05ce4 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -121,11 +121,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [InlineData(TiffEncodingMode.ColorPalette, TiffEncoderCompression.ModifiedHuffman)] [InlineData(TiffEncodingMode.Gray, TiffEncoderCompression.ModifiedHuffman)] [InlineData(TiffEncodingMode.Rgb, TiffEncoderCompression.ModifiedHuffman)] - public void TiffEncoder_IncompatibilityOptions(TiffEncodingMode mode, TiffEncoderCompression compression) - where TPixel : unmanaged, IPixel + public void TiffEncoder_IncompatibilityOptions(TiffEncodingMode mode, TiffEncoderCompression compression) { // arrange - using var input = new Image(10, 10); + using var input = new Image(10, 10); var encoder = new TiffEncoder() { Mode = mode, Compression = compression }; using var memStream = new MemoryStream(); From 677800f3267ed7b41a99a9723f492b62b4e96518 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sun, 14 Feb 2021 20:44:17 +0300 Subject: [PATCH 13/15] PackBits bug fix --- .../Compressors/PackBitsCompressor.cs | 17 +++++++++++------ .../Formats/Tiff/Writers/TiffBiColorWriter.cs | 9 +++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs index 627ca6cbb2..ce5d8a7695 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs @@ -3,8 +3,6 @@ using System; using System.IO; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; -using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors @@ -22,16 +20,23 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors public override void Initialize(int rowsPerStrip) { - int additionalBytes = (this.BytesPerRow / 127) + 1; - this.pixelData = this.Allocator.AllocateManagedByteBuffer((this.BytesPerRow + additionalBytes) * rowsPerStrip); + int additionalBytes = ((this.BytesPerRow + 126) / 127) + 1; + this.pixelData = this.Allocator.AllocateManagedByteBuffer(this.BytesPerRow + additionalBytes); } public override void CompressStrip(Span rows, int height) { + DebugGuard.IsTrue(rows.Length % height == 0, "Invalid height"); + DebugGuard.IsTrue(this.BytesPerRow == rows.Length / height, "The widths must match"); + this.pixelData.Clear(); Span span = this.pixelData.GetSpan(); - int size = PackBitsWriter.PackBits(rows, span); - this.Output.Write(span.Slice(0, size)); + for (int i = 0; i < height; i++) + { + Span row = rows.Slice(i * this.BytesPerRow, this.BytesPerRow); + int size = PackBitsWriter.PackBits(row, span); + this.Output.Write(span.Slice(0, size)); + } } protected override void Dispose(bool disposing) => this.pixelData?.Dispose(); diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs index 5db0eff733..cd17f1665b 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs @@ -51,18 +51,19 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers if (compressor.Method == TiffEncoderCompression.CcittGroup3Fax || compressor.Method == TiffEncoderCompression.ModifiedHuffman) { + // special case for T4BitCompressor compressor.CompressStrip(pixelAsGraySpan, height); } else { + int bytesPerStrip = this.BytesPerRow * height; if (this.bitStrip == null) { - int bytesPerRow = this.BytesPerRow * height; - this.bitStrip = this.MemoryAllocator.AllocateManagedByteBuffer(bytesPerRow); + this.bitStrip = this.MemoryAllocator.AllocateManagedByteBuffer(bytesPerStrip); } - this.bitStrip.Clear(); - Span rows = this.bitStrip.GetSpan(); + Span rows = this.bitStrip.Slice(0, bytesPerStrip); + rows.Clear(); int xx = 0; for (int s = 0; s < height; s++) From 60dcaac07632c836da2a0618c07752a09b4dfd9a Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Sun, 14 Feb 2021 20:53:49 +0300 Subject: [PATCH 14/15] Remove excess clearing --- .../Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs | 1 - src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs index ce5d8a7695..93c37d25dc 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs @@ -29,7 +29,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors DebugGuard.IsTrue(rows.Length % height == 0, "Invalid height"); DebugGuard.IsTrue(this.BytesPerRow == rows.Length / height, "The widths must match"); - this.pixelData.Clear(); Span span = this.pixelData.GetSpan(); for (int i = 0; i < height; i++) { diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs index cd17f1665b..91cc9ddfcb 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs @@ -41,8 +41,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers this.pixelsAsGray = this.MemoryAllocator.Allocate(height * this.Image.Width); } - this.pixelsAsGray.Clear(); - Span pixelAsGraySpan = this.pixelsAsGray.Slice(0, height * this.Image.Width); Span pixels = GetStripPixels(this.imageBlackWhite.GetRootFramePixelBuffer(), y, height); From 20726c3d074d54a689ea34452f5907a608dce3fb Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 15 Feb 2021 13:30:20 +0100 Subject: [PATCH 15/15] Clarify some DebugGuard messages and a little cleanup --- .../Compressors/DeflateCompressor.cs | 4 ++++ .../Compression/Compressors/LzwCompressor.cs | 4 ++++ .../Compression/Compressors/NoCompressor.cs | 4 ++++ .../Compressors/PackBitsCompressor.cs | 4 ++++ .../Decompressors/DeflateTiffCompression.cs | 1 + .../Decompressors/LzwTiffCompression.cs | 1 + .../Decompressors/NoneTiffCompression.cs | 1 + .../Decompressors/PackBitsTiffCompression.cs | 1 + .../Decompressors/T4TiffCompression.cs | 1 + .../Tiff/Compression/TiffBaseCompression.cs | 17 +++++++++++++- .../Tiff/Compression/TiffBaseCompressor.cs | 23 +++++++++++++++++++ .../Tiff/Compression/TiffCompressorFactory.cs | 21 ++++++++--------- .../Compression/TiffDecompressorsFactory.cs | 16 ++++++------- .../Formats/Tiff/TiffEncoderCore.cs | 7 ++++-- .../Tiff/Writers/TiffBaseColorWriter.cs | 1 + .../Formats/Tiff/Writers/TiffBiColorWriter.cs | 6 ++--- .../Tiff/Writers/TiffCompositeColorWriter.cs | 3 ++- .../Formats/Tiff/Writers/TiffGrayWriter.cs | 3 ++- .../Formats/Tiff/Writers/TiffPaletteWriter.cs | 3 +++ .../Formats/Tiff/Writers/TiffRgbWriter.cs | 3 ++- 20 files changed, 95 insertions(+), 29 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs index 64d3b1ea31..46cb63a86e 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs @@ -19,12 +19,15 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors : base(output, allocator, width, bitsPerPixel, predictor) => this.compressionLevel = compressionLevel; + /// public override TiffEncoderCompression Method => TiffEncoderCompression.Deflate; + /// public override void Initialize(int rowsPerStrip) { } + /// public override void CompressStrip(Span rows, int height) { this.memoryStream.Seek(0, SeekOrigin.Begin); @@ -52,6 +55,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors #endif } + /// protected override void Dispose(bool disposing) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs index 84dc95b5f9..d29cf61573 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs @@ -17,10 +17,13 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors { } + /// public override TiffEncoderCompression Method => TiffEncoderCompression.Lzw; + /// public override void Initialize(int rowsPerStrip) => this.lzwEncoder = new TiffLzwEncoder(this.Allocator); + /// public override void CompressStrip(Span rows, int height) { if (this.Predictor == TiffPredictor.Horizontal) @@ -31,6 +34,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors this.lzwEncoder.Encode(rows, this.Output); } + /// protected override void Dispose(bool disposing) => this.lzwEncoder?.Dispose(); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs index 6c6b9ef343..f4a902b46a 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs @@ -13,14 +13,18 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors { } + /// public override TiffEncoderCompression Method => TiffEncoderCompression.None; + /// public override void Initialize(int rowsPerStrip) { } + /// public override void CompressStrip(Span rows, int height) => this.Output.Write(rows); + /// protected override void Dispose(bool disposing) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs index 93c37d25dc..5353b17c3c 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs @@ -16,14 +16,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors { } + /// public override TiffEncoderCompression Method => TiffEncoderCompression.PackBits; + /// public override void Initialize(int rowsPerStrip) { int additionalBytes = ((this.BytesPerRow + 126) / 127) + 1; this.pixelData = this.Allocator.AllocateManagedByteBuffer(this.BytesPerRow + additionalBytes); } + /// public override void CompressStrip(Span rows, int height) { DebugGuard.IsTrue(rows.Length % height == 0, "Invalid height"); @@ -38,6 +41,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors } } + /// protected override void Dispose(bool disposing) => this.pixelData?.Dispose(); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs index a53d69027d..be63bdad86 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs @@ -54,6 +54,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso } } + /// protected override void Dispose(bool disposing) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs index b85aa3a22b..a14738e44a 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs @@ -38,6 +38,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso } } + /// protected override void Dispose(bool disposing) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs index a30997debf..f041a00e9e 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/NoneTiffCompression.cs @@ -23,6 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso /// protected override void Decompress(BufferedReadStream stream, int byteCount, Span buffer) => _ = stream.Read(buffer, 0, Math.Min(buffer.Length, byteCount)); + /// protected override void Dispose(bool disposing) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs index ab67d818d8..c7461a8073 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs @@ -88,6 +88,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso } } + /// protected override void Dispose(bool disposing) => this.compressedDataMemory?.Dispose(); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs index fe4641fb28..275e3d598d 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs @@ -81,6 +81,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Decompresso } } + /// protected override void Dispose(bool disposing) { } diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs index e47b65c991..a403ca0649 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs @@ -17,20 +17,35 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression this.Width = width; this.BitsPerPixel = bitsPerPixel; this.Predictor = predictor; - this.BytesPerRow = ((width * bitsPerPixel) + 7) / 8; } + /// + /// Gets the image width. + /// public int Width { get; } + /// + /// Gets the bits per pixel. + /// public int BitsPerPixel { get; } + /// + /// Gets the bytes per row. + /// public int BytesPerRow { get; } + /// + /// Gets the predictor to use. Should only be used with deflate or lzw compression. + /// public TiffPredictor Predictor { get; } + /// + /// Gets the memory allocator. + /// protected MemoryAllocator Allocator { get; } + /// public void Dispose() { if (this.isDisposed) diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs index 71190c7c45..6514fbe834 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompressor.cs @@ -10,16 +10,39 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression { internal abstract class TiffBaseCompressor : TiffBaseCompression { + /// + /// Initializes a new instance of the class. + /// + /// The output stream to write the compressed image to. + /// The memory allocator. + /// The image width. + /// Bits per pixel. + /// The predictor to use (should only be used with deflate or lzw compression). Defaults to none. protected TiffBaseCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor = TiffPredictor.None) : base(allocator, width, bitsPerPixel, predictor) => this.Output = output; + /// + /// Gets the compression method to use. + /// public abstract TiffEncoderCompression Method { get; } + /// + /// Gets the output stream to write the compressed image to. + /// public Stream Output { get; } + /// + /// Does any initialization required for the compression. + /// + /// The number of rows per strip. public abstract void Initialize(int rowsPerStrip); + /// + /// Compresses a strip of the image. + /// + /// Image rows to compress. + /// Image height. public abstract void CompressStrip(Span rows, int height); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs index c954de2153..eeb14fb749 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffCompressorFactory.cs @@ -1,11 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System; -using System.Buffers; using System.IO; using SixLabors.ImageSharp.Compression.Zlib; -using SixLabors.ImageSharp.Formats.Experimental.Tiff; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Memory; @@ -26,31 +23,31 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression switch (method) { case TiffEncoderCompression.None: - DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "Values must be equals"); - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); + DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "No deflate compression level is expected to be set"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return new NoCompressor(output); case TiffEncoderCompression.PackBits: - DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "Values must be equals"); - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); + DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "No deflate compression level is expected to be set"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return new PackBitsCompressor(output, allocator, width, bitsPerPixel); case TiffEncoderCompression.Deflate: return new DeflateCompressor(output, allocator, width, bitsPerPixel, predictor, compressionLevel); case TiffEncoderCompression.Lzw: - DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "Values must be equals"); + DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "No deflate compression level is expected to be set"); return new LzwCompressor(output, allocator, width, bitsPerPixel, predictor); case TiffEncoderCompression.CcittGroup3Fax: - DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "Values must be equals"); - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); + DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "No deflate compression level is expected to be set"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return new T4BitCompressor(output, allocator, width, bitsPerPixel, false); case TiffEncoderCompression.ModifiedHuffman: - DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "Values must be equals"); - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); + DebugGuard.IsTrue(compressionLevel == DeflateCompressionLevel.DefaultCompression, "No deflate compression level is expected to be set"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return new T4BitCompressor(output, allocator, width, bitsPerPixel, true); default: diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs index 50e77f4f14..130205b5b2 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs @@ -21,29 +21,29 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression switch (method) { case TiffDecoderCompressionType.None: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); - DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "Values must be equals"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); + DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return new NoneTiffCompression(); case TiffDecoderCompressionType.PackBits: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); - DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "Values must be equals"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); + DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return new PackBitsTiffCompression(allocator); case TiffDecoderCompressionType.Deflate: - DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "Values must be equals"); + DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return new DeflateTiffCompression(allocator, width, bitsPerPixel, predictor); case TiffDecoderCompressionType.Lzw: - DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "Values must be equals"); + DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return new LzwTiffCompression(allocator, width, bitsPerPixel, predictor); case TiffDecoderCompressionType.T4: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return new T4TiffCompression(allocator, faxOptions, photometricInterpretation, width); case TiffDecoderCompressionType.HuffmanRle: - DebugGuard.IsTrue(predictor == TiffPredictor.None, "Values must be equals"); + DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return new ModifiedHuffmanTiffCompression(allocator, photometricInterpretation, width); default: diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index ec9c761aa4..d9997a28d6 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -12,7 +12,6 @@ using SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; using SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers; using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; @@ -58,6 +57,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff /// private readonly DeflateCompressionLevel compressionLevel; + /// + /// The maximum number of bytes for a strip. + /// private readonly int maxStripBytes; /// @@ -252,7 +254,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff this.bitsPerPixel = TiffBitsPerPixel.Pixel1; return; } - else if (this.Mode != TiffEncodingMode.BiColor) + + if (this.Mode != TiffEncodingMode.BiColor) { TiffThrowHelper.ThrowImageFormatException($"The {this.CompressionType} compression and {this.Mode} aren't compatible. Please use {this.CompressionType} only with {TiffEncodingMode.BiColor} or {TiffEncodingMode.Default} mode."); } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs index 7d5d64f160..f61b294364 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter.cs @@ -63,6 +63,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers this.AddStripTags(rowsPerStrip, stripOffsets, stripByteCounts); } + /// public void Dispose() { if (this.isDisposed) diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs index 91cc9ddfcb..ca366f5150 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers if (compressor.Method == TiffEncoderCompression.CcittGroup3Fax || compressor.Method == TiffEncoderCompression.ModifiedHuffman) { - // special case for T4BitCompressor + // Special case for T4BitCompressor. compressor.CompressStrip(pixelAsGraySpan, height); } else @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers Span rows = this.bitStrip.Slice(0, bytesPerStrip); rows.Clear(); - int xx = 0; + int grayPixelIndex = 0; for (int s = 0; s < height; s++) { int bitIndex = 0; @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers for (int x = 0; x < this.Image.Width; x++) { int shift = 7 - bitIndex; - if (pixelAsGraySpan[xx++] == 255) + if (pixelAsGraySpan[grayPixelIndex++] == 255) { outputRow[byteIndex] |= (byte)(1 << shift); } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs index 1b2bd4ab68..018ac6fa05 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter.cs @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { private IManagedByteBuffer rowBuffer; - public TiffCompositeColorWriter(ImageFrame image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) + protected TiffCompositeColorWriter(ImageFrame image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector) : base(image, memoryAllocator, configuration, entriesCollector) { } @@ -40,6 +40,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers protected abstract void EncodePixels(Span pixels, Span buffer); + /// protected override void Dispose(bool disposing) => this.rowBuffer?.Dispose(); } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs index f2b06d8720..7e2e4e304e 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffGrayWriter.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.IO; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -16,8 +15,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { } + /// public override int BitsPerPixel => 8; + /// protected override void EncodePixels(Span pixels, Span buffer) => PixelOperations.Instance.ToL8Bytes(this.Configuration, pixels, buffer, pixels.Length); } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs index 2866637062..dc7dcf5891 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter.cs @@ -31,14 +31,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers this.AddTag(this.quantized); } + /// public override int BitsPerPixel => 8; + /// protected override void EncodeStrip(int y, int height, TiffBaseCompressor compressor) { Span pixels = GetStripPixels(((IPixelSource)this.quantized).PixelBuffer, y, height); compressor.CompressStrip(pixels, height); } + /// protected override void Dispose(bool disposing) => this.quantized?.Dispose(); private void AddTag(IndexedImageFrame quantized) diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs index 174a677279..b32b5ed90a 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffRgbWriter.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.IO; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -16,8 +15,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers { } + /// public override int BitsPerPixel => 24; + /// protected override void EncodePixels(Span pixels, Span buffer) => PixelOperations.Instance.ToRgb24Bytes(this.Configuration, pixels, buffer, pixels.Length); } }