diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/DecodeBmp.cs b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeBmp.cs new file mode 100644 index 00000000000..206fb57a7e2 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeBmp.cs @@ -0,0 +1,39 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + + public class DecodeBmp + { + private byte[] bmpBytes; + + private string TestImageFullPath + => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [GlobalSetup] + public void ReadImages() + { + if (this.bmpBytes == null) + { + this.bmpBytes = File.ReadAllBytes(this.TestImageFullPath); + } + } + + [Params(TestImages.Bmp.Car)] + public string TestImage { get; set; } + + [Benchmark(Description = "ImageSharp Bmp")] + public Size BmpImageSharp() + { + using var memoryStream = new MemoryStream(this.bmpBytes); + using var image = Image.Load(memoryStream); + return new Size(image.Width, image.Height); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/DecodeFilteredPng.cs b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeFilteredPng.cs new file mode 100644 index 00000000000..e794b65955f --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeFilteredPng.cs @@ -0,0 +1,60 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using System.Runtime.CompilerServices; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + public class DecodeFilteredPng + { + private byte[] filter0; + private byte[] filter1; + private byte[] filter2; + private byte[] filter3; + private byte[] filter4; + + [GlobalSetup] + public void ReadImages() + { + this.filter0 = File.ReadAllBytes(TestImageFullPath(TestImages.Png.Filter0)); + this.filter1 = File.ReadAllBytes(TestImageFullPath(TestImages.Png.Filter1)); + this.filter2 = File.ReadAllBytes(TestImageFullPath(TestImages.Png.Filter2)); + this.filter3 = File.ReadAllBytes(TestImageFullPath(TestImages.Png.Filter3)); + this.filter4 = File.ReadAllBytes(TestImageFullPath(TestImages.Png.Filter4)); + } + + [Benchmark(Description = "None-filtered PNG file")] + public Size PngFilter0() + => LoadPng(this.filter0); + + [Benchmark(Description = "Sub-filtered PNG file")] + public Size PngFilter1() + => LoadPng(this.filter1); + + [Benchmark(Description = "Up-filtered PNG file")] + public Size PngFilter2() + => LoadPng(this.filter2); + + [Benchmark(Description = "Average-filtered PNG file")] + public Size PngFilter3() + => LoadPng(this.filter3); + + [Benchmark(Description = "Paeth-filtered PNG file")] + public Size PngFilter4() + => LoadPng(this.filter4); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Size LoadPng(byte[] bytes) + { + using var image = Image.Load(bytes); + return image.Size(); + } + + private static string TestImageFullPath(string path) + => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, path); + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/DecodeGif.cs b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeGif.cs new file mode 100644 index 00000000000..2589b57ee94 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeGif.cs @@ -0,0 +1,38 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + public class DecodeGif + { + private byte[] gifBytes; + + private string TestImageFullPath + => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [GlobalSetup] + public void ReadImages() + { + if (this.gifBytes == null) + { + this.gifBytes = File.ReadAllBytes(this.TestImageFullPath); + } + } + + [Params(TestImages.Gif.Rings)] + public string TestImage { get; set; } + + [Benchmark(Description = "ImageSharp Gif")] + public Size GifImageSharp() + { + using var memoryStream = new MemoryStream(this.gifBytes); + using var image = Image.Load(memoryStream); + return new Size(image.Width, image.Height); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/DecodePng.cs b/src/benchmarks/real-world/ImageSharp/Codecs/DecodePng.cs new file mode 100644 index 00000000000..e400976b6f4 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/DecodePng.cs @@ -0,0 +1,39 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + + public class DecodePng + { + private byte[] pngBytes; + + private string TestImageFullPath + => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [Params(TestImages.Png.Splash)] + public string TestImage { get; set; } + + [GlobalSetup] + public void ReadImages() + { + if (this.pngBytes == null) + { + this.pngBytes = File.ReadAllBytes(this.TestImageFullPath); + } + } + + [Benchmark(Description = "ImageSharp Png")] + public Size PngImageSharp() + { + using var memoryStream = new MemoryStream(this.pngBytes); + using var image = Image.Load(memoryStream); + return image.Size(); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/DecodeTga.cs b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeTga.cs new file mode 100644 index 00000000000..424a99618ca --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/DecodeTga.cs @@ -0,0 +1,32 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Tga; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + public class DecodeTga + { + private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + private byte[] data; + + [Params(TestImages.Tga.Bit24BottomLeft)] + public string TestImage { get; set; } + + [GlobalSetup] + public void SetupData() + => this.data = File.ReadAllBytes(this.TestImageFullPath); + + [Benchmark(Description = "ImageSharp Tga")] + public int TgaImageSharp() + { + using var image = Image.Load(this.data, new TgaDecoder()); + return image.Width; + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/EncodeBmp.cs b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeBmp.cs new file mode 100644 index 00000000000..3235ba5e689 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeBmp.cs @@ -0,0 +1,44 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + public class EncodeBmp + { + private Stream bmpStream; + private MemoryStream memoryStream = new MemoryStream(); + private Image bmpCore; + + [GlobalSetup] + public void ReadImages() + { + if (this.bmpStream == null) + { + this.bmpStream = File.OpenRead(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Bmp.Car)); + this.bmpCore = Image.Load(this.bmpStream); + this.bmpStream.Position = 0; + this.memoryStream = new MemoryStream(); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.bmpStream.Dispose(); + this.bmpStream = null; + this.bmpCore.Dispose(); + } + + [Benchmark(Description = "ImageSharp Bmp")] + public void BmpImageSharp() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + this.bmpCore.SaveAsBmp(memoryStream); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/EncodeGif.cs b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeGif.cs new file mode 100644 index 00000000000..ddca5d376f9 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeGif.cs @@ -0,0 +1,58 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Gif; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + + public class EncodeGif + { + // System.Drawing needs this. + private Stream bmpStream; + private MemoryStream memoryStream = new MemoryStream(); + private Image bmpCore; + + // Try to get as close to System.Drawing's output as possible + private readonly GifEncoder encoder = new GifEncoder + { + Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4 }) + }; + + [Params(TestImages.Bmp.Car, TestImages.Png.Rgb48Bpp)] + public string TestImage { get; set; } + + [GlobalSetup] + public void ReadImages() + { + if (this.bmpStream == null) + { + this.bmpStream = File.OpenRead(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage)); + this.bmpCore = Image.Load(this.bmpStream); + this.bmpStream.Position = 0; + this.memoryStream = new MemoryStream(); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.bmpStream.Dispose(); + this.bmpStream = null; + this.bmpCore.Dispose(); + } + + [Benchmark(Description = "ImageSharp Gif")] + public void GifImageSharp() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + this.bmpCore.SaveAsGif(memoryStream, this.encoder); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/EncodeIndexedPng.cs b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeIndexedPng.cs new file mode 100644 index 00000000000..a2bf0d08cf3 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeIndexedPng.cs @@ -0,0 +1,93 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Quantization; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + /// + /// Benchmarks saving png files using different quantizers. + /// System.Drawing cannot save indexed png files so we cannot compare. + /// + public class EncodeIndexedPng + { + // System.Drawing needs this. + private Stream bmpStream; + private MemoryStream memoryStream; + private Image bmpCore; + + [GlobalSetup] + public void ReadImages() + { + if (this.bmpStream == null) + { + this.bmpStream = File.OpenRead(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Bmp.Car)); + this.bmpCore = Image.Load(this.bmpStream); + this.bmpStream.Position = 0; + this.memoryStream = new MemoryStream(); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.bmpStream.Dispose(); + this.bmpStream = null; + this.bmpCore.Dispose(); + } + + [Benchmark(Description = "ImageSharp Octree Png")] + public void PngCoreOctree() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + var options = new PngEncoder { Quantizer = KnownQuantizers.Octree }; + this.bmpCore.SaveAsPng(memoryStream, options); + } + + [Benchmark(Description = "ImageSharp Octree NoDither Png")] + public void PngCoreOctreeNoDither() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + var options = new PngEncoder { Quantizer = new OctreeQuantizer(new QuantizerOptions { Dither = null }) }; + this.bmpCore.SaveAsPng(memoryStream, options); + } + + [Benchmark(Description = "ImageSharp Palette Png")] + public void PngCorePalette() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + var options = new PngEncoder { Quantizer = KnownQuantizers.WebSafe }; + this.bmpCore.SaveAsPng(memoryStream, options); + } + + [Benchmark(Description = "ImageSharp Palette NoDither Png")] + public void PngCorePaletteNoDither() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + var options = new PngEncoder { Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = null }) }; + this.bmpCore.SaveAsPng(memoryStream, options); + } + + [Benchmark(Description = "ImageSharp Wu Png")] + public void PngCoreWu() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + var options = new PngEncoder { Quantizer = KnownQuantizers.Wu }; + this.bmpCore.SaveAsPng(memoryStream, options); + } + + [Benchmark(Description = "ImageSharp Wu NoDither Png")] + public void PngCoreWuNoDither() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + var options = new PngEncoder { Quantizer = new WuQuantizer(new QuantizerOptions { Dither = null }), ColorType = PngColorType.Palette }; + this.bmpCore.SaveAsPng(memoryStream, options); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/EncodePng.cs b/src/benchmarks/real-world/ImageSharp/Codecs/EncodePng.cs new file mode 100644 index 00000000000..e0fc598bd1f --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/EncodePng.cs @@ -0,0 +1,52 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + + public class EncodePng + { + // System.Drawing needs this. + private Stream bmpStream; + private MemoryStream memoryStream; + private Image bmpCore; + + [Params(false)] + public bool LargeImage { get; set; } + + [GlobalSetup] + public void ReadImages() + { + if (this.bmpStream == null) + { + string path = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.LargeImage ? TestImages.Jpeg.Baseline.Jpeg420Exif : TestImages.Bmp.Car); + this.bmpStream = File.OpenRead(path); + this.bmpCore = Image.Load(this.bmpStream); + this.bmpStream.Position = 0; + this.memoryStream = new MemoryStream(); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.bmpStream.Dispose(); + this.bmpStream = null; + this.bmpCore.Dispose(); + } + + [Benchmark(Description = "ImageSharp Png")] + public void PngCore() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + var encoder = new PngEncoder { FilterMethod = PngFilterMethod.None }; + this.bmpCore.SaveAsPng(memoryStream, encoder); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/EncodeTga.cs b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeTga.cs new file mode 100644 index 00000000000..a39461b12d4 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/EncodeTga.cs @@ -0,0 +1,46 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + public class EncodeTga + { + private MemoryStream memoryStream; + private Image tga; + + private string TestImageFullPath + => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [Params(TestImages.Tga.Bit24BottomLeft)] + public string TestImage { get; set; } + + [GlobalSetup] + public void ReadImages() + { + if (this.tga == null) + { + this.tga = Image.Load(this.TestImageFullPath); + this.memoryStream = new MemoryStream(); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.tga.Dispose(); + this.tga = null; + } + + [Benchmark(Description = "ImageSharp Tga")] + public void ImageSharpTga() + { + this.memoryStream.Seek(0, SeekOrigin.Begin); + this.tga.SaveAsTga(memoryStream); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Codecs/Jpeg/DecodeJpeg.cs b/src/benchmarks/real-world/ImageSharp/Codecs/Jpeg/DecodeJpeg.cs new file mode 100644 index 00000000000..86650c92da3 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Codecs/Jpeg/DecodeJpeg.cs @@ -0,0 +1,65 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg +{ + public class DecodeJpeg + { + private JpegDecoder decoder; + + private MemoryStream preloadedImageStream; + + private void GenericSetup(string imageSubpath) + { + this.decoder = new JpegDecoder(); + byte[] bytes = File.ReadAllBytes(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, imageSubpath)); + this.preloadedImageStream = new MemoryStream(bytes); + } + + private void GenericBechmark() + { + this.preloadedImageStream.Position = 0; + using Image img = this.decoder.Decode(Configuration.Default, this.preloadedImageStream, default); + } + + [GlobalSetup(Target = nameof(JpegBaselineInterleaved444))] + public void SetupBaselineInterleaved444() => + this.GenericSetup(TestImages.Jpeg.Baseline.Winter444_Interleaved); + + [GlobalSetup(Target = nameof(JpegBaselineInterleaved420))] + public void SetupBaselineInterleaved420() => + this.GenericSetup(TestImages.Jpeg.Baseline.Hiyamugi); + + [GlobalSetup(Target = nameof(JpegBaseline400))] + public void SetupBaselineSingleComponent() => + this.GenericSetup(TestImages.Jpeg.Baseline.Jpeg400); + + [GlobalSetup(Target = nameof(JpegProgressiveNonInterleaved420))] + public void SetupProgressiveNoninterleaved420() => + this.GenericSetup(TestImages.Jpeg.Progressive.Winter420_NonInterleaved); + + [GlobalCleanup] + public void Cleanup() + { + this.preloadedImageStream.Dispose(); + this.preloadedImageStream = null; + } + + [Benchmark(Description = "Baseline 4:4:4 Interleaved")] + public void JpegBaselineInterleaved444() => this.GenericBechmark(); + + [Benchmark(Description = "Baseline 4:2:0 Interleaved")] + public void JpegBaselineInterleaved420() => this.GenericBechmark(); + + [Benchmark(Description = "Baseline 4:0:0 (grayscale)")] + public void JpegBaseline400() => this.GenericBechmark(); + + [Benchmark(Description = "Progressive 4:2:0 Non-Interleaved")] + public void JpegProgressiveNonInterleaved420() => this.GenericBechmark(); + } +} \ No newline at end of file diff --git a/src/benchmarks/real-world/ImageSharp/ImageSharp.Benchmarks.csproj b/src/benchmarks/real-world/ImageSharp/ImageSharp.Benchmarks.csproj new file mode 100644 index 00000000000..5d43579a864 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/ImageSharp.Benchmarks.csproj @@ -0,0 +1,37 @@ + + + + + ImageSharp.Benchmarks + Exe + SixLabors.ImageSharp.Benchmarks + false + portable + + false + Debug;Release + true + + + + + + net7.0 + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Bmp/Car.bmp b/src/benchmarks/real-world/ImageSharp/Images/Input/Bmp/Car.bmp new file mode 100644 index 00000000000..edd8ac1feb2 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Bmp/Car.bmp differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Gif/rings.gif b/src/benchmarks/real-world/ImageSharp/Images/Input/Gif/rings.gif new file mode 100644 index 00000000000..76f093a2093 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Gif/rings.gif differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/640px-Unequalized_Hawkes_Bay_NZ.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/640px-Unequalized_Hawkes_Bay_NZ.jpg new file mode 100644 index 00000000000..5ec8165e6d7 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/640px-Unequalized_Hawkes_Bay_NZ.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Hiyamugi.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Hiyamugi.jpg new file mode 100644 index 00000000000..de758e0dc61 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Hiyamugi.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Lake.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Lake.jpg new file mode 100644 index 00000000000..c54f2fd88c9 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Lake.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Snake.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Snake.jpg new file mode 100644 index 00000000000..222754844ac Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/Snake.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/jpeg400jfif.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/jpeg400jfif.jpg new file mode 100644 index 00000000000..d71fb5cb5f8 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/jpeg400jfif.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/jpeg420exif.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/jpeg420exif.jpg new file mode 100644 index 00000000000..2289a3f633f Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/jpeg420exif.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/winter444_interleaved.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/winter444_interleaved.jpg new file mode 100644 index 00000000000..f4fc9ceda54 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/baseline/winter444_interleaved.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/issues/Issue518-Bad-RST-Progressive.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/issues/Issue518-Bad-RST-Progressive.jpg new file mode 100644 index 00000000000..7f09c4f29e4 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/issues/Issue518-Bad-RST-Progressive.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/progressive/winter420_noninterleaved.jpg b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/progressive/winter420_noninterleaved.jpg new file mode 100644 index 00000000000..9cb2c1b1710 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Jpg/progressive/winter420_noninterleaved.jpg differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter0.png b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter0.png new file mode 100644 index 00000000000..d6a1ffff62e Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter0.png differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter1.png b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter1.png new file mode 100644 index 00000000000..26fee958ce7 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter1.png differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter2.png b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter2.png new file mode 100644 index 00000000000..e590f123481 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter2.png differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter3.png b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter3.png new file mode 100644 index 00000000000..758115059d7 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter3.png differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter4.png b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter4.png new file mode 100644 index 00000000000..3c8b5116e72 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/filter4.png differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Png/rgb-48bpp.png b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/rgb-48bpp.png new file mode 100644 index 00000000000..04a2ddd7116 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/rgb-48bpp.png differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Png/splash.png b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/splash.png new file mode 100644 index 00000000000..0964ae97440 Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Png/splash.png differ diff --git a/src/benchmarks/real-world/ImageSharp/Images/Input/Tga/targa_24bit.tga b/src/benchmarks/real-world/ImageSharp/Images/Input/Tga/targa_24bit.tga new file mode 100644 index 00000000000..ebe78aea5ff Binary files /dev/null and b/src/benchmarks/real-world/ImageSharp/Images/Input/Tga/targa_24bit.tga differ diff --git a/src/benchmarks/real-world/ImageSharp/Processing/BokehBlur.cs b/src/benchmarks/real-world/ImageSharp/Processing/BokehBlur.cs new file mode 100644 index 00000000000..3f5de3fc61e --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/BokehBlur.cs @@ -0,0 +1,19 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace SixLabors.ImageSharp.Benchmarks.Processing +{ + public class BokehBlur + { + [Benchmark] + public void Blur() + { + using var image = new Image(Configuration.Default, 400, 400, Color.White); + image.Mutate(c => c.BokehBlur()); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Processing/Crop.cs b/src/benchmarks/real-world/ImageSharp/Processing/Crop.cs new file mode 100644 index 00000000000..64c3c3ec358 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/Crop.cs @@ -0,0 +1,20 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace SixLabors.ImageSharp.Benchmarks.Processing +{ + public class Crop + { + [Benchmark(Description = "ImageSharp Crop")] + public Size CropImageSharp() + { + using var image = new Image(800, 800); + image.Mutate(x => x.Crop(100, 100)); + return new Size(image.Width, image.Height); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Processing/DetectEdges.cs b/src/benchmarks/real-world/ImageSharp/Processing/DetectEdges.cs new file mode 100644 index 00000000000..a0ab9ee825d --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/DetectEdges.cs @@ -0,0 +1,38 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks +{ + public class DetectEdges + { + private Image image; + + [GlobalSetup] + public void ReadImage() + { + if (this.image == null) + { + this.image = Image.Load(File.OpenRead(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Bmp.Car))); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.image.Dispose(); + this.image = null; + } + + [Benchmark(Description = "ImageSharp DetectEdges")] + public void ImageProcessorCoreDetectEdges() + { + this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Laplacian5x5)); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Processing/Diffuse.cs b/src/benchmarks/real-world/ImageSharp/Processing/Diffuse.cs new file mode 100644 index 00000000000..06f21a22b84 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/Diffuse.cs @@ -0,0 +1,30 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace SixLabors.ImageSharp.Benchmarks.Processing +{ + public class Diffuse + { + [Benchmark] + public Size DoDiffuse() + { + using var image = new Image(Configuration.Default, 800, 800, Color.BlanchedAlmond); + image.Mutate(x => x.Dither(KnownDitherings.FloydSteinberg)); + + return image.Size(); + } + + [Benchmark] + public Size DoDither() + { + using var image = new Image(Configuration.Default, 800, 800, Color.BlanchedAlmond); + image.Mutate(x => x.Dither()); + + return image.Size(); + } + } +} \ No newline at end of file diff --git a/src/benchmarks/real-world/ImageSharp/Processing/GaussianBlur.cs b/src/benchmarks/real-world/ImageSharp/Processing/GaussianBlur.cs new file mode 100644 index 00000000000..f8178aaa44e --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/GaussianBlur.cs @@ -0,0 +1,19 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace SixLabors.ImageSharp.Benchmarks.Samplers +{ + public class GaussianBlur + { + [Benchmark] + public void Blur() + { + using var image = new Image(Configuration.Default, 400, 400, Color.White); + image.Mutate(c => c.GaussianBlur()); + } + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Processing/HistogramEqualization.cs b/src/benchmarks/real-world/ImageSharp/Processing/HistogramEqualization.cs new file mode 100644 index 00000000000..d854401f815 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/HistogramEqualization.cs @@ -0,0 +1,51 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Normalization; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Processing +{ + public class HistogramEqualization + { + private Image image; + + [GlobalSetup] + public void ReadImages() + { + if (this.image == null) + { + this.image = Image.Load(File.OpenRead(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.HistogramEqImage))); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.image.Dispose(); + this.image = null; + } + + [Benchmark(Description = "Global Histogram Equalization")] + public void GlobalHistogramEqualization() + => this.image.Mutate(img => img.HistogramEqualization( + new HistogramEqualizationOptions() + { + LuminanceLevels = 256, + Method = HistogramEqualizationMethod.Global + })); + + [Benchmark(Description = "AdaptiveHistogramEqualization (Tile interpolation)")] + public void AdaptiveHistogramEqualization() + => this.image.Mutate(img => img.HistogramEqualization( + new HistogramEqualizationOptions() + { + LuminanceLevels = 256, + Method = HistogramEqualizationMethod.AdaptiveTileInterpolation + })); + } +} diff --git a/src/benchmarks/real-world/ImageSharp/Processing/Resize.cs b/src/benchmarks/real-world/ImageSharp/Processing/Resize.cs new file mode 100644 index 00000000000..aa6d86b28c1 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/Resize.cs @@ -0,0 +1,73 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.IO; +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks +{ + public abstract class Resize + where TPixel : unmanaged, IPixel + { + private byte[] bytes = null; + + private Image sourceImage; + + + protected Configuration Configuration { get; } = new Configuration(new JpegConfigurationModule()); + + protected int DestSize { get; private set; } + + [GlobalSetup] + public virtual void Setup() + { + if (this.bytes is null) + { + this.bytes = File.ReadAllBytes(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Snake)); + + this.sourceImage = Image.Load(this.bytes); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.bytes = null; + this.sourceImage.Dispose(); + } + + [Benchmark(Description = "ImageSharp")] + public int ImageSharp_P1() => this.RunImageSharpResize(); + + protected int RunImageSharpResize() + { + this.Configuration.MaxDegreeOfParallelism = 1; + + using (Image clone = this.sourceImage.Clone(this.ExecuteResizeOperation)) + { + return clone.Width; + } + } + + protected abstract void ExecuteResizeOperation(IImageProcessingContext ctx); + } + + public class Resize_Bicubic_Rgba32 : Resize + { + protected override void ExecuteResizeOperation(IImageProcessingContext ctx) + => ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); + } + + public class Resize_Bicubic_Rgb24 : Resize + { + protected override void ExecuteResizeOperation(IImageProcessingContext ctx) + => ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); + } +} \ No newline at end of file diff --git a/src/benchmarks/real-world/ImageSharp/Processing/Rotate.cs b/src/benchmarks/real-world/ImageSharp/Processing/Rotate.cs new file mode 100644 index 00000000000..6608346d2cf --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Processing/Rotate.cs @@ -0,0 +1,21 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace SixLabors.ImageSharp.Benchmarks.Processing +{ + public class Rotate + { + [Benchmark] + public Size DoRotate() + { + using var image = new Image(Configuration.Default, 400, 400, Color.BlanchedAlmond); + image.Mutate(x => x.Rotate(37.5F)); + + return image.Size(); + } + } +} \ No newline at end of file diff --git a/src/benchmarks/real-world/ImageSharp/Program.cs b/src/benchmarks/real-world/ImageSharp/Program.cs new file mode 100644 index 00000000000..94bab77e5f3 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/Program.cs @@ -0,0 +1,24 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using BenchmarkDotNet.Extensions; +using BenchmarkDotNet.Running; +using System.IO; + +namespace SixLabors.ImageSharp.Benchmarks +{ + public class Program + { + /// + /// The main. + /// + /// + /// The arguments to pass to the program. + /// + public static void Main(string[] args) => BenchmarkSwitcher + .FromAssembly(typeof(Program).Assembly) + .Run(args, RecommendedConfig.Create( + artifactsPath: new DirectoryInfo(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "BenchmarkDotNet.Artifacts")), + mandatoryCategories: null)); + } +} diff --git a/src/benchmarks/real-world/ImageSharp/README.md b/src/benchmarks/real-world/ImageSharp/README.md new file mode 100644 index 00000000000..a66554bb4e4 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/README.md @@ -0,0 +1,5 @@ +# ImageSharp Benchmarks + +ImageSharp benchmarks copied from https://github.com/SixLabors/ImageSharp/commit/413c90c23d448480906f82bf742feeecfb7f4eb1 + +Credits: SixLabors diff --git a/src/benchmarks/real-world/ImageSharp/THIRD-PARTY-NOTICES b/src/benchmarks/real-world/ImageSharp/THIRD-PARTY-NOTICES new file mode 100644 index 00000000000..bab30dc8553 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/THIRD-PARTY-NOTICES @@ -0,0 +1,15 @@ +.NET Core uses third-party libraries or other resources that may be +distributed under licenses different than the .NET Core software. + +In the event that we accidentally failed to list a required notice, please +bring it to our attention. Post an issue or email us: + + dotnet@microsoft.com + +The attached notices are provided for information only. + +License notice for ImageSharp +---------------------------- + +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. \ No newline at end of file diff --git a/src/benchmarks/real-world/ImageSharp/TestUtilities/TestDataGenerator.cs b/src/benchmarks/real-world/ImageSharp/TestUtilities/TestDataGenerator.cs new file mode 100644 index 00000000000..859a834ec66 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/TestUtilities/TestDataGenerator.cs @@ -0,0 +1,109 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; + +namespace SixLabors.ImageSharp.Tests +{ + /// + /// Helper methods that allow the creation of random test data. + /// + internal static class TestDataGenerator + { + /// + /// Creates an of the given length consisting of random values between the two ranges. + /// + /// The pseudo-random number generator. + /// The length. + /// The minimum value. + /// The maximum value. + /// The . + public static float[] GenerateRandomFloatArray(this Random rnd, int length, float minVal, float maxVal) + { + var values = new float[length]; + + RandomFill(rnd, values, minVal, maxVal); + + return values; + } + + public static void RandomFill(this Random rnd, Span destination, float minVal, float maxVal) + { + for (int i = 0; i < destination.Length; i++) + { + destination[i] = GetRandomFloat(rnd, minVal, maxVal); + } + } + + /// + /// Creates an of the given length consisting of random values between the two ranges. + /// + /// The pseudo-random number generator. + /// The length. + /// The minimum value. + /// The maximum value. + /// The . + public static Vector4[] GenerateRandomVectorArray(this Random rnd, int length, float minVal, float maxVal) + { + var values = new Vector4[length]; + + for (int i = 0; i < length; i++) + { + ref Vector4 v = ref values[i]; + v.X = GetRandomFloat(rnd, minVal, maxVal); + v.Y = GetRandomFloat(rnd, minVal, maxVal); + v.Z = GetRandomFloat(rnd, minVal, maxVal); + v.W = GetRandomFloat(rnd, minVal, maxVal); + } + + return values; + } + + /// + /// Creates an of the given length consisting of rounded random values between the two ranges. + /// + /// The pseudo-random number generator. + /// The length. + /// The minimum value. + /// The maximum value. + /// The . + public static float[] GenerateRandomRoundedFloatArray(this Random rnd, int length, float minVal, float maxVal) + { + var values = new float[length]; + + for (int i = 0; i < length; i++) + { + values[i] = (float)Math.Round(rnd.GetRandomFloat(minVal, maxVal)); + } + + return values; + } + + /// + /// Creates an of the given length consisting of random values. + /// + /// The pseudo-random number generator. + /// The length. + /// The . + public static byte[] GenerateRandomByteArray(this Random rnd, int length) + { + var values = new byte[length]; + rnd.NextBytes(values); + return values; + } + + public static short[] GenerateRandomInt16Array(this Random rnd, int length, short minVal, short maxVal) + { + var values = new short[length]; + for (int i = 0; i < values.Length; i++) + { + values[i] = (short)rnd.Next(minVal, maxVal); + } + + return values; + } + + private static float GetRandomFloat(this Random rnd, float minVal, float maxVal) => ((float)rnd.NextDouble() * (maxVal - minVal)) + minVal; + } +} diff --git a/src/benchmarks/real-world/ImageSharp/TestUtilities/TestEnvironment.cs b/src/benchmarks/real-world/ImageSharp/TestUtilities/TestEnvironment.cs new file mode 100644 index 00000000000..0ced6c3c998 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/TestUtilities/TestEnvironment.cs @@ -0,0 +1,31 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace SixLabors.ImageSharp.Tests +{ + public static partial class TestEnvironment + { + private const string InputImagesRelativePath = @"Images\Input"; + + private static readonly FileInfo TestAssemblyFile = + new FileInfo(typeof(TestEnvironment).GetTypeInfo().Assembly.Location); + + private static readonly string TestAssemblyDirectory = Path.GetDirectoryName(TestAssemblyFile.FullName); + + private static string GetFullPath(string relativePath) => + Path.Combine(TestAssemblyDirectory, relativePath) + .Replace('\\', Path.DirectorySeparatorChar); + + /// + /// Gets the correct full path to the Input Images directory. + /// + internal static string InputImagesDirectoryFullPath => GetFullPath(InputImagesRelativePath); + } +} diff --git a/src/benchmarks/real-world/ImageSharp/TestUtilities/TestImages.cs b/src/benchmarks/real-world/ImageSharp/TestUtilities/TestImages.cs new file mode 100644 index 00000000000..53a2d866912 --- /dev/null +++ b/src/benchmarks/real-world/ImageSharp/TestUtilities/TestImages.cs @@ -0,0 +1,78 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.Linq; + +// ReSharper disable InconsistentNaming +// ReSharper disable MemberHidesStaticFromOuterClass +namespace SixLabors.ImageSharp.Tests +{ + /// + /// Class that contains all the relative test image paths in the TestImages/Formats directory. + /// Use with , . + /// + public static class TestImages + { + public static class Png + { + public const string Splash = "Png/splash.png"; + public const string Rgb48Bpp = "Png/rgb-48bpp.png"; + + // Filtered test images from http://www.schaik.com/pngsuite/pngsuite_fil_png.html + public const string Filter0 = "Png/filter0.png"; + public const string Filter1 = "Png/filter1.png"; + public const string Filter2 = "Png/filter2.png"; + public const string Filter3 = "Png/filter3.png"; + public const string Filter4 = "Png/filter4.png"; + } + + public static class Jpeg + { + public static class Baseline + { + public const string Lake = "Jpg/baseline/Lake.jpg"; + public const string Jpeg420Exif = "Jpg/baseline/jpeg420exif.jpg"; + public const string HistogramEqImage = "Jpg/baseline/640px-Unequalized_Hawkes_Bay_NZ.jpg"; + public const string Winter444_Interleaved = "Jpg/baseline/winter444_interleaved.jpg"; + public const string Hiyamugi = "Jpg/baseline/Hiyamugi.jpg"; + public const string Jpeg400 = "Jpg/baseline/jpeg400jfif.jpg"; + public const string Snake = "Jpg/baseline/snake.jpg"; + } + + public static class Issues + { + public const string BadRstProgressive518 = "Jpg/issues/Issue518-Bad-RST-Progressive.jpg"; + } + + public static class Progressive + { + public const string Winter420_NonInterleaved = "Jpg/progressive/winter420_noninterleaved.jpg"; + } + + public static class BenchmarkSuite + { + // public const string Jpeg400_SmallMonochrome = Baseline.Jpeg400; + public const string Jpeg420Exif_MidSizeYCbCr = Baseline.Jpeg420Exif; + public const string Lake_Small444YCbCr = Baseline.Lake; + + // // A few large images from the "issues" set are actually very useful for benchmarking: + public const string BadRstProgressive518_Large444YCbCr = Issues.BadRstProgressive518; + } + } + + public static class Bmp + { + public const string Car = "Bmp/Car.bmp"; + } + + public static class Gif + { + public const string Rings = "Gif/rings.gif"; + } + + public static class Tga + { + public const string Bit24BottomLeft = "Tga/targa_24bit.tga"; + } + } +} diff --git a/src/harness/BenchmarkDotNet.Extensions/RecommendedConfig.cs b/src/harness/BenchmarkDotNet.Extensions/RecommendedConfig.cs index fd512ae2d57..575986d622c 100644 --- a/src/harness/BenchmarkDotNet.Extensions/RecommendedConfig.cs +++ b/src/harness/BenchmarkDotNet.Extensions/RecommendedConfig.cs @@ -64,9 +64,13 @@ public static IConfig Create( .AddColumn(StatisticColumn.Median, StatisticColumn.Min, StatisticColumn.Max) .AddValidator(TooManyTestCasesValidator.FailOnError) .AddValidator(new UniqueArgumentsValidator()) // don't allow for duplicated arguments #404 - .AddValidator(new MandatoryCategoryValidator(mandatoryCategories)) .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(36)); // the default is 20 and trims too aggressively some benchmark results + if (mandatoryCategories != null) + { + config = config.AddValidator(new MandatoryCategoryValidator(mandatoryCategories)); + } + if (Reporter.CreateReporter().InLab) { config = config.AddExporter(new PerfLabExporter());