Browse Source

using MagickReferenceDecoder everywhere, added ReferenceDecoderBenchmarks

pull/640/head
Anton Firszov 8 years ago
parent
commit
0eec2c794f
  1. 6
      tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
  2. 4
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
  3. 2
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs
  4. 41
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs
  5. 8
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs
  6. 19
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  7. 96
      tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs

6
tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs

@ -146,7 +146,6 @@ namespace SixLabors.ImageSharp.Tests
appendSourceFileOrDescription); appendSourceFileOrDescription);
} }
/// <summary> /// <summary>
/// Encodes image by the format matching the required extension, than saves it to the recommended output file. /// Encodes image by the format matching the required extension, than saves it to the recommended output file.
/// </summary> /// </summary>
@ -154,7 +153,9 @@ namespace SixLabors.ImageSharp.Tests
/// <param name="image">The image instance</param> /// <param name="image">The image instance</param>
/// <param name="extension">The requested extension</param> /// <param name="extension">The requested extension</param>
/// <param name="encoder">Optional encoder</param> /// <param name="encoder">Optional encoder</param>
/// /// <param name="appendSourceFileOrDescription">A boolean indicating whether to append <see cref="ITestImageProvider.SourceFileOrDescription"/> to the test output file name.</param> /// <param name="appendPixelTypeToFileName">A value indicating whether to append the pixel type to the test output file name</param>
/// <param name="appendSourceFileOrDescription">A boolean indicating whether to append <see cref="ITestImageProvider.SourceFileOrDescription"/> to the test output file name.</param>
/// <param name="testOutputDetails">Additional information to append to the test output file name</param>
public string SaveTestOutputFile<TPixel>( public string SaveTestOutputFile<TPixel>(
Image<TPixel> image, Image<TPixel> image,
string extension = null, string extension = null,
@ -176,6 +177,7 @@ namespace SixLabors.ImageSharp.Tests
{ {
image.Save(stream, encoder); image.Save(stream, encoder);
} }
return path; return path;
} }

4
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs

@ -15,6 +15,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
{ {
public class MagickReferenceDecoder : IImageDecoder public class MagickReferenceDecoder : IImageDecoder
{ {
public static MagickReferenceDecoder Instance { get; } = new MagickReferenceDecoder();
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
@ -40,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
} }
else else
{ {
throw new NotImplementedException(); throw new InvalidOperationException();
} }
} }

2
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs

