Browse Source

Additional png test cases

pull/1574/head
Brian Popow 6 years ago
parent
commit
44ca0f778a
  1. 5
      src/ImageSharp/Formats/Png/PngThrowHelper.cs
  2. 15
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs
  3. 239
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
  4. 31
      tests/ImageSharp.Tests/TestImages.cs
  5. 3
      tests/Images/Input/Png/basn3p01.png
  6. 3
      tests/Images/Input/Png/basn3p02.png
  7. 3
      tests/Images/Input/Png/basn3p04.png
  8. 3
      tests/Images/Input/Png/basn3p08.png
  9. 3
      tests/Images/Input/Png/issues/Issue_410.png
  10. 3
      tests/Images/Input/Png/xc1n0g08.png
  11. 3
      tests/Images/Input/Png/xc9n2c08.png
  12. 3
      tests/Images/Input/Png/xd0n2c08.png
  13. 3
      tests/Images/Input/Png/xd3n2c08.png
  14. 3
      tests/Images/Input/Png/xdtn0g01.png

5
src/ImageSharp/Formats/Png/PngThrowHelper.cs

@ -20,11 +20,14 @@ namespace SixLabors.ImageSharp.Formats.Png
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowInvalidChunkType() => throw new InvalidImageContentException("Invalid PNG data.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowInvalidChunkType(string message) => throw new InvalidImageContentException(message);
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowInvalidChunkCrc(string chunkTypeName) => throw new InvalidImageContentException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowNotSupportedColor() => new NotSupportedException("Unsupported PNG color type");
public static void ThrowNotSupportedColor() => throw new NotSupportedException("Unsupported PNG color type");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowUnknownFilter() => throw new InvalidImageContentException("Unknown filter type.");

15
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs

@ -6,6 +6,7 @@ using System.IO;
using System.Text;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Png.Zlib;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
@ -78,6 +79,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
}
[Fact]
public void CalculateCrc_Works()
{
// arrange
var data = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
var crc = new Crc32();
// act
crc.Update(data);
// assert
Assert.Equal(0x88AA689F, crc.Value);
}
private static string GetChunkTypeName(uint value)
{
var data = new byte[4];

239
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

@ -4,7 +4,6 @@
using System.IO;
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@ -26,62 +25,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
public static readonly string[] CommonTestImages =
{
TestImages.Png.Splash,
TestImages.Png.Indexed,
TestImages.Png.FilterVar,
TestImages.Png.Bad.ChunkLength1,
TestImages.Png.Bad.CorruptedChunk,
TestImages.Png.VimImage1,
TestImages.Png.VimImage2,
TestImages.Png.VersioningImage1,
TestImages.Png.VersioningImage2,
TestImages.Png.SnakeGame,
TestImages.Png.Banner7Adam7InterlaceMode,
TestImages.Png.Banner8Index,
TestImages.Png.Bad.ChunkLength2,
TestImages.Png.VimImage2,
TestImages.Png.Rgb24BppTrans,
TestImages.Png.GrayA8Bit,
TestImages.Png.Gray1BitTrans,
TestImages.Png.Bad.ZlibOverflow,
TestImages.Png.Bad.ZlibOverflow2,
TestImages.Png.Bad.ZlibZtxtBadHeader,
TestImages.Png.Bad.Issue1047_BadEndChunk
};
public static readonly string[] TestImages48Bpp =
{
TestImages.Png.Rgb48Bpp,
TestImages.Png.Rgb48BppInterlaced
};
public static readonly string[] TestImages64Bpp =
{
TestImages.Png.Rgba64Bpp,
TestImages.Png.Rgb48BppTrans
};
public static readonly string[] TestImagesL16Bit =
{
TestImages.Png.L16Bit,
};
public static readonly string[] TestImagesGrayAlpha16Bit =
{
TestImages.Png.GrayAlpha16Bit,
TestImages.Png.GrayTrns16BitInterlaced
TestImages.Png.Bad.ChunkLength1,
TestImages.Png.Bad.ChunkLength2,
};
public static readonly string[] TestImagesL8BitInterlaced =
{
TestImages.Png.GrayAlpha1BitInterlaced,
TestImages.Png.GrayAlpha2BitInterlaced,
TestImages.Png.Gray4BitInterlaced,
TestImages.Png.GrayA8BitInterlaced
};
public static readonly string[] TestImagesIssue1014 =
{
TestImages.Png.Issue1014_1, TestImages.Png.Issue1014_2,
@ -95,6 +53,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
TestImages.Png.Issue1177_2
};
public static readonly string[] CorruptedTestImages =
{
TestImages.Png.Bad.CorruptedChunk,
TestImages.Png.Bad.ZlibOverflow,
TestImages.Png.Bad.ZlibOverflow2,
TestImages.Png.Bad.ZlibZtxtBadHeader,
};
[Theory]
[WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32)]
public void Decode<TPixel>(TestImageProvider<TPixel> provider)
@ -103,25 +69,28 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
// We don't have another x-plat reference decoder that can be compared for this image.
if (provider.Utility.SourceFileOrDescription == TestImages.Png.Bad.Issue1047_BadEndChunk)
{
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider, ImageComparer.Exact, (IImageDecoder)SystemDrawingReferenceDecoder.Instance);
}
}
else
{
image.CompareToOriginal(provider, ImageComparer.Exact);
}
[Theory]
[WithFile(TestImages.Png.GrayA8Bit, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Gray1BitTrans, PixelTypes.Rgba32)]
public void Decode_GrayWithAlpha<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
[Theory]
[WithFile(TestImages.Png.Interlaced, PixelTypes.Rgba32)]
public void Decode_Interlaced_ImageIsCorrect<TPixel>(TestImageProvider<TPixel> provider)
[WithFile(TestImages.Png.Banner7Adam7InterlaceMode, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Banner8Index, PixelTypes.Rgba32)]
public void Decode_Interlaced<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
@ -132,7 +101,25 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
[Theory]
[WithFileCollection(nameof(TestImages48Bpp), PixelTypes.Rgb48)]
[WithFile(TestImages.Png.Indexed, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Banner8Index, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.PalettedTwoColor, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.PalettedFourColor, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.PalettedSixteenColor, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Paletted256Colors, PixelTypes.Rgba32)]
public void Decode_Indexed<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
[Theory]
[WithFile(TestImages.Png.Rgb48Bpp, PixelTypes.Rgb48)]
[WithFile(TestImages.Png.Rgb48BppInterlaced, PixelTypes.Rgb48)]
public void Decode_48Bpp<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -144,7 +131,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
[Theory]
[WithFileCollection(nameof(TestImages64Bpp), PixelTypes.Rgba64)]
[WithFile(TestImages.Png.Rgba64Bpp, PixelTypes.Rgba64)]
[WithFile(TestImages.Png.Rgb48BppTrans, PixelTypes.Rgba64)]
public void Decode_64Bpp<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -156,7 +144,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
[Theory]
[WithFileCollection(nameof(TestImagesL8BitInterlaced), PixelTypes.Rgba32)]
[WithFile(TestImages.Png.GrayAlpha1BitInterlaced, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.GrayAlpha2BitInterlaced, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Gray4BitInterlaced, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.GrayA8BitInterlaced, PixelTypes.Rgba32)]
public void Decoder_L8bitInterlaced<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -168,7 +159,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
[Theory]
[WithFileCollection(nameof(TestImagesL16Bit), PixelTypes.Rgb48)]
[WithFile(TestImages.Png.L16Bit, PixelTypes.Rgb48)]
public void Decode_L16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -180,7 +171,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
[Theory]
[WithFileCollection(nameof(TestImagesGrayAlpha16Bit), PixelTypes.Rgba64)]
[WithFile(TestImages.Png.GrayAlpha16Bit, PixelTypes.Rgba64)]
[WithFile(TestImages.Png.GrayTrns16BitInterlaced, PixelTypes.Rgba64)]
public void Decode_GrayAlpha16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -193,7 +185,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
[Theory]
[WithFile(TestImages.Png.GrayA8BitInterlaced, PixelTypes)]
public void Decoder_CanDecodeGrey8bitWithAlpha<TPixel>(TestImageProvider<TPixel> provider)
public void Decoder_CanDecode_Grey8bitInterlaced_WithAlpha<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
[Theory]
[WithFileCollection(nameof(CorruptedTestImages), PixelTypes.Rgba32)]
public void Decoder_CanDecode_CorruptedImages<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
@ -232,9 +236,63 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
}
[Theory]
[WithFile(TestImages.Png.Bad.MissingDataChunk, PixelTypes.Rgba32)]
public void Decode_MissingDataChunk_ThrowsException<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
System.Exception ex = Record.Exception(
() =>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
}
});
Assert.NotNull(ex);
Assert.Contains("PNG Image does not contain a data chunk", ex.Message);
}
[Theory]
[WithFile(TestImages.Png.Bad.BitDepthZero, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Bad.BitDepthThree, PixelTypes.Rgba32)]
public void Decode_InvalidBitDepth_ThrowsException<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
System.Exception ex = Record.Exception(
() =>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
}
});
Assert.NotNull(ex);
Assert.Contains("Invalid or unsupported bit depth", ex.Message);
}
[Theory]
[WithFile(TestImages.Png.Bad.ColorTypeOne, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Bad.ColorTypeNine, PixelTypes.Rgba32)]
public void Decode_InvalidColorType_ThrowsException<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
System.Exception ex = Record.Exception(
() =>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
}
});
Assert.NotNull(ex);
Assert.Contains("Invalid or unsupported color type", ex.Message);
}
// https://github.com/SixLabors/ImageSharp/issues/1014
[Theory]
[WithFileCollection(nameof(TestImagesIssue1014), PixelTypes.Rgba32)]
public void Issue1014<TPixel>(TestImageProvider<TPixel> provider)
public void Issue1014_DataSplitOverMultipleIDatChunks<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
System.Exception ex = Record.Exception(
@ -249,9 +307,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
Assert.Null(ex);
}
// https://github.com/SixLabors/ImageSharp/issues/1177
[Theory]
[WithFileCollection(nameof(TestImagesIssue1177), PixelTypes.Rgba32)]
public void Issue1177<TPixel>(TestImageProvider<TPixel> provider)
public void Issue1177_CRC_Omitted<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
System.Exception ex = Record.Exception(
@ -266,6 +325,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
Assert.Null(ex);
}
// https://github.com/SixLabors/ImageSharp/issues/1127
[Theory]
[WithFile(TestImages.Png.Issue1127, PixelTypes.Rgba32)]
public void Issue1127<TPixel>(TestImageProvider<TPixel> provider)
@ -283,6 +343,53 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
Assert.Null(ex);
}
// https://github.com/SixLabors/ImageSharp/issues/1047
[Theory]
[WithFile(TestImages.Png.Bad.Issue1047_BadEndChunk, PixelTypes.Rgba32)]
public void Issue1047<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
System.Exception ex = Record.Exception(
() =>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
// We don't have another x-plat reference decoder that can be compared for this image.
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider, ImageComparer.Exact, SystemDrawingReferenceDecoder.Instance);
}
}
});
Assert.Null(ex);
}
// https://github.com/SixLabors/ImageSharp/issues/410
[Theory]
[WithFile(TestImages.Png.Bad.Issue410_MalformedApplePng, PixelTypes.Rgba32)]
public void Issue410_MalformedApplePng<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
System.Exception ex = Record.Exception(
() =>
{
using (Image<TPixel> image = provider.GetImage(PngDecoder))
{
image.DebugSave(provider);
// We don't have another x-plat reference decoder that can be compared for this image.
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider, ImageComparer.Exact, SystemDrawingReferenceDecoder.Instance);
}
}
});
Assert.NotNull(ex);
Assert.Contains("Malformed Apple PNG detected!", ex.Message);
}
[Theory]
[WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)]
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32)]

