From a0e83efd70122bcc6aad91e1a91b8933579714f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 09:29:38 +0000 Subject: [PATCH 1/4] Bump actions/setup-dotnet from 2 to 3 Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 2 to 3. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-and-test.yml | 4 ++-- .github/workflows/code-coverage.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index cd741acd83..c033dd133c 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -90,7 +90,7 @@ jobs: - name: DotNet Setup if: ${{ matrix.options.sdk-preview != true }} - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3 with: include-prerelease: true dotnet-version: | @@ -98,7 +98,7 @@ jobs: - name: DotNet Setup Preview if: ${{ matrix.options.sdk-preview == true }} - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3 with: include-prerelease: true dotnet-version: | diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index 85ff42b74b..049a4cba05 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -55,7 +55,7 @@ jobs: restore-keys: ${{ runner.os }}-nuget- - name: DotNet Setup - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3 with: dotnet-version: | 6.0.x From 5de5ddc8412834ac5ddad7ae32d9fdf30ab0d1ba Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Thu, 6 Oct 2022 19:55:17 +0200 Subject: [PATCH 2/4] Make sure bits per pixel is set to 1 for bilevel compression, fixes #2255 --- src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs | 7 +++++++ .../ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs | 2 +- tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs | 5 +++++ tests/ImageSharp.Tests/TestImages.cs | 1 + tests/Images/Input/Tiff/Issues/Issue2255.png | 3 +++ 5 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/Images/Input/Tiff/Issues/Issue2255.png diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index 971353dbc8..9b50b958c8 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -384,6 +384,13 @@ internal sealed class TiffEncoderCore : IImageEncoderInternals // If no photometric interpretation was chosen, the input image bit per pixel should be preserved. if (!photometricInterpretation.HasValue) { + if (IsOneBitCompression(this.CompressionType)) + { + // We need to make sure bits per pixel is set to Bit1 now. WhiteIsZero is set because its the default for bilevel compressed data. + this.SetEncoderOptions(TiffBitsPerPixel.Bit1, TiffPhotometricInterpretation.WhiteIsZero, compression, TiffPredictor.None); + return; + } + // At the moment only 8 and 32 bits per pixel can be preserved by the tiff encoder. if (inputBitsPerPixel == 8) { diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs index 594cee2e99..6da0d4fd89 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs @@ -80,7 +80,7 @@ public abstract class TiffEncoderBaseTester protected static void TestTiffEncoderCore( TestImageProvider provider, TiffBitsPerPixel? bitsPerPixel, - TiffPhotometricInterpretation photometricInterpretation, + TiffPhotometricInterpretation? photometricInterpretation, TiffCompression compression = TiffCompression.None, TiffPredictor predictor = TiffPredictor.None, bool useExactComparer = true, diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index eb421cf0ff..7b55c1c5d0 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -427,6 +427,11 @@ public class TiffEncoderTests : TiffEncoderBaseTester public void TiffEncoder_EncodeBiColor_WithCcittGroup3FaxCompression_BlackIsZero_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit1, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.CcittGroup3Fax); + [Theory] + [WithFile(Issues2255, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeBiColor_WithCcittGroup3FaxCompression_WithoutSpecifyingBitPerPixel_Works(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, null, null, TiffCompression.CcittGroup3Fax, useExactComparer: false, compareTolerance: 0.025f); + [Theory] [WithFile(Calliphora_BiColorUncompressed, PixelTypes.Rgba32)] public void TiffEncoder_EncodeBiColor_WithCcittGroup4FaxCompression_WhiteIsZero_Works(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 989776934f..fa76a2bd31 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -934,6 +934,7 @@ public static class TestImages public const string Issues1891 = "Tiff/Issues/Issue1891.tiff"; public const string Issues2123 = "Tiff/Issues/Issue2123.tiff"; public const string Issues2149 = "Tiff/Issues/Group4CompressionWithStrips.tiff"; + public const string Issues2255 = "Tiff/Issues/Issue2255.png"; public const string SmallRgbDeflate = "Tiff/rgb_small_deflate.tiff"; public const string SmallRgbLzw = "Tiff/rgb_small_lzw.tiff"; diff --git a/tests/Images/Input/Tiff/Issues/Issue2255.png b/tests/Images/Input/Tiff/Issues/Issue2255.png new file mode 100644 index 0000000000..b01bf228ae --- /dev/null +++ b/tests/Images/Input/Tiff/Issues/Issue2255.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff555fb2478406a1f3b2202c2ae3b0a691a16bfe2a5b586f38b348c9f4a858e6 +size 3635 From f66bb352a8b9ce98ba2e3956b4983e5467846410 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sat, 8 Oct 2022 17:21:45 +0200 Subject: [PATCH 3/4] Fix issue decoding lossy webp with compressed alpha data, fixes #2257 --- src/ImageSharp/Formats/Webp/AlphaDecoder.cs | 8 +++++++- .../ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs | 11 +++++++++++ .../ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs | 2 +- tests/ImageSharp.Tests/TestImages.cs | 1 + tests/Images/Input/Webp/issues/Issue2257.webp | 3 +++ 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/Images/Input/Webp/issues/Issue2257.webp diff --git a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs index 4eb2aef4cf..a9508c2b65 100644 --- a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs +++ b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs @@ -61,7 +61,13 @@ internal class AlphaDecoder : IDisposable var bitReader = new Vp8LBitReader(data); this.LosslessDecoder = new WebpLosslessDecoder(bitReader, memoryAllocator, configuration); this.LosslessDecoder.DecodeImageStream(this.Vp8LDec, width, height, true); - this.Use8BDecode = this.Vp8LDec.Transforms.Count > 0 && Is8BOptimizable(this.Vp8LDec.Metadata); + + // Special case: if alpha data uses only the color indexing transform and + // doesn't use color cache (a frequent case), we will use DecodeAlphaData() + // method that only needs allocation of 1 byte per pixel (alpha channel). + this.Use8BDecode = this.Vp8LDec.Transforms.Count is 1 + && this.Vp8LDec.Transforms[0].TransformType == Vp8LTransformType.ColorIndexingTransform + && Is8BOptimizable(this.Vp8LDec.Metadata); } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs index af709c0d86..55c6233654 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -396,6 +396,17 @@ public class WebpDecoderTests image.CompareToOriginal(provider, ReferenceDecoder); } + // https://github.com/SixLabors/ImageSharp/issues/2257 + [Theory] + [WithFile(Lossy.Issue2257, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Issue2257(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + [Theory] [WithFile(Lossless.LossLessCorruptImage3, PixelTypes.Rgba32)] public void WebpDecoder_ThrowImageFormatException_OnInvalidImages(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs index 9796d89833..5e70f04f1d 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs @@ -288,7 +288,7 @@ public class WebpEncoderTests referenceDecoder: new MagickReferenceDecoder()); int encodedBytes = File.ReadAllBytes(encodedFile).Length; - Assert.True(encodedBytes <= expectedFileSize); + Assert.True(encodedBytes <= expectedFileSize, $"encoded bytes are {encodedBytes} and should be smaller then expected file size of {expectedFileSize}"); } [Theory] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 989776934f..82c1ed98d0 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -737,6 +737,7 @@ public static class TestImages // Issues public const string Issue1594 = "Webp/issues/Issue1594.webp"; public const string Issue2243 = "Webp/issues/Issue2243.webp"; + public const string Issue2257 = "Webp/issues/Issue2257.webp"; } } diff --git a/tests/Images/Input/Webp/issues/Issue2257.webp b/tests/Images/Input/Webp/issues/Issue2257.webp new file mode 100644 index 0000000000..a5a57a2e1a --- /dev/null +++ b/tests/Images/Input/Webp/issues/Issue2257.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55f87aee4283615bad9705ac459867facba5b6be114d7e1ece51db7c1ef87916 +size 117810 From 0ce8a212442a9aea66d823434ed3c951546d970d Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sat, 8 Oct 2022 17:28:32 +0200 Subject: [PATCH 4/4] Split up alpha encoding test in compressed and uncompressed test --- .../Formats/WebP/WebpEncoderTests.cs | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs index 5e70f04f1d..4eb8b3063d 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs @@ -267,22 +267,45 @@ public class WebpEncoderTests } [Theory] - [WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, false, 64020)] - [WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, true, 16200)] - public void Encode_Lossy_WithAlpha_Works(TestImageProvider provider, bool compressed, int expectedFileSize) + [WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, 64020)] + public void Encode_Lossy_WithAlpha_Works(TestImageProvider provider, int expectedFileSize) where TPixel : unmanaged, IPixel { var encoder = new WebpEncoder() { FileFormat = WebpFileFormatType.Lossy, - UseAlphaCompression = compressed + UseAlphaCompression = false }; using Image image = provider.GetImage(); string encodedFile = image.VerifyEncoder( provider, "webp", - $"with_alpha_compressed_{compressed}", + "with_alpha", + encoder, + ImageComparer.Tolerant(0.04f), + referenceDecoder: new MagickReferenceDecoder()); + + int encodedBytes = File.ReadAllBytes(encodedFile).Length; + Assert.True(encodedBytes <= expectedFileSize, $"encoded bytes are {encodedBytes} and should be smaller then expected file size of {expectedFileSize}"); + } + + [Theory] + [WithFile(TestImages.Png.Transparency, PixelTypes.Rgba32, 16200)] + public void Encode_Lossy_WithAlphaUsingCompression_Works(TestImageProvider provider, int expectedFileSize) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossy, + UseAlphaCompression = true + }; + + using Image image = provider.GetImage(); + string encodedFile = image.VerifyEncoder( + provider, + "webp", + "with_alpha_compressed", encoder, ImageComparer.Tolerant(0.04f), referenceDecoder: new MagickReferenceDecoder());