mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
620 lines
24 KiB
620 lines
24 KiB
// Copyright (c) Six Labors.
|
|
// Licensed under the Six Labors Split License.
|
|
|
|
using System.Runtime.Intrinsics.X86;
|
|
using Microsoft.DotNet.RemoteExecutor;
|
|
using SixLabors.ImageSharp.Formats;
|
|
using SixLabors.ImageSharp.Formats.Png;
|
|
using SixLabors.ImageSharp.Memory;
|
|
using SixLabors.ImageSharp.PixelFormats;
|
|
using SixLabors.ImageSharp.Tests.TestUtilities;
|
|
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
|
|
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
|
|
|
|
// ReSharper disable InconsistentNaming
|
|
namespace SixLabors.ImageSharp.Tests.Formats.Png;
|
|
|
|
[Trait("Format", "Png")]
|
|
[ValidateDisposedMemoryAllocations]
|
|
public partial class PngDecoderTests
|
|
{
|
|
private const PixelTypes TestPixelTypes = PixelTypes.Rgba32 | PixelTypes.RgbaVector | PixelTypes.Argb32;
|
|
|
|
public static readonly string[] CommonTestImages =
|
|
{
|
|
TestImages.Png.Splash,
|
|
TestImages.Png.FilterVar,
|
|
|
|
TestImages.Png.VimImage1,
|
|
TestImages.Png.VimImage2,
|
|
TestImages.Png.VersioningImage1,
|
|
TestImages.Png.VersioningImage2,
|
|
|
|
TestImages.Png.SnakeGame,
|
|
|
|
TestImages.Png.Rgb24BppTrans,
|
|
|
|
TestImages.Png.Bad.ChunkLength1,
|
|
TestImages.Png.Bad.ChunkLength2,
|
|
};
|
|
|
|
public static readonly string[] TestImagesIssue1014 =
|
|
{
|
|
TestImages.Png.Issue1014_1, TestImages.Png.Issue1014_2,
|
|
TestImages.Png.Issue1014_3, TestImages.Png.Issue1014_4,
|
|
TestImages.Png.Issue1014_5, TestImages.Png.Issue1014_6
|
|
};
|
|
|
|
public static readonly string[] TestImagesIssue1177 =
|
|
{
|
|
TestImages.Png.Issue1177_1,
|
|
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,
|
|
};
|
|
|
|
public static readonly TheoryData<string, Type> PixelFormatRange = new()
|
|
{
|
|
{ TestImages.Png.Gray4Bpp, typeof(Image<L8>) },
|
|
{ TestImages.Png.L16Bit, typeof(Image<L16>) },
|
|
{ TestImages.Png.Gray1BitTrans, typeof(Image<La16>) },
|
|
{ TestImages.Png.Gray2BitTrans, typeof(Image<La16>) },
|
|
{ TestImages.Png.Gray4BitTrans, typeof(Image<La16>) },
|
|
{ TestImages.Png.GrayA8Bit, typeof(Image<La16>) },
|
|
{ TestImages.Png.GrayAlpha16Bit, typeof(Image<La32>) },
|
|
{ TestImages.Png.Palette8Bpp, typeof(Image<Rgba32>) },
|
|
{ TestImages.Png.PalettedTwoColor, typeof(Image<Rgba32>) },
|
|
{ TestImages.Png.Rainbow, typeof(Image<Rgb24>) },
|
|
{ TestImages.Png.Rgb24BppTrans, typeof(Image<Rgba32>) },
|
|
{ TestImages.Png.Kaboom, typeof(Image<Rgba32>) },
|
|
{ TestImages.Png.Rgb48Bpp, typeof(Image<Rgb48>) },
|
|
{ TestImages.Png.Rgb48BppTrans, typeof(Image<Rgba64>) },
|
|
{ TestImages.Png.Rgba64Bpp, typeof(Image<Rgba64>) },
|
|
};
|
|
|
|
[Theory]
|
|
[MemberData(nameof(PixelFormatRange))]
|
|
public void Decode_NonGeneric_CreatesCorrectImageType(string path, Type type)
|
|
{
|
|
string file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, path);
|
|
using Image image = Image.Load(file);
|
|
Assert.IsType(type, image);
|
|
}
|
|
|
|
[Theory]
|
|
[MemberData(nameof(PixelFormatRange))]
|
|
public async Task DecodeAsync_NonGeneric_CreatesCorrectImageType(string path, Type type)
|
|
{
|
|
string file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, path);
|
|
using Image image = await Image.LoadAsync(file);
|
|
Assert.IsType(type, image);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32)]
|
|
public void Decode<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.APng, PixelTypes.Rgba32)]
|
|
public void Decode_APng<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance); // MagickReferenceDecoder cannot decode APNGs
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)]
|
|
public void PngDecoder_Decode_Resize<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
DecoderOptions options = new()
|
|
{
|
|
TargetSize = new() { Width = 150, Height = 150 }
|
|
};
|
|
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance, options);
|
|
|
|
FormattableString details = $"{options.TargetSize.Value.Width}_{options.TargetSize.Value.Height}";
|
|
|
|
image.DebugSave(provider, testOutputDetails: details, appendPixelTypeToFileName: false);
|
|
|
|
// Floating point differences in FMA used in the ResizeKernel result in minor pixel differences.
|
|
// Output have been manually verified.
|
|
// For more details see discussion: https://github.com/SixLabors/ImageSharp/pull/1513#issuecomment-763643594
|
|
image.CompareToReferenceOutput(
|
|
ImageComparer.TolerantPercentage(Fma.IsSupported ? 0.0003F : 0.0005F),
|
|
provider,
|
|
testOutputDetails: details,
|
|
appendPixelTypeToFileName: false);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)]
|
|
public void PngDecoder_Decode_Resize_ScalarResizeKernel(TestImageProvider<Rgba32> provider)
|
|
{
|
|
HwIntrinsics intrinsicsFilter = HwIntrinsics.DisableHWIntrinsic;
|
|
|
|
FeatureTestRunner.RunWithHwIntrinsicsFeature(
|
|
RunTest,
|
|
intrinsicsFilter,
|
|
provider,
|
|
string.Empty);
|
|
|
|
static void RunTest(string arg1, string notUsed)
|
|
{
|
|
TestImageProvider<Rgba32> provider =
|
|
FeatureTestRunner.DeserializeForXunit<TestImageProvider<Rgba32>>(arg1);
|
|
|
|
DecoderOptions options = new()
|
|
{
|
|
TargetSize = new() { Width = 150, Height = 150 }
|
|
};
|
|
|
|
using Image<Rgba32> image = provider.GetImage(PngDecoder.Instance, options);
|
|
|
|
FormattableString details = $"{options.TargetSize.Value.Width}_{options.TargetSize.Value.Height}";
|
|
|
|
image.DebugSave(provider, testOutputDetails: details, appendPixelTypeToFileName: false);
|
|
|
|
image.CompareToReferenceOutput(
|
|
ImageComparer.TolerantPercentage(0.0005F),
|
|
provider,
|
|
testOutputDetails: details,
|
|
appendPixelTypeToFileName: false);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.AverageFilter3BytesPerPixel, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.AverageFilter4BytesPerPixel, PixelTypes.Rgba32)]
|
|
public void Decode_WithAverageFilter<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.SubFilter3BytesPerPixel, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.SubFilter4BytesPerPixel, PixelTypes.Rgba32)]
|
|
public void Decode_WithSubFilter<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.UpFilter, PixelTypes.Rgba32)]
|
|
public void Decode_WithUpFilter<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.PaethFilter3BytesPerPixel, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.PaethFilter4BytesPerPixel, PixelTypes.Rgba32)]
|
|
public void Decode_WithPaethFilter<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
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.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Interlaced, PixelTypes.Rgba32)]
|
|
[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.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[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.Instance);
|
|
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>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[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>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[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>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.L16Bit, PixelTypes.Rgb48)]
|
|
public void Decode_L16Bit<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[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>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.GrayA8BitInterlaced, TestPixelTypes)]
|
|
public void Decoder_CanDecode_Grey8bitInterlaced_WithAlpha<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
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.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Splash, TestPixelTypes)]
|
|
public void Decoder_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(TestImages.Png.Bpp1, 1)]
|
|
[InlineData(TestImages.Png.Gray4Bpp, 4)]
|
|
[InlineData(TestImages.Png.Palette8Bpp, 8)]
|
|
[InlineData(TestImages.Png.Pd, 24)]
|
|
[InlineData(TestImages.Png.Blur, 32)]
|
|
[InlineData(TestImages.Png.Rgb48Bpp, 48)]
|
|
[InlineData(TestImages.Png.Rgb48BppInterlaced, 48)]
|
|
public void Identify(string imagePath, int expectedPixelSize)
|
|
{
|
|
TestFile testFile = TestFile.Create(imagePath);
|
|
using MemoryStream stream = new(testFile.Bytes, false);
|
|
|
|
ImageInfo imageInfo = Image.Identify(stream);
|
|
|
|
Assert.NotNull(imageInfo);
|
|
Assert.Equal(expectedPixelSize, imageInfo.PixelType.BitsPerPixel);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Bad.MissingDataChunk, PixelTypes.Rgba32)]
|
|
public void Decode_MissingDataChunk_ThrowsException<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
});
|
|
Assert.NotNull(ex);
|
|
Assert.Contains("PNG Image does not contain a data chunk", ex.Message);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Bad.MissingPaletteChunk1, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.Bad.MissingPaletteChunk2, PixelTypes.Rgba32)]
|
|
public void Decode_MissingPaletteChunk_ThrowsException<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
});
|
|
Assert.NotNull(ex);
|
|
Assert.Contains("PNG Image does not contain a palette chunk", ex.Message);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Bad.InvalidGammaChunk, PixelTypes.Rgba32)]
|
|
public void Decode_InvalidGammaChunk_Ignored<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
});
|
|
Assert.Null(ex);
|
|
}
|
|
|
|
[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>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
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>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
});
|
|
Assert.NotNull(ex);
|
|
Assert.Contains("Invalid or unsupported color type", ex.Message);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Bad.WrongCrcDataChunk, PixelTypes.Rgba32)]
|
|
public void Decode_InvalidDataChunkCrc_ThrowsException<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
InvalidImageContentException ex = Assert.Throws<InvalidImageContentException>(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
});
|
|
Assert.NotNull(ex);
|
|
Assert.Contains("CRC Error. PNG IDAT chunk is corrupt!", ex.Message);
|
|
}
|
|
|
|
// https://github.com/SixLabors/ImageSharp/issues/1014
|
|
[Theory]
|
|
[WithFileCollection(nameof(TestImagesIssue1014), PixelTypes.Rgba32)]
|
|
public void Issue1014_DataSplitOverMultipleIDatChunks<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
});
|
|
Assert.Null(ex);
|
|
}
|
|
|
|
// https://github.com/SixLabors/ImageSharp/issues/1177
|
|
[Theory]
|
|
[WithFileCollection(nameof(TestImagesIssue1177), PixelTypes.Rgba32)]
|
|
public void Issue1177_CRC_Omitted<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
});
|
|
Assert.Null(ex);
|
|
}
|
|
|
|
// https://github.com/SixLabors/ImageSharp/issues/1127
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Issue1127, PixelTypes.Rgba32)]
|
|
public void Issue1127<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
});
|
|
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>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
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/1765
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Issue1765_Net6DeflateStreamRead, PixelTypes.Rgba32)]
|
|
public void Issue1765<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider);
|
|
image.CompareToOriginal(provider, ImageComparer.Exact);
|
|
});
|
|
Assert.Null(ex);
|
|
}
|
|
|
|
// https://github.com/SixLabors/ImageSharp/issues/2209
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Issue2209IndexedWithTransparency, PixelTypes.Rgba32)]
|
|
public void Issue2209_Decode_HasTransparencyIsTrue<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
PngMetadata metadata = image.Metadata.GetPngMetadata();
|
|
Assert.True(metadata.HasTransparency);
|
|
}
|
|
|
|
// https://github.com/SixLabors/ImageSharp/issues/2209
|
|
[Theory]
|
|
[InlineData(TestImages.Png.Issue2209IndexedWithTransparency)]
|
|
public void Issue2209_Identify_HasTransparencyIsTrue(string imagePath)
|
|
{
|
|
TestFile testFile = TestFile.Create(imagePath);
|
|
using MemoryStream stream = new(testFile.Bytes, false);
|
|
ImageInfo imageInfo = Image.Identify(stream);
|
|
PngMetadata metadata = imageInfo.Metadata.GetPngMetadata();
|
|
Assert.True(metadata.HasTransparency);
|
|
}
|
|
|
|
// 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>
|
|
{
|
|
Exception ex = Record.Exception(
|
|
() =>
|
|
{
|
|
using Image<TPixel> image = provider.GetImage(PngDecoder.Instance);
|
|
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("Proprietary Apple PNG detected!", ex.Message);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32)]
|
|
public void PngDecoder_DegenerateMemoryRequest_ShouldTranslateTo_ImageFormatException<TPixel>(TestImageProvider<TPixel> provider)
|
|
where TPixel : unmanaged, IPixel<TPixel>
|
|
{
|
|
provider.LimitAllocatorBufferCapacity().InPixelsSqrt(10);
|
|
InvalidImageContentException ex = Assert.Throws<InvalidImageContentException>(() => provider.GetImage(PngDecoder.Instance));
|
|
Assert.IsType<InvalidMemoryOperationException>(ex.InnerException);
|
|
}
|
|
|
|
[Theory]
|
|
[WithFile(TestImages.Png.Splash, PixelTypes.Rgba32)]
|
|
[WithFile(TestImages.Png.Bike, PixelTypes.Rgba32)]
|
|
public void PngDecoder_CanDecode_WithLimitedAllocatorBufferCapacity(TestImageProvider<Rgba32> provider)
|
|
{
|
|
static void RunTest(string providerDump, string nonContiguousBuffersStr)
|
|
{
|
|
TestImageProvider<Rgba32> provider = BasicSerializer.Deserialize<TestImageProvider<Rgba32>>(providerDump);
|
|
|
|
provider.LimitAllocatorBufferCapacity().InPixelsSqrt(100);
|
|
|
|
using Image<Rgba32> image = provider.GetImage(PngDecoder.Instance);
|
|
image.DebugSave(provider, testOutputDetails: nonContiguousBuffersStr);
|
|
image.CompareToOriginal(provider);
|
|
}
|
|
|
|
string providerDump = BasicSerializer.Serialize(provider);
|
|
RemoteExecutor.Invoke(
|
|
RunTest,
|
|
providerDump,
|
|
"Disco")
|
|
.Dispose();
|
|
}
|
|
}
|
|
|