Browse Source

Add 16bit decoder tests.

pull/613/head
James Jackson-South 8 years ago
parent
commit
8628aaa8a6
  1. 8
      src/ImageSharp/Formats/Png/PngConfigurationModule.cs
  2. 143
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
  3. 5
      tests/ImageSharp.Tests/TestFile.cs
  4. 6
      tests/ImageSharp.Tests/TestImages.cs
  5. 20
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
  6. 2
      tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs
  7. 13
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs
  8. BIN
      tests/Images/Input/Png/gray-16-tRNS.png
  9. BIN
      tests/Images/Input/Png/gray-16.png
  10. BIN
      tests/Images/Input/Png/gray-alpha-16.png
  11. BIN
      tests/Images/Input/Png/rgb-16-alpha.png

8
src/ImageSharp/Formats/Png/PngConfigurationModule.cs

@ -9,11 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Png
public sealed class PngConfigurationModule : IConfigurationModule
{
/// <inheritdoc/>
public void Configure(Configuration config)
public void Configure(Configuration configuration)
{
config.ImageFormatsManager.SetEncoder(ImageFormats.Png, new PngEncoder());
config.ImageFormatsManager.SetDecoder(ImageFormats.Png, new PngDecoder());
config.ImageFormatsManager.AddImageFormatDetector(new PngImageFormatDetector());
configuration.ImageFormatsManager.SetEncoder(ImageFormats.Png, new PngEncoder());
configuration.ImageFormatsManager.SetDecoder(ImageFormats.Png, new PngDecoder());
configuration.ImageFormatsManager.AddImageFormatDetector(new PngImageFormatDetector());
}
}
}

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