31
tests/ImageSharp.Tests/TestImages.cs

@ -65,6 +65,12 @@ namespace SixLabors.ImageSharp.Tests
public const string Filter3 = "Png/filter3.png";
public const string Filter4 = "Png/filter4.png";
// Paletted images also from http://www.schaik.com/pngsuite/pngsuite_fil_png.html
public const string PalettedTwoColor = "Png/basn3p01.png";
public const string PalettedFourColor = "Png/basn3p02.png";
public const string PalettedSixteenColor = "Png/basn3p04.png";
public const string Paletted256Colors = "Png/basn3p08.png";
// Filter changing per scanline
public const string FilterVar = "Png/filterVar.png";
@ -93,6 +99,8 @@ namespace SixLabors.ImageSharp.Tests
public const string Issue1014_4 = "Png/issues/Issue_1014_4.png";
public const string Issue1014_5 = "Png/issues/Issue_1014_5.png";
public const string Issue1014_6 = "Png/issues/Issue_1014_6.png";
// Issue 1127: https://github.com/SixLabors/ImageSharp/issues/1127
public const string Issue1127 = "Png/issues/Issue_1127.png";
// Issue 1177: https://github.com/SixLabors/ImageSharp/issues/1177
@ -101,14 +109,31 @@ namespace SixLabors.ImageSharp.Tests
public static class Bad
{
// Odd chunk lengths
public const string ChunkLength1 = "Png/chunklength1.png";
public const string ChunkLength2 = "Png/chunklength2.png";
public const string MissingDataChunk = "Png/xdtn0g01.png";
public const string CorruptedChunk = "Png/big-corrupted-chunk.png";
// Zlib errors.
public const string ZlibOverflow = "Png/zlib-overflow.png";
public const string ZlibOverflow2 = "Png/zlib-overflow2.png";
public const string ZlibZtxtBadHeader = "Png/zlib-ztxt-bad-header.png";
// Odd chunk lengths
public const string ChunkLength1 = "Png/chunklength1.png";
public const string ChunkLength2 = "Png/chunklength2.png";
// Issue 1047: https://github.com/SixLabors/ImageSharp/issues/1047
public const string Issue1047_BadEndChunk = "Png/issues/Issue_1047.png";
// Issue 410: https://github.com/SixLabors/ImageSharp/issues/410
public const string Issue410_MalformedApplePng = "Png/issues/Issue_410.png";
// Bad bit depth.
public const string BitDepthZero = "Png/xd0n2c08.png";
public const string BitDepthThree = "Png/xd3n2c08.png";
// Invalid color type.
public const string ColorTypeOne = "Png/xc1n0g08.png";
public const string ColorTypeNine = "Png/xc9n2c08.png";
}
public static readonly string[] All =

