From fb9e23020bf0882956ef9c509ba9dccbb09cd2f9 Mon Sep 17 00:00:00 2001 From: Brian Popow <38701097+brianpopow@users.noreply.github.com> Date: Tue, 5 Feb 2019 02:41:26 +0100 Subject: [PATCH] Fix Decoding 8-Bit grayscale png's with alpha (#830) --- .../Formats/Png/PngScanlineProcessor.cs | 3 +- .../Formats/Png/PngDecoderTests.cs | 30 +++++++++++++++++++ tests/ImageSharp.Tests/TestImages.cs | 1 + tests/Images/Input/Png/rollsroyce.png | 3 ++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/Images/Input/Png/rollsroyce.png diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs index 4242b2d55..40c284117 100644 --- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs +++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs @@ -240,9 +240,9 @@ namespace SixLabors.ImageSharp.Formats.Png else { Rgba32 rgba32 = default; + int offset = 0; for (int x = pixelOffset; x < header.Width; x += increment) { - int offset = x * bytesPerPixel; byte luminance = Unsafe.Add(ref scanlineSpanRef, offset); byte alpha = Unsafe.Add(ref scanlineSpanRef, offset + bytesPerSample); rgba32.R = luminance; @@ -252,6 +252,7 @@ namespace SixLabors.ImageSharp.Formats.Png pixel.FromRgba32(rgba32); Unsafe.Add(ref rowSpanRef, x) = pixel; + offset += bytesPerPixel; } } } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index f51f9b6c5..1452f233b 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -67,6 +67,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png TestImages.Png.GrayTrns16BitInterlaced }; + public static readonly string[] TestImagesGrayAlpha8Bit = + { + TestImages.Png.GrayAlpha8Bit, + TestImages.Png.GrayAlpha8Bit2 + }; + public static readonly TheoryData RatioFiles = new TheoryData { @@ -123,6 +129,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } } + [Theory] + [WithFileCollection(nameof(TestImagesGrayAlpha8Bit), PixelTypes.Rgba32)] + public void Decoder_Gray8bitWithAlpha(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage(new PngDecoder())) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ImageComparer.Exact); + } + } + [Theory] [WithFileCollection(nameof(TestImagesGray16Bit), PixelTypes.Rgb48)] public void Decode_Gray16Bit(TestImageProvider provider) @@ -159,6 +177,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png } } + [Theory] + [WithFile(TestImages.Png.GrayAlpha8Bit2, PixelTypes)] + public void Decoder_CanDecodeGrey8bitWithAlpha(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage(new PngDecoder())) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ImageComparer.Exact); + } + } + [Fact] public void Decode_IgnoreMetadataIsFalse_TextChunckIsRead() { diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index d83fe4907..92773df7e 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -29,6 +29,7 @@ namespace SixLabors.ImageSharp.Tests public const string Gray4Bpp = "Png/gray_4bpp.png"; public const string Gray16Bit = "Png/gray-16.png"; public const string GrayAlpha8Bit = "Png/gray-alpha-8.png"; + public const string GrayAlpha8Bit2 = "Png/rollsroyce.png"; public const string GrayAlpha16Bit = "Png/gray-alpha-16.png"; public const string GrayTrns16BitInterlaced = "Png/gray-16-tRNS-interlaced.png"; public const string Rgb24BppTrans = "Png/rgb-8-tRNS.png"; diff --git a/tests/Images/Input/Png/rollsroyce.png b/tests/Images/Input/Png/rollsroyce.png new file mode 100644 index 000000000..c2b9199ac --- /dev/null +++ b/tests/Images/Input/Png/rollsroyce.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90017d23999f41be7ac525648d8f435dcf8d1481ab98ebfd01a9ce87241e534f +size 25400