@ -21,65 +21,83 @@ namespace SixLabors.ImageSharp.Tests
private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32;
// Contains the png marker, IHDR and pHYs chunks of a 1x1 pixel 32bit png 1 a single black pixel.
private static byte[] raw1x1PngIHDRAndpHYs =
private static readonly byte[] raw1x1PngIHDRAndpHYs =
{
// PNG Identifier
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
// IHDR
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00,
// IHDR CRC
0x90, 0x77, 0x53, 0xDE,
0x90, 0x77, 0x53, 0xDE,
// pHYS
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01,
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01,
// pHYS CRC
0xC7, 0x6F, 0xA8, 0x64
};
// Contains the png marker, IDAT and IEND chunks of a 1x1 pixel 32bit png 1 a single black pixel.
private static byte[] raw1x1PngIDATAndIEND =
private static readonly byte[] raw1x1PngIDATAndIEND =
{
// IDAT
0x00, 0x00, 0x00, 0x0C, 0x49, 0x44, 0x41, 0x54, 0x18, 0x57, 0x63, 0x60, 0x60, 0x60, 0x00, 0x00,
0x00, 0x04, 0x00, 0x01,
0x00, 0x04, 0x00, 0x01,
// IDAT CRC
0x5C, 0xCD, 0xFF, 0x69,
0x5C, 0xCD, 0xFF, 0x69,
// IEND
0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
0x4E, 0x44,
0x4E, 0x44,
// IEND CRC
0xAE, 0x42, 0x60, 0x82
};
public static readonly string[] CommonTestImages =
{
TestImages.Png.Splash,
TestImages.Png.Indexed,
TestImages.Png.FilterVar,
TestImages.Png.Bad.ChunkLength1,
TestImages.Png.Bad.CorruptedChunk,
{
TestImages.Png.Splash,
TestImages.Png.Indexed,
TestImages.Png.FilterVar,
TestImages.Png.Bad.ChunkLength1,
TestImages.Png.Bad.CorruptedChunk,
TestImages.Png.VimImage1,
TestImages.Png.VersioningImage1,
TestImages.Png.VersioningImage2,
TestImages.Png.SnakeGame,
TestImages.Png.Banner7Adam7InterlaceMode,
TestImages.Png.Banner8Index,
TestImages.Png.Bad.ChunkLength2,
TestImages.Png.VimImage2,
};
TestImages.Png.VimImage1,
TestImages.Png.VersioningImage1,
TestImages.Png.VersioningImage2,
TestImages.Png.SnakeGame,
TestImages.Png.Banner7Adam7InterlaceMode,
TestImages.Png.Banner8Index,
public static readonly string[] TestImages48Bpp =
{
TestImages.Png.Rgb48Bpp,
TestImages.Png.Rgb48BppInterlaced
};
TestImages.Png.Bad.ChunkLength2,
TestImages.Png.VimImage2,
};
public static readonly string[] TestImages64Bpp =
{
TestImages.Png.Rgba64Bpp,
};
public static readonly string[] TestImagesGray16Bit =
{
TestImages.Png.Gray16Bit,
};
public static readonly string[] TestImages48Bpp =
{
TestImages.Png.Rgb48Bpp,
TestImages.Png.Rgb48BppInterlaced
};
public static readonly string[] TestImagesGrayAlpha16Bit =
{
TestImages.Png.GrayAlpha16Bit,
TestImages.Png.GrayTrns16Bit
};
// This is a workaround for Mono-s decoder being incompatible with ours and GDI+.
// We shouldn't mix these with the Interleaved cases (which are also failing with Mono System.Drawing). Let's go AAA!
@ -142,20 +160,66 @@ namespace SixLabors.ImageSharp.Tests
}
}
// TODO: We need to decode these into Rgba64 properly, and do 'CompareToOriginal' in a Rgba64 mode! (See #285)
[Theory(Skip = "Skipped for now until we can update the reference images from libpng samples.")]
[WithFileCollection(nameof(TestImages48Bpp), PixelTypes.Rgba32)]
[Theory]
[WithFileCollection(nameof(TestImages48Bpp), PixelTypes.Rgb48)]
public void Decode_48Bpp<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
image.DebugSave(provider);
var encoder = new PngEncoder { ColorType = PngColorType.Rgb, BitDepth = PngBitDepth.Bit16 };
// Workaround a bug in mono-s System.Drawing PNG decoder. It can't deal with 48Bpp png-s :(
if (!TestEnvironment.IsLinux && !TestEnvironment.IsMono)
if (!SkipVerification(provider))
{
image.CompareToOriginal(provider, ImageComparer.Exact);
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ImageComparer.Exact);
}
}
}
[Theory]
[WithFileCollection(nameof(TestImages64Bpp), PixelTypes.Rgba64)]
public void Decode_64Bpp<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
var encoder = new PngEncoder { ColorType = PngColorType.RgbWithAlpha, BitDepth = PngBitDepth.Bit16 };
if (!SkipVerification(provider))
{
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ImageComparer.Exact);
}
}
}
[Theory]
[WithFileCollection(nameof(TestImagesGray16Bit), PixelTypes.Rgb48)]
public void Decode_Gray16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
var encoder = new PngEncoder { ColorType = PngColorType.Grayscale, BitDepth = PngBitDepth.Bit16 };
if (!SkipVerification(provider))
{
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ImageComparer.Exact);
}
}
}
[Theory]
[WithFileCollection(nameof(TestImagesGrayAlpha16Bit), PixelTypes.Rgba64)]
public void Decode_GrayAlpha16Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
var encoder = new PngEncoder { ColorType = PngColorType.GrayscaleWithAlpha, BitDepth = PngBitDepth.Bit16 };
if (!SkipVerification(provider))
{
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ImageComparer.Exact);
}
}
}
@ -233,7 +297,7 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(TestImages.Png.Rgb48BppInterlaced, 48)]
public void DetectPixelSize(string imagePath, int expectedPixelSize)
{
TestFile testFile = TestFile.Create(imagePath);
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
{
Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel);
@ -257,10 +321,7 @@ namespace SixLabors.ImageSharp.Tests
var decoder = new PngDecoder();
ImageFormatException exception = Assert.Throws<ImageFormatException>(() =>
{
decoder.Decode<Rgb24>(null, memStream);
});
ImageFormatException exception = Assert.Throws<ImageFormatException>(() => decoder.Decode<Rgb24>(null, memStream));
Assert.Equal($"CRC Error. PNG {chunkName} chunk is corrupt!", exception.Message);
}

5
tests/ImageSharp.Tests/TestFile.cs

@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Tests
/// </summary>
// ReSharper disable once InconsistentNaming
private static readonly Lazy<string> inputImagesDirectory = new Lazy<string>(() => TestEnvironment.InputImagesDirectoryFullPath);
/// <summary>
/// The image (lazy initialized value)
/// </summary>
@ -74,9 +74,10 @@ namespace SixLabors.ImageSharp.Tests
private Image<Rgba32> Image => this.image ?? (this.image = ImageSharp.Image.Load<Rgba32>(this.Bytes));
/// <summary>
/// Gets the input image directory.
/// </summary>
private static string InputImagesDirectory => inputImagesDirectory.Value;
/// <summary>
/// Gets the full qualified path to the input test file.
/// </summary>