3
tests/Images/Input/Png/basn3p01.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c2d7cd682df5f74506b33a5d70c344aaee248fda79fdfef8e873426fd6f2b75b
size 112

3
tests/Images/Input/Png/basn3p02.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0466bb7ed9984cf03b70704564bcffab1df8ec0e8167473ba0f75e4fedce5a8f
size 146

3
tests/Images/Input/Png/basn3p04.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e1fc7be978d3149b98533d0076245ae64353b7967290f4204c1282ecb4ec1aba
size 216

3
tests/Images/Input/Png/basn3p08.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d58256cd2eb16b5740d4c1403d25ce43d8dd03e270627ab709d2fb141e3d904c
size 1286

3
tests/Images/Input/Png/issues/Issue_410.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fe3c66fb0f52b989f7398bc6bcaa18e83625120a53b4972023705a7a5925eab1
size 674

3
tests/Images/Input/Png/xc1n0g08.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4059f7e6a1c5bac1801f70e09f9ec1e1297dcdce34055c13ab2703d6d9613c7e
size 138

3
tests/Images/Input/Png/xc9n2c08.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e252a0e7df3e794e52ce4a831edafef76e7043d0d8d84019db0f7fd0b30e20f4
size 145

3
tests/Images/Input/Png/xd0n2c08.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c1287690808e809dc5d4fb89d8a7fd69ed93521f290abd42021ca00a061a1ba4
size 145

3
tests/Images/Input/Png/xd3n2c08.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:00b53c3bbd0641454521b982bc6f6bcfda7c91f1874cefb3a9bac37d80a1a269
size 145

3
tests/Images/Input/Png/xdtn0g01.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f9d1fb2a708703518368c392c74765a6e3e5b49dbb9717df3974452291032df9
size 61
Loading…
Cancel
Save