@ -20,6 +20,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
public static SystemDrawingReferenceEncoder Png { get; } = new SystemDrawingReferenceEncoder(ImageFormat.Png); public static SystemDrawingReferenceEncoder Png { get; } = new SystemDrawingReferenceEncoder(ImageFormat.Png);
public static SystemDrawingReferenceEncoder Bmp { get; } = new SystemDrawingReferenceEncoder(ImageFormat.Bmp);
public void Encode<TPixel>(Image<TPixel> image, Stream stream) public void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {

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

@ -14,9 +14,9 @@ namespace SixLabors.ImageSharp.Tests
{ {
public static partial class TestEnvironment public static partial class TestEnvironment
{ {
private static Lazy<Configuration> configuration = new Lazy<Configuration>(CreateDefaultConfiguration); private static readonly Lazy<Configuration> ConfigurationLazy = new Lazy<Configuration>(CreateDefaultConfiguration);
internal static Configuration Configuration => configuration.Value; internal static Configuration Configuration => ConfigurationLazy.Value;
internal static IImageDecoder GetReferenceDecoder(string filePath) internal static IImageDecoder GetReferenceDecoder(string filePath)
{ {
@ -52,36 +52,25 @@ namespace SixLabors.ImageSharp.Tests
private static Configuration CreateDefaultConfiguration() private static Configuration CreateDefaultConfiguration()
{ {
var configuration = new Configuration( var cfg = new Configuration(
new PngConfigurationModule(),
new JpegConfigurationModule(), new JpegConfigurationModule(),
new GifConfigurationModule() new GifConfigurationModule()
); );
if (!IsLinux) // Magick codecs should work on all
{ cfg.ConfigureCodecs(
// TODO: System.Drawing on Windows can decode 48bit and 64bit pngs but ImageFormats.Png,
// it doesn't preserve the accuracy we require for comparison. MagickReferenceDecoder.Instance,
// This makes CompareToOriginal method non-useful. SystemDrawingReferenceEncoder.Png,
configuration.ConfigureCodecs( new PngImageFormatDetector());
ImageFormats.Png,
SystemDrawingReferenceDecoder.Instance,
SystemDrawingReferenceEncoder.Png,
new PngImageFormatDetector());
configuration.ConfigureCodecs( cfg.ConfigureCodecs(
ImageFormats.Bmp, ImageFormats.Bmp,
SystemDrawingReferenceDecoder.Instance, MagickReferenceDecoder.Instance,
SystemDrawingReferenceEncoder.Png, SystemDrawingReferenceEncoder.Bmp,
new PngImageFormatDetector()); new BmpImageFormatDetector());
}
else
{
configuration.Configure(new PngConfigurationModule());
configuration.Configure(new BmpConfigurationModule());
}
return configuration; return cfg;
} }
} }
} }

8
tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs

@ -21,9 +21,9 @@ namespace SixLabors.ImageSharp.Tests
private const string ToolsDirectoryRelativePath = @"tests\Images\External\tools"; private const string ToolsDirectoryRelativePath = @"tests\Images\External\tools";
private static Lazy<string> solutionDirectoryFullPath = new Lazy<string>(GetSolutionDirectoryFullPathImpl); private static readonly Lazy<string> SolutionDirectoryFullPathLazy = new Lazy<string>(GetSolutionDirectoryFullPathImpl);
private static Lazy<bool> runsOnCi = new Lazy<bool>( private static readonly Lazy<bool> RunsOnCiLazy = new Lazy<bool>(
() => () =>
{ {
bool isCi; bool isCi;
@ -41,9 +41,9 @@ namespace SixLabors.ImageSharp.Tests
/// <summary> /// <summary>
/// Gets a value indicating whether test execution runs on CI. /// Gets a value indicating whether test execution runs on CI.
/// </summary> /// </summary>
internal static bool RunsOnCI => runsOnCi.Value; internal static bool RunsOnCI => RunsOnCiLazy.Value;
internal static string SolutionDirectoryFullPath => solutionDirectoryFullPath.Value; internal static string SolutionDirectoryFullPath => SolutionDirectoryFullPathLazy.Value;
private static string GetSolutionDirectoryFullPathImpl() private static string GetSolutionDirectoryFullPathImpl()
{ {

19
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -499,16 +499,18 @@ namespace SixLabors.ImageSharp.Tests
public static Image<TPixel> CompareToOriginal<TPixel>( public static Image<TPixel> CompareToOriginal<TPixel>(
this Image<TPixel> image, this Image<TPixel> image,
ITestImageProvider provider) ITestImageProvider provider,
IImageDecoder referenceDecoder = null)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
return CompareToOriginal(image, provider, ImageComparer.Tolerant()); return CompareToOriginal(image, provider, ImageComparer.Tolerant(), referenceDecoder);
} }
public static Image<TPixel> CompareToOriginal<TPixel>( public static Image<TPixel> CompareToOriginal<TPixel>(
this Image<TPixel> image, this Image<TPixel> image,
ITestImageProvider provider, ITestImageProvider provider,
ImageComparer comparer) ImageComparer comparer,
IImageDecoder referenceDecoder = null)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
string path = TestImageProvider<TPixel>.GetFilePathOrNull(provider); string path = TestImageProvider<TPixel>.GetFilePathOrNull(provider);
@ -519,15 +521,8 @@ namespace SixLabors.ImageSharp.Tests
var testFile = TestFile.Create(path); var testFile = TestFile.Create(path);
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(path); referenceDecoder = referenceDecoder ?? TestEnvironment.GetReferenceDecoder(path);
IImageFormat format = TestEnvironment.GetImageFormat(path);
IImageDecoder defaultDecoder = Configuration.Default.ImageFormatsManager.FindDecoder(format);
//if (referenceDecoder.GetType() == defaultDecoder.GetType())
//{
// throw new InvalidOperationException($"Can't use CompareToOriginal(): no actual reference decoder registered for {format.Name}");
//}
using (var original = Image.Load<TPixel>(testFile.Bytes, referenceDecoder)) using (var original = Image.Load<TPixel>(testFile.Bytes, referenceDecoder))
{ {
comparer.VerifySimilarity(original, image); comparer.VerifySimilarity(original, image);

96
tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs

@ -0,0 +1,96 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
{
public class ReferenceDecoderBenchmarks
{
private ITestOutputHelper Output { get; }
public const string SkipBenchmarks =
#if false
"Benchmark, enable manually!";
#else
null;
#endif
public const int DefaultExecutionCount = 50;
public static readonly string[] PngBenchmarkFiles =
{
TestImages.Png.CalliphoraPartial,
TestImages.Png.Kaboom,
TestImages.Png.Bike,
TestImages.Png.Splash,
TestImages.Png.SplashInterlaced
};
public static readonly string[] BmpBenchmarkFiles =
{
TestImages.Bmp.NegHeight,
TestImages.Bmp.Car,
TestImages.Bmp.V5Header
};
public ReferenceDecoderBenchmarks(ITestOutputHelper output)
{
this.Output = output;
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkMagickPngDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(PngBenchmarkFiles, new MagickReferenceDecoder(), $@"Magick Decode Png");
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkSystemDrawingPngDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(PngBenchmarkFiles, new SystemDrawingReferenceDecoder(), $@"System.Drawing Decode Png");
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkMagickBmpDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(BmpBenchmarkFiles, new MagickReferenceDecoder(), $@"Magick Decode Bmp");
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkSystemDrawingBmpDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(BmpBenchmarkFiles, new SystemDrawingReferenceDecoder(), $@"System.Drawing Decode Bmp");
}
private void BenckmarkDecoderImpl(IEnumerable<string> testFiles, IImageDecoder decoder, string info, int times = DefaultExecutionCount)
{
var measure = new MeasureFixture(this.Output);
measure.Measure(times,
() =>
{
foreach (string testFile in testFiles)
{
Image<Rgba32> image = TestFile.Create(testFile).CreateImage(decoder);
image.Dispose();
}
},
info);
}
}
}
Loading…
Cancel
Save