diff --git a/src/ImageSharp/Common/Helpers/InliningOptions.cs b/src/ImageSharp/Common/Helpers/InliningOptions.cs new file mode 100644 index 0000000000..d218acdbaa --- /dev/null +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -0,0 +1,22 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// Uncomment this for verbose profiler results: +// #define PROFILING +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp +{ + /// + /// Global inlining options. Helps temporally disable inling for better profiler output. + /// + internal static class InliningOptions + { +#if PROFILING + public const MethodImplOptions ShortMethod = 0; +#else + public const MethodImplOptions ShortMethod = MethodImplOptions.AggressiveInlining; +#endif + public const MethodImplOptions ColdPath = MethodImplOptions.NoInlining; + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs b/src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs new file mode 100644 index 0000000000..c7f3666604 --- /dev/null +++ b/src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs @@ -0,0 +1,26 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.Formats.Jpeg +{ + internal static class JpegThrowHelper + { + /// + /// Cold path optimization for throwing -s + /// + /// The error message for the exception + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowImageFormatException(string errorMessage) + { + throw new ImageFormatException(errorMessage); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowBadHuffmanCode() + { + throw new ImageFormatException("Bad Huffman code."); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs index cc9d4d470e..74772ec617 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs @@ -665,7 +665,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private int GetBits(int n) { if (this.codeBits < n) @@ -680,7 +680,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components return (int)k; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private int GetBit() { if (this.codeBits < 1) @@ -695,7 +695,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components return (int)(k & 0x80000000); } - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(InliningOptions.ColdPath)] private void FillBuffer() { // Attempt to load at least the minimum nbumber of required bits into the buffer. @@ -748,7 +748,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components while (this.codeBits <= 24); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private int DecodeHuffman(ref PdfJsHuffmanTable table) { this.CheckBits(); @@ -773,7 +773,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components return this.DecodeHuffmanSlow(ref table); } - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(InliningOptions.ColdPath)] private int DecodeHuffmanSlow(ref PdfJsHuffmanTable table) { // Naive test is to shift the code_buffer down so k bits are @@ -813,7 +813,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components return table.Values[c]; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private int ExtendReceive(int n) { if (this.codeBits < n) @@ -829,7 +829,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components return (int)(k + (Bias[n] & ~sgn)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private void CheckBits() { if (this.codeBits < 16) @@ -838,10 +838,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private int PeekBits() => (int)((this.codeBuffer >> (32 - FastBits)) & ((1 << FastBits) - 1)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private bool ContinueOnMcuComplete() { if (--this.todo > 0) @@ -871,14 +871,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components return true; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] private bool HasRestart() { byte m = this.marker; return m >= JpegConstants.Markers.RST0 && m <= JpegConstants.Markers.RST7; } - [MethodImpl(MethodImplOptions.NoInlining)] private void Reset() { this.codeBits = 0;