6
tests/ImageSharp.Tests/TestImages.cs

@ -27,7 +27,11 @@ namespace SixLabors.ImageSharp.Tests
public const string Palette8Bpp = "Png/palette-8bpp.png";
public const string Bpp1 = "Png/bpp1.png";
public const string Gray4Bpp = "Png/gray_4bpp.png";
public const string Gray16Bit = "Png/gray-16.png";
public const string GrayAlpha16Bit = "Png/gray-alpha-16.png";
public const string GrayTrns16Bit = "Png/gray-16-tRNS.png";
public const string Rgb48Bpp = "Png/rgb-48bpp.png";
public const string Rgba64Bpp = "Png/rgb-16-alpha.png";
public const string CalliphoraPartial = "Png/CalliphoraPartial.png";
public const string CalliphoraPartialGrayscale = "Png/CalliphoraPartialGrayscale.png";
public const string Bike = "Png/Bike.png";
@ -126,7 +130,7 @@ namespace SixLabors.ImageSharp.Tests
};
}
public class Issues
public static class Issues
{
public const string CriticalEOF214 = "Jpg/issues/Issue214-CriticalEOF.jpg";
public const string MissingFF00ProgressiveGirl159 = "Jpg/issues/Issue159-MissingFF00-Progressive-Girl.jpg";

20
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs

@ -80,11 +80,12 @@ namespace SixLabors.ImageSharp.Tests
stride = 1;
}
TPixel[] c = {
NamedColors<TPixel>.HotPink,
NamedColors<TPixel>.Blue
};
TPixel[] c =
{
NamedColors<TPixel>.HotPink,
NamedColors<TPixel>.Blue
};
for (int y = top; y < bottom; y++)
{
int p = 0;
@ -112,10 +113,11 @@ namespace SixLabors.ImageSharp.Tests
int top = 0;
int bottom = pixels.Height / 2;
int stride = pixels.Width / 6;
TPixel[] c = {
NamedColors<TPixel>.Black,
NamedColors<TPixel>.White
};
TPixel[] c =
{
NamedColors<TPixel>.Black,
NamedColors<TPixel>.White
};
int p = 0;
for (int y = top; y < bottom; y++)

2
tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs

@ -56,6 +56,8 @@ namespace SixLabors.ImageSharp.Tests
Bgra32 = 1 << 20,
Rgb48 = 1 << 21,
// TODO: Add multi-flag entries by rules defined in PackedPixelConverterHelper
// "All" is handled as a separate, individual case instead of using bitwise OR

13
tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs

@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.Tests
private static Lazy<Configuration> configuration = new Lazy<Configuration>(CreateDefaultConfiguration);
internal static Configuration Configuration => configuration.Value;
internal static IImageDecoder GetReferenceDecoder(string filePath)
{
IImageFormat format = GetImageFormat(filePath);
@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests
internal static IImageFormat GetImageFormat(string filePath)
{
string extension = Path.GetExtension(filePath);
IImageFormat format = Configuration.ImageFormatsManager.FindFormatByFileExtension(extension);
return format;
}
@ -60,11 +60,10 @@ namespace SixLabors.ImageSharp.Tests
if (!IsLinux)
{
configuration.ConfigureCodecs(
ImageFormats.Png,
SystemDrawingReferenceDecoder.Instance,
SystemDrawingReferenceEncoder.Png,
new PngImageFormatDetector());
// System.Drawing on Windows can decode 48bit and 64bit pngs but
// it doesn't preserve the accuracy we require for comparison.
// This makes CompareToOriginal method non-useful.
configuration.Configure(new PngConfigurationModule());
configuration.ConfigureCodecs(
ImageFormats.Bmp,

BIN
tests/Images/Input/Png/gray-16-tRNS.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

BIN
tests/Images/Input/Png/gray-16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

BIN
tests/Images/Input/Png/gray-alpha-16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

BIN
tests/Images/Input/Png/rgb-16-alpha.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Loading…
Cancel
Save