diff --git a/.editorconfig b/.editorconfig index 753a4dbc2a..f84e6de2a0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,5 @@ -# Version: 2.1.0 (Using https://semver.org/) -# Updated: 2021-03-03 +# Version: 4.1.1 (Using https://semver.org/) +# Updated: 2022-05-23 # See https://github.com/RehanSaeed/EditorConfig/releases for release notes. # See https://github.com/RehanSaeed/EditorConfig for updates to this file. # See http://EditorConfig.org for more information about .editorconfig files. @@ -49,11 +49,11 @@ indent_size = 2 indent_size = 2 # Markdown Files -[*.md] +[*.{md,mdx}] trim_trailing_whitespace = false # Web Files -[*.{htm,html,js,jsm,ts,tsx,css,sass,scss,less,svg,vue}] +[*.{htm,html,js,jsm,ts,tsx,cjs,cts,ctsx,mjs,mts,mtsx,css,sass,scss,less,pcss,svg,vue}] indent_size = 2 # Batch Files @@ -75,7 +75,7 @@ indent_style = tab [*.{cs,csx,cake,vb,vbx}] # Default Severity for all .NET Code Style rules below -dotnet_analyzer_diagnostic.category-style.severity = warning +dotnet_analyzer_diagnostic.severity = warning ########################################## # Language Rules @@ -128,14 +128,15 @@ file_header_template = Copyright (c) Six Labors.\nLicensed under the Six Labors # dotnet_diagnostic.SA1636.severity = none # Undocumented -dotnet_style_operator_placement_when_wrapping = end_of_line +dotnet_style_operator_placement_when_wrapping = end_of_line:warning +csharp_style_prefer_null_check_over_type_check = true:warning # C# Style Rules # https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/language-rules#c-style-rules [*.{cs,csx,cake}] # 'var' preferences -csharp_style_var_for_built_in_types = never -csharp_style_var_when_type_is_apparent = true:warning +csharp_style_var_for_built_in_types = false:warning +csharp_style_var_when_type_is_apparent = false:warning csharp_style_var_elsewhere = false:warning # Expression-bodied members csharp_style_expression_bodied_methods = true:warning @@ -200,12 +201,15 @@ dotnet_diagnostic.IDE0059.severity = suggestion # Organize using directives dotnet_sort_system_directives_first = true dotnet_separate_import_directive_groups = false +# Dotnet namespace options +dotnet_style_namespace_match_folder = true:suggestion +dotnet_diagnostic.IDE0130.severity = suggestion # C# formatting rules # https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#c-formatting-rules [*.{cs,csx,cake}] # Newline options -# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#new-line-options +# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#new-line-options csharp_new_line_before_open_brace = all csharp_new_line_before_else = true csharp_new_line_before_catch = true @@ -214,7 +218,7 @@ csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_anonymous_types = true csharp_new_line_between_query_expression_clauses = true # Indentation options -# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#indentation-options +# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#indentation-options csharp_indent_case_contents = true csharp_indent_switch_labels = true csharp_indent_labels = no_change @@ -222,7 +226,7 @@ csharp_indent_block_contents = true csharp_indent_braces = false csharp_indent_case_contents_when_block = false # Spacing options -# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#spacing-options +# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#spacing-options csharp_space_after_cast = false csharp_space_after_keywords_in_control_flow_statements = true csharp_space_between_parentheses = false @@ -246,7 +250,7 @@ csharp_space_before_open_square_brackets = false csharp_space_between_empty_square_brackets = false csharp_space_between_square_brackets = false # Wrap options -# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#wrap-options +# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#wrap-options csharp_preserve_single_line_statements = false csharp_preserve_single_line_blocks = true @@ -448,4 +452,4 @@ dotnet_naming_rule.parameters_rule.severity = warning # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. -########################################## +########################################## \ No newline at end of file diff --git a/shared-infrastructure b/shared-infrastructure index c0e0353c1e..5eb77e2d9e 160000 --- a/shared-infrastructure +++ b/shared-infrastructure @@ -1 +1 @@ -Subproject commit c0e0353c1ee89398def0ccdc3e945380034fbea8 +Subproject commit 5eb77e2d9eb4f0ece012c996941ab78db1af2a41 diff --git a/src/Directory.Build.props b/src/Directory.Build.props index faa29865f2..cfc3d82225 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -21,6 +21,10 @@ true + + ..\ImageSharp.ruleset + + diff --git a/src/ImageSharp.ruleset b/src/ImageSharp.ruleset new file mode 100644 index 0000000000..e88c43f838 --- /dev/null +++ b/src/ImageSharp.ruleset @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 8a7046c9ad..2fbb429957 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Text; using System.Threading; @@ -34,11 +35,11 @@ public static IImageEncoder DetectEncoder(this Image source, string filePath) IImageFormat format = source.GetConfiguration().ImageFormatsManager.FindFormatByFileExtension(ext); if (format is null) { - var sb = new StringBuilder(); - sb.AppendLine($"No encoder was found for extension '{ext}'. Registered encoders include:"); + StringBuilder sb = new(); + sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}'. Registered encoders include:"); foreach (IImageFormat fmt in source.GetConfiguration().ImageFormats) { - sb.AppendFormat(" - {0} : {1}{2}", fmt.Name, string.Join(", ", fmt.FileExtensions), Environment.NewLine); + sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", fmt.Name, string.Join(", ", fmt.FileExtensions), Environment.NewLine); } throw new NotSupportedException(sb.ToString()); @@ -48,11 +49,11 @@ public static IImageEncoder DetectEncoder(this Image source, string filePath) if (encoder is null) { - var sb = new StringBuilder(); - sb.AppendLine($"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:"); + StringBuilder sb = new(); + sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:"); foreach (KeyValuePair enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders) { - sb.AppendFormat(" - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine); + sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine); } throw new NotSupportedException(sb.ToString()); @@ -116,6 +117,7 @@ private static Configuration GetConfiguration(IConfigurationProvider source) /// Certain Image Processors may invalidate the returned and all it's buffers, /// therefore it's not recommended to mutate the image while holding a reference to it's . /// + /// Thrown when the in . public static IMemoryGroup GetPixelMemoryGroup(this ImageFrame source) where TPixel : unmanaged, IPixel => source?.PixelBuffer.FastMemoryGroup.View ?? throw new ArgumentNullException(nameof(source)); @@ -131,13 +133,14 @@ public static IMemoryGroup GetPixelMemoryGroup(this ImageFrame and all it's buffers, /// therefore it's not recommended to mutate the image while holding a reference to it's . /// + /// Thrown when the in . public static IMemoryGroup GetPixelMemoryGroup(this Image source) where TPixel : unmanaged, IPixel => source?.Frames.RootFrame.GetPixelMemoryGroup() ?? throw new ArgumentNullException(nameof(source)); /// /// Gets the representation of the pixels as a of contiguous memory - /// at row beginning from the the first pixel on that row. + /// at row beginning from the first pixel on that row. /// /// The type of the pixel. /// The source. @@ -154,8 +157,8 @@ public static Memory DangerousGetPixelRowMemory(this ImageFrame< } /// - /// Gets the representation of the pixels as of of contiguous memory - /// at row beginning from the the first pixel on that row. + /// Gets the representation of the pixels as of contiguous memory + /// at row beginning from the first pixel on that row. /// /// The type of the pixel. /// The source. diff --git a/src/ImageSharp/Advanced/PreserveAttribute.cs b/src/ImageSharp/Advanced/PreserveAttribute.cs index d543a043c8..5e3a712707 100644 --- a/src/ImageSharp/Advanced/PreserveAttribute.cs +++ b/src/ImageSharp/Advanced/PreserveAttribute.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System; + namespace SixLabors.ImageSharp.Advanced { /// @@ -8,7 +10,8 @@ namespace SixLabors.ImageSharp.Advanced /// The only thing that matters is the class name. /// There is no need to use or inherit from the PreserveAttribute class in each environment. /// - internal sealed class PreserveAttribute : System.Attribute + [AttributeUsage(AttributeTargets.Method)] + internal sealed class PreserveAttribute : Attribute { } } diff --git a/src/ImageSharp/Color/Color.cs b/src/ImageSharp/Color/Color.cs index d8fb348913..9cff680e46 100644 --- a/src/ImageSharp/Color/Color.cs +++ b/src/ImageSharp/Color/Color.cs @@ -151,7 +151,7 @@ public static Color FromPixel(TPixel pixel) [MethodImpl(InliningOptions.ShortMethod)] public static Color ParseHex(string hex) { - var rgba = Rgba32.ParseHex(hex); + Rgba32 rgba = Rgba32.ParseHex(hex); return new Color(rgba); } @@ -193,6 +193,7 @@ public static bool TryParseHex(string hex, out Color result) /// /// The . /// + /// Input string is not in the correct format. public static Color Parse(string input) { Guard.NotNull(input, nameof(input)); @@ -241,7 +242,7 @@ public static bool TryParse(string input, out Color result) /// The color having it's alpha channel altered. public Color WithAlpha(float alpha) { - var v = (Vector4)this; + Vector4 v = (Vector4)this; v.W = alpha; return new Color(v); } @@ -290,12 +291,12 @@ public TPixel ToPixel() /// The source color span. /// The destination pixel span. [MethodImpl(InliningOptions.ShortMethod)] - public static void ToPixel( - Configuration configuration, - ReadOnlySpan source, - Span destination) +#pragma warning disable RCS1163 // Unused parameter. + public static void ToPixel(Configuration configuration, ReadOnlySpan source, Span destination) +#pragma warning restore RCS1163 // Unused parameter. where TPixel : unmanaged, IPixel { + // TODO: Investigate bulk operations utilizing configuration parameter here. Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); for (int i = 0; i < source.Length; i++) { diff --git a/src/ImageSharp/ColorSpaces/CieLab.cs b/src/ImageSharp/ColorSpaces/CieLab.cs index b72a2eecd4..bc84342dec 100644 --- a/src/ImageSharp/ColorSpaces/CieLab.cs +++ b/src/ImageSharp/ColorSpaces/CieLab.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -19,29 +19,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public static readonly CieXyz DefaultWhitePoint = Illuminants.D50; - /// - /// Gets the lightness dimension. - /// A value usually ranging between 0 (black), 100 (diffuse white) or higher (specular white). - /// - public readonly float L; - - /// - /// Gets the a color component. - /// A value usually ranging from -100 to 100. Negative is green, positive magenta. - /// - public readonly float A; - - /// - /// Gets the b color component. - /// A value usually ranging from -100 to 100. Negative is blue, positive is yellow - /// - public readonly float B; - - /// - /// Gets the reference white point of this color - /// - public readonly CieXyz WhitePoint; - /// /// Initializes a new instance of the struct. /// @@ -95,6 +72,29 @@ public CieLab(Vector3 vector, CieXyz whitePoint) this.WhitePoint = whitePoint; } + /// + /// Gets the lightness dimension. + /// A value usually ranging between 0 (black), 100 (diffuse white) or higher (specular white). + /// + public readonly float L { get; } + + /// + /// Gets the a color component. + /// A value usually ranging from -100 to 100. Negative is green, positive magenta. + /// + public readonly float A { get; } + + /// + /// Gets the b color component. + /// A value usually ranging from -100 to 100. Negative is blue, positive is yellow + /// + public readonly float B { get; } + + /// + /// Gets the reference white point of this color + /// + public readonly CieXyz WhitePoint { get; } + /// /// Compares two objects for equality. /// @@ -128,12 +128,10 @@ public CieLab(Vector3 vector, CieXyz whitePoint) /// [MethodImpl(InliningOptions.ShortMethod)] - public bool Equals(CieLab other) - { - return this.L.Equals(other.L) - && this.A.Equals(other.A) - && this.B.Equals(other.B) - && this.WhitePoint.Equals(other.WhitePoint); - } + public bool Equals(CieLab other) => + this.L.Equals(other.L) + && this.A.Equals(other.A) + && this.B.Equals(other.B) + && this.WhitePoint.Equals(other.WhitePoint); } } diff --git a/src/ImageSharp/ColorSpaces/CieLch.cs b/src/ImageSharp/ColorSpaces/CieLch.cs index 899c7d8dbc..0c46e9b7cc 100644 --- a/src/ImageSharp/ColorSpaces/CieLch.cs +++ b/src/ImageSharp/ColorSpaces/CieLch.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -19,31 +19,8 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public static readonly CieXyz DefaultWhitePoint = Illuminants.D50; - private static readonly Vector3 Min = new Vector3(0, -200, 0); - private static readonly Vector3 Max = new Vector3(100, 200, 360); - - /// - /// Gets the lightness dimension. - /// A value ranging between 0 (black), 100 (diffuse white) or higher (specular white). - /// - public readonly float L; - - /// - /// Gets the a chroma component. - /// A value ranging from 0 to 200. - /// - public readonly float C; - - /// - /// Gets the h° hue component in degrees. - /// A value ranging from 0 to 360. - /// - public readonly float H; - - /// - /// Gets the reference white point of this color - /// - public readonly CieXyz WhitePoint; + private static readonly Vector3 Min = new(0, -200, 0); + private static readonly Vector3 Max = new(100, 200, 360); /// /// Initializes a new instance of the struct. @@ -97,6 +74,29 @@ public CieLch(Vector3 vector, CieXyz whitePoint) this.WhitePoint = whitePoint; } + /// + /// Gets the lightness dimension. + /// A value ranging between 0 (black), 100 (diffuse white) or higher (specular white). + /// + public readonly float L { get; } + + /// + /// Gets the a chroma component. + /// A value ranging from 0 to 200. + /// + public readonly float C { get; } + + /// + /// Gets the h° hue component in degrees. + /// A value ranging from 0 to 360. + /// + public readonly float H { get; } + + /// + /// Gets the reference white point of this color + /// + public readonly CieXyz WhitePoint { get; } + /// /// Compares two objects for equality. /// @@ -121,9 +121,7 @@ public CieLch(Vector3 vector, CieXyz whitePoint) /// public override int GetHashCode() - { - return HashCode.Combine(this.L, this.C, this.H, this.WhitePoint); - } + => HashCode.Combine(this.L, this.C, this.H, this.WhitePoint); /// public override string ToString() => FormattableString.Invariant($"CieLch({this.L:#0.##}, {this.C:#0.##}, {this.H:#0.##})"); @@ -135,12 +133,10 @@ public override int GetHashCode() /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(CieLch other) - { - return this.L.Equals(other.L) - && this.C.Equals(other.C) - && this.H.Equals(other.H) - && this.WhitePoint.Equals(other.WhitePoint); - } + => this.L.Equals(other.L) + && this.C.Equals(other.C) + && this.H.Equals(other.H) + && this.WhitePoint.Equals(other.WhitePoint); /// /// Computes the saturation of the color (chroma normalized by lightness) diff --git a/src/ImageSharp/ColorSpaces/CieLchuv.cs b/src/ImageSharp/ColorSpaces/CieLchuv.cs index 2a41fd490c..2227b60225 100644 --- a/src/ImageSharp/ColorSpaces/CieLchuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLchuv.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -13,8 +13,8 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public readonly struct CieLchuv : IEquatable { - private static readonly Vector3 Min = new Vector3(0, -200, 0); - private static readonly Vector3 Max = new Vector3(100, 200, 360); + private static readonly Vector3 Min = new(0, -200, 0); + private static readonly Vector3 Max = new(100, 200, 360); /// /// D50 standard illuminant. @@ -22,29 +22,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public static readonly CieXyz DefaultWhitePoint = Illuminants.D65; - /// - /// Gets the lightness dimension. - /// A value ranging between 0 (black), 100 (diffuse white) or higher (specular white). - /// - public readonly float L; - - /// - /// Gets the a chroma component. - /// A value ranging from 0 to 200. - /// - public readonly float C; - - /// - /// Gets the h° hue component in degrees. - /// A value ranging from 0 to 360. - /// - public readonly float H; - - /// - /// Gets the reference white point of this color - /// - public readonly CieXyz WhitePoint; - /// /// Initializes a new instance of the struct. /// @@ -98,6 +75,29 @@ public CieLchuv(Vector3 vector, CieXyz whitePoint) this.WhitePoint = whitePoint; } + /// + /// Gets the lightness dimension. + /// A value ranging between 0 (black), 100 (diffuse white) or higher (specular white). + /// + public readonly float L { get; } + + /// + /// Gets the a chroma component. + /// A value ranging from 0 to 200. + /// + public readonly float C { get; } + + /// + /// Gets the h° hue component in degrees. + /// A value ranging from 0 to 360. + /// + public readonly float H { get; } + + /// + /// Gets the reference white point of this color + /// + public readonly CieXyz WhitePoint { get; } + /// /// Compares two objects for equality. /// @@ -130,12 +130,10 @@ public CieLchuv(Vector3 vector, CieXyz whitePoint) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(CieLchuv other) - { - return this.L.Equals(other.L) - && this.C.Equals(other.C) - && this.H.Equals(other.H) - && this.WhitePoint.Equals(other.WhitePoint); - } + => this.L.Equals(other.L) + && this.C.Equals(other.C) + && this.H.Equals(other.H) + && this.WhitePoint.Equals(other.WhitePoint); /// /// Computes the saturation of the color (chroma normalized by lightness) diff --git a/src/ImageSharp/ColorSpaces/CieLuv.cs b/src/ImageSharp/ColorSpaces/CieLuv.cs index a45042ba85..32481bcb52 100644 --- a/src/ImageSharp/ColorSpaces/CieLuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLuv.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -21,29 +21,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public static readonly CieXyz DefaultWhitePoint = Illuminants.D65; - /// - /// Gets the lightness dimension - /// A value usually ranging between 0 and 100. - /// - public readonly float L; - - /// - /// Gets the blue-yellow chromaticity coordinate of the given whitepoint. - /// A value usually ranging between -100 and 100. - /// - public readonly float U; - - /// - /// Gets the red-green chromaticity coordinate of the given whitepoint. - /// A value usually ranging between -100 and 100. - /// - public readonly float V; - - /// - /// Gets the reference white point of this color - /// - public readonly CieXyz WhitePoint; - /// /// Initializes a new instance of the struct. /// @@ -96,6 +73,29 @@ public CieLuv(Vector3 vector, CieXyz whitePoint) this.WhitePoint = whitePoint; } + /// + /// Gets the lightness dimension + /// A value usually ranging between 0 and 100. + /// + public readonly float L { get; } + + /// + /// Gets the blue-yellow chromaticity coordinate of the given whitepoint. + /// A value usually ranging between -100 and 100. + /// + public readonly float U { get; } + + /// + /// Gets the red-green chromaticity coordinate of the given whitepoint. + /// A value usually ranging between -100 and 100. + /// + public readonly float V { get; } + + /// + /// Gets the reference white point of this color + /// + public readonly CieXyz WhitePoint { get; } + /// /// Compares two objects for equality. /// @@ -130,11 +130,9 @@ public CieLuv(Vector3 vector, CieXyz whitePoint) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(CieLuv other) - { - return this.L.Equals(other.L) - && this.U.Equals(other.U) - && this.V.Equals(other.V) - && this.WhitePoint.Equals(other.WhitePoint); - } + => this.L.Equals(other.L) + && this.U.Equals(other.U) + && this.V.Equals(other.V) + && this.WhitePoint.Equals(other.WhitePoint); } } diff --git a/src/ImageSharp/ColorSpaces/CieXyy.cs b/src/ImageSharp/ColorSpaces/CieXyy.cs index 9306606db9..6bbcad075c 100644 --- a/src/ImageSharp/ColorSpaces/CieXyy.cs +++ b/src/ImageSharp/ColorSpaces/CieXyy.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -13,24 +13,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public readonly struct CieXyy : IEquatable { - /// - /// Gets the X chrominance component. - /// A value usually ranging between 0 and 1. - /// - public readonly float X; - - /// - /// Gets the Y chrominance component. - /// A value usually ranging between 0 and 1. - /// - public readonly float Y; - - /// - /// Gets the Y luminance component. - /// A value usually ranging between 0 and 1. - /// - public readonly float Yl; - /// /// Initializes a new instance of the struct. /// @@ -60,6 +42,24 @@ public CieXyy(Vector3 vector) this.Yl = vector.Z; } + /// + /// Gets the X chrominance component. + /// A value usually ranging between 0 and 1. + /// + public readonly float X { get; } + + /// + /// Gets the Y chrominance component. + /// A value usually ranging between 0 and 1. + /// + public readonly float Y { get; } + + /// + /// Gets the Y luminance component. + /// A value usually ranging between 0 and 1. + /// + public readonly float Yl { get; } + /// /// Compares two objects for equality. /// @@ -94,10 +94,8 @@ public CieXyy(Vector3 vector) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(CieXyy other) - { - return this.X.Equals(other.X) - && this.Y.Equals(other.Y) - && this.Yl.Equals(other.Yl); - } + => this.X.Equals(other.X) + && this.Y.Equals(other.Y) + && this.Yl.Equals(other.Yl); } } diff --git a/src/ImageSharp/ColorSpaces/CieXyz.cs b/src/ImageSharp/ColorSpaces/CieXyz.cs index e52904c558..b767128438 100644 --- a/src/ImageSharp/ColorSpaces/CieXyz.cs +++ b/src/ImageSharp/ColorSpaces/CieXyz.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -13,24 +13,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public readonly struct CieXyz : IEquatable { - /// - /// Gets the X component. A mix (a linear combination) of cone response curves chosen to be nonnegative. - /// A value usually ranging between 0 and 1. - /// - public readonly float X; - - /// - /// Gets the Y luminance component. - /// A value usually ranging between 0 and 1. - /// - public readonly float Y; - - /// - /// Gets the Z component. Quasi-equal to blue stimulation, or the S cone response. - /// A value usually ranging between 0 and 1. - /// - public readonly float Z; - /// /// Initializes a new instance of the struct. /// @@ -56,6 +38,24 @@ public CieXyz(Vector3 vector) this.Z = vector.Z; } + /// + /// Gets the X component. A mix (a linear combination) of cone response curves chosen to be nonnegative. + /// A value usually ranging between 0 and 1. + /// + public readonly float X { get; } + + /// + /// Gets the Y luminance component. + /// A value usually ranging between 0 and 1. + /// + public readonly float Y { get; } + + /// + /// Gets the Z component. Quasi-equal to blue stimulation, or the S cone response. + /// A value usually ranging between 0 and 1. + /// + public readonly float Z { get; } + /// /// Compares two objects for equality. /// @@ -83,7 +83,7 @@ public CieXyz(Vector3 vector) /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public Vector3 ToVector3() => new Vector3(this.X, this.Y, this.Z); + public Vector3 ToVector3() => new(this.X, this.Y, this.Z); /// public override int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Z); @@ -97,10 +97,8 @@ public CieXyz(Vector3 vector) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(CieXyz other) - { - return this.X.Equals(other.X) - && this.Y.Equals(other.Y) - && this.Z.Equals(other.Z); - } + => this.X.Equals(other.X) + && this.Y.Equals(other.Y) + && this.Z.Equals(other.Z); } } diff --git a/src/ImageSharp/ColorSpaces/Cmyk.cs b/src/ImageSharp/ColorSpaces/Cmyk.cs index cd2899ee7d..fad331101c 100644 --- a/src/ImageSharp/ColorSpaces/Cmyk.cs +++ b/src/ImageSharp/ColorSpaces/Cmyk.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -15,30 +15,6 @@ namespace SixLabors.ImageSharp.ColorSpaces private static readonly Vector4 Min = Vector4.Zero; private static readonly Vector4 Max = Vector4.One; - /// - /// Gets the cyan color component. - /// A value ranging between 0 and 1. - /// - public readonly float C; - - /// - /// Gets the magenta color component. - /// A value ranging between 0 and 1. - /// - public readonly float M; - - /// - /// Gets the yellow color component. - /// A value ranging between 0 and 1. - /// - public readonly float Y; - - /// - /// Gets the keyline black color component. - /// A value ranging between 0 and 1. - /// - public readonly float K; - /// /// Initializes a new instance of the struct. /// @@ -66,6 +42,30 @@ public Cmyk(Vector4 vector) this.K = vector.W; } + /// + /// Gets the cyan color component. + /// A value ranging between 0 and 1. + /// + public readonly float C { get; } + + /// + /// Gets the magenta color component. + /// A value ranging between 0 and 1. + /// + public readonly float M { get; } + + /// + /// Gets the yellow color component. + /// A value ranging between 0 and 1. + /// + public readonly float Y { get; } + + /// + /// Gets the keyline black color component. + /// A value ranging between 0 and 1. + /// + public readonly float K { get; } + /// /// Compares two objects for equality. /// @@ -101,11 +101,9 @@ public Cmyk(Vector4 vector) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(Cmyk other) - { - return this.C.Equals(other.C) - && this.M.Equals(other.M) - && this.Y.Equals(other.Y) - && this.K.Equals(other.K); - } + => this.C.Equals(other.C) + && this.M.Equals(other.M) + && this.Y.Equals(other.Y) + && this.K.Equals(other.K); } } diff --git a/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs b/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs index 1337af702c..82e9a123be 100644 --- a/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs +++ b/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs @@ -5,10 +5,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.ColorSpaces.Companding { @@ -25,10 +23,10 @@ public static class SRgbCompanding private const int Length = Scale + 2; // 256kb @ 16bit precision. private const int Scale = (1 << 16) - 1; - private static readonly Lazy LazyCompressTable = new Lazy( + private static readonly Lazy LazyCompressTable = new( () => { - var result = new float[Length]; + float[] result = new float[Length]; for (int i = 0; i < result.Length; i++) { @@ -49,10 +47,10 @@ public static class SRgbCompanding }, true); - private static readonly Lazy LazyExpandTable = new Lazy( + private static readonly Lazy LazyExpandTable = new( () => { - var result = new float[Length]; + float[] result = new float[Length]; for (int i = 0; i < result.Length; i++) { @@ -84,7 +82,6 @@ public static class SRgbCompanding [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Expand(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { CompandAvx2(vectors, ExpandTable); @@ -92,11 +89,10 @@ public static void Expand(Span vectors) if (Numerics.Modulo2(vectors.Length) != 0) { // Vector4 fits neatly in pairs. Any overlap has to be equal to 1. - Expand(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1))); + Expand(ref MemoryMarshal.GetReference(vectors[^1..])); } } else -#endif { CompandScalar(vectors, ExpandTable); } @@ -109,7 +105,6 @@ public static void Expand(Span vectors) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Compress(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { CompandAvx2(vectors, CompressTable); @@ -117,11 +112,10 @@ public static unsafe void Compress(Span vectors) if (Numerics.Modulo2(vectors.Length) != 0) { // Vector4 fits neatly in pairs. Any overlap has to be equal to 1. - Compress(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1))); + Compress(ref MemoryMarshal.GetReference(vectors[^1..])); } } else -#endif { CompandScalar(vectors, CompressTable); } @@ -171,8 +165,6 @@ public static float Expand(float channel) public static float Compress(float channel) => channel <= 0.0031308F ? 12.92F * channel : (1.055F * MathF.Pow(channel, 0.416666666666667F)) - 0.055F; -#if SUPPORTS_RUNTIME_INTRINSICS - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe void CompandAvx2(Span vectors, float[] table) { @@ -204,7 +196,6 @@ private static unsafe void CompandAvx2(Span vectors, float[] table) } } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe void CompandScalar(Span vectors, float[] table) diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs index 60ae18b5c9..d200aa83ec 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs @@ -150,9 +150,9 @@ public Rgb Adapt(in Rgb color) return color; } - var linearInput = this.ToLinearRgb(color); + var linearInput = ToLinearRgb(color); LinearRgb linearOutput = this.Adapt(linearInput); - return this.ToRgb(linearOutput); + return ToRgb(linearOutput); } } } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs index 1a7c627db5..c3dd3b473f 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLab.cs @@ -12,11 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - /// - /// The converter for converting between CieLch to CieLab. - /// - private static readonly CieLchToCieLabConverter CieLchToCieLabConverter = new CieLchToCieLabConverter(); - /// /// Converts a into a . /// @@ -58,7 +53,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in CieLchuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -91,7 +86,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -124,7 +119,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -190,7 +185,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in Cmyk color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -222,7 +217,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in Hsl color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -255,7 +250,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in Hsv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -287,7 +282,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -320,7 +315,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -353,7 +348,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in LinearRgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -386,7 +381,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in Rgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -419,7 +414,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLab ToCieLab(in YCbCr color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLab(xyzColor); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs index 06ff11b1ec..ec7d48b783 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLch.cs @@ -12,11 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - /// - /// The converter for converting between CieLab to CieLch. - /// - private static readonly CieLabToCieLchConverter CieLabToCieLchConverter = new CieLabToCieLchConverter(); - /// /// Converts a into a /// @@ -123,7 +118,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLch ToCieLch(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + var xyzColor = ToCieXyz(color); return this.ToCieLch(xyzColor); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs index 5752cb9b11..52c092a2e8 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLchuv.cs @@ -12,11 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - /// - /// The converter for converting between CieLab to CieLchuv. - /// - private static readonly CieLuvToCieLchuvConverter CieLuvToCieLchuvConverter = new CieLuvToCieLchuvConverter(); - /// /// Converts a into a /// @@ -24,7 +19,7 @@ public partial class ColorSpaceConverter /// The public CieLchuv ToCieLchuv(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -57,7 +52,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -123,7 +118,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -156,7 +151,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in CieXyz color) { - var luvColor = this.ToCieLuv(color); + CieLuv luvColor = this.ToCieLuv(color); return this.ToCieLchuv(luvColor); } @@ -189,7 +184,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in Cmyk color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -222,7 +217,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in Hsl color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -255,7 +250,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in Hsv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -288,7 +283,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -321,7 +316,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in LinearRgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -354,7 +349,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -387,7 +382,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in Rgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -420,7 +415,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLchuv ToCieLchuv(in YCbCr color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLchuv(xyzColor); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs index 486924b9aa..572d8875db 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieLuv.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly CieLchuvToCieLuvConverter CieLchuvToCieLuvConverter = new CieLchuvToCieLuvConverter(); - /// /// Converts a into a . /// @@ -21,7 +19,7 @@ public partial class ColorSpaceConverter /// The public CieLuv ToCieLuv(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -53,7 +51,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -120,7 +118,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -187,7 +185,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in Cmyk color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -219,7 +217,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in Hsl color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -251,7 +249,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in Hsv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -283,7 +281,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -315,7 +313,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -347,7 +345,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in LinearRgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -379,7 +377,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in Rgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -411,7 +409,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieLuv ToCieLuv(in YCbCr color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCieLuv(xyzColor); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs index 603308751c..b5d655e680 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyy.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly CieXyzAndCieXyyConverter CieXyzAndCieXyyConverter = new CieXyzAndCieXyyConverter(); - /// /// Converts a into a /// @@ -21,9 +19,9 @@ public partial class ColorSpaceConverter /// The public CieXyy ToCieXyy(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -54,9 +52,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -87,9 +85,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in CieLchuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -120,9 +118,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -151,14 +149,14 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public CieXyy ToCieXyy(in CieXyz color) => CieXyzAndCieXyyConverter.Convert(color); + public static CieXyy ToCieXyy(in CieXyz color) => CieXyzAndCieXyyConverter.Convert(color); /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -170,7 +168,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref CieXyz sp = ref Unsafe.Add(ref sourceRef, i); ref CieXyy dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToCieXyy(sp); + dp = ToCieXyy(sp); } } @@ -181,9 +179,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in Cmyk color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -214,9 +212,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(Hsl color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -247,9 +245,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in Hsv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -280,9 +278,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -313,9 +311,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in LinearRgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -346,9 +344,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -379,9 +377,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in Rgb color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// @@ -412,9 +410,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyy ToCieXyy(in YCbCr color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); - return this.ToCieXyy(xyzColor); + return ToCieXyy(xyzColor); } /// diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs index 242392acc0..d1f0ca489d 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.CieXyz.cs @@ -12,12 +12,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly CieLabToCieXyzConverter CieLabToCieXyzConverter = new CieLabToCieXyzConverter(); - - private static readonly CieLuvToCieXyzConverter CieLuvToCieXyzConverter = new CieLuvToCieXyzConverter(); - - private static readonly HunterLabToCieXyzConverter - HunterLabToCieXyzConverter = new HunterLabToCieXyzConverter(); + private static readonly HunterLabToCieXyzConverter HunterLabToCieXyzConverter = new(); private LinearRgbToCieXyzConverter linearRgbToCieXyzConverter; @@ -166,18 +161,17 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public CieXyz ToCieXyz(in CieXyy color) - { + public static CieXyz ToCieXyz(in CieXyy color) + // Conversion - return CieXyzAndCieXyyConverter.Convert(color); - } + => CieXyzAndCieXyyConverter.Convert(color); /// /// Performs the bulk conversion from into . /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -189,7 +183,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref CieXyy sp = ref Unsafe.Add(ref sourceRef, i); ref CieXyz dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToCieXyz(sp); + dp = ToCieXyz(sp); } } @@ -200,7 +194,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyz ToCieXyz(in Cmyk color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return this.ToCieXyz(rgb); } @@ -233,7 +227,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyz ToCieXyz(in Hsl color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return this.ToCieXyz(rgb); } @@ -267,7 +261,7 @@ public void Convert(ReadOnlySpan source, Span destination) public CieXyz ToCieXyz(in Hsv color) { // Conversion - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return this.ToCieXyz(rgb); } @@ -367,9 +361,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The color to convert. /// The public CieXyz ToCieXyz(in Lms color) - { - return this.cieXyzAndLmsConverter.Convert(color); - } + => this.cieXyzAndLmsConverter.Convert(color); /// /// Performs the bulk conversion from into . @@ -432,7 +424,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public CieXyz ToCieXyz(in YCbCr color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return this.ToCieXyz(rgb); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs index 664511be9a..152a7f7fc6 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Cmyk.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly CmykAndRgbConverter CmykAndRgbConverter = new CmykAndRgbConverter(); - /// /// Converts a into a . /// @@ -21,7 +19,7 @@ public partial class ColorSpaceConverter /// The public Cmyk ToCmyk(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -54,7 +52,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -87,7 +85,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in CieLchuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -120,7 +118,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -153,7 +151,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -186,7 +184,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in CieXyz color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return CmykAndRgbConverter.Convert(rgb); } @@ -217,9 +215,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Cmyk ToCmyk(in Hsl color) + public static Cmyk ToCmyk(in Hsl color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return CmykAndRgbConverter.Convert(rgb); } @@ -229,7 +227,7 @@ public Cmyk ToCmyk(in Hsl color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -241,7 +239,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsl sp = ref Unsafe.Add(ref sourceRef, i); ref Cmyk dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToCmyk(sp); + dp = ToCmyk(sp); } } @@ -250,9 +248,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Cmyk ToCmyk(in Hsv color) + public static Cmyk ToCmyk(in Hsv color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return CmykAndRgbConverter.Convert(rgb); } @@ -262,7 +260,7 @@ public Cmyk ToCmyk(in Hsv color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -274,7 +272,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsv sp = ref Unsafe.Add(ref sourceRef, i); ref Cmyk dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToCmyk(sp); + dp = ToCmyk(sp); } } @@ -285,7 +283,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -316,9 +314,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Cmyk ToCmyk(in LinearRgb color) + public static Cmyk ToCmyk(in LinearRgb color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return CmykAndRgbConverter.Convert(rgb); } @@ -328,7 +326,7 @@ public Cmyk ToCmyk(in LinearRgb color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -340,7 +338,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref LinearRgb sp = ref Unsafe.Add(ref sourceRef, i); ref Cmyk dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToCmyk(sp); + dp = ToCmyk(sp); } } @@ -351,7 +349,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -382,14 +380,14 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Cmyk ToCmyk(in Rgb color) => CmykAndRgbConverter.Convert(color); + public static Cmyk ToCmyk(in Rgb color) => CmykAndRgbConverter.Convert(color); /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -401,7 +399,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Rgb sp = ref Unsafe.Add(ref sourceRef, i); ref Cmyk dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToCmyk(sp); + dp = ToCmyk(sp); } } @@ -412,7 +410,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Cmyk ToCmyk(in YCbCr color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return CmykAndRgbConverter.Convert(rgb); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs index 666a6b03cf..19e1bef0d0 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsl.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly HslAndRgbConverter HslAndRgbConverter = new HslAndRgbConverter(); - /// /// Converts a into a . /// @@ -21,7 +19,7 @@ public partial class ColorSpaceConverter /// The public Hsl ToHsl(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -54,7 +52,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -87,7 +85,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(in CieLchuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -120,7 +118,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -153,7 +151,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -186,7 +184,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(in CieXyz color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return HslAndRgbConverter.Convert(rgb); } @@ -217,9 +215,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsl ToHsl(in Cmyk color) + public static Hsl ToHsl(in Cmyk color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return HslAndRgbConverter.Convert(rgb); } @@ -229,7 +227,7 @@ public Hsl ToHsl(in Cmyk color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -241,7 +239,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Cmyk sp = ref Unsafe.Add(ref sourceRef, i); ref Hsl dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsl(sp); + dp = ToHsl(sp); } } @@ -250,9 +248,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsl ToHsl(in Hsv color) + public static Hsl ToHsl(in Hsv color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return HslAndRgbConverter.Convert(rgb); } @@ -262,7 +260,7 @@ public Hsl ToHsl(in Hsv color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -274,7 +272,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsv sp = ref Unsafe.Add(ref sourceRef, i); ref Hsl dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsl(sp); + dp = ToHsl(sp); } } @@ -285,7 +283,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -316,9 +314,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsl ToHsl(in LinearRgb color) + public static Hsl ToHsl(in LinearRgb color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return HslAndRgbConverter.Convert(rgb); } @@ -328,7 +326,7 @@ public Hsl ToHsl(in LinearRgb color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -340,7 +338,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref LinearRgb sp = ref Unsafe.Add(ref sourceRef, i); ref Hsl dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsl(sp); + dp = ToHsl(sp); } } @@ -351,7 +349,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -382,14 +380,14 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsl ToHsl(in Rgb color) => HslAndRgbConverter.Convert(color); + public static Hsl ToHsl(in Rgb color) => HslAndRgbConverter.Convert(color); /// /// Performs the bulk conversion from into . /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -401,7 +399,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Rgb sp = ref Unsafe.Add(ref sourceRef, i); ref Hsl dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsl(sp); + dp = ToHsl(sp); } } @@ -412,7 +410,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsl ToHsl(in YCbCr color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return HslAndRgbConverter.Convert(rgb); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs index 615a26e36c..c6a3a68d78 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Hsv.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly HsvAndRgbConverter HsvAndRgbConverter = new HsvAndRgbConverter(); - /// /// Converts a into a /// @@ -21,7 +19,7 @@ public partial class ColorSpaceConverter /// The public Hsv ToHsv(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -54,7 +52,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -87,7 +85,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(in CieLchuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -120,7 +118,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -153,7 +151,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -186,7 +184,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(in CieXyz color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return HsvAndRgbConverter.Convert(rgb); } @@ -217,9 +215,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsv ToHsv(in Cmyk color) + public static Hsv ToHsv(in Cmyk color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return HsvAndRgbConverter.Convert(rgb); } @@ -229,7 +227,7 @@ public Hsv ToHsv(in Cmyk color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -241,7 +239,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Cmyk sp = ref Unsafe.Add(ref sourceRef, i); ref Hsv dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsv(sp); + dp = ToHsv(sp); } } @@ -250,9 +248,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsv ToHsv(in Hsl color) + public static Hsv ToHsv(in Hsl color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return HsvAndRgbConverter.Convert(rgb); } @@ -262,7 +260,7 @@ public Hsv ToHsv(in Hsl color) /// /// The span to the source colors /// The span to the destination colors. - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -274,7 +272,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsl sp = ref Unsafe.Add(ref sourceRef, i); ref Hsv dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsv(sp); + dp = ToHsv(sp); } } @@ -285,7 +283,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -316,9 +314,9 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsv ToHsv(in LinearRgb color) + public static Hsv ToHsv(in LinearRgb color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return HsvAndRgbConverter.Convert(rgb); } @@ -328,7 +326,7 @@ public Hsv ToHsv(in LinearRgb color) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -340,7 +338,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref LinearRgb sp = ref Unsafe.Add(ref sourceRef, i); ref Hsv dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsv(sp); + dp = ToHsv(sp); } } @@ -351,7 +349,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -382,14 +380,14 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The color to convert. /// The - public Hsv ToHsv(in Rgb color) => HsvAndRgbConverter.Convert(color); + public static Hsv ToHsv(in Rgb color) => HsvAndRgbConverter.Convert(color); /// /// Performs the bulk conversion from into /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -401,7 +399,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Rgb sp = ref Unsafe.Add(ref sourceRef, i); ref Hsv dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToHsv(sp); + dp = ToHsv(sp); } } @@ -412,7 +410,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Hsv ToHsv(in YCbCr color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return HsvAndRgbConverter.Convert(rgb); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs index ad2fbd626d..0e880ed591 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs @@ -336,7 +336,7 @@ public HunterLab ToHunterLab(in CieLuv color) /// The public HunterLab ToHunterLab(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + var xyzColor = ToCieXyz(color); return this.ToHunterLab(xyzColor); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs index c317c8e8bb..c5801b0b40 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.LinearRgb.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly RgbToLinearRgbConverter RgbToLinearRgbConverter = new RgbToLinearRgbConverter(); - /// /// Performs the bulk conversion from into . /// @@ -145,7 +143,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors. /// The span to the destination colors. - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -157,7 +155,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Cmyk sp = ref Unsafe.Add(ref sourceRef, i); ref LinearRgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToLinearRgb(sp); + dp = ToLinearRgb(sp); } } @@ -166,7 +164,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors. /// The span to the destination colors. - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -178,7 +176,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsl sp = ref Unsafe.Add(ref sourceRef, i); ref LinearRgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToLinearRgb(sp); + dp = ToLinearRgb(sp); } } @@ -187,7 +185,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors. /// The span to the destination colors. - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -199,7 +197,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsv sp = ref Unsafe.Add(ref sourceRef, i); ref LinearRgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToLinearRgb(sp); + dp = ToLinearRgb(sp); } } @@ -250,7 +248,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -262,7 +260,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Rgb sp = ref Unsafe.Add(ref sourceRef, i); ref LinearRgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToLinearRgb(sp); + dp = ToLinearRgb(sp); } } @@ -294,7 +292,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public LinearRgb ToLinearRgb(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -305,7 +303,7 @@ public LinearRgb ToLinearRgb(in CieLab color) /// The public LinearRgb ToLinearRgb(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -316,7 +314,7 @@ public LinearRgb ToLinearRgb(in CieLch color) /// The public LinearRgb ToLinearRgb(in CieLchuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -327,7 +325,7 @@ public LinearRgb ToLinearRgb(in CieLchuv color) /// The public LinearRgb ToLinearRgb(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -338,7 +336,7 @@ public LinearRgb ToLinearRgb(in CieLuv color) /// The public LinearRgb ToLinearRgb(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -361,10 +359,10 @@ public LinearRgb ToLinearRgb(in CieXyz color) /// /// The color to convert. /// The - public LinearRgb ToLinearRgb(in Cmyk color) + public static LinearRgb ToLinearRgb(in Cmyk color) { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); + Rgb rgb = ToRgb(color); + return ToLinearRgb(rgb); } /// @@ -372,10 +370,10 @@ public LinearRgb ToLinearRgb(in Cmyk color) /// /// The color to convert. /// The - public LinearRgb ToLinearRgb(in Hsl color) + public static LinearRgb ToLinearRgb(in Hsl color) { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); + Rgb rgb = ToRgb(color); + return ToLinearRgb(rgb); } /// @@ -383,10 +381,10 @@ public LinearRgb ToLinearRgb(in Hsl color) /// /// The color to convert. /// The - public LinearRgb ToLinearRgb(in Hsv color) + public static LinearRgb ToLinearRgb(in Hsv color) { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); + Rgb rgb = ToRgb(color); + return ToLinearRgb(rgb); } /// @@ -396,7 +394,7 @@ public LinearRgb ToLinearRgb(in Hsv color) /// The public LinearRgb ToLinearRgb(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -407,7 +405,7 @@ public LinearRgb ToLinearRgb(in HunterLab color) /// The public LinearRgb ToLinearRgb(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -416,11 +414,8 @@ public LinearRgb ToLinearRgb(in Lms color) /// /// The color to convert. /// The - public LinearRgb ToLinearRgb(in Rgb color) - { - // Conversion - return RgbToLinearRgbConverter.Convert(color); - } + public static LinearRgb ToLinearRgb(in Rgb color) + => RgbToLinearRgbConverter.Convert(color); /// /// Converts a into a . @@ -429,8 +424,8 @@ public LinearRgb ToLinearRgb(in Rgb color) /// The public LinearRgb ToLinearRgb(in YCbCr color) { - var rgb = this.ToRgb(color); - return this.ToLinearRgb(rgb); + Rgb rgb = this.ToRgb(color); + return ToLinearRgb(rgb); } } } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs index be36c46dc3..dbaaa4dd0e 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs @@ -336,7 +336,7 @@ public Lms ToLms(in CieLuv color) /// The public Lms ToLms(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + var xyzColor = ToCieXyz(color); return this.ToLms(xyzColor); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs index cfb6d3b76b..461ce8c21c 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Rgb.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly LinearRgbToRgbConverter LinearRgbToRgbConverter = new LinearRgbToRgbConverter(); - /// /// Performs the bulk conversion from into /// @@ -145,7 +143,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -157,7 +155,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Cmyk sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToRgb(sp); + dp = ToRgb(sp); } } @@ -166,7 +164,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -178,7 +176,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsv sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToRgb(sp); + dp = ToRgb(sp); } } @@ -187,7 +185,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -199,7 +197,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsl sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToRgb(sp); + dp = ToRgb(sp); } } @@ -229,7 +227,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -241,7 +239,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref LinearRgb sp = ref Unsafe.Add(ref sourceRef, i); ref Rgb dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToRgb(sp); + dp = ToRgb(sp); } } @@ -294,7 +292,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public Rgb ToRgb(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToRgb(xyzColor); } @@ -305,7 +303,7 @@ public Rgb ToRgb(in CieLab color) /// The public Rgb ToRgb(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToRgb(xyzColor); } @@ -316,7 +314,7 @@ public Rgb ToRgb(in CieLch color) /// The public Rgb ToRgb(in CieLchuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToRgb(xyzColor); } @@ -327,7 +325,7 @@ public Rgb ToRgb(in CieLchuv color) /// The public Rgb ToRgb(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToRgb(xyzColor); } @@ -338,7 +336,7 @@ public Rgb ToRgb(in CieLuv color) /// The public Rgb ToRgb(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToRgb(xyzColor); } @@ -350,10 +348,10 @@ public Rgb ToRgb(in CieXyy color) public Rgb ToRgb(in CieXyz color) { // Conversion - var linear = this.ToLinearRgb(color); + LinearRgb linear = this.ToLinearRgb(color); // Compand - return this.ToRgb(linear); + return ToRgb(linear); } /// @@ -361,33 +359,21 @@ public Rgb ToRgb(in CieXyz color) /// /// The color to convert. /// The - public Rgb ToRgb(in Cmyk color) - { - // Conversion - return CmykAndRgbConverter.Convert(color); - } + public static Rgb ToRgb(in Cmyk color) => CmykAndRgbConverter.Convert(color); /// /// Converts a into a /// /// The color to convert. /// The - public Rgb ToRgb(in Hsv color) - { - // Conversion - return HsvAndRgbConverter.Convert(color); - } + public static Rgb ToRgb(in Hsv color) => HsvAndRgbConverter.Convert(color); /// /// Converts a into a /// /// The color to convert. /// The - public Rgb ToRgb(in Hsl color) - { - // Conversion - return HslAndRgbConverter.Convert(color); - } + public static Rgb ToRgb(in Hsl color) => HslAndRgbConverter.Convert(color); /// /// Converts a into a @@ -396,7 +382,7 @@ public Rgb ToRgb(in Hsl color) /// The public Rgb ToRgb(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToRgb(xyzColor); } @@ -405,11 +391,7 @@ public Rgb ToRgb(in HunterLab color) /// /// The color to convert. /// The - public Rgb ToRgb(in LinearRgb color) - { - // Conversion - return LinearRgbToRgbConverter.Convert(color); - } + public static Rgb ToRgb(in LinearRgb color) => LinearRgbToRgbConverter.Convert(color); /// /// Converts a into a @@ -418,7 +400,7 @@ public Rgb ToRgb(in LinearRgb color) /// The public Rgb ToRgb(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToRgb(xyzColor); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs index db6dc21338..48bb8ebd61 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.YCbCr.cs @@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public partial class ColorSpaceConverter { - private static readonly YCbCrAndRgbConverter YCbCrAndRgbConverter = new YCbCrAndRgbConverter(); - /// /// Performs the bulk conversion from into . /// @@ -124,7 +122,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -136,7 +134,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Cmyk sp = ref Unsafe.Add(ref sourceRef, i); ref YCbCr dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToYCbCr(sp); + dp = ToYCbCr(sp); } } @@ -145,7 +143,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -157,7 +155,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsl sp = ref Unsafe.Add(ref sourceRef, i); ref YCbCr dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToYCbCr(sp); + dp = ToYCbCr(sp); } } @@ -166,7 +164,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -178,7 +176,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Hsv sp = ref Unsafe.Add(ref sourceRef, i); ref YCbCr dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToYCbCr(sp); + dp = ToYCbCr(sp); } } @@ -208,7 +206,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -220,7 +218,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref LinearRgb sp = ref Unsafe.Add(ref sourceRef, i); ref YCbCr dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToYCbCr(sp); + dp = ToYCbCr(sp); } } @@ -250,7 +248,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// /// The span to the source colors /// The span to the destination colors - public void Convert(ReadOnlySpan source, Span destination) + public static void Convert(ReadOnlySpan source, Span destination) { Guard.DestinationShouldNotBeTooShort(source, destination, nameof(destination)); int count = source.Length; @@ -262,7 +260,7 @@ public void Convert(ReadOnlySpan source, Span destination) { ref Rgb sp = ref Unsafe.Add(ref sourceRef, i); ref YCbCr dp = ref Unsafe.Add(ref destRef, i); - dp = this.ToYCbCr(sp); + dp = ToYCbCr(sp); } } @@ -273,7 +271,7 @@ public void Convert(ReadOnlySpan source, Span destination) /// The public YCbCr ToYCbCr(in CieLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToYCbCr(xyzColor); } @@ -285,7 +283,7 @@ public YCbCr ToYCbCr(in CieLab color) /// The public YCbCr ToYCbCr(in CieLch color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToYCbCr(xyzColor); } @@ -297,7 +295,7 @@ public YCbCr ToYCbCr(in CieLch color) /// The public YCbCr ToYCbCr(in CieLuv color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToYCbCr(xyzColor); } @@ -309,7 +307,7 @@ public YCbCr ToYCbCr(in CieLuv color) /// The public YCbCr ToYCbCr(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToYCbCr(xyzColor); } @@ -321,7 +319,7 @@ public YCbCr ToYCbCr(in CieXyy color) /// The public YCbCr ToYCbCr(in CieXyz color) { - var rgb = this.ToRgb(color); + Rgb rgb = this.ToRgb(color); return YCbCrAndRgbConverter.Convert(rgb); } @@ -331,9 +329,9 @@ public YCbCr ToYCbCr(in CieXyz color) /// /// The color to convert. /// The - public YCbCr ToYCbCr(in Cmyk color) + public static YCbCr ToYCbCr(in Cmyk color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return YCbCrAndRgbConverter.Convert(rgb); } @@ -343,9 +341,9 @@ public YCbCr ToYCbCr(in Cmyk color) /// /// The color to convert. /// The - public YCbCr ToYCbCr(in Hsl color) + public static YCbCr ToYCbCr(in Hsl color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return YCbCrAndRgbConverter.Convert(rgb); } @@ -355,9 +353,9 @@ public YCbCr ToYCbCr(in Hsl color) /// /// The color to convert. /// The - public YCbCr ToYCbCr(in Hsv color) + public static YCbCr ToYCbCr(in Hsv color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return YCbCrAndRgbConverter.Convert(rgb); } @@ -369,7 +367,7 @@ public YCbCr ToYCbCr(in Hsv color) /// The public YCbCr ToYCbCr(in HunterLab color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToYCbCr(xyzColor); } @@ -379,9 +377,9 @@ public YCbCr ToYCbCr(in HunterLab color) /// /// The color to convert. /// The - public YCbCr ToYCbCr(in LinearRgb color) + public static YCbCr ToYCbCr(in LinearRgb color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return YCbCrAndRgbConverter.Convert(rgb); } @@ -393,7 +391,7 @@ public YCbCr ToYCbCr(in LinearRgb color) /// The public YCbCr ToYCbCr(in Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToYCbCr(xyzColor); } @@ -403,6 +401,6 @@ public YCbCr ToYCbCr(in Lms color) /// /// The color to convert. /// The - public YCbCr ToYCbCr(in Rgb color) => YCbCrAndRgbConverter.Convert(color); + public static YCbCr ToYCbCr(in Rgb color) => YCbCrAndRgbConverter.Convert(color); } } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/CieXyChromaticityCoordinates.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/CieXyChromaticityCoordinates.cs index 728d7cd222..bb021f6100 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/CieXyChromaticityCoordinates.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/CieXyChromaticityCoordinates.cs @@ -12,13 +12,25 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// public readonly struct CieXyChromaticityCoordinates : IEquatable { + /// + /// Initializes a new instance of the struct. + /// + /// Chromaticity coordinate x (usually from 0 to 1) + /// Chromaticity coordinate y (usually from 0 to 1) + [MethodImpl(InliningOptions.ShortMethod)] + public CieXyChromaticityCoordinates(float x, float y) + { + this.X = x; + this.Y = y; + } + /// /// Gets the chromaticity X-coordinate. /// /// /// Ranges usually from 0 to 1. /// - public readonly float X; + public readonly float X { get; } /// /// Gets the chromaticity Y-coordinate @@ -26,19 +38,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Ranges usually from 0 to 1. /// - public readonly float Y; - - /// - /// Initializes a new instance of the struct. - /// - /// Chromaticity coordinate x (usually from 0 to 1) - /// Chromaticity coordinate y (usually from 0 to 1) - [MethodImpl(InliningOptions.ShortMethod)] - public CieXyChromaticityCoordinates(float x, float y) - { - this.X = x; - this.Y = y; - } + public readonly float Y { get; } /// /// Compares two objects for equality. @@ -49,7 +49,8 @@ public CieXyChromaticityCoordinates(float x, float y) /// True if the current left is equal to the parameter; otherwise, false. /// [MethodImpl(InliningOptions.ShortMethod)] - public static bool operator ==(CieXyChromaticityCoordinates left, CieXyChromaticityCoordinates right) => left.Equals(right); + public static bool operator ==(CieXyChromaticityCoordinates left, CieXyChromaticityCoordinates right) + => left.Equals(right); /// /// Compares two objects for inequality @@ -60,20 +61,25 @@ public CieXyChromaticityCoordinates(float x, float y) /// True if the current left is unequal to the parameter; otherwise, false. /// [MethodImpl(InliningOptions.ShortMethod)] - public static bool operator !=(CieXyChromaticityCoordinates left, CieXyChromaticityCoordinates right) => !left.Equals(right); + public static bool operator !=(CieXyChromaticityCoordinates left, CieXyChromaticityCoordinates right) + => !left.Equals(right); /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() => HashCode.Combine(this.X, this.Y); + public override int GetHashCode() + => HashCode.Combine(this.X, this.Y); /// - public override string ToString() => FormattableString.Invariant($"CieXyChromaticityCoordinates({this.X:#0.##}, {this.Y:#0.##})"); + public override string ToString() + => FormattableString.Invariant($"CieXyChromaticityCoordinates({this.X:#0.##}, {this.Y:#0.##})"); /// - public override bool Equals(object obj) => obj is CieXyChromaticityCoordinates other && this.Equals(other); + public override bool Equals(object obj) + => obj is CieXyChromaticityCoordinates other && this.Equals(other); /// [MethodImpl(InliningOptions.ShortMethod)] - public bool Equals(CieXyChromaticityCoordinates other) => this.X.Equals(other.X) && this.Y.Equals(other.Y); + public bool Equals(CieXyChromaticityCoordinates other) + => this.X.Equals(other.X) && this.Y.Equals(other.Y); } } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs index 6485da0762..9da7826c40 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Converts from to . /// - internal sealed class CieLchToCieLabConverter + internal static class CieLchToCieLabConverter { /// /// Performs the conversion from the input to an instance of type. @@ -17,7 +17,7 @@ internal sealed class CieLchToCieLabConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieLab Convert(in CieLch input) + public static CieLab Convert(in CieLch input) { // Conversion algorithm described here: // https://en.wikipedia.org/wiki/Lab_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs index 0aefeda856..da7d3f509e 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieLchConverter.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Converts from to . /// - internal sealed class CieLabToCieLchConverter + internal static class CieLabToCieLchConverter { /// /// Performs the conversion from the input to an instance of type. @@ -17,7 +17,7 @@ internal sealed class CieLabToCieLchConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieLch Convert(in CieLab input) + public static CieLch Convert(in CieLab input) { // Conversion algorithm described here: // https://en.wikipedia.org/wiki/Lab_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs index 3634ebe99b..e852e61bea 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Converts from to . /// - internal sealed class CieLabToCieXyzConverter + internal static class CieLabToCieXyzConverter { /// /// Performs the conversion from the input to an instance of type. @@ -17,7 +17,7 @@ internal sealed class CieLabToCieXyzConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieXyz Convert(in CieLab input) + public static CieXyz Convert(in CieLab input) { // Conversion algorithm described here: http://www.brucelindbloom.com/index.html?Eqn_Lab_to_XYZ.html float l = input.L, a = input.A, b = input.B; @@ -32,10 +32,10 @@ public CieXyz Convert(in CieLab input) float yr = l > CieConstants.Kappa * CieConstants.Epsilon ? Numerics.Pow3((l + 16F) / 116F) : l / CieConstants.Kappa; float zr = fz3 > CieConstants.Epsilon ? fz3 : ((116F * fz) - 16F) / CieConstants.Kappa; - var wxyz = new Vector3(input.WhitePoint.X, input.WhitePoint.Y, input.WhitePoint.Z); + Vector3 wxyz = new(input.WhitePoint.X, input.WhitePoint.Y, input.WhitePoint.Z); // Avoids XYZ coordinates out range (restricted by 0 and XYZ reference white) - var xyzr = Vector3.Clamp(new Vector3(xr, yr, zr), Vector3.Zero, Vector3.One); + Vector3 xyzr = Vector3.Clamp(new Vector3(xr, yr, zr), Vector3.Zero, Vector3.One); Vector3 xyz = xyzr * wxyz; return new CieXyz(xyz); diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs index fc064a6ded..c2f2e5d294 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLchuvToCieLuvConverter.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Converts from to . /// - internal sealed class CieLchuvToCieLuvConverter + internal static class CieLchuvToCieLuvConverter { /// /// Performs the conversion from the input to an instance of type. @@ -17,7 +17,7 @@ internal sealed class CieLchuvToCieLuvConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieLuv Convert(in CieLchuv input) + public static CieLuv Convert(in CieLchuv input) { // Conversion algorithm described here: // https://en.wikipedia.org/wiki/CIELUV#Cylindrical_representation_.28CIELCH.29 diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs index d69fb46970..f894d748ba 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieLchuvConverter.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Converts from to . /// - internal sealed class CieLuvToCieLchuvConverter + internal static class CieLuvToCieLchuvConverter { /// /// Performs the conversion from the input to an instance of type. @@ -17,7 +17,7 @@ internal sealed class CieLuvToCieLchuvConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieLchuv Convert(in CieLuv input) + public static CieLchuv Convert(in CieLuv input) { // Conversion algorithm described here: // https://en.wikipedia.org/wiki/CIELUV#Cylindrical_representation_.28CIELCH.29 diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs index 0b4a4a9b85..aa12e511e5 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs @@ -8,14 +8,14 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Converts from to . /// - internal sealed class CieLuvToCieXyzConverter + internal static class CieLuvToCieXyzConverter { /// /// Performs the conversion from the input to an instance of type. /// /// The input color instance. /// The converted result - public CieXyz Convert(in CieLuv input) + public static CieXyz Convert(in CieLuv input) { // Conversion algorithm described here: http://www.brucelindbloom.com/index.html?Eqn_Luv_to_XYZ.html float l = input.L, u = input.U, v = input.V; diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndCieXyyConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndCieXyyConverter.cs index 5db91eb754..619d04d0cc 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndCieXyyConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndCieXyyConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// Color converter between CIE XYZ and CIE xyY. /// for formulas. /// - internal sealed class CieXyzAndCieXyyConverter + internal static class CieXyzAndCieXyyConverter { /// /// Performs the conversion from the input to an instance of type. @@ -18,7 +18,7 @@ internal sealed class CieXyzAndCieXyyConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieXyy Convert(in CieXyz input) + public static CieXyy Convert(in CieXyz input) { float x = input.X / (input.X + input.Y + input.Z); float y = input.Y / (input.X + input.Y + input.Z); @@ -37,7 +37,7 @@ public CieXyy Convert(in CieXyz input) /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieXyz Convert(in CieXyy input) + public static CieXyz Convert(in CieXyy input) { if (MathF.Abs(input.Y) < Constants.Epsilon) { diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndLmsConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndLmsConverter.cs index 533d94465b..ac9f1f6363 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndLmsConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndLmsConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Numerics; @@ -49,7 +49,7 @@ public CieXyzAndLmsConverter(Matrix4x4 transformationMatrix) [MethodImpl(InliningOptions.ShortMethod)] public Lms Convert(in CieXyz input) { - var vector = Vector3.Transform(input.ToVector3(), this.transformationMatrix); + Vector3 vector = Vector3.Transform(input.ToVector3(), this.transformationMatrix); return new Lms(vector); } @@ -62,7 +62,7 @@ public Lms Convert(in CieXyz input) [MethodImpl(InliningOptions.ShortMethod)] public CieXyz Convert(in Lms input) { - var vector = Vector3.Transform(input.ToVector3(), this.inverseTransformationMatrix); + Vector3 vector = Vector3.Transform(input.ToVector3(), this.inverseTransformationMatrix); return new CieXyz(vector); } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CmykAndRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CmykAndRgbConverter.cs index 20a03fb41d..31b11575b6 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CmykAndRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CmykAndRgbConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Color converter between and . /// - internal sealed class CmykAndRgbConverter + internal static class CmykAndRgbConverter { /// /// Performs the conversion from the input to an instance of type. @@ -18,7 +18,7 @@ internal sealed class CmykAndRgbConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public Rgb Convert(in Cmyk input) + public static Rgb Convert(in Cmyk input) { Vector3 rgb = (Vector3.One - new Vector3(input.C, input.M, input.Y)) * (Vector3.One - new Vector3(input.K)); return new Rgb(rgb); @@ -30,13 +30,13 @@ public Rgb Convert(in Cmyk input) /// The input color instance. /// The converted result. [MethodImpl(InliningOptions.ShortMethod)] - public Cmyk Convert(in Rgb input) + public static Cmyk Convert(in Rgb input) { // To CMY Vector3 cmy = Vector3.One - input.ToVector3(); // To CMYK - var k = new Vector3(MathF.Min(cmy.X, MathF.Min(cmy.Y, cmy.Z))); + Vector3 k = new(MathF.Min(cmy.X, MathF.Min(cmy.Y, cmy.Z))); if (MathF.Abs(k.X - 1F) < Constants.Epsilon) { diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HslAndRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HslAndRgbConverter.cs index c5a599e9e5..70cc064a8b 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HslAndRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HslAndRgbConverter.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// Color converter between HSL and Rgb /// See for formulas. /// - internal sealed class HslAndRgbConverter + internal static class HslAndRgbConverter { /// /// Performs the conversion from the input to an instance of type. @@ -18,7 +18,7 @@ internal sealed class HslAndRgbConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public Rgb Convert(in Hsl input) + public static Rgb Convert(in Hsl input) { float rangedH = input.H / 360F; float r = 0; @@ -53,7 +53,7 @@ public Rgb Convert(in Hsl input) /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public Hsl Convert(in Rgb input) + public static Hsl Convert(in Rgb input) { float r = input.R; float g = input.G; diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HsvAndRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HsvAndRgbConverter.cs index de187ee593..9b01c80887 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HsvAndRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HsvAndRgbConverter.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// Color converter between HSV and Rgb /// See for formulas. /// - internal sealed class HsvAndRgbConverter + internal static class HsvAndRgbConverter { /// /// Performs the conversion from the input to an instance of type. @@ -18,7 +18,7 @@ internal sealed class HsvAndRgbConverter /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public Rgb Convert(in Hsv input) + public static Rgb Convert(in Hsv input) { float s = input.S; float v = input.V; @@ -85,7 +85,7 @@ public Rgb Convert(in Hsv input) /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public Hsv Convert(in Rgb input) + public static Hsv Convert(in Rgb input) { float r = input.R; float g = input.G; diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs index a804d1d5f5..424b43b129 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs @@ -17,7 +17,7 @@ internal sealed class HunterLabToCieXyzConverter : CieXyzAndHunterLabConverterBa /// The input color instance. /// The converted result [MethodImpl(InliningOptions.ShortMethod)] - public CieXyz Convert(in HunterLab input) + public static CieXyz Convert(in HunterLab input) { // Conversion algorithm described here: http://en.wikipedia.org/wiki/Lab_color_space#Hunter_Lab float l = input.L, a = input.A, b = input.B; diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbAndCieXyzConverterBase.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbAndCieXyzConverterBase.cs index 8a406cb333..ac0ab73119 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbAndCieXyzConverterBase.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbAndCieXyzConverterBase.cs @@ -28,25 +28,22 @@ public static Matrix4x4 GetRgbToCieXyzMatrix(RgbWorkingSpace workingSpace) float yb = chromaticity.B.Y; float mXr = xr / yr; - const float Yr = 1; float mZr = (1 - xr - yr) / yr; float mXg = xg / yg; - const float Yg = 1; float mZg = (1 - xg - yg) / yg; float mXb = xb / yb; - const float Yb = 1; float mZb = (1 - xb - yb) / yb; - var xyzMatrix = new Matrix4x4 + Matrix4x4 xyzMatrix = new() { M11 = mXr, M21 = mXg, M31 = mXb, - M12 = Yr, - M22 = Yg, - M32 = Yb, + M12 = 1F, + M22 = 1F, + M32 = 1F, M13 = mZr, M23 = mZg, M33 = mZb, @@ -55,7 +52,7 @@ public static Matrix4x4 GetRgbToCieXyzMatrix(RgbWorkingSpace workingSpace) Matrix4x4.Invert(xyzMatrix, out Matrix4x4 inverseXyzMatrix); - var vector = Vector3.Transform(workingSpace.WhitePoint.ToVector3(), inverseXyzMatrix); + Vector3 vector = Vector3.Transform(workingSpace.WhitePoint.ToVector3(), inverseXyzMatrix); // Use transposed Rows/Columns // TODO: Is there a built in method for this multiplication? @@ -64,9 +61,9 @@ public static Matrix4x4 GetRgbToCieXyzMatrix(RgbWorkingSpace workingSpace) M11 = vector.X * mXr, M21 = vector.Y * mXg, M31 = vector.Z * mXb, - M12 = vector.X * Yr, - M22 = vector.Y * Yg, - M32 = vector.Z * Yb, + M12 = vector.X * 1, + M22 = vector.Y * 1, + M32 = vector.Z * 1, M13 = vector.X * mZr, M23 = vector.Y * mZg, M33 = vector.Z * mZb, diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToCieXyzConverter.cs index f124fdd807..5f0755969b 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToCieXyzConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToCieXyzConverter.cs @@ -46,7 +46,7 @@ public CieXyz Convert(in LinearRgb input) { DebugGuard.IsTrue(input.WorkingSpace.Equals(this.SourceWorkingSpace), nameof(input.WorkingSpace), "Input and source working spaces must be equal."); - var vector = Vector3.Transform(input.ToVector3(), this.conversionMatrix); + Vector3 vector = Vector3.Transform(input.ToVector3(), this.conversionMatrix); return new CieXyz(vector); } } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToRgbConverter.cs index ea5ef2bc11..d8cfa7c567 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToRgbConverter.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Color converter between and . /// - internal sealed class LinearRgbToRgbConverter + internal static class LinearRgbToRgbConverter { /// /// Performs the conversion from the input to an instance of type. @@ -16,13 +16,11 @@ internal sealed class LinearRgbToRgbConverter /// The input color instance. /// The converted result. [MethodImpl(InliningOptions.ShortMethod)] - public Rgb Convert(in LinearRgb input) - { - return new Rgb( + public static Rgb Convert(in LinearRgb input) => + new( r: input.WorkingSpace.Compress(input.R), g: input.WorkingSpace.Compress(input.G), b: input.WorkingSpace.Compress(input.B), workingSpace: input.WorkingSpace); - } } } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/RgbToLinearRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/RgbToLinearRgbConverter.cs index 5ce09802c4..08a684baab 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/RgbToLinearRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/RgbToLinearRgbConverter.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// Color converter between Rgb and LinearRgb. /// - internal class RgbToLinearRgbConverter + internal static class RgbToLinearRgbConverter { /// /// Performs the conversion from the input to an instance of type. @@ -16,13 +16,11 @@ internal class RgbToLinearRgbConverter /// The input color instance. /// The converted result. [MethodImpl(InliningOptions.ShortMethod)] - public LinearRgb Convert(in Rgb input) - { - return new LinearRgb( + public static LinearRgb Convert(in Rgb input) + => new( r: input.WorkingSpace.Expand(input.R), g: input.WorkingSpace.Expand(input.G), b: input.WorkingSpace.Expand(input.B), workingSpace: input.WorkingSpace); - } } } diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/YCbCrAndRgbConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/YCbCrAndRgbConverter.cs index 727c89dd7a..ac4d857385 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/YCbCrAndRgbConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/YCbCrAndRgbConverter.cs @@ -11,9 +11,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// Color converter between and /// See for formulas. /// - internal sealed class YCbCrAndRgbConverter + internal static class YCbCrAndRgbConverter { - private static readonly Vector3 MaxBytes = new Vector3(255F); + private static readonly Vector3 MaxBytes = new(255F); /// /// Performs the conversion from the input to an instance of type. @@ -21,7 +21,7 @@ internal sealed class YCbCrAndRgbConverter /// The input color instance. /// The converted result. [MethodImpl(InliningOptions.ShortMethod)] - public Rgb Convert(in YCbCr input) + public static Rgb Convert(in YCbCr input) { float y = input.Y; float cb = input.Cb - 128F; @@ -40,7 +40,7 @@ public Rgb Convert(in YCbCr input) /// The input color instance. /// The converted result. [MethodImpl(InliningOptions.ShortMethod)] - public YCbCr Convert(in Rgb input) + public static YCbCr Convert(in Rgb input) { Vector3 rgb = input.ToVector3() * MaxBytes; float r = rgb.X; diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs index b107aacafa..5723d26914 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs @@ -75,7 +75,7 @@ public void Transform( if (sourceWhitePoint.Equals(destinationWhitePoint)) { - source.CopyTo(destination.Slice(0, count)); + source.CopyTo(destination[..count]); return; } diff --git a/src/ImageSharp/ColorSpaces/Hsl.cs b/src/ImageSharp/ColorSpaces/Hsl.cs index 98f9bdb7c2..01ea512a6d 100644 --- a/src/ImageSharp/ColorSpaces/Hsl.cs +++ b/src/ImageSharp/ColorSpaces/Hsl.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -13,25 +13,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public readonly struct Hsl : IEquatable { private static readonly Vector3 Min = Vector3.Zero; - private static readonly Vector3 Max = new Vector3(360, 1, 1); - - /// - /// Gets the hue component. - /// A value ranging between 0 and 360. - /// - public readonly float H; - - /// - /// Gets the saturation component. - /// A value ranging between 0 and 1. - /// - public readonly float S; - - /// - /// Gets the lightness component. - /// A value ranging between 0 and 1. - /// - public readonly float L; + private static readonly Vector3 Max = new(360, 1, 1); /// /// Initializes a new instance of the struct. @@ -58,6 +40,24 @@ public Hsl(Vector3 vector) this.L = vector.Z; } + /// + /// Gets the hue component. + /// A value ranging between 0 and 360. + /// + public readonly float H { get; } + + /// + /// Gets the saturation component. + /// A value ranging between 0 and 1. + /// + public readonly float S { get; } + + /// + /// Gets the lightness component. + /// A value ranging between 0 and 1. + /// + public readonly float L { get; } + /// /// Compares two objects for equality. /// @@ -95,10 +95,8 @@ public Hsl(Vector3 vector) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(Hsl other) - { - return this.H.Equals(other.H) - && this.S.Equals(other.S) - && this.L.Equals(other.L); - } + => this.H.Equals(other.H) + && this.S.Equals(other.S) + && this.L.Equals(other.L); } } diff --git a/src/ImageSharp/ColorSpaces/Hsv.cs b/src/ImageSharp/ColorSpaces/Hsv.cs index a44aebbb17..284ef4e535 100644 --- a/src/ImageSharp/ColorSpaces/Hsv.cs +++ b/src/ImageSharp/ColorSpaces/Hsv.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -13,25 +13,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public readonly struct Hsv : IEquatable { private static readonly Vector3 Min = Vector3.Zero; - private static readonly Vector3 Max = new Vector3(360, 1, 1); - - /// - /// Gets the hue component. - /// A value ranging between 0 and 360. - /// - public readonly float H; - - /// - /// Gets the saturation component. - /// A value ranging between 0 and 1. - /// - public readonly float S; - - /// - /// Gets the value (brightness) component. - /// A value ranging between 0 and 1. - /// - public readonly float V; + private static readonly Vector3 Max = new(360, 1, 1); /// /// Initializes a new instance of the struct. @@ -58,6 +40,24 @@ public Hsv(Vector3 vector) this.V = vector.Z; } + /// + /// Gets the hue component. + /// A value ranging between 0 and 360. + /// + public readonly float H { get; } + + /// + /// Gets the saturation component. + /// A value ranging between 0 and 1. + /// + public readonly float S { get; } + + /// + /// Gets the value (brightness) component. + /// A value ranging between 0 and 1. + /// + public readonly float V { get; } + /// /// Compares two objects for equality. /// @@ -93,10 +93,8 @@ public Hsv(Vector3 vector) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(Hsv other) - { - return this.H.Equals(other.H) - && this.S.Equals(other.S) - && this.V.Equals(other.V); - } + => this.H.Equals(other.H) + && this.S.Equals(other.S) + && this.V.Equals(other.V); } } diff --git a/src/ImageSharp/ColorSpaces/HunterLab.cs b/src/ImageSharp/ColorSpaces/HunterLab.cs index c3d808c6c3..4b5ea842d4 100644 --- a/src/ImageSharp/ColorSpaces/HunterLab.cs +++ b/src/ImageSharp/ColorSpaces/HunterLab.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -19,29 +19,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public static readonly CieXyz DefaultWhitePoint = Illuminants.C; - /// - /// Gets the lightness dimension. - /// A value usually ranging between 0 (black), 100 (diffuse white) or higher (specular white). - /// - public readonly float L; - - /// - /// Gets the a color component. - /// A value usually ranging from -100 to 100. Negative is green, positive magenta. - /// - public readonly float A; - - /// - /// Gets the b color component. - /// A value usually ranging from -100 to 100. Negative is blue, positive is yellow - /// - public readonly float B; - - /// - /// Gets the reference white point of this color. - /// - public readonly CieXyz WhitePoint; - /// /// Initializes a new instance of the struct. /// @@ -94,6 +71,29 @@ public HunterLab(Vector3 vector, CieXyz whitePoint) this.WhitePoint = whitePoint; } + /// + /// Gets the lightness dimension. + /// A value usually ranging between 0 (black), 100 (diffuse white) or higher (specular white). + /// + public readonly float L { get; } + + /// + /// Gets the a color component. + /// A value usually ranging from -100 to 100. Negative is green, positive magenta. + /// + public readonly float A { get; } + + /// + /// Gets the b color component. + /// A value usually ranging from -100 to 100. Negative is blue, positive is yellow + /// + public readonly float B { get; } + + /// + /// Gets the reference white point of this color. + /// + public readonly CieXyz WhitePoint { get; } + /// /// Compares two objects for equality. /// @@ -128,11 +128,9 @@ public HunterLab(Vector3 vector, CieXyz whitePoint) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(HunterLab other) - { - return this.L.Equals(other.L) - && this.A.Equals(other.A) - && this.B.Equals(other.B) - && this.WhitePoint.Equals(other.WhitePoint); - } + => this.L.Equals(other.L) + && this.A.Equals(other.A) + && this.B.Equals(other.B) + && this.WhitePoint.Equals(other.WhitePoint); } } diff --git a/src/ImageSharp/ColorSpaces/LinearRgb.cs b/src/ImageSharp/ColorSpaces/LinearRgb.cs index 5dffea678a..abf2c6e81a 100644 --- a/src/ImageSharp/ColorSpaces/LinearRgb.cs +++ b/src/ImageSharp/ColorSpaces/LinearRgb.cs @@ -21,29 +21,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public static readonly RgbWorkingSpace DefaultWorkingSpace = RgbWorkingSpaces.SRgb; - /// - /// Gets the red component. - /// A value usually ranging between 0 and 1. - /// - public readonly float R; - - /// - /// Gets the green component. - /// A value usually ranging between 0 and 1. - /// - public readonly float G; - - /// - /// Gets the blue component. - /// A value usually ranging between 0 and 1. - /// - public readonly float B; - - /// - /// Gets the LinearRgb color space - /// - public readonly RgbWorkingSpace WorkingSpace; - /// /// Initializes a new instance of the struct. /// @@ -95,6 +72,29 @@ public LinearRgb(Vector3 vector, RgbWorkingSpace workingSpace) this.WorkingSpace = workingSpace; } + /// + /// Gets the red component. + /// A value usually ranging between 0 and 1. + /// + public readonly float R { get; } + + /// + /// Gets the green component. + /// A value usually ranging between 0 and 1. + /// + public readonly float G { get; } + + /// + /// Gets the blue component. + /// A value usually ranging between 0 and 1. + /// + public readonly float B { get; } + + /// + /// Gets the LinearRgb color space + /// + public readonly RgbWorkingSpace WorkingSpace { get; } + /// /// Compares two objects for equality. /// @@ -122,7 +122,7 @@ public LinearRgb(Vector3 vector, RgbWorkingSpace workingSpace) /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public Vector3 ToVector3() => new Vector3(this.R, this.G, this.B); + public Vector3 ToVector3() => new(this.R, this.G, this.B); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -137,10 +137,8 @@ public LinearRgb(Vector3 vector, RgbWorkingSpace workingSpace) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(LinearRgb other) - { - return this.R.Equals(other.R) - && this.G.Equals(other.G) - && this.B.Equals(other.B); - } + => this.R.Equals(other.R) + && this.G.Equals(other.G) + && this.B.Equals(other.B); } } diff --git a/src/ImageSharp/ColorSpaces/Lms.cs b/src/ImageSharp/ColorSpaces/Lms.cs index 7ca8c3cf0f..ee77118909 100644 --- a/src/ImageSharp/ColorSpaces/Lms.cs +++ b/src/ImageSharp/ColorSpaces/Lms.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -14,24 +14,6 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public readonly struct Lms : IEquatable { - /// - /// Gets the L long component. - /// A value usually ranging between -1 and 1. - /// - public readonly float L; - - /// - /// Gets the M medium component. - /// A value usually ranging between -1 and 1. - /// - public readonly float M; - - /// - /// Gets the S short component. - /// A value usually ranging between -1 and 1. - /// - public readonly float S; - /// /// Initializes a new instance of the struct. /// @@ -57,6 +39,24 @@ public Lms(Vector3 vector) this.S = vector.Z; } + /// + /// Gets the L long component. + /// A value usually ranging between -1 and 1. + /// + public readonly float L { get; } + + /// + /// Gets the M medium component. + /// A value usually ranging between -1 and 1. + /// + public readonly float M { get; } + + /// + /// Gets the S short component. + /// A value usually ranging between -1 and 1. + /// + public readonly float S { get; } + /// /// Compares two objects for equality. /// @@ -84,7 +84,7 @@ public Lms(Vector3 vector) /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public Vector3 ToVector3() => new Vector3(this.L, this.M, this.S); + public Vector3 ToVector3() => new(this.L, this.M, this.S); /// public override int GetHashCode() => HashCode.Combine(this.L, this.M, this.S); @@ -98,10 +98,8 @@ public Lms(Vector3 vector) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(Lms other) - { - return this.L.Equals(other.L) - && this.M.Equals(other.M) - && this.S.Equals(other.S); - } + => this.L.Equals(other.L) + && this.M.Equals(other.M) + && this.S.Equals(other.S); } } diff --git a/src/ImageSharp/ColorSpaces/Rgb.cs b/src/ImageSharp/ColorSpaces/Rgb.cs index 4902d98fd6..76d55d04d1 100644 --- a/src/ImageSharp/ColorSpaces/Rgb.cs +++ b/src/ImageSharp/ColorSpaces/Rgb.cs @@ -22,29 +22,6 @@ namespace SixLabors.ImageSharp.ColorSpaces private static readonly Vector3 Min = Vector3.Zero; private static readonly Vector3 Max = Vector3.One; - /// - /// Gets the red component. - /// A value usually ranging between 0 and 1. - /// - public readonly float R; - - /// - /// Gets the green component. - /// A value usually ranging between 0 and 1. - /// - public readonly float G; - - /// - /// Gets the blue component. - /// A value usually ranging between 0 and 1. - /// - public readonly float B; - - /// - /// Gets the Rgb color space - /// - public readonly RgbWorkingSpace WorkingSpace; - /// /// Initializes a new instance of the struct. /// @@ -95,6 +72,29 @@ public Rgb(Vector3 vector, RgbWorkingSpace workingSpace) this.WorkingSpace = workingSpace; } + /// + /// Gets the red component. + /// A value usually ranging between 0 and 1. + /// + public readonly float R { get; } + + /// + /// Gets the green component. + /// A value usually ranging between 0 and 1. + /// + public readonly float G { get; } + + /// + /// Gets the blue component. + /// A value usually ranging between 0 and 1. + /// + public readonly float B { get; } + + /// + /// Gets the Rgb color space + /// + public readonly RgbWorkingSpace WorkingSpace { get; } + /// /// Allows the implicit conversion of an instance of to a /// . @@ -102,7 +102,7 @@ public Rgb(Vector3 vector, RgbWorkingSpace workingSpace) /// The instance of to convert. /// An instance of . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Rgb(Rgb24 color) => new Rgb(color.R / 255F, color.G / 255F, color.B / 255F); + public static implicit operator Rgb(Rgb24 color) => new(color.R / 255F, color.G / 255F, color.B / 255F); /// /// Allows the implicit conversion of an instance of to a @@ -111,7 +111,7 @@ public Rgb(Vector3 vector, RgbWorkingSpace workingSpace) /// The instance of to convert. /// An instance of . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Rgb(Rgba32 color) => new Rgb(color.R / 255F, color.G / 255F, color.B / 255F); + public static implicit operator Rgb(Rgba32 color) => new(color.R / 255F, color.G / 255F, color.B / 255F); /// /// Compares two objects for equality. @@ -144,7 +144,7 @@ public Rgb(Vector3 vector, RgbWorkingSpace workingSpace) /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public Vector3 ToVector3() => new Vector3(this.R, this.G, this.B); + public Vector3 ToVector3() => new(this.R, this.G, this.B); /// public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B); @@ -158,10 +158,8 @@ public Rgb(Vector3 vector, RgbWorkingSpace workingSpace) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(Rgb other) - { - return this.R.Equals(other.R) - && this.G.Equals(other.G) - && this.B.Equals(other.B); - } + => this.R.Equals(other.R) + && this.G.Equals(other.G) + && this.B.Equals(other.B); } } diff --git a/src/ImageSharp/ColorSpaces/YCbCr.cs b/src/ImageSharp/ColorSpaces/YCbCr.cs index cb4d7d091b..2670a27008 100644 --- a/src/ImageSharp/ColorSpaces/YCbCr.cs +++ b/src/ImageSharp/ColorSpaces/YCbCr.cs @@ -15,25 +15,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public readonly struct YCbCr : IEquatable { private static readonly Vector3 Min = Vector3.Zero; - private static readonly Vector3 Max = new Vector3(255); - - /// - /// Gets the Y luminance component. - /// A value ranging between 0 and 255. - /// - public readonly float Y; - - /// - /// Gets the Cb chroma component. - /// A value ranging between 0 and 255. - /// - public readonly float Cb; - - /// - /// Gets the Cr chroma component. - /// A value ranging between 0 and 255. - /// - public readonly float Cr; + private static readonly Vector3 Max = new(255); /// /// Initializes a new instance of the struct. @@ -60,6 +42,24 @@ public YCbCr(Vector3 vector) this.Cr = vector.Z; } + /// + /// Gets the Y luminance component. + /// A value ranging between 0 and 255. + /// + public readonly float Y { get; } + + /// + /// Gets the Cb chroma component. + /// A value ranging between 0 and 255. + /// + public readonly float Cb { get; } + + /// + /// Gets the Cr chroma component. + /// A value ranging between 0 and 255. + /// + public readonly float Cr { get; } + /// /// Compares two objects for equality. /// @@ -94,10 +94,8 @@ public YCbCr(Vector3 vector) /// [MethodImpl(InliningOptions.ShortMethod)] public bool Equals(YCbCr other) - { - return this.Y.Equals(other.Y) - && this.Cb.Equals(other.Cb) - && this.Cr.Equals(other.Cr); - } + => this.Y.Equals(other.Y) + && this.Cb.Equals(other.Cb) + && this.Cr.Equals(other.Cr); } } diff --git a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs b/src/ImageSharp/Common/Extensions/EncoderExtensions.cs deleted file mode 100644 index b49e1234fa..0000000000 --- a/src/ImageSharp/Common/Extensions/EncoderExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -#if !SUPPORTS_ENCODING_STRING -using System; -using System.Text; - -namespace SixLabors.ImageSharp -{ - /// - /// Extension methods for the type. - /// - internal static unsafe class EncoderExtensions - { - /// - /// Gets a string from the provided buffer data. - /// - /// The encoding. - /// The buffer. - /// The string. - public static string GetString(this Encoding encoding, ReadOnlySpan buffer) - { - if (buffer.Length == 0) - { - return string.Empty; - } - - fixed (byte* bytes = buffer) - { - return encoding.GetString(bytes, buffer.Length); - } - } - } -} -#endif diff --git a/src/ImageSharp/Common/Extensions/StreamExtensions.cs b/src/ImageSharp/Common/Extensions/StreamExtensions.cs index e21d9e96b1..3018b2d0eb 100644 --- a/src/ImageSharp/Common/Extensions/StreamExtensions.cs +++ b/src/ImageSharp/Common/Extensions/StreamExtensions.cs @@ -70,51 +70,5 @@ public static void Skip(this Stream stream, int count) ArrayPool.Shared.Return(buffer); } } - -#if !SUPPORTS_SPAN_STREAM - // This is a port of the CoreFX implementation and is MIT Licensed: - // https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L742 - public static int Read(this Stream stream, Span buffer) - { - // This uses ArrayPool.Shared, rather than taking a MemoryAllocator, - // in order to match the signature of the framework method that exists in - // .NET Core. - byte[] sharedBuffer = ArrayPool.Shared.Rent(buffer.Length); - try - { - int numRead = stream.Read(sharedBuffer, 0, buffer.Length); - if ((uint)numRead > (uint)buffer.Length) - { - throw new IOException("Stream was too long."); - } - - new Span(sharedBuffer, 0, numRead).CopyTo(buffer); - return numRead; - } - finally - { - ArrayPool.Shared.Return(sharedBuffer); - } - } - - // This is a port of the CoreFX implementation and is MIT Licensed: - // https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L775 - public static void Write(this Stream stream, ReadOnlySpan buffer) - { - // This uses ArrayPool.Shared, rather than taking a MemoryAllocator, - // in order to match the signature of the framework method that exists in - // .NET Core. - byte[] sharedBuffer = ArrayPool.Shared.Rent(buffer.Length); - try - { - buffer.CopyTo(sharedBuffer); - stream.Write(sharedBuffer, 0, buffer.Length); - } - finally - { - ArrayPool.Shared.Return(sharedBuffer); - } - } -#endif } } diff --git a/src/ImageSharp/Common/Helpers/HexConverter.cs b/src/ImageSharp/Common/Helpers/HexConverter.cs index 27a5a40f6d..40f80a86f8 100644 --- a/src/ImageSharp/Common/Helpers/HexConverter.cs +++ b/src/ImageSharp/Common/Helpers/HexConverter.cs @@ -30,7 +30,7 @@ public static int HexStringToBytes(ReadOnlySpan chars, Span bytes) { // Slightly better performance in the loop below, allows us to skip a bounds check // while still supporting output buffers that are larger than necessary - bytes = bytes.Slice(0, chars.Length / 2); + bytes = bytes[..(chars.Length / 2)]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ImageSharp/Common/Helpers/InliningOptions.cs b/src/ImageSharp/Common/Helpers/InliningOptions.cs index a6c6d021c6..520c19201b 100644 --- a/src/ImageSharp/Common/Helpers/InliningOptions.cs +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -18,13 +18,11 @@ internal static class InliningOptions public const MethodImplOptions AlwaysInline = MethodImplOptions.AggressiveInlining; #if PROFILING public const MethodImplOptions HotPath = MethodImplOptions.NoInlining; + public const MethodImplOptions ShortMethod = MethodImplOptions.NoInlining; #else -#if SUPPORTS_HOTPATH public const MethodImplOptions HotPath = MethodImplOptions.AggressiveOptimization; -#else - public const MethodImplOptions HotPath = MethodImplOptions.AggressiveInlining; -#endif + public const MethodImplOptions ShortMethod = MethodImplOptions.AggressiveInlining; #endif public const MethodImplOptions ColdPath = MethodImplOptions.NoInlining; diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs index c149cc7b6c..8be59ca9a1 100644 --- a/src/ImageSharp/Common/Helpers/Numerics.cs +++ b/src/ImageSharp/Common/Helpers/Numerics.cs @@ -5,10 +5,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp { @@ -18,20 +16,8 @@ namespace SixLabors.ImageSharp /// internal static class Numerics { -#if SUPPORTS_RUNTIME_INTRINSICS public const int BlendAlphaControl = 0b_10_00_10_00; private const int ShuffleAlphaControl = 0b_11_11_11_11; -#endif - -#if !SUPPORTS_BITOPERATIONS - private static ReadOnlySpan Log2DeBruijn => new byte[32] - { - 00, 09, 01, 10, 13, 21, 02, 29, - 11, 14, 16, 18, 22, 25, 03, 30, - 08, 12, 20, 28, 15, 17, 24, 07, - 19, 27, 23, 06, 26, 05, 04, 31 - }; -#endif /// /// Determine the Greatest CommonDivisor (GCD) of two numbers. @@ -129,13 +115,13 @@ public static int Abs(int x) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Gaussian(float x, float sigma) { - const float Numerator = 1.0f; + const float numerator = 1.0f; float denominator = MathF.Sqrt(2 * MathF.PI) * sigma; float exponentNumerator = -x * x; float exponentDenominator = 2 * Pow2(sigma); - float left = Numerator / denominator; + float left = numerator / denominator; float right = MathF.Exp(exponentNumerator / exponentDenominator); return left * right; @@ -300,7 +286,7 @@ public static Vector4 Clamp(Vector4 value, Vector4 min, Vector4 max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, byte min, byte max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -325,7 +311,7 @@ public static void Clamp(Span span, byte min, byte max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, uint min, uint max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -350,7 +336,7 @@ public static void Clamp(Span span, uint min, uint max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, int min, int max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -375,7 +361,7 @@ public static void Clamp(Span span, int min, int max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, float min, float max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -400,7 +386,7 @@ public static void Clamp(Span span, float min, float max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Clamp(Span span, double min, double max) { - Span remainder = span.Slice(ClampReduce(span, min, max)); + Span remainder = span[ClampReduce(span, min, max)..]; if (remainder.Length > 0) { @@ -427,7 +413,7 @@ private static int ClampReduce(Span span, T min, T max) if (adjustedCount > 0) { - ClampImpl(span.Slice(0, adjustedCount), min, max); + ClampImpl(span[..adjustedCount], min, max); } return adjustedCount; @@ -512,7 +498,6 @@ public static void UnPremultiply(ref Vector4 source) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Premultiply(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { // Divide by 2 as 4 elements per Vector4 and 8 per Vector256 @@ -530,11 +515,10 @@ public static void Premultiply(Span vectors) if (Modulo2(vectors.Length) != 0) { // Vector4 fits neatly in pairs. Any overlap has to be equal to 1. - Premultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1))); + Premultiply(ref MemoryMarshal.GetReference(vectors[^1..])); } } else -#endif { ref Vector4 vectorsStart = ref MemoryMarshal.GetReference(vectors); ref Vector4 vectorsEnd = ref Unsafe.Add(ref vectorsStart, vectors.Length); @@ -555,7 +539,6 @@ public static void Premultiply(Span vectors) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void UnPremultiply(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && vectors.Length >= 2) { // Divide by 2 as 4 elements per Vector4 and 8 per Vector256 @@ -573,11 +556,10 @@ public static void UnPremultiply(Span vectors) if (Modulo2(vectors.Length) != 0) { // Vector4 fits neatly in pairs. Any overlap has to be equal to 1. - UnPremultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1))); + UnPremultiply(ref MemoryMarshal.GetReference(vectors[^1..])); } } else -#endif { ref Vector4 vectorsStart = ref MemoryMarshal.GetReference(vectors); ref Vector4 vectorsEnd = ref Unsafe.Add(ref vectorsStart, vectors.Length); @@ -627,7 +609,6 @@ public static unsafe void CubePowOnXYZ(Span vectors) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void CubeRootOnXYZ(Span vectors) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported) { ref Vector128 vectors128Ref = ref Unsafe.As>(ref MemoryMarshal.GetReference(vectors)); @@ -678,7 +659,6 @@ public static unsafe void CubeRootOnXYZ(Span vectors) } } else -#endif { ref Vector4 vectorsRef = ref MemoryMarshal.GetReference(vectors); ref Vector4 vectorsEnd = ref Unsafe.Add(ref vectorsRef, vectors.Length); @@ -727,8 +707,6 @@ public static unsafe void CubeRootOnXYZ(Span vectors) } } -#if SUPPORTS_RUNTIME_INTRINSICS - /// /// Performs a linear interpolation between two values based on the given weighting. /// @@ -752,7 +730,6 @@ public static Vector256 Lerp( return Avx.Add(Avx.Multiply(diff, amount), value1); } } -#endif /// /// Performs a linear interpolation between two values based on the given weighting. @@ -765,8 +742,6 @@ public static Vector256 Lerp( public static float Lerp(float value1, float value2, float amount) => ((value2 - value1) * amount) + value1; -#if SUPPORTS_RUNTIME_INTRINSICS - /// /// Accumulates 8-bit integers into by /// widening them to 32-bit integers and performing four additions. @@ -860,51 +835,6 @@ public static int EvenReduceSum(Vector256 accumulator) // Vector128.ToScalar() isn't optimized pre-net5.0 https://github.com/dotnet/runtime/pull/37882 return Sse2.ConvertToInt32(vsum); } -#endif - - /// - /// Calculates floored log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. - /// - /// The value. - public static int Log2(uint value) - { -#if SUPPORTS_BITOPERATIONS - return BitOperations.Log2(value); -#else - return Log2SoftwareFallback(value); -#endif - } - -#if !SUPPORTS_BITOPERATIONS - /// - /// Calculates floored log of the specified value, base 2. - /// Note that by convention, input value 0 returns 0 since Log(0) is undefined. - /// Bit hacking with deBruijn sequence, extremely fast yet does not use any intrinsics so will work on every platform/runtime. - /// - /// - /// Description of this bit hacking can be found here: - /// https://cstheory.stackexchange.com/questions/19524/using-the-de-bruijn-sequence-to-find-the-lceil-log-2-v-rceil-of-an-integer - /// - /// The value. - private static int Log2SoftwareFallback(uint value) - { - // No AggressiveInlining due to large method size - // Has conventional contract 0->0 (Log(0) is undefined) by default, no need for if checking - - // Fill trailing zeros with ones, eg 00010010 becomes 00011111 - value |= value >> 01; - value |= value >> 02; - value |= value >> 04; - value |= value >> 08; - value |= value >> 16; - - // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check - return Unsafe.AddByteOffset( - ref MemoryMarshal.GetReference(Log2DeBruijn), - (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)); // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here - } -#endif /// /// Fast division with ceiling for numbers. @@ -914,62 +844,6 @@ ref MemoryMarshal.GetReference(Log2DeBruijn), /// Ceiled division result. public static uint DivideCeil(uint value, uint divisor) => (value + divisor - 1) / divisor; - /// - /// Rotates the specified value left by the specified number of bits. - /// - /// The value to rotate. - /// The number of bits to rotate with. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateLeft(uint value, int offset) - { -#if SUPPORTS_BITOPERATIONS - return BitOperations.RotateLeft(value, offset); -#else - return RotateLeftSoftwareFallback(value, offset); -#endif - } - -#if !SUPPORTS_BITOPERATIONS - /// - /// Rotates the specified value left by the specified number of bits. - /// - /// The value to rotate. - /// The number of bits to rotate with. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateLeftSoftwareFallback(uint value, int offset) - => (value << offset) | (value >> (32 - offset)); -#endif - - /// - /// Rotates the specified value right by the specified number of bits. - /// - /// The value to rotate. - /// The number of bits to rotate with. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateRight(uint value, int offset) - { -#if SUPPORTS_BITOPERATIONS - return BitOperations.RotateRight(value, offset); -#else - return RotateRightSoftwareFallback(value, offset); -#endif - } - -#if !SUPPORTS_BITOPERATIONS - /// - /// Rotates the specified value right by the specified number of bits. - /// - /// The value to rotate. - /// The number of bits to rotate with. - /// The rotated value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static uint RotateRightSoftwareFallback(uint value, int offset) - => (value >> offset) | (value << (32 - offset)); -#endif - /// /// Tells whether input value is outside of the given range. /// diff --git a/src/ImageSharp/Common/Helpers/RuntimeEnvironment.cs b/src/ImageSharp/Common/Helpers/RuntimeEnvironment.cs deleted file mode 100644 index 925925ff95..0000000000 --- a/src/ImageSharp/Common/Helpers/RuntimeEnvironment.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System; -using System.Runtime.InteropServices; - -namespace SixLabors.ImageSharp -{ - /// - /// Provides information about the .NET runtime installation. - /// Many methods defer to when available. - /// - internal static class RuntimeEnvironment - { - private static readonly Lazy IsNetCoreLazy = new Lazy(() => FrameworkDescription.StartsWith(".NET Core", StringComparison.OrdinalIgnoreCase)); - - /// - /// Gets a value indicating whether the .NET installation is .NET Core 3.1 or lower. - /// - public static bool IsNetCore => IsNetCoreLazy.Value; - - /// - /// Gets the name of the .NET installation on which an app is running. - /// - public static string FrameworkDescription => RuntimeInformation.FrameworkDescription; - - /// - /// Indicates whether the current application is running on the specified platform. - /// - public static bool IsOSPlatform(OSPlatform osPlatform) => RuntimeInformation.IsOSPlatform(osPlatform); - } -} diff --git a/src/ImageSharp/Common/Helpers/RuntimeUtility.cs b/src/ImageSharp/Common/Helpers/RuntimeUtility.cs new file mode 100644 index 0000000000..9c8348c0dc --- /dev/null +++ b/src/ImageSharp/Common/Helpers/RuntimeUtility.cs @@ -0,0 +1,46 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.Common.Helpers +{ + /// + /// A helper class that with utility methods for dealing with references, and other low-level details. + /// + internal static class RuntimeUtility + { + // Tuple swap uses 2 more IL bytes +#pragma warning disable IDE0180 // Use tuple to swap values + /// + /// Swaps the two references. + /// + /// The type to swap. + /// The first item. + /// The second item. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Swap(ref T a, ref T b) + { + T tmp = a; + a = b; + b = tmp; + } + + /// + /// Swaps the two references. + /// + /// The type to swap. + /// The first item. + /// The second item. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Swap(ref Span a, ref Span b) + { + // Tuple swap uses 2 more IL bytes + Span tmp = a; + a = b; + b = tmp; + } +#pragma warning restore IDE0180 // Use tuple to swap values + } +} diff --git a/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs b/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs index 0d27ea437f..9cd7db10d4 100644 --- a/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs +++ b/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs @@ -3,6 +3,7 @@ using System; using System.Buffers.Binary; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -157,7 +158,7 @@ public void RunFallbackShuffle(ReadOnlySpan source, Span dest) // packed = [W Z Y X] // ROTR(8, packedArgb) = [Y Z W X] - Unsafe.Add(ref dBase, i) = Numerics.RotateRight(packed, 8); + Unsafe.Add(ref dBase, i) = BitOperations.RotateRight(packed, 8); } } } @@ -188,7 +189,7 @@ public void RunFallbackShuffle(ReadOnlySpan source, Span dest) // tmp1 + tmp3 = [W X Y Z] uint tmp1 = packed & 0xFF00FF00; uint tmp2 = packed & 0x00FF00FF; - uint tmp3 = Numerics.RotateLeft(tmp2, 16); + uint tmp3 = BitOperations.RotateLeft(tmp2, 16); Unsafe.Add(ref dBase, i) = tmp1 + tmp3; } @@ -221,7 +222,7 @@ public void RunFallbackShuffle(ReadOnlySpan source, Span dest) // tmp1 + tmp3 = [Y Z W X] uint tmp1 = packed & 0x00FF00FF; uint tmp2 = packed & 0xFF00FF00; - uint tmp3 = Numerics.RotateLeft(tmp2, 16); + uint tmp3 = BitOperations.RotateLeft(tmp2, 16); Unsafe.Add(ref dBase, i) = tmp1 + tmp3; } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs deleted file mode 100644 index 7e878677f1..0000000000 --- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Tuples; - -// ReSharper disable MemberHidesStaticFromOuterClass -namespace SixLabors.ImageSharp -{ - internal static partial class SimdUtils - { - /// - /// Implementation with 256bit / AVX2 intrinsics NOT depending on newer API-s (Vector.Widen etc.) - /// - public static class BasicIntrinsics256 - { - public static bool IsAvailable { get; } = HasVector8; - -#if !SUPPORTS_EXTENDED_INTRINSICS - /// - /// as many elements as possible, slicing them down (keeping the remainder). - /// - [MethodImpl(InliningOptions.ShortMethod)] - internal static void ByteToNormalizedFloatReduce( - ref ReadOnlySpan source, - ref Span dest) - { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); - - if (!IsAvailable) - { - return; - } - - int remainder = Numerics.Modulo8(source.Length); - int adjustedCount = source.Length - remainder; - - if (adjustedCount > 0) - { - ByteToNormalizedFloat( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); - - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); - } - } - - /// - /// as many elements as possible, slicing them down (keeping the remainder). - /// - [MethodImpl(InliningOptions.ShortMethod)] - internal static void NormalizedFloatToByteSaturateReduce( - ref ReadOnlySpan source, - ref Span dest) - { - DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); - - if (!IsAvailable) - { - return; - } - - int remainder = Numerics.Modulo8(source.Length); - int adjustedCount = source.Length - remainder; - - if (adjustedCount > 0) - { - NormalizedFloatToByteSaturate(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); - - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); - } - } -#endif - - /// - /// SIMD optimized implementation for . - /// Works only with span Length divisible by 8. - /// Implementation adapted from: - /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions - /// http://stackoverflow.com/a/536278 - /// - internal static void ByteToNormalizedFloat(ReadOnlySpan source, Span dest) - { - VerifyHasVector8(nameof(ByteToNormalizedFloat)); - VerifySpanInput(source, dest, 8); - - var bVec = new Vector(256.0f / 255.0f); - var magicFloat = new Vector(32768.0f); - var magicInt = new Vector(1191182336); // reinterpreted value of 32768.0f - var mask = new Vector(255); - - ref Octet sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet destBaseAsWideOctet = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - - ref Vector destBaseAsFloat = ref Unsafe.As, Vector>(ref destBaseAsWideOctet); - - int n = dest.Length / 8; - - for (int i = 0; i < n; i++) - { - ref Octet s = ref Unsafe.Add(ref sourceBase, i); - ref Octet d = ref Unsafe.Add(ref destBaseAsWideOctet, i); - d.LoadFrom(ref s); - } - - for (int i = 0; i < n; i++) - { - ref Vector df = ref Unsafe.Add(ref destBaseAsFloat, i); - - var vi = Vector.AsVectorUInt32(df); - vi &= mask; - vi |= magicInt; - - var vf = Vector.AsVectorSingle(vi); - vf = (vf - magicFloat) * bVec; - - df = vf; - } - } - - /// - /// Implementation of which is faster on older runtimes. - /// - internal static void NormalizedFloatToByteSaturate(ReadOnlySpan source, Span dest) - { - VerifyHasVector8(nameof(NormalizedFloatToByteSaturate)); - VerifySpanInput(source, dest, 8); - - if (source.Length == 0) - { - return; - } - - ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - int n = source.Length / 8; - - var magick = new Vector(32768.0f); - var scale = new Vector(255f) / new Vector(256f); - - // need to copy to a temporary struct, because - // SimdUtils.Octet temp = Unsafe.As, SimdUtils.Octet>(ref x) - // does not work. TODO: This might be a CoreClr bug, need to ask/report - var temp = default(Octet); - ref Vector tempRef = ref Unsafe.As, Vector>(ref temp); - - for (int i = 0; i < n; i++) - { - // union { float f; uint32_t i; } u; - // u.f = 32768.0f + x * (255.0f / 256.0f); - // return (uint8_t)u.i; - Vector x = Unsafe.Add(ref srcBase, i); - x = Vector.Max(x, Vector.Zero); - x = Vector.Min(x, Vector.One); - - x = (x * scale) + magick; - tempRef = x; - - ref Octet d = ref Unsafe.Add(ref destBase, i); - d.LoadFrom(ref temp); - } - } - - /// - /// Convert all values normalized into [0..1] from 'source' - /// into 'dest' buffer of . The values are scaled up into [0-255] and rounded. - /// This implementation is SIMD optimized and works only when span Length is divisible by 8. - /// Based on: - /// - /// http://lolengine.net/blog/2011/3/20/understanding-fast-float-integer-conversions - /// - /// - internal static void BulkConvertNormalizedFloatToByte(ReadOnlySpan source, Span dest) - { - VerifyHasVector8(nameof(BulkConvertNormalizedFloatToByte)); - VerifySpanInput(source, dest, 8); - - if (source.Length == 0) - { - return; - } - - ref Vector srcBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); - ref Octet destBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(dest)); - int n = source.Length / 8; - - var magick = new Vector(32768.0f); - var scale = new Vector(255f) / new Vector(256f); - - // need to copy to a temporary struct, because - // SimdUtils.Octet temp = Unsafe.As, SimdUtils.Octet>(ref x) - // does not work. TODO: This might be a CoreClr bug, need to ask/report - var temp = default(Octet); - ref Vector tempRef = ref Unsafe.As, Vector>(ref temp); - - for (int i = 0; i < n; i++) - { - // union { float f; uint32_t i; } u; - // u.f = 32768.0f + x * (255.0f / 256.0f); - // return (uint8_t)u.i; - Vector x = Unsafe.Add(ref srcBase, i); - x = (x * scale) + magick; - tempRef = x; - - ref Octet d = ref Unsafe.Add(ref destBase, i); - d.LoadFrom(ref temp); - } - } - } - } -} diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index 336ff3abc2..3a143cda29 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -21,12 +21,7 @@ internal static partial class SimdUtils /// public static class ExtendedIntrinsics { - public static bool IsAvailable { get; } = -#if SUPPORTS_EXTENDED_INTRINSICS - Vector.IsHardwareAccelerated; -#else - false; -#endif + public static bool IsAvailable { get; } = Vector.IsHardwareAccelerated; /// /// Widen and convert a vector of values into 2 vectors of -s. @@ -62,10 +57,10 @@ internal static void ByteToNormalizedFloatReduce( if (adjustedCount > 0) { - ByteToNormalizedFloat(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); + ByteToNormalizedFloat(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -89,12 +84,10 @@ internal static void NormalizedFloatToByteSaturateReduce( if (adjustedCount > 0) { - NormalizedFloatToByteSaturate( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + NormalizedFloatToByteSaturate(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -160,12 +153,10 @@ internal static void NormalizedFloatToByteSaturate( Vector w2 = ConvertToUInt32(f2); Vector w3 = ConvertToUInt32(f3); - Vector u0 = Vector.Narrow(w0, w1); - Vector u1 = Vector.Narrow(w2, w3); + var u0 = Vector.Narrow(w0, w1); + var u1 = Vector.Narrow(w2, w3); - Vector b = Vector.Narrow(u0, u1); - - Unsafe.Add(ref destBase, i) = b; + Unsafe.Add(ref destBase, i) = Vector.Narrow(u0, u1); } } @@ -176,15 +167,15 @@ private static Vector ConvertToUInt32(Vector vf) vf *= maxBytes; vf += new Vector(0.5f); vf = Vector.Min(Vector.Max(vf, Vector.Zero), maxBytes); - Vector vi = Vector.ConvertToInt32(vf); + var vi = Vector.ConvertToInt32(vf); return Vector.AsVectorUInt32(vi); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector ConvertToSingle(Vector u) { - Vector vi = Vector.AsVectorInt32(u); - Vector v = Vector.ConvertToSingle(vi); + var vi = Vector.AsVectorInt32(u); + var v = Vector.ConvertToSingle(vi); v *= new Vector(1f / 255f); return v; } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs index c035ac72f7..92c5bf5fb4 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs @@ -33,12 +33,10 @@ internal static void ByteToNormalizedFloatReduce( if (adjustedCount > 0) { - ByteToNormalizedFloat( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + ByteToNormalizedFloat(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -58,11 +56,11 @@ internal static void NormalizedFloatToByteSaturateReduce( if (adjustedCount > 0) { NormalizedFloatToByteSaturate( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + source[..adjustedCount], + dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } @@ -83,7 +81,7 @@ internal static void ByteToNormalizedFloat(ReadOnlySpan source, Span(ref MemoryMarshal.GetReference(source)); ref Vector4 dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest)); - const float Scale = 1f / 255f; + const float scale = 1f / 255f; Vector4 d = default; for (int i = 0; i < count; i++) @@ -93,7 +91,7 @@ internal static void ByteToNormalizedFloat(ReadOnlySpan source, Span 0) { Shuffle4( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount), + source[..adjustedCount], + dest[..adjustedCount], control); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -101,12 +100,12 @@ public static void Shuffle4Reduce( if (adjustedCount > 0) { Shuffle4( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount), + source[..adjustedCount], + dest[..adjustedCount], control); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -133,12 +132,12 @@ public static void Shuffle3Reduce( if (adjustedCount > 0) { Shuffle3( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount), + source[..adjustedCount], + dest[..adjustedCount], control); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -166,12 +165,12 @@ public static void Pad3Shuffle4Reduce( if (sourceCount > 0) { Pad3Shuffle4( - source.Slice(0, sourceCount), - dest.Slice(0, destCount), + source[..sourceCount], + dest[..destCount], control); - source = source.Slice(sourceCount); - dest = dest.Slice(destCount); + source = source[sourceCount..]; + dest = dest[destCount..]; } } } @@ -199,12 +198,12 @@ public static void Shuffle4Slice3Reduce( if (sourceCount > 0) { Shuffle4Slice3( - source.Slice(0, sourceCount), - dest.Slice(0, destCount), + source[..sourceCount], + dest[..destCount], control); - source = source.Slice(sourceCount); - dest = dest.Slice(destCount); + source = source[sourceCount..]; + dest = dest[destCount..]; } } } @@ -607,10 +606,10 @@ internal static void ByteToNormalizedFloatReduce( if (adjustedCount > 0) { - ByteToNormalizedFloat(source.Slice(0, adjustedCount), dest.Slice(0, adjustedCount)); + ByteToNormalizedFloat(source[..adjustedCount], dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -740,11 +739,11 @@ internal static void NormalizedFloatToByteSaturateReduce( if (adjustedCount > 0) { NormalizedFloatToByteSaturate( - source.Slice(0, adjustedCount), - dest.Slice(0, adjustedCount)); + source[..adjustedCount], + dest[..adjustedCount]); - source = source.Slice(adjustedCount); - dest = dest.Slice(adjustedCount); + source = source[adjustedCount..]; + dest = dest[adjustedCount..]; } } } @@ -848,13 +847,12 @@ internal static void PackFromRgbPlanesAvx2Reduce( int count = redChannel.Length / Vector256.Count; - ref byte control1Bytes = ref MemoryMarshal.GetReference(SimdUtils.HwIntrinsics.PermuteMaskEvenOdd8x32); + ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32); Vector256 control1 = Unsafe.As>(ref control1Bytes); ref byte control2Bytes = ref MemoryMarshal.GetReference(PermuteMaskShiftAlpha8x32); Vector256 control2 = Unsafe.As>(ref control2Bytes); - - Vector256 a = Vector256.Create((byte)255); + var a = Vector256.Create((byte)255); Vector256 shuffleAlpha = Unsafe.As>(ref MemoryMarshal.GetReference(ShuffleMaskShiftAlpha)); @@ -902,10 +900,10 @@ internal static void PackFromRgbPlanesAvx2Reduce( } int slice = count * Vector256.Count; - redChannel = redChannel.Slice(slice); - greenChannel = greenChannel.Slice(slice); - blueChannel = blueChannel.Slice(slice); - destination = destination.Slice(slice); + redChannel = redChannel[slice..]; + greenChannel = greenChannel[slice..]; + blueChannel = blueChannel[slice..]; + destination = destination[slice..]; } internal static void PackFromRgbPlanesAvx2Reduce( @@ -920,16 +918,9 @@ internal static void PackFromRgbPlanesAvx2Reduce( ref Vector256 dBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(destination)); int count = redChannel.Length / Vector256.Count; - - ref byte control1Bytes = ref MemoryMarshal.GetReference(SimdUtils.HwIntrinsics.PermuteMaskEvenOdd8x32); + ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32); Vector256 control1 = Unsafe.As>(ref control1Bytes); - - ref byte control2Bytes = ref MemoryMarshal.GetReference(PermuteMaskShiftAlpha8x32); - Vector256 control2 = Unsafe.As>(ref control2Bytes); - - Vector256 a = Vector256.Create((byte)255); - - Vector256 shuffleAlpha = Unsafe.As>(ref MemoryMarshal.GetReference(ShuffleMaskShiftAlpha)); + var a = Vector256.Create((byte)255); for (int i = 0; i < count; i++) { @@ -961,10 +952,10 @@ internal static void PackFromRgbPlanesAvx2Reduce( } int slice = count * Vector256.Count; - redChannel = redChannel.Slice(slice); - greenChannel = greenChannel.Slice(slice); - blueChannel = blueChannel.Slice(slice); - destination = destination.Slice(slice); + redChannel = redChannel[slice..]; + greenChannel = greenChannel[slice..]; + blueChannel = blueChannel[slice..]; + destination = destination[slice..]; } internal static void UnpackToRgbPlanesAvx2Reduce( @@ -1012,4 +1003,3 @@ internal static void UnpackToRgbPlanesAvx2Reduce( } } } -#endif diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs b/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs index fb62cb77e5..1643234b13 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif +using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp { @@ -15,7 +13,6 @@ internal static partial class SimdUtils { [MethodImpl(InliningOptions.ShortMethod)] internal static void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, @@ -25,13 +22,11 @@ internal static void PackFromRgbPlanes( DebugGuard.IsTrue(blueChannel.Length == redChannel.Length, nameof(blueChannel), "Channels must be of same size!"); DebugGuard.IsTrue(destination.Length > redChannel.Length + 2, nameof(destination), "'destination' must contain a padding of 3 elements!"); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { HwIntrinsics.PackFromRgbPlanesAvx2Reduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } else -#endif { PackFromRgbPlanesScalarBatchedReduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } @@ -41,7 +36,6 @@ internal static void PackFromRgbPlanes( [MethodImpl(InliningOptions.ShortMethod)] internal static void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, @@ -51,13 +45,11 @@ internal static void PackFromRgbPlanes( DebugGuard.IsTrue(blueChannel.Length == redChannel.Length, nameof(blueChannel), "Channels must be of same size!"); DebugGuard.IsTrue(destination.Length > redChannel.Length, nameof(destination), "'destination' span should not be shorter than the source channels!"); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { HwIntrinsics.PackFromRgbPlanesAvx2Reduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } else -#endif { PackFromRgbPlanesScalarBatchedReduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } @@ -125,10 +117,10 @@ private static void PackFromRgbPlanesScalarBatchedReduce( } int finished = count * 4; - redChannel = redChannel.Slice(finished); - greenChannel = greenChannel.Slice(finished); - blueChannel = blueChannel.Slice(finished); - destination = destination.Slice(finished); + redChannel = redChannel[finished..]; + greenChannel = greenChannel[finished..]; + blueChannel = blueChannel[finished..]; + destination = destination[finished..]; } private static void PackFromRgbPlanesScalarBatchedReduce( @@ -173,10 +165,10 @@ private static void PackFromRgbPlanesScalarBatchedReduce( } int finished = count * 4; - redChannel = redChannel.Slice(finished); - greenChannel = greenChannel.Slice(finished); - blueChannel = blueChannel.Slice(finished); - destination = destination.Slice(finished); + redChannel = redChannel[finished..]; + greenChannel = greenChannel[finished..]; + blueChannel = blueChannel[finished..]; + destination = destination[finished..]; } private static void PackFromRgbPlanesRemainder( diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs b/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs index db86afd64d..1459601eaf 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs @@ -25,9 +25,7 @@ public static void Shuffle4( { VerifyShuffle4SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Reduce(ref source, ref dest, control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -52,9 +50,7 @@ public static void Shuffle4( { VerifyShuffle4SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -80,9 +76,7 @@ public static void Shuffle3( // Source length should be smaller than dest length, and divisible by 3. VerifyShuffle3SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle3Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -107,9 +101,7 @@ public static void Pad3Shuffle4( { VerifyPad3Shuffle4SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Pad3Shuffle4Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -134,9 +126,7 @@ public static void Shuffle4Slice3( { VerifyShuffle4Slice3SpanInput(source, dest); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Slice3Reduce(ref source, ref dest, shuffle.Control); -#endif // Deal with the remainder: if (source.Length > 0) @@ -266,10 +256,10 @@ public static void InverseMmShuffle( out int p1, out int p0) { - p3 = control >> 6 & 0x3; - p2 = control >> 4 & 0x3; - p1 = control >> 2 & 0x3; - p0 = control >> 0 & 0x3; + p3 = (control >> 6) & 0x3; + p2 = (control >> 4) & 0x3; + p1 = (control >> 2) & 0x3; + p0 = (control >> 0) & 0x3; } } } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 0384cc4edb..1a8d50a5d4 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -6,11 +6,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp { @@ -56,8 +53,6 @@ internal static Vector4 PseudoRound(this Vector4 v) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Vector FastRound(this Vector v) { -#if SUPPORTS_RUNTIME_INTRINSICS - if (Avx2.IsSupported) { ref Vector256 v256 = ref Unsafe.As, Vector256>(ref v); @@ -65,7 +60,6 @@ internal static Vector FastRound(this Vector v) return Unsafe.As, Vector>(ref vRound); } else -#endif { var magic0 = new Vector(int.MinValue); // 0x80000000 var sgn0 = Vector.AsVectorSingle(magic0); @@ -87,13 +81,8 @@ internal static Vector FastRound(this Vector v) internal static void ByteToNormalizedFloat(ReadOnlySpan source, Span dest) { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if SUPPORTS_RUNTIME_INTRINSICS + HwIntrinsics.ByteToNormalizedFloatReduce(ref source, ref dest); -#elif SUPPORTS_EXTENDED_INTRINSICS - ExtendedIntrinsics.ByteToNormalizedFloatReduce(ref source, ref dest); -#else - BasicIntrinsics256.ByteToNormalizedFloatReduce(ref source, ref dest); -#endif // Also deals with the remainder from previous conversions: FallbackIntrinsics128.ByteToNormalizedFloatReduce(ref source, ref dest); @@ -118,13 +107,7 @@ internal static void NormalizedFloatToByteSaturate(ReadOnlySpan source, S { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.NormalizedFloatToByteSaturateReduce(ref source, ref dest); -#elif SUPPORTS_EXTENDED_INTRINSICS - ExtendedIntrinsics.NormalizedFloatToByteSaturateReduce(ref source, ref dest); -#else - BasicIntrinsics256.NormalizedFloatToByteSaturateReduce(ref source, ref dest); -#endif // Also deals with the remainder from previous conversions: FallbackIntrinsics128.NormalizedFloatToByteSaturateReduce(ref source, ref dest); diff --git a/src/ImageSharp/Common/Helpers/UnitConverter.cs b/src/ImageSharp/Common/Helpers/UnitConverter.cs index ba7bdb0e03..09bb40312c 100644 --- a/src/ImageSharp/Common/Helpers/UnitConverter.cs +++ b/src/ImageSharp/Common/Helpers/UnitConverter.cs @@ -114,11 +114,10 @@ public static ExifResolutionValues GetExifResolutionValues(PixelResolutionUnit u case PixelResolutionUnit.PixelsPerCentimeter: break; case PixelResolutionUnit.PixelsPerMeter: - { + unit = PixelResolutionUnit.PixelsPerCentimeter; horizontal = MeterToCm(horizontal); vertical = MeterToCm(vertical); - } break; default: diff --git a/src/ImageSharp/Compression/Zlib/Adler32.cs b/src/ImageSharp/Compression/Zlib/Adler32.cs index 7c3b4ae18b..d8234e1b82 100644 --- a/src/ImageSharp/Compression/Zlib/Adler32.cs +++ b/src/ImageSharp/Compression/Zlib/Adler32.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif #pragma warning disable IDE0007 // Use implicit type namespace SixLabors.ImageSharp.Compression.Zlib @@ -29,7 +27,6 @@ internal static class Adler32 // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 private const uint NMAX = 5552; -#if SUPPORTS_RUNTIME_INTRINSICS private const int MinBufferSize = 64; private const int BlockSize = 1 << 5; @@ -40,7 +37,6 @@ internal static class Adler32 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, // tap1 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 // tap2 }; -#endif /// /// Calculates the Adler32 checksum with the bytes taken from the span. @@ -65,7 +61,6 @@ public static uint Calculate(uint adler, ReadOnlySpan buffer) return adler; } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && buffer.Length >= MinBufferSize) { return CalculateAvx2(adler, buffer); @@ -77,13 +72,9 @@ public static uint Calculate(uint adler, ReadOnlySpan buffer) } return CalculateScalar(adler, buffer); -#else - return CalculateScalar(adler, buffer); -#endif } // Based on https://github.com/chromium/chromium/blob/master/third_party/zlib/adler32_simd.c -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static unsafe uint CalculateSse(uint adler, ReadOnlySpan buffer) { @@ -149,15 +140,15 @@ private static unsafe uint CalculateSse(uint adler, ReadOnlySpan buffer) v_s2 = Sse2.Add(v_s2, Sse2.ShiftLeftLogical(v_ps, 5)); // Sum epi32 ints v_s1(s2) and accumulate in s1(s2). - const byte S2301 = 0b1011_0001; // A B C D -> B A D C - const byte S1032 = 0b0100_1110; // A B C D -> C D A B + const byte s2301 = 0b1011_0001; // A B C D -> B A D C + const byte s1032 = 0b0100_1110; // A B C D -> C D A B - v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, S1032)); + v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, s1032)); s1 += v_s1.ToScalar(); - v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S2301)); - v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S1032)); + v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, s2301)); + v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, s1032)); s2 = v_s2.ToScalar(); @@ -290,7 +281,6 @@ private static unsafe void HandleLeftOver(byte* localBufferPtr, uint length, ref s2 %= BASE; } -#endif [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static unsafe uint CalculateScalar(uint adler, ReadOnlySpan buffer) @@ -301,7 +291,7 @@ private static unsafe uint CalculateScalar(uint adler, ReadOnlySpan buffer fixed (byte* bufferPtr = buffer) { - var localBufferPtr = bufferPtr; + byte* localBufferPtr = bufferPtr; uint length = (uint)buffer.Length; while (length > 0) diff --git a/src/ImageSharp/Compression/Zlib/Crc32.cs b/src/ImageSharp/Compression/Zlib/Crc32.cs index 0d900cc178..757682a3fc 100644 --- a/src/ImageSharp/Compression/Zlib/Crc32.cs +++ b/src/ImageSharp/Compression/Zlib/Crc32.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Compression.Zlib { @@ -22,7 +20,6 @@ internal static partial class Crc32 /// public const uint SeedValue = 0U; -#if SUPPORTS_RUNTIME_INTRINSICS private const int MinBufferSize = 64; private const int ChunksizeMask = 15; @@ -35,7 +32,6 @@ internal static partial class Crc32 0x0163cd6124, 0x0000000000, // k5, k0 0x01db710641, 0x01f7011641 // polynomial }; -#endif /// /// Calculates the CRC checksum with the bytes taken from the span. @@ -60,21 +56,14 @@ public static uint Calculate(uint crc, ReadOnlySpan buffer) return crc; } -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported && Pclmulqdq.IsSupported && buffer.Length >= MinBufferSize) { return ~CalculateSse(~crc, buffer); } - else - { - return ~CalculateScalar(~crc, buffer); - } -#else + return ~CalculateScalar(~crc, buffer); -#endif } -#if SUPPORTS_RUNTIME_INTRINSICS // Based on https://github.com/chromium/chromium/blob/master/third_party/zlib/crc32_simd.c [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static unsafe uint CalculateSse(uint crc, ReadOnlySpan buffer) @@ -194,11 +183,10 @@ private static unsafe uint CalculateSse(uint crc, ReadOnlySpan buffer) x1 = Sse2.Xor(x1, x2); crc = (uint)Sse41.Extract(x1.AsInt32(), 1); - return buffer.Length - chunksize == 0 ? crc : CalculateScalar(crc, buffer.Slice(chunksize)); + return buffer.Length - chunksize == 0 ? crc : CalculateScalar(crc, buffer[chunksize..]); } } } -#endif [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static uint CalculateScalar(uint crc, ReadOnlySpan buffer) diff --git a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs index a77c22bf81..2d19aabb57 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs @@ -276,8 +276,8 @@ public void Reset() this.lookahead = 0; this.prevAvailable = false; this.matchLen = DeflaterConstants.MIN_MATCH - 1; - this.head.Span.Slice(0, DeflaterConstants.HASH_SIZE).Clear(); - this.prev.Span.Slice(0, DeflaterConstants.WSIZE).Clear(); + this.head.Span[..DeflaterConstants.HASH_SIZE].Clear(); + this.prev.Span[..DeflaterConstants.WSIZE].Clear(); } /// @@ -286,7 +286,7 @@ public void Reset() /// The value to set the level to. public void SetLevel(int level) { - if ((level < 0) || (level > 9)) + if (level is < 0 or > 9) { DeflateThrowHelper.ThrowOutOfRange(nameof(level)); } diff --git a/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs b/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs index 9ba9d34b13..5b8673da8e 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs @@ -95,7 +95,7 @@ private void Deflate(bool flushing) break; } - this.rawStream.Write(this.buffer.Span.Slice(0, deflateCount)); + this.rawStream.Write(this.buffer.Span[..deflateCount]); } if (!this.deflater.IsNeedingInput) @@ -115,7 +115,7 @@ private void Finish() break; } - this.rawStream.Write(this.buffer.Span.Slice(0, len)); + this.rawStream.Write(this.buffer.Span[..len]); } if (!this.deflater.IsFinished) diff --git a/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs b/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs index b24150faf4..1ab6349f02 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs @@ -75,7 +75,7 @@ public void WriteBlock(ReadOnlySpan block, int offset, int length) { Unsafe.CopyBlockUnaligned( ref this.buffer.Span[this.end], - ref MemoryMarshal.GetReference(block.Slice(offset)), + ref MemoryMarshal.GetReference(block[offset..]), unchecked((uint)length)); this.end += length; diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index ea1c4eea23..76c2b31b38 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -70,7 +70,7 @@ public int MaxDegreeOfParallelism get => this.maxDegreeOfParallelism; set { - if (value == 0 || value < -1) + if (value is 0 or < -1) { throw new ArgumentOutOfRangeException(nameof(this.MaxDegreeOfParallelism)); } diff --git a/src/ImageSharp/Diagnostics/MemoryDiagnostics.cs b/src/ImageSharp/Diagnostics/MemoryDiagnostics.cs index 274486cec5..2cd286cd6f 100644 --- a/src/ImageSharp/Diagnostics/MemoryDiagnostics.cs +++ b/src/ImageSharp/Diagnostics/MemoryDiagnostics.cs @@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Diagnostics /// /// Represents the method to handle . /// + /// The allocation stack trace. public delegate void UndisposedAllocationDelegate(string allocationStackTrace); /// @@ -85,16 +86,10 @@ internal static void RaiseUndisposedMemoryResource(string allocationStackTrace) } // Schedule on the ThreadPool, to avoid user callback messing up the finalizer thread. -#if NETSTANDARD2_1 || NETCOREAPP2_1_OR_GREATER ThreadPool.QueueUserWorkItem( stackTrace => undisposedAllocation?.Invoke(stackTrace), allocationStackTrace, preferLocal: false); -#else - ThreadPool.QueueUserWorkItem( - stackTrace => undisposedAllocation?.Invoke((string)stackTrace), - allocationStackTrace); -#endif } } } diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index 298982f8dc..0b4b987490 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -491,7 +491,7 @@ private void UncompressRle4(int w, Span buffer, Span undefinedPixels int max = cmd[1]; int bytesToRead = (max + 1) / 2; - var run = new byte[bytesToRead]; + byte[] run = new byte[bytesToRead]; this.stream.Read(run, 0, run.Length); @@ -501,13 +501,11 @@ private void UncompressRle4(int w, Span buffer, Span undefinedPixels byte twoPixels = run[idx]; if (i % 2 == 0) { - byte leftPixel = (byte)((twoPixels >> 4) & 0xF); - buffer[count++] = leftPixel; + buffer[count++] = (byte)((twoPixels >> 4) & 0xF); } else { - byte rightPixel = (byte)(twoPixels & 0xF); - buffer[count++] = rightPixel; + buffer[count++] = (byte)(twoPixels & 0xF); idx++; } } @@ -597,11 +595,11 @@ private void UncompressRle8(int w, Span buffer, Span undefinedPixels // Take this number of bytes from the stream as uncompressed data. int length = cmd[1]; - var run = new byte[length]; + byte[] run = new byte[length]; this.stream.Read(run, 0, run.Length); - run.AsSpan().CopyTo(buffer.Slice(count)); + run.AsSpan().CopyTo(buffer[count..]); count += run.Length; @@ -676,11 +674,11 @@ private void UncompressRle24(int w, Span buffer, Span undefinedPixel // Take this number of bytes from the stream as uncompressed data. int length = cmd[1]; - var run = new byte[length * 3]; + byte[] run = new byte[length * 3]; this.stream.Read(run, 0, run.Length); - run.AsSpan().CopyTo(buffer.Slice(start: uncompressedPixels * 3)); + run.AsSpan().CopyTo(buffer[(uncompressedPixels * 3)..]); uncompressedPixels += length; @@ -903,13 +901,13 @@ private void ReadRgb16(Buffer2D pixels, int width, int height, b int offset = 0; for (int x = 0; x < width; x++) { - short temp = BinaryPrimitives.ReadInt16LittleEndian(bufferSpan.Slice(offset)); + short temp = BinaryPrimitives.ReadInt16LittleEndian(bufferSpan[offset..]); // Rescale values, so the values range from 0 to 255. int r = (redMaskBits == 5) ? GetBytesFrom5BitValue((temp & redMask) >> rightShiftRedMask) : GetBytesFrom6BitValue((temp & redMask) >> rightShiftRedMask); int g = (greenMaskBits == 5) ? GetBytesFrom5BitValue((temp & greenMask) >> rightShiftGreenMask) : GetBytesFrom6BitValue((temp & greenMask) >> rightShiftGreenMask); int b = (blueMaskBits == 5) ? GetBytesFrom5BitValue((temp & blueMask) >> rightShiftBlueMask) : GetBytesFrom6BitValue((temp & blueMask) >> rightShiftBlueMask); - var rgb = new Rgb24((byte)r, (byte)g, (byte)b); + Rgb24 rgb = new((byte)r, (byte)g, (byte)b); color.FromRgb24(rgb); pixelRow[x] = color; @@ -1156,7 +1154,7 @@ private void ReadRgb32BitFields(Buffer2D pixels, int width, int int offset = 0; for (int x = 0; x < width; x++) { - uint temp = BinaryPrimitives.ReadUInt32LittleEndian(bufferSpan.Slice(offset)); + uint temp = BinaryPrimitives.ReadUInt32LittleEndian(bufferSpan[offset..]); if (unusualBitMask) { @@ -1164,7 +1162,7 @@ private void ReadRgb32BitFields(Buffer2D pixels, int width, int uint g = (uint)(temp & greenMask) >> rightShiftGreenMask; uint b = (uint)(temp & blueMask) >> rightShiftBlueMask; float alpha = alphaMask != 0 ? invMaxValueAlpha * ((uint)(temp & alphaMask) >> rightShiftAlphaMask) : 1.0f; - var vector4 = new Vector4( + Vector4 vector4 = new( r * invMaxValueRed, g * invMaxValueGreen, b * invMaxValueBlue, @@ -1246,7 +1244,7 @@ private void ReadInfoHeader() this.stream.Read(buffer, 0, BmpInfoHeader.HeaderSizeSize); int headerSize = BinaryPrimitives.ReadInt32LittleEndian(buffer); - if (headerSize < BmpInfoHeader.CoreSize || headerSize > BmpInfoHeader.MaxHeaderSize) + if (headerSize is < BmpInfoHeader.CoreSize or > BmpInfoHeader.MaxHeaderSize) { BmpThrowHelper.ThrowNotSupportedException($"ImageSharp does not support this BMP file. HeaderSize is '{headerSize}'."); } @@ -1277,19 +1275,19 @@ private void ReadInfoHeader() // color masks for each color channel follow the info header. if (this.infoHeader.Compression == BmpCompression.BitFields) { - var bitfieldsBuffer = new byte[12]; + byte[] bitfieldsBuffer = new byte[12]; this.stream.Read(bitfieldsBuffer, 0, 12); Span data = bitfieldsBuffer.AsSpan(); - this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)); + this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data[..4]); this.infoHeader.GreenMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)); this.infoHeader.BlueMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)); } else if (this.infoHeader.Compression == BmpCompression.BI_ALPHABITFIELDS) { - var bitfieldsBuffer = new byte[16]; + byte[] bitfieldsBuffer = new byte[16]; this.stream.Read(bitfieldsBuffer, 0, 16); Span data = bitfieldsBuffer.AsSpan(); - this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)); + this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data[..4]); this.infoHeader.GreenMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)); this.infoHeader.BlueMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)); this.infoHeader.AlphaMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(12, 4)); @@ -1396,6 +1394,9 @@ private void ReadFileHeader() /// /// Reads the and from the stream and sets the corresponding fields. /// + /// The input stream. + /// Whether the image orientation is inverted. + /// The color palette. /// Bytes per color palette entry. Usually 4 bytes, but in case of Windows 2.x bitmaps or OS/2 1.x bitmaps /// the bytes per color palette entry's can be 3 bytes instead of 4. private int ReadImageHeaders(BufferedReadStream stream, out bool inverted, out byte[] palette) diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index 257159bd23..b216fd7a57 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -160,10 +160,10 @@ public void Encode(Image image, Stream stream, CancellationToken Span buffer = stackalloc byte[infoHeaderSize]; - this.WriteBitmapFileHeader(stream, infoHeaderSize, colorPaletteSize, iccProfileSize, infoHeader, buffer); + WriteBitmapFileHeader(stream, infoHeaderSize, colorPaletteSize, iccProfileSize, infoHeader, buffer); this.WriteBitmapInfoHeader(stream, infoHeader, buffer, infoHeaderSize); this.WriteImage(stream, image.Frames.RootFrame); - this.WriteColorProfile(stream, iccProfileData, buffer); + WriteColorProfile(stream, iccProfileData, buffer); stream.Flush(); } @@ -184,34 +184,33 @@ private BmpInfoHeader CreateBmpInfoHeader(int width, int height, int infoHeaderS int hResolution = 0; int vResolution = 0; - if (metadata.ResolutionUnits != PixelResolutionUnit.AspectRatio) + if (metadata.ResolutionUnits != PixelResolutionUnit.AspectRatio + && metadata.HorizontalResolution > 0 + && metadata.VerticalResolution > 0) { - if (metadata.HorizontalResolution > 0 && metadata.VerticalResolution > 0) + switch (metadata.ResolutionUnits) { - switch (metadata.ResolutionUnits) - { - case PixelResolutionUnit.PixelsPerInch: + case PixelResolutionUnit.PixelsPerInch: - hResolution = (int)Math.Round(UnitConverter.InchToMeter(metadata.HorizontalResolution)); - vResolution = (int)Math.Round(UnitConverter.InchToMeter(metadata.VerticalResolution)); - break; + hResolution = (int)Math.Round(UnitConverter.InchToMeter(metadata.HorizontalResolution)); + vResolution = (int)Math.Round(UnitConverter.InchToMeter(metadata.VerticalResolution)); + break; - case PixelResolutionUnit.PixelsPerCentimeter: + case PixelResolutionUnit.PixelsPerCentimeter: - hResolution = (int)Math.Round(UnitConverter.CmToMeter(metadata.HorizontalResolution)); - vResolution = (int)Math.Round(UnitConverter.CmToMeter(metadata.VerticalResolution)); - break; + hResolution = (int)Math.Round(UnitConverter.CmToMeter(metadata.HorizontalResolution)); + vResolution = (int)Math.Round(UnitConverter.CmToMeter(metadata.VerticalResolution)); + break; - case PixelResolutionUnit.PixelsPerMeter: - hResolution = (int)Math.Round(metadata.HorizontalResolution); - vResolution = (int)Math.Round(metadata.VerticalResolution); + case PixelResolutionUnit.PixelsPerMeter: + hResolution = (int)Math.Round(metadata.HorizontalResolution); + vResolution = (int)Math.Round(metadata.VerticalResolution); - break; - } + break; } } - var infoHeader = new BmpInfoHeader( + BmpInfoHeader infoHeader = new( headerSize: infoHeaderSize, height: height, width: width, @@ -248,7 +247,7 @@ private BmpInfoHeader CreateBmpInfoHeader(int width, int height, int infoHeaderS /// The stream to write to. /// The color profile data. /// The buffer. - private void WriteColorProfile(Stream stream, byte[] iccProfileData, Span buffer) + private static void WriteColorProfile(Stream stream, byte[] iccProfileData, Span buffer) { if (iccProfileData != null) { @@ -257,7 +256,7 @@ private void WriteColorProfile(Stream stream, byte[] iccProfileData, Span stream.Write(iccProfileData); BinaryPrimitives.WriteInt32LittleEndian(buffer, streamPositionAfterImageData); stream.Position = BmpFileHeader.Size + 112; - stream.Write(buffer.Slice(0, 4)); + stream.Write(buffer[..4]); } } @@ -270,9 +269,9 @@ private void WriteColorProfile(Stream stream, byte[] iccProfileData, Span /// The size in bytes of the color profile. /// The information header to write. /// The buffer to write to. - private void WriteBitmapFileHeader(Stream stream, int infoHeaderSize, int colorPaletteSize, int iccProfileSize, BmpInfoHeader infoHeader, Span buffer) + private static void WriteBitmapFileHeader(Stream stream, int infoHeaderSize, int colorPaletteSize, int iccProfileSize, BmpInfoHeader infoHeader, Span buffer) { - var fileHeader = new BmpFileHeader( + BmpFileHeader fileHeader = new( type: BmpConstants.TypeMarkers.Bitmap, fileSize: BmpFileHeader.Size + infoHeaderSize + colorPaletteSize + iccProfileSize + infoHeader.ImageSize, reserved: 0, @@ -555,7 +554,7 @@ private void Write4BitPixelData(Stream stream, ImageFrame image) if (pixelRowSpan.Length % 2 != 0) { - stream.WriteByte((byte)((pixelRowSpan[pixelRowSpan.Length - 1] << 4) | 0)); + stream.WriteByte((byte)((pixelRowSpan[^1] << 4) | 0)); } for (int i = 0; i < rowPadding; i++) @@ -675,7 +674,7 @@ private void WriteColorPalette(Stream stream, ReadOnlySpan quant where TPixel : unmanaged, IPixel { int quantizedColorBytes = quantizedColorPalette.Length * 4; - PixelOperations.Instance.ToBgra32(this.configuration, quantizedColorPalette, MemoryMarshal.Cast(colorPalette.Slice(0, quantizedColorBytes))); + PixelOperations.Instance.ToBgra32(this.configuration, quantizedColorPalette, MemoryMarshal.Cast(colorPalette[..quantizedColorBytes])); Span colorPaletteAsUInt = MemoryMarshal.Cast(colorPalette); for (int i = 0; i < colorPaletteAsUInt.Length; i++) { diff --git a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs index 60aa6732cf..ac3bc9d3cc 100644 --- a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs +++ b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs @@ -308,7 +308,7 @@ public BmpInfoHeader( /// The parsed header. /// public static BmpInfoHeader ParseCore(ReadOnlySpan data) => new( - headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), + headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]), width: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(4, 2)), height: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(6, 2)), planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(8, 2)), @@ -322,7 +322,7 @@ public BmpInfoHeader( /// The parsed header. /// public static BmpInfoHeader ParseOs22Short(ReadOnlySpan data) => new( - headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), + headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]), width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)), @@ -335,7 +335,7 @@ public BmpInfoHeader( /// The parsed header. /// public static BmpInfoHeader ParseV3(ReadOnlySpan data) => new( - headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), + headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]), width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)), @@ -356,7 +356,7 @@ public BmpInfoHeader( /// The parsed header. /// public static BmpInfoHeader ParseAdobeV3(ReadOnlySpan data, bool withAlpha = true) => new( - headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), + headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]), width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)), @@ -382,18 +382,16 @@ public BmpInfoHeader( /// public static BmpInfoHeader ParseOs2Version2(ReadOnlySpan data) { - var infoHeader = new BmpInfoHeader( - headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), + BmpInfoHeader infoHeader = new( + headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]), width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)), bitsPerPixel: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(14, 2))); - int compression = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(16, 4)); - // The compression value in OS/2 bitmap has a different meaning than in windows bitmaps. // Map the OS/2 value to the windows values. - switch (compression) + switch (BinaryPrimitives.ReadInt32LittleEndian(data.Slice(16, 4))) { case 0: infoHeader.Compression = BmpCompression.RGB; @@ -430,7 +428,7 @@ public static BmpInfoHeader ParseOs2Version2(ReadOnlySpan data) /// The parsed header. /// public static BmpInfoHeader ParseV4(ReadOnlySpan data) => new( - headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), + headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]), width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)), @@ -465,11 +463,12 @@ public static BmpInfoHeader ParseOs2Version2(ReadOnlySpan data) /// The data to parse. /// The parsed header. /// + /// Invalid size. public static BmpInfoHeader ParseV5(ReadOnlySpan data) { if (data.Length < SizeV5) { - throw new ArgumentException(nameof(data), $"Must be {SizeV5} bytes. Was {data.Length} bytes."); + throw new ArgumentException($"Must be {SizeV5} bytes. Was {data.Length} bytes.", nameof(data)); } return MemoryMarshal.Cast(data)[0]; @@ -482,7 +481,7 @@ public static BmpInfoHeader ParseV5(ReadOnlySpan data) public void WriteV3Header(Span buffer) { buffer.Clear(); - BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(0, 4), SizeV3); + BinaryPrimitives.WriteInt32LittleEndian(buffer[..4], SizeV3); BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(4, 4), this.Width); BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(8, 4), this.Height); BinaryPrimitives.WriteInt16LittleEndian(buffer.Slice(12, 2), this.Planes); @@ -502,7 +501,7 @@ public void WriteV3Header(Span buffer) public void WriteV4Header(Span buffer) { buffer.Clear(); - BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(0, 4), SizeV4); + BinaryPrimitives.WriteInt32LittleEndian(buffer[..4], SizeV4); BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(4, 4), this.Width); BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(8, 4), this.Height); BinaryPrimitives.WriteInt16LittleEndian(buffer.Slice(12, 2), this.Planes); diff --git a/src/ImageSharp/Formats/DecoderOptions.cs b/src/ImageSharp/Formats/DecoderOptions.cs index 8f16c6ecc7..e21f21f7b2 100644 --- a/src/ImageSharp/Formats/DecoderOptions.cs +++ b/src/ImageSharp/Formats/DecoderOptions.cs @@ -29,7 +29,7 @@ public sealed class DecoderOptions /// /// Gets or sets the target size to decode the image into. /// - public Size? TargetSize { get; set; } = null; + public Size? TargetSize { get; set; } /// /// Gets or sets the sampler to use when resizing during decoding. @@ -39,7 +39,7 @@ public sealed class DecoderOptions /// /// Gets or sets a value indicating whether to ignore encoded metadata when decoding. /// - public bool SkipMetadata { get; set; } = false; + public bool SkipMetadata { get; set; } /// /// Gets or sets the maximum number of image frames to decode, inclusive. diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs index bb45c8364b..f354e42f32 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -108,10 +108,10 @@ public void Encode(Image image, Stream stream, CancellationToken this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length); // Write the header. - this.WriteHeader(stream); + WriteHeader(stream); // Write the LSD. - int index = this.GetTransparentIndex(quantized); + int index = GetTransparentIndex(quantized); this.WriteLogicalScreenDescriptor(metadata, image.Width, image.Height, index, useGlobalTable, stream); if (useGlobalTable) @@ -193,7 +193,7 @@ private void EncodeLocal(Image image, IndexedImageFrame if (previousFrame != null && previousMeta.ColorTableLength != frameMetadata.ColorTableLength && frameMetadata.ColorTableLength > 0) { - var options = new QuantizerOptions + QuantizerOptions options = new() { Dither = this.quantizer.Options.Dither, DitherScale = this.quantizer.Options.DitherScale, @@ -211,7 +211,7 @@ private void EncodeLocal(Image image, IndexedImageFrame } this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length); - this.WriteGraphicalControlExtension(frameMetadata, this.GetTransparentIndex(quantized), stream); + this.WriteGraphicalControlExtension(frameMetadata, GetTransparentIndex(quantized), stream); this.WriteImageDescriptor(frame, true, stream); this.WriteColorTable(quantized, stream); this.WriteImageData(quantized, stream); @@ -231,7 +231,7 @@ private void EncodeLocal(Image image, IndexedImageFrame /// /// The . /// - private int GetTransparentIndex(IndexedImageFrame quantized) + private static int GetTransparentIndex(IndexedImageFrame quantized) where TPixel : unmanaged, IPixel { // Transparent pixels are much more likely to be found at the end of a palette. @@ -259,7 +259,7 @@ private int GetTransparentIndex(IndexedImageFrame quantized) /// /// The stream to write to. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteHeader(Stream stream) => stream.Write(GifConstants.MagicNumber); + private static void WriteHeader(Stream stream) => stream.Write(GifConstants.MagicNumber); /// /// Writes the logical screen descriptor to the stream. @@ -308,7 +308,7 @@ private void WriteLogicalScreenDescriptor( } } - var descriptor = new GifLogicalScreenDescriptor( + GifLogicalScreenDescriptor descriptor = new( width: (ushort)width, height: (ushort)height, packed: packedValue, @@ -332,14 +332,14 @@ private void WriteApplicationExtensions(Stream stream, int frameCount, ushort re // Application Extension: Loop repeat count. if (frameCount > 1 && repeatCount != 1) { - var loopingExtension = new GifNetscapeLoopingApplicationExtension(repeatCount); + GifNetscapeLoopingApplicationExtension loopingExtension = new(repeatCount); this.WriteExtension(loopingExtension, stream); } // Application Extension: XMP Profile. if (xmpProfile != null) { - var xmpExtension = new GifXmpApplicationExtension(xmpProfile.Data); + GifXmpApplicationExtension xmpExtension = new(xmpProfile.Data); this.WriteExtension(xmpExtension, stream); } } @@ -411,7 +411,7 @@ private void WriteGraphicalControlExtension(GifFrameMetadata metadata, int trans disposalMethod: metadata.DisposalMethod, transparencyFlag: transparencyIndex > -1); - var extension = new GifGraphicControlExtension( + GifGraphicControlExtension extension = new( packed: packedValue, delayTime: (ushort)metadata.FrameDelay, transparencyIndex: unchecked((byte)transparencyIndex)); @@ -422,6 +422,7 @@ private void WriteGraphicalControlExtension(GifFrameMetadata metadata, int trans /// /// Writes the provided extension to the stream. /// + /// The type of gif extension. /// The extension to write to the stream. /// The stream to write to. private void WriteExtension(TGifExtension extension, Stream stream) @@ -448,7 +449,7 @@ private void WriteExtension(TGifExtension extension, Stream strea extensionBuffer[0] = GifConstants.ExtensionIntroducer; extensionBuffer[1] = extension.Label; - extension.WriteTo(extensionBuffer.Slice(2)); + extension.WriteTo(extensionBuffer[2..]); extensionBuffer[extensionSize + 2] = GifConstants.Terminator; @@ -472,7 +473,7 @@ private void WriteImageDescriptor(ImageFrame image, bool hasColo sortFlag: false, localColorTableSize: this.bitDepth - 1); - var descriptor = new GifImageDescriptor( + GifImageDescriptor descriptor = new( left: 0, top: 0, width: (ushort)image.Width, @@ -517,7 +518,7 @@ private void WriteColorTable(IndexedImageFrame image, Stream str private void WriteImageData(IndexedImageFrame image, Stream stream) where TPixel : unmanaged, IPixel { - using var encoder = new LzwEncoder(this.memoryAllocator, (byte)this.bitDepth); + using LzwEncoder encoder = new(this.memoryAllocator, (byte)this.bitDepth); encoder.Encode(((IPixelSource)image).PixelBuffer, stream); } } diff --git a/src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs b/src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs index 07e0f6f0ce..9f7755b013 100644 --- a/src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs +++ b/src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs @@ -71,7 +71,7 @@ public void WriteTo(Span buffer) { buffer[0] = GifConstants.ImageDescriptorLabel; - ref GifImageDescriptor dest = ref Unsafe.As(ref MemoryMarshal.GetReference(buffer.Slice(1))); + ref GifImageDescriptor dest = ref Unsafe.As(ref MemoryMarshal.GetReference(buffer[1..])); dest = this; } diff --git a/src/ImageSharp/Formats/Gif/Sections/GifNetscapeLoopingApplicationExtension.cs b/src/ImageSharp/Formats/Gif/Sections/GifNetscapeLoopingApplicationExtension.cs index d9ee93883d..8965ae345d 100644 --- a/src/ImageSharp/Formats/Gif/Sections/GifNetscapeLoopingApplicationExtension.cs +++ b/src/ImageSharp/Formats/Gif/Sections/GifNetscapeLoopingApplicationExtension.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Gif public static GifNetscapeLoopingApplicationExtension Parse(ReadOnlySpan buffer) { - ushort repeatCount = BinaryPrimitives.ReadUInt16LittleEndian(buffer.Slice(0, 2)); + ushort repeatCount = BinaryPrimitives.ReadUInt16LittleEndian(buffer[..2]); return new GifNetscapeLoopingApplicationExtension(repeatCount); } diff --git a/src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs b/src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs index d3a621e7be..9f8d8e4d07 100644 --- a/src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs +++ b/src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs @@ -55,11 +55,11 @@ public int WriteTo(Span buffer) // Write "XMP DataXMP" ReadOnlySpan idBytes = GifConstants.XmpApplicationIdentificationBytes; - idBytes.CopyTo(buffer.Slice(bytesWritten)); + idBytes.CopyTo(buffer[bytesWritten..]); bytesWritten += idBytes.Length; // XMP Data itself - this.Data.CopyTo(buffer.Slice(bytesWritten)); + this.Data.CopyTo(buffer[bytesWritten..]); bytesWritten += this.Data.Length; // Write the Magic Trailer diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index 9f3f0d47fe..78e797dcd7 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -101,7 +101,7 @@ public IImageFormat FindFormatByFileExtension(string extension) if (extension[0] == '.') { - extension = extension.Substring(1); + extension = extension[1..]; } return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs index 8eba118fda..82eb8324a2 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -36,4 +35,3 @@ internal unsafe partial struct Block8x8 public Vector256 V67; } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs index 040f7092f7..8462cf64b8 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs @@ -5,11 +5,10 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using System.Text; +using SixLabors.ImageSharp.Common.Helpers; namespace SixLabors.ImageSharp.Formats.Jpeg.Components { @@ -188,7 +187,6 @@ public override string ToString() [MethodImpl(InliningOptions.ShortMethod)] public nint GetLastNonZeroIndex() { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { const int equalityMask = unchecked((int)0b1111_1111_1111_1111_1111_1111_1111_1111); @@ -222,7 +220,6 @@ public nint GetLastNonZeroIndex() return -1; } else -#endif { nint index = Size - 1; ref short elemRef = ref Unsafe.As(ref this); @@ -245,53 +242,46 @@ public void TransposeInplace() ref short elemRef = ref Unsafe.As(ref this); // row #0 - Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8)); - Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16)); - Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24)); - Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32)); - Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40)); - Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48)); - Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56)); // row #1 - Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17)); - Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25)); - Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33)); - Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41)); - Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49)); - Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57)); // row #2 - Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26)); - Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34)); - Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42)); - Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50)); - Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58)); // row #3 - Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35)); - Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43)); - Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51)); - Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59)); // row #4 - Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44)); - Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52)); - Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60)); // row #5 - Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53)); - Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61)); // row #6 - Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62)); - - static void Swap(ref short a, ref short b) - { - short tmp = a; - a = b; - b = tmp; - } + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62)); } /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs index 2a03f911b9..4c19510b7e 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Numerics; using System.Runtime.CompilerServices; @@ -43,7 +42,7 @@ private static unsafe void MultiplyIntoInt16_Avx2(ref Block8x8F a, ref Block8x8F ref Vector256 bBase = ref b.V0; ref Vector256 destRef = ref dest.V01; - Vector256 multiplyIntoInt16ShuffleMask = Vector256.Create(0, 1, 4, 5, 2, 3, 6, 7); + var multiplyIntoInt16ShuffleMask = Vector256.Create(0, 1, 4, 5, 2, 3, 6, 7); for (nint i = 0; i < 8; i += 2) { @@ -145,4 +144,3 @@ private void TransposeInplace_Avx() } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index d2f3e9664b..16d95f99f6 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -5,11 +5,10 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using System.Text; +using SixLabors.ImageSharp.Common.Helpers; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Jpeg.Components @@ -160,10 +159,9 @@ public float[] ToArray() [MethodImpl(InliningOptions.ShortMethod)] public void MultiplyInPlace(float value) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { - var valueVec = Vector256.Create(value); + Vector256 valueVec = Vector256.Create(value); this.V0 = Avx.Multiply(this.V0, valueVec); this.V1 = Avx.Multiply(this.V1, valueVec); this.V2 = Avx.Multiply(this.V2, valueVec); @@ -174,9 +172,8 @@ public void MultiplyInPlace(float value) this.V7 = Avx.Multiply(this.V7, valueVec); } else -#endif { - var valueVec = new Vector4(value); + Vector4 valueVec = new(value); this.V0L *= valueVec; this.V0R *= valueVec; this.V1L *= valueVec; @@ -199,10 +196,10 @@ public void MultiplyInPlace(float value) /// /// Multiply all elements of the block by the corresponding elements of 'other'. /// + /// The other block. [MethodImpl(InliningOptions.ShortMethod)] public unsafe void MultiplyInPlace(ref Block8x8F other) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { this.V0 = Avx.Multiply(this.V0, other.V0); @@ -215,7 +212,6 @@ public unsafe void MultiplyInPlace(ref Block8x8F other) this.V7 = Avx.Multiply(this.V7, other.V7); } else -#endif { this.V0L *= other.V0L; this.V0R *= other.V0R; @@ -243,10 +239,9 @@ public unsafe void MultiplyInPlace(ref Block8x8F other) [MethodImpl(InliningOptions.ShortMethod)] public void AddInPlace(float value) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { - var valueVec = Vector256.Create(value); + Vector256 valueVec = Vector256.Create(value); this.V0 = Avx.Add(this.V0, valueVec); this.V1 = Avx.Add(this.V1, valueVec); this.V2 = Avx.Add(this.V2, valueVec); @@ -257,9 +252,8 @@ public void AddInPlace(float value) this.V7 = Avx.Add(this.V7, valueVec); } else -#endif { - var valueVec = new Vector4(value); + Vector4 valueVec = new(value); this.V0L += valueVec; this.V0R += valueVec; this.V1L += valueVec; @@ -287,7 +281,6 @@ public void AddInPlace(float value) /// The quantization table. public static void Quantize(ref Block8x8F block, ref Block8x8 dest, ref Block8x8F qt) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { MultiplyIntoInt16_Avx2(ref block, ref qt, ref dest); @@ -299,7 +292,6 @@ public static void Quantize(ref Block8x8F block, ref Block8x8 dest, ref Block8x8 ZigZag.ApplyTransposingZigZagOrderingSsse3(ref dest); } else -#endif { for (int i = 0; i < Size; i++) { @@ -339,6 +331,7 @@ public Block8x8 RoundAsInt16Block() /// /// Level shift by +maximum/2, clip to [0..maximum], and round all the values in the block. /// + /// The maximum value. public void NormalizeColorsAndRoundInPlace(float maximum) { if (SimdUtils.HasVector8) @@ -379,13 +372,12 @@ public void RoundInPlace() [MethodImpl(InliningOptions.ShortMethod)] public void LoadFrom(ref Block8x8 source) { -#if SUPPORTS_EXTENDED_INTRINSICS if (SimdUtils.HasVector8) { this.LoadFromInt16ExtendedAvx2(ref source); return; } -#endif + this.LoadFromInt16Scalar(ref source); } @@ -427,12 +419,11 @@ public void LoadFromInt16ExtendedAvx2(ref Block8x8 source) /// Value to compare to. public bool EqualsToScalar(int value) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { const int equalityMask = unchecked((int)0b1111_1111_1111_1111_1111_1111_1111_1111); - var targetVector = Vector256.Create(value); + Vector256 targetVector = Vector256.Create(value); ref Vector256 blockStride = ref this.V0; for (int i = 0; i < RowCount; i++) @@ -446,20 +437,18 @@ public bool EqualsToScalar(int value) return true; } -#endif - { - ref float scalars = ref Unsafe.As(ref this); - for (int i = 0; i < Size; i++) + ref float scalars = ref Unsafe.As(ref this); + + for (int i = 0; i < Size; i++) + { + if ((int)Unsafe.Add(ref scalars, i) != value) { - if ((int)Unsafe.Add(ref scalars, i) != value) - { - return false; - } + return false; } - - return true; } + + return true; } /// @@ -481,20 +470,46 @@ public bool Equals(Block8x8F other) && this.V7L == other.V7L && this.V7R == other.V7R; + /// + public override bool Equals(object obj) => this.Equals((Block8x8F)obj); + + /// + public override int GetHashCode() + { + int left = HashCode.Combine( + this.V0L, + this.V1L, + this.V2L, + this.V3L, + this.V4L, + this.V5L, + this.V6L, + this.V7L); + + int right = HashCode.Combine( + this.V0R, + this.V1R, + this.V2R, + this.V3R, + this.V4R, + this.V5R, + this.V6R, + this.V7R); + + return HashCode.Combine(left, right); + } + /// public override string ToString() { - var sb = new StringBuilder(); + StringBuilder sb = new(); sb.Append('['); for (int i = 0; i < Size - 1; i++) { - sb.Append(this[i]); - sb.Append(','); + sb.Append(this[i]).Append(','); } - sb.Append(this[Size - 1]); - - sb.Append(']'); + sb.Append(this[Size - 1]).Append(']'); return sb.ToString(); } @@ -504,13 +519,11 @@ public override string ToString() [MethodImpl(InliningOptions.ShortMethod)] public void TransposeInplace() { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { this.TransposeInplace_Avx(); } else -#endif { this.TransposeInplace_Scalar(); } @@ -525,53 +538,46 @@ private void TransposeInplace_Scalar() ref float elemRef = ref Unsafe.As(ref this); // row #0 - Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8)); - Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16)); - Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24)); - Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32)); - Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40)); - Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48)); - Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 1), ref Unsafe.Add(ref elemRef, 8)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 2), ref Unsafe.Add(ref elemRef, 16)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 3), ref Unsafe.Add(ref elemRef, 24)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 4), ref Unsafe.Add(ref elemRef, 32)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 5), ref Unsafe.Add(ref elemRef, 40)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 6), ref Unsafe.Add(ref elemRef, 48)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 7), ref Unsafe.Add(ref elemRef, 56)); // row #1 - Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17)); - Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25)); - Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33)); - Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41)); - Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49)); - Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 10), ref Unsafe.Add(ref elemRef, 17)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 11), ref Unsafe.Add(ref elemRef, 25)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 12), ref Unsafe.Add(ref elemRef, 33)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 13), ref Unsafe.Add(ref elemRef, 41)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 14), ref Unsafe.Add(ref elemRef, 49)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 15), ref Unsafe.Add(ref elemRef, 57)); // row #2 - Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26)); - Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34)); - Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42)); - Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50)); - Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 19), ref Unsafe.Add(ref elemRef, 26)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 20), ref Unsafe.Add(ref elemRef, 34)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 21), ref Unsafe.Add(ref elemRef, 42)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 22), ref Unsafe.Add(ref elemRef, 50)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 23), ref Unsafe.Add(ref elemRef, 58)); // row #3 - Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35)); - Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43)); - Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51)); - Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 28), ref Unsafe.Add(ref elemRef, 35)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 29), ref Unsafe.Add(ref elemRef, 43)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 30), ref Unsafe.Add(ref elemRef, 51)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 31), ref Unsafe.Add(ref elemRef, 59)); // row #4 - Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44)); - Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52)); - Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 37), ref Unsafe.Add(ref elemRef, 44)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 38), ref Unsafe.Add(ref elemRef, 52)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 39), ref Unsafe.Add(ref elemRef, 60)); // row #5 - Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53)); - Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 46), ref Unsafe.Add(ref elemRef, 53)); + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 47), ref Unsafe.Add(ref elemRef, 61)); // row #6 - Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62)); - - static void Swap(ref float a, ref float b) - { - float tmp = a; - a = b; - b = tmp; - } + RuntimeUtility.Swap(ref Unsafe.Add(ref elemRef, 55), ref Unsafe.Add(ref elemRef, 62)); } [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs index 8edaa2efe3..63e112dd77 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -96,4 +95,3 @@ public static void ConvertFromRgb(in ComponentValues values, float maxValue, Spa } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs index 26e8791853..0fc1fcd551 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -69,4 +68,3 @@ public override void ConvertFromRgb(in ComponentValues values, Span rLane } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs index 5fd97e3684..08247e7dac 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -53,4 +52,3 @@ public override void ConvertFromRgb(in ComponentValues values, Span rLane } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs index 219584b05e..62e0fc1b62 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -122,4 +121,3 @@ public override void ConvertFromRgb(in ComponentValues values, Span rLane } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs index f4549911ef..dea9fa0a73 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -133,4 +132,3 @@ public override void ConvertFromRgb(in ComponentValues values, Span rLane } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs index 4af31abac9..c9b0054c3b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -34,4 +33,3 @@ protected JpegColorConverterAvx(JpegColorSpace colorSpace, int precision) } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs index c2e01df998..c159ed7d21 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs @@ -20,6 +20,8 @@ internal abstract partial class JpegColorConverterBase /// /// Initializes a new instance of the class. /// + /// The color space. + /// The precision in bits. protected JpegColorConverterBase(JpegColorSpace colorSpace, int precision) { this.ColorSpace = colorSpace; @@ -66,6 +68,9 @@ protected JpegColorConverterBase(JpegColorSpace colorSpace, int precision) /// /// Returns the corresponding to the given /// + /// The color space. + /// The precision in bits. + /// Invalid colorspace. public static JpegColorConverterBase GetConverter(JpegColorSpace colorSpace, int precision) { JpegColorConverterBase converter = Array.Find( @@ -75,7 +80,7 @@ public static JpegColorConverterBase GetConverter(JpegColorSpace colorSpace, int if (converter is null) { - throw new Exception($"Could not find any converter for JpegColorSpace {colorSpace}!"); + throw new InvalidImageContentException($"Could not find any converter for JpegColorSpace {colorSpace}!"); } return converter; @@ -104,7 +109,7 @@ private static JpegColorConverterBase[] CreateConverters() // 5 color types with 2 supported precisions: 8 bit & 12 bit const int colorConvertersCount = 5 * 2; - var converters = new JpegColorConverterBase[colorConvertersCount]; + JpegColorConverterBase[] converters = new JpegColorConverterBase[colorConvertersCount]; // 8-bit converters converters[0] = GetYCbCrConverter(8); @@ -126,6 +131,7 @@ private static JpegColorConverterBase[] CreateConverters() /// /// Returns the s for the YCbCr colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetYCbCrConverter(int precision) { if (JpegColorConverterAvx.IsSupported) @@ -144,6 +150,7 @@ private static JpegColorConverterBase GetYCbCrConverter(int precision) /// /// Returns the s for the YccK colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetYccKConverter(int precision) { if (JpegColorConverterAvx.IsSupported) @@ -162,6 +169,7 @@ private static JpegColorConverterBase GetYccKConverter(int precision) /// /// Returns the s for the CMYK colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetCmykConverter(int precision) { if (JpegColorConverterAvx.IsSupported) @@ -180,6 +188,7 @@ private static JpegColorConverterBase GetCmykConverter(int precision) /// /// Returns the s for the gray scale colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetGrayScaleConverter(int precision) { if (JpegColorConverterAvx.IsSupported) @@ -198,6 +207,7 @@ private static JpegColorConverterBase GetGrayScaleConverter(int precision) /// /// Returns the s for the RGB colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetRgbConverter(int precision) { if (JpegColorConverterAvx.IsSupported) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ArithmeticScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ArithmeticScanDecoder.cs index ae97c7e54a..21727bc99c 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ArithmeticScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ArithmeticScanDecoder.cs @@ -225,10 +225,10 @@ public void InitDecodingTables(List arithmeticDecodingT { for (int i = 0; i < this.components.Length; i++) { - var component = this.components[i] as ArithmeticDecodingComponent; - this.dcDecodingTables[i] = this.GetArithmeticTable(arithmeticDecodingTables, true, component.DcTableId); + ArithmeticDecodingComponent component = this.components[i] as ArithmeticDecodingComponent; + this.dcDecodingTables[i] = GetArithmeticTable(arithmeticDecodingTables, true, component.DcTableId); component.DcStatistics = this.CreateOrGetStatisticsBin(true, component.DcTableId); - this.acDecodingTables[i] = this.GetArithmeticTable(arithmeticDecodingTables, false, component.AcTableId); + this.acDecodingTables[i] = GetArithmeticTable(arithmeticDecodingTables, false, component.AcTableId); component.AcStatistics = this.CreateOrGetStatisticsBin(false, component.AcTableId); } } @@ -276,7 +276,7 @@ public void InjectFrameData(JpegFrame frame, IRawJpegData jpegData) this.spectralConverter.InjectFrameData(frame, jpegData); } - private ArithmeticDecodingTable GetArithmeticTable(List arithmeticDecodingTables, bool isDcTable, int identifier) + private static ArithmeticDecodingTable GetArithmeticTable(List arithmeticDecodingTables, bool isDcTable, int identifier) { int tableClass = isDcTable ? 0 : 1; @@ -306,15 +306,16 @@ private ArithmeticStatistics CreateOrGetStatisticsBin(bool dc, int identifier, b } } - var statistic = new ArithmeticStatistics(dc, identifier); + ArithmeticStatistics statistic = new(dc, identifier); this.statistics.Add(statistic); return statistic; } private void ParseBaselineData() { - foreach (ArithmeticDecodingComponent component in this.components) + for (int i = 0; i < this.components.Length; i++) { + ArithmeticDecodingComponent component = (ArithmeticDecodingComponent)this.components[i]; component.DcPredictor = 0; component.DcContext = 0; component.DcStatistics?.Reset(); @@ -441,7 +442,7 @@ private void ParseBaselineDataInterleaved() for (int k = 0; k < this.scanComponentCount; k++) { int order = this.frame.ComponentOrder[k]; - var component = this.components[order] as ArithmeticDecodingComponent; + ArithmeticDecodingComponent component = this.components[order] as ArithmeticDecodingComponent; ref ArithmeticDecodingTable dcDecodingTable = ref this.dcDecodingTables[component.DcTableId]; ref ArithmeticDecodingTable acDecodingTable = ref this.acDecodingTables[component.AcTableId]; @@ -491,7 +492,7 @@ ref Unsafe.Add(ref blockRef, (nint)(uint)blockCol), private void ParseBaselineDataSingleComponent() { - var component = this.frame.Components[0] as ArithmeticDecodingComponent; + ArithmeticDecodingComponent component = this.frame.Components[0] as ArithmeticDecodingComponent; int mcuLines = this.frame.McusPerColumn; int w = component.WidthInBlocks; int h = component.SamplingFactors.Height; @@ -537,7 +538,7 @@ ref Unsafe.Add(ref blockRef, (nint)(uint)k), private void ParseBaselineDataNonInterleaved() { - var component = (ArithmeticDecodingComponent)this.components[this.frame.ComponentOrder[0]]; + ArithmeticDecodingComponent component = (ArithmeticDecodingComponent)this.components[this.frame.ComponentOrder[0]]; ref JpegBitReader reader = ref this.scanBuffer; int w = component.WidthInBlocks; @@ -586,7 +587,7 @@ private void ParseProgressiveDataInterleaved() for (int k = 0; k < this.scanComponentCount; k++) { int order = this.frame.ComponentOrder[k]; - var component = this.components[order] as ArithmeticDecodingComponent; + ArithmeticDecodingComponent component = this.components[order] as ArithmeticDecodingComponent; ref ArithmeticDecodingTable dcDecodingTable = ref this.dcDecodingTables[component.DcTableId]; int h = component.HorizontalSamplingFactor; @@ -628,7 +629,7 @@ ref Unsafe.Add(ref blockRef, (nint)(uint)blockCol), private void ParseProgressiveDataNonInterleaved() { - var component = this.components[this.frame.ComponentOrder[0]] as ArithmeticDecodingComponent; + ArithmeticDecodingComponent component = this.components[this.frame.ComponentOrder[0]] as ArithmeticDecodingComponent; ref JpegBitReader reader = ref this.scanBuffer; int w = component.WidthInBlocks; @@ -1140,7 +1141,7 @@ private void Reset() { for (int i = 0; i < this.components.Length; i++) { - var component = this.components[i] as ArithmeticDecodingComponent; + ArithmeticDecodingComponent component = this.components[i] as ArithmeticDecodingComponent; component.DcPredictor = 0; } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFileMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFileMarker.cs index f3ceb3584a..185e5b06b0 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFileMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFileMarker.cs @@ -1,6 +1,7 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Globalization; using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder @@ -62,8 +63,6 @@ public long Position /// public override string ToString() - { - return this.Marker.ToString("X"); - } + => this.Marker.ToString("X", CultureInfo.InvariantCulture); } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs index 9f1d4d91ff..ed678bd2b2 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs @@ -89,7 +89,7 @@ internal static class ProfileResolver public static bool IsProfile(ReadOnlySpan bytesToCheck, ReadOnlySpan profileIdentifier) { return bytesToCheck.Length >= profileIdentifier.Length - && bytesToCheck.Slice(0, profileIdentifier.Length).SequenceEqual(profileIdentifier); + && bytesToCheck[..profileIdentifier.Length].SequenceEqual(profileIdentifier); } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs index c96f4acc21..938815daea 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs @@ -155,13 +155,13 @@ private void ConvertStride(int spectralStep) // pack pixels to a temporary, padded proxy buffer, then copy the relevant values to the destination row. if (this.pixelBuffer.DangerousTryGetPaddedRowSpan(yy, 3, out Span destRow)) { - PixelOperations.Instance.PackFromRgbPlanes(this.configuration, r, g, b, destRow); + PixelOperations.Instance.PackFromRgbPlanes(r, g, b, destRow); } else { Span proxyRow = this.paddedProxyPixelRow.GetSpan(); - PixelOperations.Instance.PackFromRgbPlanes(this.configuration, r, g, b, proxyRow); - proxyRow.Slice(0, width).CopyTo(this.pixelBuffer.DangerousGetRowSpan(yy)); + PixelOperations.Instance.PackFromRgbPlanes(r, g, b, proxyRow); + proxyRow[..width].CopyTo(this.pixelBuffer.DangerousGetRowSpan(yy)); } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/EncodingConfigs/JpegFrameConfig.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/EncodingConfigs/JpegFrameConfig.cs index 18afff7383..feb1ae8eef 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/EncodingConfigs/JpegFrameConfig.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/EncodingConfigs/JpegFrameConfig.cs @@ -39,6 +39,6 @@ public JpegFrameConfig(JpegColorSpace colorType, JpegEncodingColor encodingColor public int MaxVerticalSamplingFactor { get; } - public byte? AdobeColorTransformMarkerFlag { get; set; } = null; + public byte? AdobeColorTransformMarkerFlag { get; set; } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs index f8f7cdfe81..fe61df5e3a 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs @@ -541,7 +541,7 @@ private void EmitHuffRLE(int[] table, int runLength, int value) internal static int GetHuffmanEncodingLength(uint value) { DebugGuard.IsTrue(value <= (1 << 16), "Huffman encoder is supposed to encode a value of 16bit size max"); -#if SUPPORTS_BITOPERATIONS + // This should have been implemented as (BitOperations.Log2(value) + 1) as in non-intrinsic implementation // But internal log2 is implemented like this: (31 - (int)Lzcnt.LeadingZeroCount(value)) @@ -550,19 +550,6 @@ internal static int GetHuffmanEncodingLength(uint value) // Fallback code if Lzcnt is not supported still use if-check // But most modern CPUs support this instruction so this should not be a problem return 32 - BitOperations.LeadingZeroCount(value); -#else - // Ideally: - // if 0 - return 0 in this case - // else - return log2(value) + 1 - // - // Hack based on input value constraint: - // We know that input values are guaranteed to be maximum 16 bit large for huffman encoding - // We can safely shift input value for one bit -> log2(value << 1) - // Because of the 16 bit value constraint it won't overflow - // With that input value change we no longer need to add 1 before returning - // And this eliminates need to check if input value is zero - it is a standard convention which Log2SoftwareFallback adheres to - return Numerics.Log2(value << 1); -#endif } /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs index 97f051c76c..1a262f480d 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs @@ -122,16 +122,6 @@ public readonly struct HuffmanSpec 0xf9, 0xfa }); - /// - /// Gets count[i] - The number of codes of length i bits. - /// - public readonly byte[] Count; - - /// - /// Gets value[i] - The decoded value of the codeword at the given index. - /// - public readonly byte[] Values; - /// /// Initializes a new instance of the struct. /// @@ -146,5 +136,15 @@ public HuffmanSpec(byte[] count, byte[] values) this.Count = count; this.Values = values; } + + /// + /// Gets the count[i] - The number of codes of length i bits. + /// + public readonly byte[] Count { get; } + + /// + /// Gets the value[i] - The decoded value of the codeword at the given index. + /// + public readonly byte[] Values { get; } } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs index 19349e454b..4bc4181ff6 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -45,7 +44,7 @@ static void FDCT8x8_1D_Avx(ref Block8x8F block) block.V0 = Avx.Add(tmp10, tmp11); block.V4 = Avx.Subtract(tmp10, tmp11); - Vector256 mm256_F_0_7071 = Vector256.Create(0.707106781f); + var mm256_F_0_7071 = Vector256.Create(0.707106781f); Vector256 z1 = Avx.Multiply(Avx.Add(tmp12, tmp13), mm256_F_0_7071); block.V2 = Avx.Add(tmp13, z1); block.V6 = Avx.Subtract(tmp13, z1); @@ -98,7 +97,7 @@ static void IDCT8x8_1D_Avx(ref Block8x8F block) Vector256 tmp10 = Avx.Add(z5, tmp2); Vector256 tmp11 = Avx.Subtract(z5, tmp2); - Vector256 mm256_F_1_4142 = Vector256.Create(1.414213562f); + var mm256_F_1_4142 = Vector256.Create(1.414213562f); Vector256 tmp13 = Avx.Add(tmp1, tmp3); Vector256 tmp12 = SimdUtils.HwIntrinsics.MultiplySubstract(tmp13, Avx.Subtract(tmp1, tmp3), mm256_F_1_4142); @@ -142,4 +141,3 @@ static void IDCT8x8_1D_Avx(ref Block8x8F block) } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs index 37ec6e1905..cf0d69ef48 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs @@ -4,9 +4,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Jpeg.Components @@ -112,13 +110,11 @@ public static void AdjustToFDCT(ref Block8x8F quantTable) /// Input block. public static void TransformIDCT(ref Block8x8F block) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { IDCT8x8_Avx(ref block); } else -#endif { IDCT_Vector4(ref block); } @@ -134,13 +130,11 @@ public static void TransformIDCT(ref Block8x8F block) /// Input block. public static void TransformFDCT(ref Block8x8F block) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx.IsSupported) { FDCT8x8_Avx(ref block); } else -#endif { FDCT_Vector4(ref block); } diff --git a/src/ImageSharp/Formats/Jpeg/Components/RowOctet.cs b/src/ImageSharp/Formats/Jpeg/Components/RowOctet.cs index c899cf3adb..5872d47678 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/RowOctet.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/RowOctet.cs @@ -11,6 +11,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Cache 8 pixel rows on the stack, which may originate from different buffers of a . /// + /// The type of element in each row. [StructLayout(LayoutKind.Sequential)] internal ref struct RowOctet where T : struct @@ -92,6 +93,8 @@ public void Update(Buffer2D buffer, int startY) [MethodImpl(MethodImplOptions.NoInlining)] private static Span ThrowIndexOutOfRangeException() +#pragma warning disable CA2201 // Do not raise reserved exception types => throw new IndexOutOfRangeException(); +#pragma warning restore CA2201 // Do not raise reserved exception types } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs index ee1ec501b9..2fa1d835e7 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.Intrinsic.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; @@ -304,4 +303,3 @@ public static unsafe void ApplyTransposingZigZagOrderingAvx2(ref Block8x8 block) } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index c91749f95f..50c08eb771 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -213,7 +213,7 @@ public static JpegFileMarker FindNextFileMarker(BufferedReadStream stream) public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - using var spectralConverter = new SpectralConverter(this.configuration, this.resizeMode == JpegDecoderResizeMode.ScaleOnly ? null : this.Options.TargetSize); + using SpectralConverter spectralConverter = new(this.configuration, this.resizeMode == JpegDecoderResizeMode.ScaleOnly ? null : this.Options.TargetSize); this.ParseStream(stream, spectralConverter, cancellationToken); this.InitExifProfile(); this.InitIccProfile(); @@ -257,12 +257,12 @@ public void LoadTables(byte[] tableBytes, IJpegScanDecoder scanDecoder) JpegThrowHelper.ThrowInvalidImageContentException("Not enough data to read marker"); } - using var ms = new MemoryStream(tableBytes); - using var stream = new BufferedReadStream(this.configuration, ms); + using MemoryStream ms = new(tableBytes); + using BufferedReadStream stream = new(this.configuration, ms); // Check for the Start Of Image marker. int bytesRead = stream.Read(this.markerBuffer, 0, 2); - var fileMarker = new JpegFileMarker(this.markerBuffer[1], 0); + JpegFileMarker fileMarker = new(this.markerBuffer[1], 0); if (fileMarker.Marker != JpegConstants.Markers.SOI) { JpegThrowHelper.ThrowInvalidImageContentException("Missing SOI marker."); @@ -290,7 +290,6 @@ public void LoadTables(byte[] tableBytes, IJpegScanDecoder scanDecoder) switch (fileMarker.Marker) { case JpegConstants.Markers.SOI: - break; case JpegConstants.Markers.RST0: case JpegConstants.Markers.RST7: break; @@ -335,7 +334,7 @@ internal void ParseStream(BufferedReadStream stream, SpectralConverter spectralC // Check for the Start Of Image marker. stream.Read(this.markerBuffer, 0, 2); - var fileMarker = new JpegFileMarker(this.markerBuffer[1], 0); + JpegFileMarker fileMarker = new(this.markerBuffer[1], 0); if (fileMarker.Marker != JpegConstants.Markers.SOI) { JpegThrowHelper.ThrowInvalidImageContentException("Missing SOI marker."); @@ -409,12 +408,10 @@ internal void ParseStream(BufferedReadStream stream, SpectralConverter spectralC this.ProcessStartOfScanMarker(stream, markerContentByteSize); break; } - else - { - // It's highly unlikely that APPn related data will be found after the SOS marker - // We should have gathered everything we need by now. - return; - } + + // It's highly unlikely that APPn related data will be found after the SOS marker + // We should have gathered everything we need by now. + return; case JpegConstants.Markers.DHT: @@ -654,7 +651,7 @@ private void InitIccProfile() { if (this.hasIcc) { - var profile = new IccProfile(this.iccData); + IccProfile profile = new(this.iccData); if (profile.CheckIsValid()) { this.Metadata.IccProfile = profile; @@ -669,8 +666,7 @@ private void InitIptcProfile() { if (this.hasIptc) { - var profile = new IptcProfile(this.iptcData); - this.Metadata.IptcProfile = profile; + this.Metadata.IptcProfile = new IptcProfile(this.iptcData); } } @@ -681,8 +677,7 @@ private void InitXmpProfile() { if (this.hasXmp) { - var profile = new XmpProfile(this.xmpData); - this.Metadata.XmpProfile = profile; + this.Metadata.XmpProfile = new XmpProfile(this.xmpData); } } @@ -723,7 +718,7 @@ private double GetExifResolutionValue(ExifTag tag) /// /// The profile data array. /// The array containing addition profile data. - private void ExtendProfile(ref byte[] profile, byte[] extension) + private static void ExtendProfile(ref byte[] profile, byte[] extension) { int currentLength = profile.Length; @@ -749,9 +744,12 @@ private void ProcessApplicationHeaderMarker(BufferedReadStream stream, int remai } stream.Read(this.temp, 0, JFifMarker.Length); - remaining -= JFifMarker.Length; + if (!JFifMarker.TryParse(this.temp, out this.jFif)) + { + JpegThrowHelper.ThrowNotSupportedException("Unknown App0 Marker - Expected JFIF."); + } - JFifMarker.TryParse(this.temp, out this.jFif); + remaining -= JFifMarker.Length; // TODO: thumbnail if (remaining > 0) @@ -772,9 +770,9 @@ private void ProcessApplicationHeaderMarker(BufferedReadStream stream, int remai /// The remaining bytes in the segment block. private void ProcessApp1Marker(BufferedReadStream stream, int remaining) { - const int ExifMarkerLength = 6; - const int XmpMarkerLength = 29; - if (remaining < ExifMarkerLength || this.skipMetadata) + const int exifMarkerLength = 6; + const int xmpMarkerLength = 29; + if (remaining < exifMarkerLength || this.skipMetadata) { // Skip the application header length. stream.Skip(remaining); @@ -787,8 +785,8 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining) } // XMP marker is the longer then the EXIF marker, so first try read the EXIF marker bytes. - stream.Read(this.temp, 0, ExifMarkerLength); - remaining -= ExifMarkerLength; + stream.Read(this.temp, 0, exifMarkerLength); + remaining -= exifMarkerLength; if (ProfileResolver.IsProfile(this.temp, ProfileResolver.ExifMarker)) { @@ -803,15 +801,15 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining) else { // If the EXIF information exceeds 64K, it will be split over multiple APP1 markers. - this.ExtendProfile(ref this.exifData, profile); + ExtendProfile(ref this.exifData, profile); } remaining = 0; } - if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker.Slice(0, ExifMarkerLength))) + if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker[..exifMarkerLength])) { - const int remainingXmpMarkerBytes = XmpMarkerLength - ExifMarkerLength; + const int remainingXmpMarkerBytes = xmpMarkerLength - exifMarkerLength; if (remaining < remainingXmpMarkerBytes || this.skipMetadata) { // Skip the application header length. @@ -819,7 +817,7 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining) return; } - stream.Read(this.temp, ExifMarkerLength, remainingXmpMarkerBytes); + stream.Read(this.temp, exifMarkerLength, remainingXmpMarkerBytes); remaining -= remainingXmpMarkerBytes; if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker)) { @@ -834,7 +832,7 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining) else { // If the XMP information exceeds 64K, it will be split over multiple APP1 markers. - this.ExtendProfile(ref this.xmpData, profile); + ExtendProfile(ref this.xmpData, profile); } remaining = 0; @@ -853,16 +851,16 @@ private void ProcessApp1Marker(BufferedReadStream stream, int remaining) private void ProcessApp2Marker(BufferedReadStream stream, int remaining) { // Length is 14 though we only need to check 12. - const int Icclength = 14; - if (remaining < Icclength || this.skipMetadata) + const int icclength = 14; + if (remaining < icclength || this.skipMetadata) { stream.Skip(remaining); return; } - byte[] identifier = new byte[Icclength]; - stream.Read(identifier, 0, Icclength); - remaining -= Icclength; // We have read it by this point + byte[] identifier = new byte[icclength]; + stream.Read(identifier, 0, icclength); + remaining -= icclength; // We have read it by this point if (ProfileResolver.IsProfile(identifier, ProfileResolver.IccMarker)) { @@ -877,7 +875,7 @@ private void ProcessApp2Marker(BufferedReadStream stream, int remaining) else { // If the ICC information exceeds 64K, it will be split over multiple APP2 markers - this.ExtendProfile(ref this.iccData, profile); + ExtendProfile(ref this.iccData, profile); } } else @@ -911,13 +909,13 @@ private void ProcessApp13Marker(BufferedReadStream stream, int remaining) while (blockDataSpan.Length > 12) { - if (!ProfileResolver.IsProfile(blockDataSpan.Slice(0, 4), ProfileResolver.AdobeImageResourceBlockMarker)) + if (!ProfileResolver.IsProfile(blockDataSpan[..4], ProfileResolver.AdobeImageResourceBlockMarker)) { return; } - blockDataSpan = blockDataSpan.Slice(4); - Span imageResourceBlockId = blockDataSpan.Slice(0, 2); + blockDataSpan = blockDataSpan[4..]; + Span imageResourceBlockId = blockDataSpan[..2]; if (ProfileResolver.IsProfile(imageResourceBlockId, ProfileResolver.AdobeIptcMarker)) { int resourceBlockNameLength = ReadImageResourceNameLength(blockDataSpan); @@ -941,7 +939,7 @@ private void ProcessApp13Marker(BufferedReadStream stream, int remaining) break; } - blockDataSpan = blockDataSpan.Slice(dataStartIdx + resourceDataSize); + blockDataSpan = blockDataSpan[(dataStartIdx + resourceDataSize)..]; } } } @@ -971,7 +969,7 @@ private void ProcessArithmeticTable(BufferedReadStream stream, int remaining) byte conditioningTableValue = (byte)stream.ReadByte(); remaining--; - var arithmeticTable = new ArithmeticDecodingTable(tableClass, identifier); + ArithmeticDecodingTable arithmeticTable = new(tableClass, identifier); arithmeticTable.Configure(conditioningTableValue); bool tableEntryReplaced = false; @@ -1029,16 +1027,16 @@ private static int ReadResourceDataLength(Span blockDataSpan, int resource /// The remaining bytes in the segment block. private void ProcessApp14Marker(BufferedReadStream stream, int remaining) { - const int MarkerLength = AdobeMarker.Length; - if (remaining < MarkerLength) + const int markerLength = AdobeMarker.Length; + if (remaining < markerLength) { // Skip the application header length stream.Skip(remaining); return; } - stream.Read(this.temp, 0, MarkerLength); - remaining -= MarkerLength; + stream.Read(this.temp, 0, markerLength); + remaining -= markerLength; if (AdobeMarker.TryParse(this.temp, out this.adobe)) { @@ -1086,7 +1084,6 @@ private void ProcessDefineQuantizationTablesMarker(BufferedReadStream stream, in { // 8 bit values case 0: - { // Validate: 8 bit table needs exactly 64 bytes if (remaining < 64) { @@ -1103,11 +1100,9 @@ private void ProcessDefineQuantizationTablesMarker(BufferedReadStream stream, in } break; - } // 16 bit values case 1: - { // Validate: 16 bit table needs exactly 128 bytes if (remaining < 128) { @@ -1124,14 +1119,11 @@ private void ProcessDefineQuantizationTablesMarker(BufferedReadStream stream, in } break; - } // Unknown precision - error default: - { JpegThrowHelper.ThrowBadQuantizationTablePrecision(tablePrecision); break; - } } // Estimating quality @@ -1139,17 +1131,13 @@ private void ProcessDefineQuantizationTablesMarker(BufferedReadStream stream, in { // luminance table case 0: - { jpegMetadata.LuminanceQuality = Quantization.EstimateLuminanceQuality(ref table); break; - } // chrominance table case 1: - { jpegMetadata.ChrominanceQuality = Quantization.EstimateChrominanceQuality(ref table); break; - } } } } @@ -1312,7 +1300,7 @@ private void ProcessDefineHuffmanTablesMarker(BufferedReadStream stream, int rem const int codeValuesMaxByteSize = 256; const int totalBufferSize = codeLengthsByteSize + codeValuesMaxByteSize + HuffmanTable.WorkspaceByteSize; - var huffmanScanDecoder = this.scanDecoder as HuffmanScanDecoder; + HuffmanScanDecoder huffmanScanDecoder = this.scanDecoder as HuffmanScanDecoder; if (huffmanScanDecoder is null) { JpegThrowHelper.ThrowInvalidImageContentException("missing huffman table data"); @@ -1322,9 +1310,9 @@ private void ProcessDefineHuffmanTablesMarker(BufferedReadStream stream, int rem using (IMemoryOwner buffer = this.configuration.MemoryAllocator.Allocate(totalBufferSize)) { Span bufferSpan = buffer.GetSpan(); - Span huffmanLengthsSpan = bufferSpan.Slice(0, codeLengthsByteSize); + Span huffmanLengthsSpan = bufferSpan[..codeLengthsByteSize]; Span huffmanValuesSpan = bufferSpan.Slice(codeLengthsByteSize, codeValuesMaxByteSize); - Span tableWorkspace = MemoryMarshal.Cast(bufferSpan.Slice(codeLengthsByteSize + codeValuesMaxByteSize)); + Span tableWorkspace = MemoryMarshal.Cast(bufferSpan[(codeLengthsByteSize + codeValuesMaxByteSize)..]); for (int i = 2; i < remaining;) { @@ -1367,7 +1355,7 @@ private void ProcessDefineHuffmanTablesMarker(BufferedReadStream stream, int rem tableType, tableIndex, huffmanLengthsSpan, - huffmanValuesSpan.Slice(0, codeLengthSum), + huffmanValuesSpan[..codeLengthSum], tableWorkspace); } } @@ -1399,6 +1387,8 @@ private void ProcessDefineRestartIntervalMarker(BufferedReadStream stream, int r /// /// Processes the SOS (Start of scan marker). /// + /// The input stream. + /// The remaining bytes in the segment block. private void ProcessStartOfScanMarker(BufferedReadStream stream, int remaining) { if (this.Frame is null) @@ -1479,11 +1469,9 @@ private void ProcessStartOfScanMarker(BufferedReadStream stream, int remaining) JpegThrowHelper.ThrowInvalidImageContentException("Not enough data to read progressive scan decoding data"); } - int spectralStart = this.temp[0]; - this.scanDecoder.SpectralStart = spectralStart; + this.scanDecoder.SpectralStart = this.temp[0]; - int spectralEnd = this.temp[1]; - this.scanDecoder.SpectralEnd = spectralEnd; + this.scanDecoder.SpectralEnd = this.temp[1]; int successiveApproximation = this.temp[2]; this.scanDecoder.SuccessiveHigh = successiveApproximation >> 4; diff --git a/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs b/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs index fbbe210ff0..61b4a36ad7 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -15,22 +15,18 @@ public sealed class JpegImageFormatDetector : IImageFormatDetector /// public IImageFormat DetectFormat(ReadOnlySpan header) - { - return this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null; - } + => this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null; private bool IsSupportedFileFormat(ReadOnlySpan header) - { - return header.Length >= this.HeaderSize && - (this.IsJfif(header) || this.IsExif(header) || this.IsJpeg(header)); - } + => header.Length >= this.HeaderSize + && (IsJfif(header) || IsExif(header) || IsJpeg(header)); /// /// Returns a value indicating whether the given bytes identify Jfif data. /// /// The bytes representing the file header. /// The - private bool IsJfif(ReadOnlySpan header) => + private static bool IsJfif(ReadOnlySpan header) => header[6] == 0x4A && // J header[7] == 0x46 && // F header[8] == 0x49 && // I @@ -42,7 +38,7 @@ private bool IsJfif(ReadOnlySpan header) => /// /// The bytes representing the file header. /// The - private bool IsExif(ReadOnlySpan header) => + private static bool IsExif(ReadOnlySpan header) => header[6] == 0x45 && // E header[7] == 0x78 && // X header[8] == 0x69 && // I @@ -55,7 +51,7 @@ private bool IsExif(ReadOnlySpan header) => /// /// The bytes representing the file header. /// The - private bool IsJpeg(ReadOnlySpan header) => + private static bool IsJpeg(ReadOnlySpan header) => header[0] == 0xFF && // 255 header[1] == 0xD8; // 216 } diff --git a/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs b/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs index 25c7ee450e..431eea4c42 100644 --- a/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs +++ b/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs @@ -145,17 +145,17 @@ private void WriteHeader(Stream stream, byte signature, Size pixelSize) buffer[1] = signature; buffer[2] = NewLine; - Utf8Formatter.TryFormat(pixelSize.Width, buffer.Slice(written), out int bytesWritten); + Utf8Formatter.TryFormat(pixelSize.Width, buffer[written..], out int bytesWritten); written += bytesWritten; buffer[written++] = Space; - Utf8Formatter.TryFormat(pixelSize.Height, buffer.Slice(written), out bytesWritten); + Utf8Formatter.TryFormat(pixelSize.Height, buffer[written..], out bytesWritten); written += bytesWritten; buffer[written++] = NewLine; if (this.colorType != PbmColorType.BlackAndWhite) { int maxPixelValue = this.componentType == PbmComponentType.Short ? 65535 : 255; - Utf8Formatter.TryFormat(maxPixelValue, buffer.Slice(written), out bytesWritten); + Utf8Formatter.TryFormat(maxPixelValue, buffer[written..], out bytesWritten); written += bytesWritten; buffer[written++] = NewLine; } diff --git a/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs b/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs index b8d776a37d..4446d4b186 100644 --- a/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs @@ -18,13 +18,11 @@ public sealed class PbmImageFormatDetector : IImageFormatDetector public int HeaderSize => 2; /// - public IImageFormat DetectFormat(ReadOnlySpan header) => this.IsSupportedFileFormat(header) ? PbmFormat.Instance : null; + public IImageFormat DetectFormat(ReadOnlySpan header) => IsSupportedFileFormat(header) ? PbmFormat.Instance : null; - private bool IsSupportedFileFormat(ReadOnlySpan header) + private static bool IsSupportedFileFormat(ReadOnlySpan header) { -#pragma warning disable SA1131 // Use readable conditions - if (1 < (uint)header.Length) -#pragma warning restore SA1131 // Use readable conditions + if ((uint)header.Length > 1) { // Signature should be between P1 and P6. return header[0] == P && (uint)(header[1] - Zero - 1) < (Seven - Zero - 1); diff --git a/src/ImageSharp/Formats/Pbm/PlainEncoder.cs b/src/ImageSharp/Formats/Pbm/PlainEncoder.cs index b858d1e63a..d989b6e660 100644 --- a/src/ImageSharp/Formats/Pbm/PlainEncoder.cs +++ b/src/ImageSharp/Formats/Pbm/PlainEncoder.cs @@ -94,7 +94,7 @@ private static void WriteGrayscale(Configuration configuration, Stream s int written = 0; for (int x = 0; x < width; x++) { - Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan.Slice(written), out int bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan[written..], out int bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; } @@ -127,7 +127,7 @@ private static void WriteWideGrayscale(Configuration configuration, Stre int written = 0; for (int x = 0; x < width; x++) { - Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan.Slice(written), out int bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan[written..], out int bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; } @@ -160,13 +160,13 @@ private static void WriteRgb(Configuration configuration, Stream stream, int written = 0; for (int x = 0; x < width; x++) { - Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan.Slice(written), out int bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan[written..], out int bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; - Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan.Slice(written), out bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan[written..], out bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; - Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan.Slice(written), out bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan[written..], out bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; } @@ -199,13 +199,13 @@ private static void WriteWideRgb(Configuration configuration, Stream str int written = 0; for (int x = 0; x < width; x++) { - Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan.Slice(written), out int bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan[written..], out int bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; - Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan.Slice(written), out bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan[written..], out bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; - Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan.Slice(written), out bytesWritten, DecimalFormat); + Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan[written..], out bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; } diff --git a/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs b/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs index 8ad2c5a4ab..31b845e19b 100644 --- a/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs +++ b/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs @@ -47,7 +47,7 @@ public PhysicalChunkData(uint x, uint y, byte unitSpecifier) /// The parsed PhysicalChunkData. public static PhysicalChunkData Parse(ReadOnlySpan data) { - uint hResolution = BinaryPrimitives.ReadUInt32BigEndian(data.Slice(0, 4)); + uint hResolution = BinaryPrimitives.ReadUInt32BigEndian(data[..4]); uint vResolution = BinaryPrimitives.ReadUInt32BigEndian(data.Slice(4, 4)); byte unit = data[8]; @@ -102,7 +102,7 @@ public static PhysicalChunkData FromMetadata(ImageMetadata meta) /// The buffer. public void WriteTo(Span buffer) { - BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(0, 4), this.XAxisPixelsPerUnit); + BinaryPrimitives.WriteUInt32BigEndian(buffer[..4], this.XAxisPixelsPerUnit); BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(4, 4), this.YAxisPixelsPerUnit); buffer[8] = this.UnitSpecifier; } diff --git a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs index b381442bd8..4471b355ef 100644 --- a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs @@ -4,11 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -35,19 +32,16 @@ public static void Decode(Span scanline, Span previousScanline, int // With pixels positioned like this: // prev: c b // row: a d -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported && bytesPerPixel is 4) { DecodeSse2(scanline, previousScanline); } else -#endif { DecodeScalar(scanline, previousScanline, bytesPerPixel); } } -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeSse2(Span scanline, Span previousScanline) { @@ -81,7 +75,6 @@ private static void DecodeSse2(Span scanline, Span previousScanline) offset += 4; } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline, int bytesPerPixel) @@ -139,7 +132,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan previo sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -210,7 +202,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan previo sum += Numerics.ReduceSum(sumAccumulator); } -#endif for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) { diff --git a/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs index fd2d9eab49..c0e14d4ab0 100644 --- a/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs @@ -23,8 +23,8 @@ public static void Encode(ReadOnlySpan scanline, Span result) { // Insert a byte before the data. result[0] = 0; - result = result.Slice(1); - scanline.Slice(0, Math.Min(scanline.Length, result.Length)).CopyTo(result); + result = result[1..]; + scanline[..Math.Min(scanline.Length, result.Length)].CopyTo(result); } } } diff --git a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs index 03d8834542..0676f618b1 100644 --- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs @@ -5,11 +5,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -38,20 +35,16 @@ public static void Decode(Span scanline, Span previousScanline, int // row: a d // The Paeth function predicts d to be whichever of a, b, or c is nearest to // p = a + b - c. -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported && bytesPerPixel is 4) { DecodeSse41(scanline, previousScanline); } else -#endif { DecodeScalar(scanline, previousScanline, bytesPerPixel); } } -#if SUPPORTS_RUNTIME_INTRINSICS - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeSse41(Span scanline, Span previousScanline) { @@ -107,8 +100,6 @@ private static void DecodeSse41(Span scanline, Span previousScanline } } -#endif - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline, int bytesPerPixel) { @@ -168,7 +159,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan previo sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -213,7 +203,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan previo sum += (int)sumAccumulator[i]; } } -#endif for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) { @@ -261,7 +250,6 @@ private static byte PaethPredictor(byte left, byte above, byte upperLeft) return upperLeft; } -#if SUPPORTS_RUNTIME_INTRINSICS private static Vector256 PaethPredictor(Vector256 left, Vector256 above, Vector256 upleft) { Vector256 zero = Vector256.Zero; @@ -324,6 +312,5 @@ private static Vector PaethPredictor(Vector left, Vector ab left: above, right: upperLeft)); } -#endif } } diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs index a7044837e1..063cc11c36 100644 --- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs @@ -5,11 +5,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -29,19 +26,16 @@ internal static class SubFilter public static void Decode(Span scanline, int bytesPerPixel) { // The Sub filter predicts each pixel as the previous pixel. -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported && bytesPerPixel is 4) { DecodeSse2(scanline); } else -#endif { DecodeScalar(scanline, bytesPerPixel); } } -#if SUPPORTS_RUNTIME_INTRINSICS private static void DecodeSse2(Span scanline) { ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); @@ -64,7 +58,6 @@ private static void DecodeSse2(Span scanline) offset += 4; } } -#endif private static void DecodeScalar(Span scanline, int bytesPerPixel) { @@ -110,7 +103,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan result sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -151,7 +143,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan result sum += (int)sumAccumulator[i]; } } -#endif for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) { @@ -163,7 +154,7 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan result sum += Numerics.Abs(unchecked((sbyte)res)); } - sum -= 1; + sum--; } } } diff --git a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs index c5003d1114..e80c5d22b4 100644 --- a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs @@ -5,11 +5,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Png.Filters { @@ -30,7 +27,6 @@ public static void Decode(Span scanline, Span previousScanline) { DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { DecodeAvx2(scanline, previousScanline); @@ -40,13 +36,11 @@ public static void Decode(Span scanline, Span previousScanline) DecodeSse2(scanline, previousScanline); } else -#endif { DecodeScalar(scanline, previousScanline); } } -#if SUPPORTS_RUNTIME_INTRINSICS private static void DecodeAvx2(Span scanline, Span previousScanline) { ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline); @@ -110,7 +104,6 @@ private static void DecodeSse2(Span scanline, Span previousScanline) offset++; } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline) @@ -150,7 +143,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan previo int x = 0; -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -191,7 +183,6 @@ public static void Encode(ReadOnlySpan scanline, ReadOnlySpan previo sum += (int)sumAccumulator[i]; } } -#endif for (; x < scanline.Length; /* Note: ++x happens in the body to avoid one add operation */) { diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 6ab9f4c4b0..3d9fc68fa0 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -4,6 +4,7 @@ using System; using System.Buffers; using System.Buffers.Binary; +using System.Globalization; using System.IO; using System.IO.Compression; using System.Runtime.CompilerServices; @@ -150,7 +151,7 @@ internal PngDecoderCore(DecoderOptions options, bool colorMetadataOnly) public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - var metadata = new ImageMetadata(); + ImageMetadata metadata = new(); PngMetadata pngMetadata = metadata.GetPngMetadata(); this.currentStream = stream; this.currentStream.Skip(8); @@ -167,10 +168,10 @@ public Image Decode(BufferedReadStream stream, CancellationToken this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan()); break; case PngChunkType.Physical: - this.ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); + ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); break; case PngChunkType.Gamma: - this.ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); + ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); break; case PngChunkType.Data: if (image is null) @@ -206,7 +207,7 @@ public Image Decode(BufferedReadStream stream, CancellationToken { byte[] exifData = new byte[chunk.Length]; chunk.Data.GetSpan().CopyTo(exifData); - this.MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); + MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); } break; @@ -250,7 +251,7 @@ public Image Decode(BufferedReadStream stream, CancellationToken /// public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) { - var metadata = new ImageMetadata(); + ImageMetadata metadata = new(); PngMetadata pngMetadata = metadata.GetPngMetadata(); this.currentStream = stream; this.currentStream.Skip(8); @@ -272,7 +273,7 @@ public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancella break; } - this.ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); + ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); break; case PngChunkType.Gamma: if (this.colorMetadataOnly) @@ -281,7 +282,7 @@ public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancella break; } - this.ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); + ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); break; case PngChunkType.Data: @@ -343,7 +344,7 @@ public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancella { byte[] exifData = new byte[chunk.Length]; chunk.Data.GetSpan().CopyTo(exifData); - this.MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); + MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true); } break; @@ -432,9 +433,9 @@ private bool TryScaleUpTo8BitArray(ReadOnlySpan source, int bytesPerScanli /// /// The metadata to read to. /// The data containing physical data. - private void ReadPhysicalChunk(ImageMetadata metadata, ReadOnlySpan data) + private static void ReadPhysicalChunk(ImageMetadata metadata, ReadOnlySpan data) { - var physicalChunk = PhysicalChunkData.Parse(data); + PhysicalChunkData physicalChunk = PhysicalChunkData.Parse(data); metadata.ResolutionUnits = physicalChunk.UnitSpecifier == byte.MinValue ? PixelResolutionUnit.AspectRatio @@ -449,7 +450,7 @@ private void ReadPhysicalChunk(ImageMetadata metadata, ReadOnlySpan data) /// /// The metadata to read to. /// The data containing physical data. - private void ReadGammaChunk(PngMetadata pngMetadata, ReadOnlySpan data) + private static void ReadGammaChunk(PngMetadata pngMetadata, ReadOnlySpan data) { if (data.Length < 4) { @@ -519,26 +520,15 @@ private int CalculateBitsPerPixel() /// /// The private int CalculateBytesPerPixel() - { - switch (this.pngColorType) + => this.pngColorType + switch { - case PngColorType.Grayscale: - return this.header.BitDepth == 16 ? 2 : 1; - - case PngColorType.GrayscaleWithAlpha: - return this.header.BitDepth == 16 ? 4 : 2; - - case PngColorType.Palette: - return 1; - - case PngColorType.Rgb: - return this.header.BitDepth == 16 ? 6 : 3; - - case PngColorType.RgbWithAlpha: - default: - return this.header.BitDepth == 16 ? 8 : 4; - } - } + PngColorType.Grayscale => this.header.BitDepth == 16 ? 2 : 1, + PngColorType.GrayscaleWithAlpha => this.header.BitDepth == 16 ? 4 : 2, + PngColorType.Palette => 1, + PngColorType.Rgb => this.header.BitDepth == 16 ? 6 : 3, + _ => this.header.BitDepth == 16 ? 8 : 4, + }; /// /// Calculates the scanline length. @@ -571,7 +561,7 @@ private int CalculateScanlineLength(int width) private void ReadScanlines(PngChunk chunk, ImageFrame image, PngMetadata pngMetadata) where TPixel : unmanaged, IPixel { - using var deframeStream = new ZlibInflateStream(this.currentStream, this.ReadNextDataChunk); + using ZlibInflateStream deframeStream = new(this.currentStream, this.ReadNextDataChunk); deframeStream.AllocateNewBytes(chunk.Length, true); DeflateStream dataStream = deframeStream.CompressedStream; @@ -752,7 +742,7 @@ private void ProcessDefilteredScanline(ReadOnlySpan defilteredScan Span rowSpan = pixels.PixelBuffer.DangerousGetRowSpan(this.currentRow); // Trim the first marker byte from the buffer - ReadOnlySpan trimmed = defilteredScanline.Slice(1, defilteredScanline.Length - 1); + ReadOnlySpan trimmed = defilteredScanline[1..]; // Convert 1, 2, and 4 bit pixel data into the 8 bit equivalent. IMemoryOwner buffer = null; @@ -844,7 +834,7 @@ private void ProcessInterlacedDefilteredScanline(ReadOnlySpan defi where TPixel : unmanaged, IPixel { // Trim the first marker byte from the buffer - ReadOnlySpan trimmed = defilteredScanline.Slice(1, defilteredScanline.Length - 1); + ReadOnlySpan trimmed = defilteredScanline[1..]; // Convert 1, 2, and 4 bit pixel data into the 8 bit equivalent. IMemoryOwner buffer = null; @@ -944,7 +934,7 @@ private void AssignTransparentMarkers(ReadOnlySpan alpha, PngMetadata pngM { if (this.header.BitDepth == 16) { - ushort rc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2)); + ushort rc = BinaryPrimitives.ReadUInt16LittleEndian(alpha[..2]); ushort gc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(2, 2)); ushort bc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(4, 2)); @@ -966,7 +956,7 @@ private void AssignTransparentMarkers(ReadOnlySpan alpha, PngMetadata pngM { if (this.header.BitDepth == 16) { - pngMetadata.TransparentL16 = new L16(BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2))); + pngMetadata.TransparentL16 = new L16(BinaryPrimitives.ReadUInt16LittleEndian(alpha[..2])); } else { @@ -1021,15 +1011,15 @@ private void ReadTextChunk(ImageMetadata baseMetadata, PngMetadata metadata, Rea return; } - ReadOnlySpan keywordBytes = data.Slice(0, zeroIndex); - if (!this.TryReadTextKeyword(keywordBytes, out string name)) + ReadOnlySpan keywordBytes = data[..zeroIndex]; + if (!TryReadTextKeyword(keywordBytes, out string name)) { return; } - string value = PngConstants.Encoding.GetString(data.Slice(zeroIndex + 1)); + string value = PngConstants.Encoding.GetString(data[(zeroIndex + 1)..]); - if (!this.TryReadTextChunkMetadata(baseMetadata, name, value)) + if (!TryReadTextChunkMetadata(baseMetadata, name, value)) { metadata.TextData.Add(new PngTextData(name, value, string.Empty, string.Empty)); } @@ -1049,7 +1039,7 @@ private void ReadCompressedTextChunk(ImageMetadata baseMetadata, PngMetadata met } int zeroIndex = data.IndexOf((byte)0); - if (zeroIndex < PngConstants.MinTextKeywordLength || zeroIndex > PngConstants.MaxTextKeywordLength) + if (zeroIndex is < PngConstants.MinTextKeywordLength or > PngConstants.MaxTextKeywordLength) { return; } @@ -1061,16 +1051,16 @@ private void ReadCompressedTextChunk(ImageMetadata baseMetadata, PngMetadata met return; } - ReadOnlySpan keywordBytes = data.Slice(0, zeroIndex); - if (!this.TryReadTextKeyword(keywordBytes, out string name)) + ReadOnlySpan keywordBytes = data[..zeroIndex]; + if (!TryReadTextKeyword(keywordBytes, out string name)) { return; } - ReadOnlySpan compressedData = data.Slice(zeroIndex + 2); + ReadOnlySpan compressedData = data[(zeroIndex + 2)..]; - if (this.TryUncompressTextData(compressedData, PngConstants.Encoding, out string uncompressed) && - !this.TryReadTextChunkMetadata(baseMetadata, name, uncompressed)) + if (this.TryUncompressTextData(compressedData, PngConstants.Encoding, out string uncompressed) + && !TryReadTextChunkMetadata(baseMetadata, name, uncompressed)) { metadata.TextData.Add(new PngTextData(name, uncompressed, string.Empty, string.Empty)); } @@ -1085,10 +1075,10 @@ private void ReadCompressedTextChunk(ImageMetadata baseMetadata, PngMetadata met /// True if metadata was successfully parsed from the text chunk. False if the /// text chunk was not identified as metadata, and should be stored in the metadata /// object unmodified. - private bool TryReadTextChunkMetadata(ImageMetadata baseMetadata, string chunkName, string chunkText) + private static bool TryReadTextChunkMetadata(ImageMetadata baseMetadata, string chunkName, string chunkText) { if (chunkName.Equals("Raw profile type exif", StringComparison.OrdinalIgnoreCase) && - this.TryReadLegacyExifTextChunk(baseMetadata, chunkText)) + TryReadLegacyExifTextChunk(baseMetadata, chunkText)) { // Successfully parsed legacy exif data from text return true; @@ -1107,24 +1097,24 @@ private bool TryReadTextChunkMetadata(ImageMetadata baseMetadata, string chunkNa /// /// The to store the decoded exif tags into. /// The contents of the "raw profile type exif" text chunk. - private bool TryReadLegacyExifTextChunk(ImageMetadata metadata, string data) + private static bool TryReadLegacyExifTextChunk(ImageMetadata metadata, string data) { ReadOnlySpan dataSpan = data.AsSpan(); dataSpan = dataSpan.TrimStart(); - if (!StringEqualsInsensitive(dataSpan.Slice(0, 4), "exif".AsSpan())) + if (!StringEqualsInsensitive(dataSpan[..4], "exif".AsSpan())) { // "exif" identifier is missing from the beginning of the text chunk return false; } // Skip to the data length - dataSpan = dataSpan.Slice(4).TrimStart(); + dataSpan = dataSpan[4..].TrimStart(); int dataLengthEnd = dataSpan.IndexOf('\n'); - int dataLength = ParseInt32(dataSpan.Slice(0, dataSpan.IndexOf('\n'))); + int dataLength = ParseInt32(dataSpan[..dataSpan.IndexOf('\n')]); // Skip to the hex-encoded data - dataSpan = dataSpan.Slice(dataLengthEnd).Trim(); + dataSpan = dataSpan[dataLengthEnd..].Trim(); // Sequence of bytes for the exif header ("Exif" ASCII and two zero bytes). // This doesn't actually allocate. @@ -1149,15 +1139,15 @@ private bool TryReadLegacyExifTextChunk(ImageMetadata metadata, string data) tempExifBuf = new byte[exifHeader.Length]; } - HexConverter.HexStringToBytes(dataSpan.Slice(0, exifHeader.Length * 2), tempExifBuf); - if (!tempExifBuf.AsSpan().Slice(0, exifHeader.Length).SequenceEqual(exifHeader)) + HexConverter.HexStringToBytes(dataSpan[..(exifHeader.Length * 2)], tempExifBuf); + if (!tempExifBuf.AsSpan()[..exifHeader.Length].SequenceEqual(exifHeader)) { // Exif header in the hex data is not valid return false; } // Skip over the exif header we just tested - dataSpan = dataSpan.Slice(exifHeader.Length * 2); + dataSpan = dataSpan[(exifHeader.Length * 2)..]; dataLength -= exifHeader.Length; // Load the hex-encoded data, one line at a time @@ -1168,12 +1158,12 @@ private bool TryReadLegacyExifTextChunk(ImageMetadata metadata, string data) int newlineIndex = dataSpan.IndexOf('\n'); if (newlineIndex != -1) { - lineSpan = dataSpan.Slice(0, newlineIndex); + lineSpan = dataSpan[..newlineIndex]; } - i += HexConverter.HexStringToBytes(lineSpan, exifBlob.AsSpan().Slice(i)); + i += HexConverter.HexStringToBytes(lineSpan, exifBlob.AsSpan()[i..]); - dataSpan = dataSpan.Slice(newlineIndex + 1); + dataSpan = dataSpan[(newlineIndex + 1)..]; } } catch @@ -1181,7 +1171,7 @@ private bool TryReadLegacyExifTextChunk(ImageMetadata metadata, string data) return false; } - this.MergeOrSetExifProfile(metadata, new ExifProfile(exifBlob), replaceExistingKeys: false); + MergeOrSetExifProfile(metadata, new ExifProfile(exifBlob), replaceExistingKeys: false); return true; } @@ -1205,13 +1195,13 @@ private void ReadColorProfileChunk(ImageMetadata metadata, ReadOnlySpan da return; } - ReadOnlySpan keywordBytes = data.Slice(0, zeroIndex); - if (!this.TryReadTextKeyword(keywordBytes, out string name)) + ReadOnlySpan keywordBytes = data[..zeroIndex]; + if (!TryReadTextKeyword(keywordBytes, out string name)) { return; } - ReadOnlySpan compressedData = data.Slice(zeroIndex + 2); + ReadOnlySpan compressedData = data[(zeroIndex + 2)..]; if (this.TryUncompressZlibData(compressedData, out byte[] iccpProfileBytes)) { @@ -1229,29 +1219,28 @@ private unsafe bool TryUncompressZlibData(ReadOnlySpan compressedData, out { fixed (byte* compressedDataBase = compressedData) { - using (IMemoryOwner destBuffer = this.memoryAllocator.Allocate(this.configuration.StreamProcessingBufferSize)) - using (var memoryStreamOutput = new MemoryStream(compressedData.Length)) - using (var memoryStreamInput = new UnmanagedMemoryStream(compressedDataBase, compressedData.Length)) - using (var bufferedStream = new BufferedReadStream(this.configuration, memoryStreamInput)) - using (var inflateStream = new ZlibInflateStream(bufferedStream)) - { - Span destUncompressedData = destBuffer.GetSpan(); - if (!inflateStream.AllocateNewBytes(compressedData.Length, false)) - { - uncompressedBytesArray = Array.Empty(); - return false; - } + using IMemoryOwner destBuffer = this.memoryAllocator.Allocate(this.configuration.StreamProcessingBufferSize); + using MemoryStream memoryStreamOutput = new(compressedData.Length); + using UnmanagedMemoryStream memoryStreamInput = new(compressedDataBase, compressedData.Length); + using BufferedReadStream bufferedStream = new(this.configuration, memoryStreamInput); + using ZlibInflateStream inflateStream = new(bufferedStream); - int bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length); - while (bytesRead != 0) - { - memoryStreamOutput.Write(destUncompressedData.Slice(0, bytesRead)); - bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length); - } + Span destUncompressedData = destBuffer.GetSpan(); + if (!inflateStream.AllocateNewBytes(compressedData.Length, false)) + { + uncompressedBytesArray = Array.Empty(); + return false; + } - uncompressedBytesArray = memoryStreamOutput.ToArray(); - return true; + int bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length); + while (bytesRead != 0) + { + memoryStreamOutput.Write(destUncompressedData[..bytesRead]); + bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length); } + + uncompressedBytesArray = memoryStreamOutput.ToArray(); + return true; } } @@ -1263,31 +1252,14 @@ private unsafe bool TryUncompressZlibData(ReadOnlySpan compressedData, out /// The second to compare. /// True if the spans were identical, false otherwise. private static bool StringEqualsInsensitive(ReadOnlySpan span1, ReadOnlySpan span2) - { -#pragma warning disable IDE0022 // Use expression body for methods -#if NETSTANDARD2_1 || NETCOREAPP2_1_OR_GREATER - return span1.Equals(span2, StringComparison.OrdinalIgnoreCase); -#else - return span1.ToString().Equals(span2.ToString(), StringComparison.OrdinalIgnoreCase); -#endif -#pragma warning restore IDE0022 // Use expression body for methods - } + => span1.Equals(span2, StringComparison.OrdinalIgnoreCase); /// /// int.Parse() a ReadOnlySpan<char>, with a fallback for older frameworks. /// /// The to parse. /// The parsed . - private static int ParseInt32(ReadOnlySpan span) - { -#pragma warning disable IDE0022 // Use expression body for methods -#if NETSTANDARD2_1 || NETCOREAPP2_1_OR_GREATER - return int.Parse(span); -#else - return int.Parse(span.ToString()); -#endif -#pragma warning restore IDE0022 // Use expression body for methods - } + private static int ParseInt32(ReadOnlySpan span) => int.Parse(span, provider: CultureInfo.InvariantCulture); /// /// Sets the in to , @@ -1298,7 +1270,7 @@ private static int ParseInt32(ReadOnlySpan span) /// If already contains an , /// controls whether existing exif tags in will be overwritten with any conflicting /// tags from . - private void MergeOrSetExifProfile(ImageMetadata metadata, ExifProfile newProfile, bool replaceExistingKeys) + private static void MergeOrSetExifProfile(ImageMetadata metadata, ExifProfile newProfile, bool replaceExistingKeys) { if (metadata.ExifProfile is null) { @@ -1338,13 +1310,13 @@ private void ReadInternationalTextChunk(ImageMetadata metadata, ReadOnlySpan PngConstants.MaxTextKeywordLength) + if (zeroIndexKeyword is < PngConstants.MinTextKeywordLength or > PngConstants.MaxTextKeywordLength) { return; } byte compressionFlag = data[zeroIndexKeyword + 1]; - if (!(compressionFlag == 0 || compressionFlag == 1)) + if (compressionFlag is not (0 or 1)) { return; } @@ -1357,7 +1329,7 @@ private void ReadInternationalTextChunk(ImageMetadata metadata, ReadOnlySpan keywordBytes = data.Slice(0, zeroIndexKeyword); - if (!this.TryReadTextKeyword(keywordBytes, out string keyword)) + ReadOnlySpan keywordBytes = data[..zeroIndexKeyword]; + if (!TryReadTextKeyword(keywordBytes, out string keyword)) { return; } @@ -1378,21 +1350,20 @@ private void ReadInternationalTextChunk(ImageMetadata metadata, ReadOnlySpan compressedData = data.Slice(dataStartIdx); + ReadOnlySpan compressedData = data[dataStartIdx..]; if (this.TryUncompressTextData(compressedData, PngConstants.TranslatedEncoding, out string uncompressed)) { pngMetadata.TextData.Add(new PngTextData(keyword, uncompressed, language, translatedKeyword)); } } - else if (this.IsXmpTextData(keywordBytes)) + else if (IsXmpTextData(keywordBytes)) { - var xmpProfile = new XmpProfile(data.Slice(dataStartIdx).ToArray()); - metadata.XmpProfile = xmpProfile; + metadata.XmpProfile = new XmpProfile(data[dataStartIdx..].ToArray()); } else { - string value = PngConstants.TranslatedEncoding.GetString(data.Slice(dataStartIdx)); + string value = PngConstants.TranslatedEncoding.GetString(data[dataStartIdx..]); pngMetadata.TextData.Add(new PngTextData(keyword, value, language, translatedKeyword)); } } @@ -1590,18 +1561,17 @@ private PngChunkType ReadChunkType() { return (PngChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.buffer); } - else - { - PngThrowHelper.ThrowInvalidChunkType(); - // The IDE cannot detect the throw here. - return default; - } + PngThrowHelper.ThrowInvalidChunkType(); + + // The IDE cannot detect the throw here. + return default; } /// /// Attempts to read the length of the next chunk. /// + /// The result length. If the return type is this parameter is passed uninitialized. /// /// Whether the length was read. /// @@ -1627,14 +1597,14 @@ private bool TryReadChunkLength(out int result) /// The keyword bytes. /// The name. /// True, if the keyword could be read and is valid. - private bool TryReadTextKeyword(ReadOnlySpan keywordBytes, out string name) + private static bool TryReadTextKeyword(ReadOnlySpan keywordBytes, out string name) { name = string.Empty; // Keywords shall contain only printable Latin-1. foreach (byte c in keywordBytes) { - if (!((c >= 32 && c <= 126) || (c >= 161 && c <= 255))) + if (c is not ((>= 32 and <= 126) or (>= 161 and <= 255))) { return false; } @@ -1642,21 +1612,15 @@ private bool TryReadTextKeyword(ReadOnlySpan keywordBytes, out string name // Keywords should not be empty or have leading or trailing whitespace. name = PngConstants.Encoding.GetString(keywordBytes); - if (string.IsNullOrWhiteSpace(name) || name.StartsWith(" ") || name.EndsWith(" ")) - { - return false; - } - - return true; + return !string.IsNullOrWhiteSpace(name) + && !name.StartsWith(" ", StringComparison.Ordinal) + && !name.EndsWith(" ", StringComparison.Ordinal); } - private bool IsXmpTextData(ReadOnlySpan keywordBytes) => keywordBytes.SequenceEqual(PngConstants.XmpKeyword); + private static bool IsXmpTextData(ReadOnlySpan keywordBytes) + => keywordBytes.SequenceEqual(PngConstants.XmpKeyword); private void SwapScanlineBuffers() - { - IMemoryOwner temp = this.previousScanline; - this.previousScanline = this.scanline; - this.scanline = temp; - } + => (this.scanline, this.previousScanline) = (this.previousScanline, this.scanline); } } diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 9ae8f299a2..7ba28393db 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -8,6 +8,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Compression.Zlib; using SixLabors.ImageSharp.Formats.Png.Chunks; using SixLabors.ImageSharp.Formats.Png.Filters; @@ -244,62 +245,56 @@ private void CollectGrayscaleBytes(ReadOnlySpan rowSpan) } } } - else + else if (this.bitDepth == 8) { - if (this.bitDepth == 8) - { - // 8 bit grayscale - PixelOperations.Instance.ToL8Bytes( - this.configuration, - rowSpan, - rawScanlineSpan, - rowSpan.Length); - } - else - { - // 1, 2, and 4 bit grayscale - using IMemoryOwner temp = this.memoryAllocator.Allocate(rowSpan.Length, AllocationOptions.Clean); - int scaleFactor = 255 / (ColorNumerics.GetColorCountForBitDepth(this.bitDepth) - 1); - Span tempSpan = temp.GetSpan(); - - // We need to first create an array of luminance bytes then scale them down to the correct bit depth. - PixelOperations.Instance.ToL8Bytes( - this.configuration, - rowSpan, - tempSpan, - rowSpan.Length); - PngEncoderHelpers.ScaleDownFrom8BitArray(tempSpan, rawScanlineSpan, this.bitDepth, scaleFactor); - } - } - } - else - { - if (this.use16Bit) - { - // 16 bit grayscale + alpha - using IMemoryOwner laBuffer = this.memoryAllocator.Allocate(rowSpan.Length); - Span laSpan = laBuffer.GetSpan(); - ref La32 laRef = ref MemoryMarshal.GetReference(laSpan); - PixelOperations.Instance.ToLa32(this.configuration, rowSpan, laSpan); - - // Can't map directly to byte array as it's big endian. - for (int x = 0, o = 0; x < laSpan.Length; x++, o += 4) - { - La32 la = Unsafe.Add(ref laRef, x); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), la.L); - BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), la.A); - } + // 8 bit grayscale + PixelOperations.Instance.ToL8Bytes( + this.configuration, + rowSpan, + rawScanlineSpan, + rowSpan.Length); } else { - // 8 bit grayscale + alpha - PixelOperations.Instance.ToLa16Bytes( + // 1, 2, and 4 bit grayscale + using IMemoryOwner temp = this.memoryAllocator.Allocate(rowSpan.Length, AllocationOptions.Clean); + int scaleFactor = 255 / (ColorNumerics.GetColorCountForBitDepth(this.bitDepth) - 1); + Span tempSpan = temp.GetSpan(); + + // We need to first create an array of luminance bytes then scale them down to the correct bit depth. + PixelOperations.Instance.ToL8Bytes( this.configuration, rowSpan, - rawScanlineSpan, + tempSpan, rowSpan.Length); + PngEncoderHelpers.ScaleDownFrom8BitArray(tempSpan, rawScanlineSpan, this.bitDepth, scaleFactor); } } + else if (this.use16Bit) + { + // 16 bit grayscale + alpha + using IMemoryOwner laBuffer = this.memoryAllocator.Allocate(rowSpan.Length); + Span laSpan = laBuffer.GetSpan(); + ref La32 laRef = ref MemoryMarshal.GetReference(laSpan); + PixelOperations.Instance.ToLa32(this.configuration, rowSpan, laSpan); + + // Can't map directly to byte array as it's big endian. + for (int x = 0, o = 0; x < laSpan.Length; x++, o += 4) + { + La32 la = Unsafe.Add(ref laRef, x); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), la.L); + BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), la.A); + } + } + else + { + // 8 bit grayscale + alpha + PixelOperations.Instance.ToLa16Bytes( + this.configuration, + rowSpan, + rawScanlineSpan, + rowSpan.Length); + } } /// @@ -315,7 +310,7 @@ private void CollectTPixelBytes(ReadOnlySpan rowSpan) switch (this.bytesPerPixel) { case 4: - { + // 8 bit Rgba PixelOperations.Instance.ToRgba32Bytes( this.configuration, @@ -323,10 +318,9 @@ private void CollectTPixelBytes(ReadOnlySpan rowSpan) rawScanlineSpan, rowSpan.Length); break; - } case 3: - { + // 8 bit Rgb PixelOperations.Instance.ToRgb24Bytes( this.configuration, @@ -334,10 +328,9 @@ private void CollectTPixelBytes(ReadOnlySpan rowSpan) rawScanlineSpan, rowSpan.Length); break; - } case 8: - { + // 16 bit Rgba using (IMemoryOwner rgbaBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { @@ -357,10 +350,9 @@ private void CollectTPixelBytes(ReadOnlySpan rowSpan) } break; - } default: - { + // 16 bit Rgb using (IMemoryOwner rgbBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { @@ -379,7 +371,6 @@ private void CollectTPixelBytes(ReadOnlySpan rowSpan) } break; - } } } @@ -412,8 +403,6 @@ private void CollectPixelBytes(ReadOnlySpan rowSpan, IndexedImag case PngColorType.GrayscaleWithAlpha: this.CollectGrayscaleBytes(rowSpan); break; - case PngColorType.Rgb: - case PngColorType.RgbWithAlpha: default: this.CollectTPixelBytes(rowSpan); break; @@ -423,6 +412,8 @@ private void CollectPixelBytes(ReadOnlySpan rowSpan, IndexedImag /// /// Apply the line filter for the raw scanline to enable better compression. /// + /// The filtered buffer. + /// Used for attempting optimized filtering. private void FilterPixelBytes(ref Span filter, ref Span attempt) { switch (this.options.FilterMethod) @@ -445,7 +436,6 @@ private void FilterPixelBytes(ref Span filter, ref Span attempt) case PngFilterMethod.Paeth: PaethFilter.Encode(this.currentScanline.GetSpan(), this.previousScanline.GetSpan(), filter, this.bytesPerPixel, out int _); break; - case PngFilterMethod.Adaptive: default: this.ApplyOptimalFilteredScanline(ref filter, ref attempt); break; @@ -502,6 +492,8 @@ private void EncodeAdam7IndexedPixelRow( /// Applies all PNG filters to the given scanline and returns the filtered scanline that is deemed /// to be most compressible, using lowest total variation as proxy for compressibility. /// + /// The filtered buffer. + /// Used for attempting optimized filtering. private void ApplyOptimalFilteredScanline(ref Span filter, ref Span attempt) { // Palette images don't compress well with adaptive filtering. @@ -520,27 +512,27 @@ private void ApplyOptimalFilteredScanline(ref Span filter, ref Span if (sum < min) { min = sum; - SwapSpans(ref filter, ref attempt); + RuntimeUtility.Swap(ref filter, ref attempt); } UpFilter.Encode(current, previous, attempt, out sum); if (sum < min) { min = sum; - SwapSpans(ref filter, ref attempt); + RuntimeUtility.Swap(ref filter, ref attempt); } AverageFilter.Encode(current, previous, attempt, this.bytesPerPixel, out sum); if (sum < min) { min = sum; - SwapSpans(ref filter, ref attempt); + RuntimeUtility.Swap(ref filter, ref attempt); } PaethFilter.Encode(current, previous, attempt, this.bytesPerPixel, out sum); if (sum < min) { - SwapSpans(ref filter, ref attempt); + RuntimeUtility.Swap(ref filter, ref attempt); } } @@ -550,7 +542,7 @@ private void ApplyOptimalFilteredScanline(ref Span filter, ref Span /// The containing image data. private void WriteHeaderChunk(Stream stream) { - var header = new PngHeader( + PngHeader header = new( width: this.width, height: this.height, bitDepth: this.bitDepth, @@ -687,25 +679,24 @@ private void WriteXmpChunk(Stream stream, ImageMetadata meta) } int payloadLength = xmpData.Length + PngConstants.XmpKeyword.Length + iTxtHeaderSize; - using (IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength)) - { - Span payload = owner.GetSpan(); - PngConstants.XmpKeyword.CopyTo(payload); - int bytesWritten = PngConstants.XmpKeyword.Length; - - // Write the iTxt header (all zeros in this case). - Span iTxtHeader = payload.Slice(bytesWritten); - iTxtHeader[4] = 0; - iTxtHeader[3] = 0; - iTxtHeader[2] = 0; - iTxtHeader[1] = 0; - iTxtHeader[0] = 0; - bytesWritten += 5; - - // And the XMP data itself. - xmpData.CopyTo(payload.Slice(bytesWritten)); - this.WriteChunk(stream, PngChunkType.InternationalText, payload); - } + + using IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength); + Span payload = owner.GetSpan(); + PngConstants.XmpKeyword.CopyTo(payload); + int bytesWritten = PngConstants.XmpKeyword.Length; + + // Write the iTxt header (all zeros in this case). + Span iTxtHeader = payload[bytesWritten..]; + iTxtHeader[4] = 0; + iTxtHeader[3] = 0; + iTxtHeader[2] = 0; + iTxtHeader[1] = 0; + iTxtHeader[0] = 0; + bytesWritten += 5; + + // And the XMP data itself. + xmpData.CopyTo(payload[bytesWritten..]); + this.WriteChunk(stream, PngChunkType.InternationalText, payload); } /// @@ -724,16 +715,15 @@ private void WriteColorProfileChunk(Stream stream, ImageMetadata metaData) byte[] compressedData = this.GetZlibCompressedBytes(iccProfileBytes); int payloadLength = ColorProfileName.Length + compressedData.Length + 2; - using (IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength)) - { - Span outputBytes = owner.GetSpan(); - PngConstants.Encoding.GetBytes(ColorProfileName).CopyTo(outputBytes); - int bytesWritten = ColorProfileName.Length; - outputBytes[bytesWritten++] = 0; // Null separator. - outputBytes[bytesWritten++] = 0; // Compression. - compressedData.CopyTo(outputBytes.Slice(bytesWritten)); - this.WriteChunk(stream, PngChunkType.EmbeddedColorProfile, outputBytes); - } + + using IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength); + Span outputBytes = owner.GetSpan(); + PngConstants.Encoding.GetBytes(ColorProfileName).CopyTo(outputBytes); + int bytesWritten = ColorProfileName.Length; + outputBytes[bytesWritten++] = 0; // Null separator. + outputBytes[bytesWritten++] = 0; // Compression. + compressedData.CopyTo(outputBytes[bytesWritten..]); + this.WriteChunk(stream, PngChunkType.EmbeddedColorProfile, outputBytes); } /// @@ -749,21 +739,21 @@ private void WriteTextChunks(Stream stream, PngMetadata meta) return; } - const int MaxLatinCode = 255; + const int maxLatinCode = 255; for (int i = 0; i < meta.TextData.Count; i++) { PngTextData textData = meta.TextData[i]; bool hasUnicodeCharacters = false; - foreach (var c in textData.Value) + foreach (char c in textData.Value) { - if (c > MaxLatinCode) + if (c > maxLatinCode) { hasUnicodeCharacters = true; break; } } - if (hasUnicodeCharacters || (!string.IsNullOrWhiteSpace(textData.LanguageTag) || !string.IsNullOrWhiteSpace(textData.TranslatedKeyword))) + if (hasUnicodeCharacters || !string.IsNullOrWhiteSpace(textData.LanguageTag) || !string.IsNullOrWhiteSpace(textData.TranslatedKeyword)) { // Write iTXt chunk. byte[] keywordBytes = PngConstants.Encoding.GetBytes(textData.Keyword); @@ -775,65 +765,59 @@ private void WriteTextChunks(Stream stream, PngMetadata meta) byte[] languageTag = PngConstants.LanguageEncoding.GetBytes(textData.LanguageTag); int payloadLength = keywordBytes.Length + textBytes.Length + translatedKeyword.Length + languageTag.Length + 5; - using (IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength)) - { - Span outputBytes = owner.GetSpan(); - keywordBytes.CopyTo(outputBytes); - int bytesWritten = keywordBytes.Length; - outputBytes[bytesWritten++] = 0; - if (textData.Value.Length > this.options.TextCompressionThreshold) - { - // Indicate that the text is compressed. - outputBytes[bytesWritten++] = 1; - } - else - { - outputBytes[bytesWritten++] = 0; - } - outputBytes[bytesWritten++] = 0; - languageTag.CopyTo(outputBytes.Slice(bytesWritten)); - bytesWritten += languageTag.Length; - outputBytes[bytesWritten++] = 0; - translatedKeyword.CopyTo(outputBytes.Slice(bytesWritten)); - bytesWritten += translatedKeyword.Length; - outputBytes[bytesWritten++] = 0; - textBytes.CopyTo(outputBytes.Slice(bytesWritten)); - this.WriteChunk(stream, PngChunkType.InternationalText, outputBytes); - } - } - else - { + using IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength); + Span outputBytes = owner.GetSpan(); + keywordBytes.CopyTo(outputBytes); + int bytesWritten = keywordBytes.Length; + outputBytes[bytesWritten++] = 0; if (textData.Value.Length > this.options.TextCompressionThreshold) { - // Write zTXt chunk. - byte[] compressedData = this.GetZlibCompressedBytes(PngConstants.Encoding.GetBytes(textData.Value)); - int payloadLength = textData.Keyword.Length + compressedData.Length + 2; - using (IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength)) - { - Span outputBytes = owner.GetSpan(); - PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes); - int bytesWritten = textData.Keyword.Length; - outputBytes[bytesWritten++] = 0; // Null separator. - outputBytes[bytesWritten++] = 0; // Compression. - compressedData.CopyTo(outputBytes.Slice(bytesWritten)); - this.WriteChunk(stream, PngChunkType.CompressedText, outputBytes); - } + // Indicate that the text is compressed. + outputBytes[bytesWritten++] = 1; } else { - // Write tEXt chunk. - int payloadLength = textData.Keyword.Length + textData.Value.Length + 1; - using (IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength)) - { - Span outputBytes = owner.GetSpan(); - PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes); - int bytesWritten = textData.Keyword.Length; - outputBytes[bytesWritten++] = 0; - PngConstants.Encoding.GetBytes(textData.Value).CopyTo(outputBytes.Slice(bytesWritten)); - this.WriteChunk(stream, PngChunkType.Text, outputBytes); - } + outputBytes[bytesWritten++] = 0; } + + outputBytes[bytesWritten++] = 0; + languageTag.CopyTo(outputBytes[bytesWritten..]); + bytesWritten += languageTag.Length; + outputBytes[bytesWritten++] = 0; + translatedKeyword.CopyTo(outputBytes[bytesWritten..]); + bytesWritten += translatedKeyword.Length; + outputBytes[bytesWritten++] = 0; + textBytes.CopyTo(outputBytes[bytesWritten..]); + this.WriteChunk(stream, PngChunkType.InternationalText, outputBytes); + } + else if (textData.Value.Length > this.options.TextCompressionThreshold) + { + // Write zTXt chunk. + byte[] compressedData = this.GetZlibCompressedBytes(PngConstants.Encoding.GetBytes(textData.Value)); + int payloadLength = textData.Keyword.Length + compressedData.Length + 2; + + using IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength); + Span outputBytes = owner.GetSpan(); + PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes); + int bytesWritten = textData.Keyword.Length; + outputBytes[bytesWritten++] = 0; // Null separator. + outputBytes[bytesWritten++] = 0; // Compression. + compressedData.CopyTo(outputBytes[bytesWritten..]); + this.WriteChunk(stream, PngChunkType.CompressedText, outputBytes); + } + else + { + // Write tEXt chunk. + int payloadLength = textData.Keyword.Length + textData.Value.Length + 1; + + using IMemoryOwner owner = this.memoryAllocator.Allocate(payloadLength); + Span outputBytes = owner.GetSpan(); + PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes); + int bytesWritten = textData.Keyword.Length; + outputBytes[bytesWritten++] = 0; + PngConstants.Encoding.GetBytes(textData.Value).CopyTo(outputBytes[bytesWritten..]); + this.WriteChunk(stream, PngChunkType.Text, outputBytes); } } } @@ -845,15 +829,13 @@ private void WriteTextChunks(Stream stream, PngMetadata meta) /// The compressed byte array. private byte[] GetZlibCompressedBytes(byte[] dataBytes) { - using (var memoryStream = new MemoryStream()) + using MemoryStream memoryStream = new(); + using (ZlibDeflateStream deflateStream = new(this.memoryAllocator, memoryStream, this.options.CompressionLevel)) { - using (var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, this.options.CompressionLevel)) - { - deflateStream.Write(dataBytes); - } - - return memoryStream.ToArray(); + deflateStream.Write(dataBytes); } + + return memoryStream.ToArray(); } /// @@ -943,9 +925,9 @@ private void WriteDataChunks(Image pixels, IndexedImageFrame data, int o uint crc = Crc32.Calculate(this.buffer.AsSpan(4, 4)); // Write the type buffer - if (data != null && length > 0) + if (data.Length > 0 && length > 0) { stream.Write(data, offset, length); @@ -1206,18 +1188,12 @@ private int CalculateScanlineLength(int width) return scanlineLength / mod; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SwapScanlineBuffers() { - IMemoryOwner temp = this.previousScanline; - this.previousScanline = this.currentScanline; - this.currentScanline = temp; - } - - private static void SwapSpans(ref Span a, ref Span b) - { - Span t = b; - b = a; - a = t; + ref IMemoryOwner prev = ref this.previousScanline; + ref IMemoryOwner current = ref this.currentScanline; + RuntimeUtility.Swap(ref prev, ref current); } } } diff --git a/src/ImageSharp/Formats/Png/PngHeader.cs b/src/ImageSharp/Formats/Png/PngHeader.cs index da747a1897..3e4609aad3 100644 --- a/src/ImageSharp/Formats/Png/PngHeader.cs +++ b/src/ImageSharp/Formats/Png/PngHeader.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -104,7 +104,7 @@ public void Validate() } // The png specification only defines 'None' and 'Adam7' as interlaced methods. - if (this.InterlaceMethod != PngInterlaceMode.None && this.InterlaceMethod != PngInterlaceMode.Adam7) + if (this.InterlaceMethod is not PngInterlaceMode.None and not PngInterlaceMode.Adam7) { throw new NotSupportedException($"Invalid interlace method. Expected 'None' or 'Adam7'. Was '{this.InterlaceMethod}'."); } @@ -116,7 +116,7 @@ public void Validate() /// The buffer to write to. public void WriteTo(Span buffer) { - BinaryPrimitives.WriteInt32BigEndian(buffer.Slice(0, 4), this.Width); + BinaryPrimitives.WriteInt32BigEndian(buffer[..4], this.Width); BinaryPrimitives.WriteInt32BigEndian(buffer.Slice(4, 4), this.Height); buffer[8] = this.BitDepth; @@ -132,15 +132,13 @@ public void WriteTo(Span buffer) /// The data to parse. /// The parsed PngHeader. public static PngHeader Parse(ReadOnlySpan data) - { - return new PngHeader( - width: BinaryPrimitives.ReadInt32BigEndian(data.Slice(0, 4)), - height: BinaryPrimitives.ReadInt32BigEndian(data.Slice(4, 4)), - bitDepth: data[8], - colorType: (PngColorType)data[9], - compressionMethod: data[10], - filterMethod: data[11], - interlaceMethod: (PngInterlaceMode)data[12]); - } + => new( + width: BinaryPrimitives.ReadInt32BigEndian(data[..4]), + height: BinaryPrimitives.ReadInt32BigEndian(data.Slice(4, 4)), + bitDepth: data[8], + colorType: (PngColorType)data[9], + compressionMethod: data[10], + filterMethod: data[11], + interlaceMethod: (PngInterlaceMode)data[12]); } } diff --git a/src/ImageSharp/Formats/Png/PngTextData.cs b/src/ImageSharp/Formats/Png/PngTextData.cs index 3d495cba6e..7db26b60be 100644 --- a/src/ImageSharp/Formats/Png/PngTextData.cs +++ b/src/ImageSharp/Formats/Png/PngTextData.cs @@ -72,9 +72,7 @@ public PngTextData(string keyword, string value, string languageTag, string tran /// True if the current left is equal to the parameter; otherwise, false. /// public static bool operator ==(PngTextData left, PngTextData right) - { - return left.Equals(right); - } + => left.Equals(right); /// /// Compares two objects. The result specifies whether the values @@ -90,9 +88,7 @@ public PngTextData(string keyword, string value, string languageTag, string tran /// True if the current left is unequal to the parameter; otherwise, false. /// public static bool operator !=(PngTextData left, PngTextData right) - { - return !(left == right); - } + => !(left == right); /// /// Indicates whether this instance and a specified object are equal. @@ -105,9 +101,7 @@ public PngTextData(string keyword, string value, string languageTag, string tran /// same value; otherwise, false. /// public override bool Equals(object obj) - { - return obj is PngTextData other && this.Equals(other); - } + => obj is PngTextData other && this.Equals(other); /// /// Returns the hash code for this instance. @@ -115,7 +109,8 @@ public override bool Equals(object obj) /// /// A 32-bit signed integer that is the hash code for this instance. /// - public override int GetHashCode() => HashCode.Combine(this.Keyword, this.Value, this.LanguageTag, this.TranslatedKeyword); + public override int GetHashCode() + => HashCode.Combine(this.Keyword, this.Value, this.LanguageTag, this.TranslatedKeyword); /// /// Returns the fully qualified type name of this instance. @@ -123,7 +118,8 @@ public override bool Equals(object obj) /// /// A containing a fully qualified type name. /// - public override string ToString() => $"PngTextData [ Name={this.Keyword}, Value={this.Value} ]"; + public override string ToString() + => $"PngTextData [ Name={this.Keyword}, Value={this.Value} ]"; /// /// Indicates whether the current object is equal to another object of the same type. @@ -133,11 +129,9 @@ public override bool Equals(object obj) /// /// An object to compare with this object. public bool Equals(PngTextData other) - { - return this.Keyword.Equals(other.Keyword) - && this.Value.Equals(other.Value) - && this.LanguageTag.Equals(other.LanguageTag) - && this.TranslatedKeyword.Equals(other.TranslatedKeyword); - } + => this.Keyword.Equals(other.Keyword, StringComparison.OrdinalIgnoreCase) + && this.Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase) + && this.LanguageTag.Equals(other.LanguageTag, StringComparison.OrdinalIgnoreCase) + && this.TranslatedKeyword.Equals(other.TranslatedKeyword, StringComparison.OrdinalIgnoreCase); } } diff --git a/src/ImageSharp/Formats/Png/PngThrowHelper.cs b/src/ImageSharp/Formats/Png/PngThrowHelper.cs index 7cf954f1d6..c62775f87a 100644 --- a/src/ImageSharp/Formats/Png/PngThrowHelper.cs +++ b/src/ImageSharp/Formats/Png/PngThrowHelper.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Formats.Png @@ -11,31 +12,40 @@ namespace SixLabors.ImageSharp.Formats.Png /// internal static class PngThrowHelper { + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowInvalidImageContentException(string errorMessage, Exception innerException) => throw new InvalidImageContentException(errorMessage, innerException); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowNoHeader() => throw new InvalidImageContentException("PNG Image does not contain a header chunk"); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowNoData() => throw new InvalidImageContentException("PNG Image does not contain a data chunk"); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowMissingPalette() => throw new InvalidImageContentException("PNG Image does not contain a palette chunk"); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowInvalidChunkType() => throw new InvalidImageContentException("Invalid PNG data."); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowInvalidChunkType(string message) => throw new InvalidImageContentException(message); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowInvalidChunkCrc(string chunkTypeName) => throw new InvalidImageContentException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!"); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowNotSupportedColor() => throw new NotSupportedException("Unsupported PNG color type"); + [DoesNotReturn] [MethodImpl(InliningOptions.ColdPath)] public static void ThrowUnknownFilter() => throw new InvalidImageContentException("Unknown filter type."); } diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs index 0f46d5953e..d901759d1f 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -826,7 +826,7 @@ private void UncompressRle(int width, int height, Span buffer, int bytesPe int bufferIdx = uncompressedPixels * bytesPerPixel; for (int i = 0; i < runLength + 1; i++, uncompressedPixels++) { - pixel.CopyTo(buffer.Slice(bufferIdx)); + pixel.CopyTo(buffer[bufferIdx..]); bufferIdx += bytesPerPixel; } } @@ -843,7 +843,7 @@ private void UncompressRle(int width, int height, Span buffer, int bytesPe TgaThrowHelper.ThrowInvalidImageContentException("Not enough data to read a pixel from the stream"); } - pixel.CopyTo(buffer.Slice(bufferIdx)); + pixel.CopyTo(buffer[bufferIdx..]); bufferIdx += bytesPerPixel; } } diff --git a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs index fa0ea6f90b..5cfdf3022c 100644 --- a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs @@ -5,6 +5,7 @@ using System.Buffers; using System.Buffers.Binary; using System.IO; +using System.Numerics; using System.Runtime.CompilerServices; using System.Threading; using SixLabors.ImageSharp.Advanced; @@ -99,7 +100,7 @@ public void Encode(Image image, Stream stream, CancellationToken imageDescriptor |= 0x1; } - var fileHeader = new TgaFileHeader( + TgaFileHeader fileHeader = new( idLength: 0, colorMapType: 0, imageType: imageType, @@ -158,8 +159,6 @@ private void WriteImage(Stream stream, ImageFrame image) case TgaBitsPerPixel.Pixel32: this.Write32Bit(stream, pixels); break; - default: - break; } } @@ -181,7 +180,7 @@ private void WriteRunLengthEncodedImage(Stream stream, ImageFrame 0) { @@ -193,7 +192,7 @@ private void WriteRunLengthEncodedImage(Stream stream, ImageFrame(Stream stream, TPixel currentPixel, Rgba32 color break; case TgaBitsPerPixel.Pixel16: - var bgra5551 = new Bgra5551(color.ToVector4()); + Bgra5551 bgra5551 = new(color.ToVector4()); BinaryPrimitives.TryWriteInt16LittleEndian(this.buffer, (short)bgra5551.PackedValue); stream.WriteByte(this.buffer[0]); stream.WriteByte(this.buffer[1]); @@ -246,8 +245,6 @@ private void WritePixel(Stream stream, TPixel currentPixel, Rgba32 color stream.WriteByte(color.R); stream.WriteByte(color.A); break; - default: - break; } } @@ -258,7 +255,7 @@ private void WritePixel(Stream stream, TPixel currentPixel, Rgba32 color /// A pixel row of the image to encode. /// X coordinate to start searching for the same pixels. /// The number of equal pixels. - private byte FindEqualPixels(Span pixelRow, int xStart) + private static byte FindEqualPixels(Span pixelRow, int xStart) where TPixel : unmanaged, IPixel { byte equalPixelCount = 0; @@ -291,7 +288,7 @@ private byte FindEqualPixels(Span pixelRow, int xStart) /// A pixel row of the image to encode. /// X coordinate to start searching for the unequal pixels. /// The number of equal pixels. - private byte FindUnEqualPixels(Span pixelRow, int xStart) + private static byte FindUnEqualPixels(Span pixelRow, int xStart) where TPixel : unmanaged, IPixel { byte unEqualPixelCount = 0; @@ -419,12 +416,13 @@ private void Write32Bit(Stream stream, Buffer2D pixels) /// /// Convert the pixel values to grayscale using ITU-R Recommendation BT.709. /// + /// The type of pixel format. /// The pixel to get the luminance from. [MethodImpl(InliningOptions.ShortMethod)] public static int GetLuminance(TPixel sourcePixel) where TPixel : unmanaged, IPixel { - var vector = sourcePixel.ToVector4(); + Vector4 vector = sourcePixel.ToVector4(); return ColorNumerics.GetBT709Luminance(ref vector, 256); } } diff --git a/src/ImageSharp/Formats/Tga/TgaMetadata.cs b/src/ImageSharp/Formats/Tga/TgaMetadata.cs index a29eac21e4..61b92d7313 100644 --- a/src/ImageSharp/Formats/Tga/TgaMetadata.cs +++ b/src/ImageSharp/Formats/Tga/TgaMetadata.cs @@ -20,9 +20,7 @@ public TgaMetadata() /// /// The metadata to create an instance from. private TgaMetadata(TgaMetadata other) - { - this.BitsPerPixel = other.BitsPerPixel; - } + => this.BitsPerPixel = other.BitsPerPixel; /// /// Gets or sets the number of bits per pixel. @@ -30,9 +28,9 @@ private TgaMetadata(TgaMetadata other) public TgaBitsPerPixel BitsPerPixel { get; set; } = TgaBitsPerPixel.Pixel24; /// - /// Gets or sets the the number of alpha bits per pixel. + /// Gets or sets the number of alpha bits per pixel. /// - public byte AlphaChannelBits { get; set; } = 0; + public byte AlphaChannelBits { get; set; } /// public IDeepCloneable DeepClone() => new TgaMetadata(this); diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs index 01613222e3..472ceb21e4 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs @@ -39,7 +39,7 @@ public override void CompressStrip(Span rows, int height) { Span row = rows.Slice(i * this.BytesPerRow, this.BytesPerRow); int size = PackBitsWriter.PackBits(row, span); - this.Output.Write(span.Slice(0, size)); + this.Output.Write(span[..size]); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs index 06e2d663c9..5c9a707291 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs @@ -65,7 +65,7 @@ private static void WriteLiteralRun(ReadOnlySpan rowSpan, int end, int lit int literalRunStart = end - literalRunLength; sbyte runLength = (sbyte)(literalRunLength - 1); compressedRowSpan[compressedRowPos] = (byte)runLength; - rowSpan.Slice(literalRunStart, literalRunLength).CopyTo(compressedRowSpan.Slice(compressedRowPos + 1)); + rowSpan.Slice(literalRunStart, literalRunLength).CopyTo(compressedRowSpan[(compressedRowPos + 1)..]); } private static void WriteRun(ReadOnlySpan rowSpan, int start, int runLength, Span compressedRowSpan, int compressedRowPos) diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs index 11bc49f27e..7c3ecc643e 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs @@ -93,14 +93,14 @@ protected override void CompressStrip(Span pixelsAsGray, int height, Span< uint codeLength; if (runLength <= 63) { - code = this.GetTermCode(runLength, out codeLength, isWhiteRun); + code = GetTermCode(runLength, out codeLength, isWhiteRun); this.WriteCode(codeLength, code, compressedData); x += (int)runLength; } else { - runLength = this.GetBestFittingMakeupRunLength(runLength); - code = this.GetMakeupCode(runLength, out codeLength, isWhiteRun); + runLength = GetBestFittingMakeupRunLength(runLength); + code = GetMakeupCode(runLength, out codeLength, isWhiteRun); this.WriteCode(codeLength, code, compressedData); x += (int)runLength; diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs index 7e0b6042cb..99b4a9fccc 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs @@ -61,12 +61,12 @@ protected override void CompressStrip(Span pixelsAsGray, int height, Span< { Span row = pixelsAsGray.Slice(y * this.Width, this.Width); uint a0 = 0; - uint a1 = row[0] == 0 ? 0 : this.FindRunEnd(row, 0); - uint b1 = referenceLine[0] == 0 ? 0 : this.FindRunEnd(referenceLine, 0); + uint a1 = row[0] == 0 ? 0 : FindRunEnd(row, 0); + uint b1 = referenceLine[0] == 0 ? 0 : FindRunEnd(referenceLine, 0); while (true) { - uint b2 = this.FindRunEnd(referenceLine, b1); + uint b2 = FindRunEnd(referenceLine, b1); if (b2 < a1) { // Pass mode. @@ -85,7 +85,7 @@ protected override void CompressStrip(Span pixelsAsGray, int height, Span< d = -(int)(a1 - b1); } - if ((d >= -3) && (d <= 3)) + if (d is >= -3 and <= 3) { // Vertical mode. (uint length, uint code) = VerticalCodes[d + 3]; @@ -97,7 +97,7 @@ protected override void CompressStrip(Span pixelsAsGray, int height, Span< // Horizontal mode. this.WriteCode(3, 1, compressedData); - uint a2 = this.FindRunEnd(row, a1); + uint a2 = FindRunEnd(row, a1); if ((a0 + a1 == 0) || (row[(int)a0] != 0)) { this.WriteRun(a1 - a0, true, compressedData); @@ -119,9 +119,9 @@ protected override void CompressStrip(Span pixelsAsGray, int height, Span< } byte thisPixel = row[(int)a0]; - a1 = this.FindRunEnd(row, a0, thisPixel); - b1 = this.FindRunEnd(referenceLine, a0, (byte)~thisPixel); - b1 = this.FindRunEnd(referenceLine, b1, thisPixel); + a1 = FindRunEnd(row, a0, thisPixel); + b1 = FindRunEnd(referenceLine, a0, (byte)~thisPixel); + b1 = FindRunEnd(referenceLine, b1, thisPixel); } // This row is now the reference line. @@ -149,14 +149,14 @@ protected override void Dispose(bool disposing) /// The index of the first pixel at or after /// that does not match , or the length of , /// whichever comes first. - private uint FindRunEnd(Span row, uint startIndex, byte? color = null) + private static uint FindRunEnd(Span row, uint startIndex, byte? color = null) { if (startIndex >= row.Length) { return (uint)row.Length; } - byte colorValue = color.GetValueOrDefault(row[(int)startIndex]); + byte colorValue = color ?? row[(int)startIndex]; for (int i = (int)startIndex; i < row.Length; i++) { if (row[i] != colorValue) @@ -188,13 +188,13 @@ private void WriteRun(uint runLength, bool isWhiteRun, Span compressedData uint codeLength; while (runLength > 63) { - uint makeupLength = this.GetBestFittingMakeupRunLength(runLength); - code = this.GetMakeupCode(makeupLength, out codeLength, isWhiteRun); + uint makeupLength = GetBestFittingMakeupRunLength(runLength); + code = GetMakeupCode(makeupLength, out codeLength, isWhiteRun); this.WriteCode(codeLength, code, compressedData); runLength -= makeupLength; } - code = this.GetTermCode(runLength, out codeLength, isWhiteRun); + code = GetTermCode(runLength, out codeLength, isWhiteRun); this.WriteCode(codeLength, code, compressedData); } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs b/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs index 511c6914f3..c43f24774b 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs @@ -195,191 +195,191 @@ protected TiffCcittCompressor(Stream output, MemoryAllocator allocator, int widt this.bitPosition = 0; } - private uint GetWhiteMakeupCode(uint runLength, out uint codeLength) + private static uint GetWhiteMakeupCode(uint runLength, out uint codeLength) { codeLength = 0; - if (WhiteLen5MakeupCodes.ContainsKey(runLength)) + if (WhiteLen5MakeupCodes.TryGetValue(runLength, out uint value)) { codeLength = 5; - return WhiteLen5MakeupCodes[runLength]; + return value; } - if (WhiteLen6MakeupCodes.ContainsKey(runLength)) + if (WhiteLen6MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 6; - return WhiteLen6MakeupCodes[runLength]; + return value; } - if (WhiteLen7MakeupCodes.ContainsKey(runLength)) + if (WhiteLen7MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 7; - return WhiteLen7MakeupCodes[runLength]; + return value; } - if (WhiteLen8MakeupCodes.ContainsKey(runLength)) + if (WhiteLen8MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 8; - return WhiteLen8MakeupCodes[runLength]; + return value; } - if (WhiteLen9MakeupCodes.ContainsKey(runLength)) + if (WhiteLen9MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 9; - return WhiteLen9MakeupCodes[runLength]; + return value; } - if (WhiteLen11MakeupCodes.ContainsKey(runLength)) + if (WhiteLen11MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 11; - return WhiteLen11MakeupCodes[runLength]; + return value; } - if (WhiteLen12MakeupCodes.ContainsKey(runLength)) + if (WhiteLen12MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 12; - return WhiteLen12MakeupCodes[runLength]; + return value; } return 0; } - private uint GetBlackMakeupCode(uint runLength, out uint codeLength) + private static uint GetBlackMakeupCode(uint runLength, out uint codeLength) { codeLength = 0; - if (BlackLen10MakeupCodes.ContainsKey(runLength)) + if (BlackLen10MakeupCodes.TryGetValue(runLength, out uint value)) { codeLength = 10; - return BlackLen10MakeupCodes[runLength]; + return value; } - if (BlackLen11MakeupCodes.ContainsKey(runLength)) + if (BlackLen11MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 11; - return BlackLen11MakeupCodes[runLength]; + return value; } - if (BlackLen12MakeupCodes.ContainsKey(runLength)) + if (BlackLen12MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 12; - return BlackLen12MakeupCodes[runLength]; + return value; } - if (BlackLen13MakeupCodes.ContainsKey(runLength)) + if (BlackLen13MakeupCodes.TryGetValue(runLength, out value)) { codeLength = 13; - return BlackLen13MakeupCodes[runLength]; + return value; } return 0; } - private uint GetWhiteTermCode(uint runLength, out uint codeLength) + private static uint GetWhiteTermCode(uint runLength, out uint codeLength) { codeLength = 0; - if (WhiteLen4TermCodes.ContainsKey(runLength)) + if (WhiteLen4TermCodes.TryGetValue(runLength, out uint value)) { codeLength = 4; - return WhiteLen4TermCodes[runLength]; + return value; } - if (WhiteLen5TermCodes.ContainsKey(runLength)) + if (WhiteLen5TermCodes.TryGetValue(runLength, out value)) { codeLength = 5; - return WhiteLen5TermCodes[runLength]; + return value; } - if (WhiteLen6TermCodes.ContainsKey(runLength)) + if (WhiteLen6TermCodes.TryGetValue(runLength, out value)) { codeLength = 6; - return WhiteLen6TermCodes[runLength]; + return value; } - if (WhiteLen7TermCodes.ContainsKey(runLength)) + if (WhiteLen7TermCodes.TryGetValue(runLength, out value)) { codeLength = 7; - return WhiteLen7TermCodes[runLength]; + return value; } - if (WhiteLen8TermCodes.ContainsKey(runLength)) + if (WhiteLen8TermCodes.TryGetValue(runLength, out value)) { codeLength = 8; - return WhiteLen8TermCodes[runLength]; + return value; } return 0; } - private uint GetBlackTermCode(uint runLength, out uint codeLength) + private static uint GetBlackTermCode(uint runLength, out uint codeLength) { codeLength = 0; - if (BlackLen2TermCodes.ContainsKey(runLength)) + if (BlackLen2TermCodes.TryGetValue(runLength, out uint value)) { codeLength = 2; - return BlackLen2TermCodes[runLength]; + return value; } - if (BlackLen3TermCodes.ContainsKey(runLength)) + if (BlackLen3TermCodes.TryGetValue(runLength, out value)) { codeLength = 3; - return BlackLen3TermCodes[runLength]; + return value; } - if (BlackLen4TermCodes.ContainsKey(runLength)) + if (BlackLen4TermCodes.TryGetValue(runLength, out value)) { codeLength = 4; - return BlackLen4TermCodes[runLength]; + return value; } - if (BlackLen5TermCodes.ContainsKey(runLength)) + if (BlackLen5TermCodes.TryGetValue(runLength, out value)) { codeLength = 5; - return BlackLen5TermCodes[runLength]; + return value; } - if (BlackLen6TermCodes.ContainsKey(runLength)) + if (BlackLen6TermCodes.TryGetValue(runLength, out value)) { codeLength = 6; - return BlackLen6TermCodes[runLength]; + return value; } - if (BlackLen7TermCodes.ContainsKey(runLength)) + if (BlackLen7TermCodes.TryGetValue(runLength, out value)) { codeLength = 7; - return BlackLen7TermCodes[runLength]; + return value; } - if (BlackLen8TermCodes.ContainsKey(runLength)) + if (BlackLen8TermCodes.TryGetValue(runLength, out value)) { codeLength = 8; - return BlackLen8TermCodes[runLength]; + return value; } - if (BlackLen9TermCodes.ContainsKey(runLength)) + if (BlackLen9TermCodes.TryGetValue(runLength, out value)) { codeLength = 9; - return BlackLen9TermCodes[runLength]; + return value; } - if (BlackLen10TermCodes.ContainsKey(runLength)) + if (BlackLen10TermCodes.TryGetValue(runLength, out value)) { codeLength = 10; - return BlackLen10TermCodes[runLength]; + return value; } - if (BlackLen11TermCodes.ContainsKey(runLength)) + if (BlackLen11TermCodes.TryGetValue(runLength, out value)) { codeLength = 11; - return BlackLen11TermCodes[runLength]; + return value; } - if (BlackLen12TermCodes.ContainsKey(runLength)) + if (BlackLen12TermCodes.TryGetValue(runLength, out value)) { codeLength = 12; - return BlackLen12TermCodes[runLength]; + return value; } return 0; @@ -390,7 +390,7 @@ private uint GetBlackTermCode(uint runLength, out uint codeLength) /// /// A run length needing a makeup code /// The makeup length for . - protected uint GetBestFittingMakeupRunLength(uint runLength) + protected static uint GetBestFittingMakeupRunLength(uint runLength) { DebugGuard.MustBeGreaterThanOrEqualTo(runLength, MakeupRunLength[0], nameof(runLength)); @@ -402,7 +402,7 @@ protected uint GetBestFittingMakeupRunLength(uint runLength) } } - return MakeupRunLength[MakeupRunLength.Length - 1]; + return MakeupRunLength[^1]; } /// @@ -413,14 +413,14 @@ protected uint GetBestFittingMakeupRunLength(uint runLength) /// If true, the run is of white pixels. /// If false the run is of black pixels /// The terminating code for a run of length - protected uint GetTermCode(uint runLength, out uint codeLength, bool isWhiteRun) + protected static uint GetTermCode(uint runLength, out uint codeLength, bool isWhiteRun) { if (isWhiteRun) { - return this.GetWhiteTermCode(runLength, out codeLength); + return GetWhiteTermCode(runLength, out codeLength); } - return this.GetBlackTermCode(runLength, out codeLength); + return GetBlackTermCode(runLength, out codeLength); } /// @@ -431,14 +431,14 @@ protected uint GetTermCode(uint runLength, out uint codeLength, bool isWhiteRun) /// If true, the run is of white pixels. /// If false the run is of black pixels /// The makeup code for a run of length - protected uint GetMakeupCode(uint runLength, out uint codeLength, bool isWhiteRun) + protected static uint GetMakeupCode(uint runLength, out uint codeLength, bool isWhiteRun) { if (isWhiteRun) { - return this.GetWhiteMakeupCode(runLength, out codeLength); + return GetWhiteMakeupCode(runLength, out codeLength); } - return this.GetBlackMakeupCode(runLength, out codeLength); + return GetBlackMakeupCode(runLength, out codeLength); } /// @@ -494,12 +494,12 @@ protected void WriteCode(uint codeLength, uint code, Span compressedData) /// /// Writes a image compressed with CCITT T6 to the stream. /// - /// The pixels as 8-bit gray array. + /// The pixels as 8-bit gray array. /// The strip height. - public override void CompressStrip(Span pixelsAsGray, int height) + public override void CompressStrip(Span rows, int height) { - DebugGuard.IsTrue(pixelsAsGray.Length / height == this.Width, "Values must be equals"); - DebugGuard.IsTrue(pixelsAsGray.Length % height == 0, "Values must be equals"); + DebugGuard.IsTrue(rows.Length / height == this.Width, "Values must be equals"); + DebugGuard.IsTrue(rows.Length % height == 0, "Values must be equals"); this.compressedDataBuffer.Clear(); Span compressedData = this.compressedDataBuffer.GetSpan(); @@ -507,11 +507,11 @@ public override void CompressStrip(Span pixelsAsGray, int height) this.bytePosition = 0; this.bitPosition = 0; - this.CompressStrip(pixelsAsGray, height, compressedData); + this.CompressStrip(rows, height, compressedData); // Write the compressed data to the stream. int bytesToWrite = this.bitPosition != 0 ? this.bytePosition + 1 : this.bytePosition; - this.Output.Write(compressedData.Slice(0, bytesToWrite)); + this.Output.Write(compressedData[..bytesToWrite]); } /// diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs index bb2828b912..1b66cbf80b 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs @@ -100,7 +100,7 @@ private int FindB1ForNormalLine(int a0, byte a0Byte) offset = a0; } - ReadOnlySpan searchSpace = this.scanLine.Slice(offset); + ReadOnlySpan searchSpace = this.scanLine[offset..]; byte searchByte = (byte)~a0Byte; int index = searchSpace.IndexOf(searchByte); if (index < 0) @@ -120,7 +120,7 @@ private int FindB1ForNormalLine(int a0, byte a0Byte) return this.scanLine.Length; } - searchSpace = searchSpace.Slice(index); + searchSpace = searchSpace[index..]; offset += index; index = searchSpace.IndexOf((byte)~searchByte); if (index < 0) @@ -143,7 +143,7 @@ private int FindB2ForNormalLine(int b1) byte searchByte = (byte)~this.scanLine[b1]; int offset = b1 + 1; - ReadOnlySpan searchSpace = this.scanLine.Slice(offset); + ReadOnlySpan searchSpace = this.scanLine[offset..]; int index = searchSpace.IndexOf(searchByte); if (index == -1) { diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs index ef44263a56..d2247e2d22 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs @@ -102,7 +102,7 @@ private static void CopyImageBytesToBuffer(Span buffer, Buffer2D pi { Span pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y); Span rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan); - rgbBytes.CopyTo(buffer.Slice(offset)); + rgbBytes.CopyTo(buffer[offset..]); offset += rgbBytes.Length; } } @@ -114,7 +114,7 @@ private static void CopyImageBytesToBuffer(Span buffer, Buffer2D pixel { Span pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y); Span rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan); - rgbBytes.CopyTo(buffer.Slice(offset)); + rgbBytes.CopyTo(buffer[offset..]); offset += rgbBytes.Length; } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs index 230f9f5c92..80abe0e857 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs @@ -60,7 +60,7 @@ protected override void Decompress(BufferedReadStream stream, int byteCount, int TiffThrowHelper.ThrowImageFormatException("Tiff packbits compression error: not enough data."); } - compressedData.Slice(literalOffset, literalLength).CopyTo(buffer.Slice(decompressedOffset)); + compressedData.Slice(literalOffset, literalLength).CopyTo(buffer[decompressedOffset..]); compressedOffset += literalLength + 1; decompressedOffset += literalLength; diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs index 1a105e96a9..2c10edbea5 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs @@ -56,7 +56,7 @@ protected override void Decompress(BufferedReadStream stream, int byteCount, int buffer.Clear(); using System.Buffers.IMemoryOwner scanLineBuffer = this.Allocator.Allocate(this.width * 2); - Span scanLine = scanLineBuffer.GetSpan().Slice(0, this.width); + Span scanLine = scanLineBuffer.GetSpan()[..this.width]; Span referenceScanLineSpan = scanLineBuffer.GetSpan().Slice(this.width, this.width); var bitReader = new T6BitReader(stream, this.FillOrder, byteCount); @@ -155,7 +155,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.Pass: int b2 = referenceScanline.FindB2(b1); - scanline.Slice(unpacked, b2 - unpacked).Fill(fillByte); + scanline[unpacked..b2].Fill(fillByte); unpacked = b2; a0 = b2; break; @@ -190,7 +190,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.Vertical0: a1 = b1; - scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte); + scanline[unpacked..a1].Fill(fillByte); unpacked = a1; a0 = a1; fillByte = (byte)~fillByte; @@ -199,7 +199,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.VerticalR1: a1 = b1 + 1; - scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte); + scanline[unpacked..a1].Fill(fillByte); unpacked = a1; a0 = a1; fillByte = (byte)~fillByte; @@ -208,7 +208,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.VerticalR2: a1 = b1 + 2; - scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte); + scanline[unpacked..a1].Fill(fillByte); unpacked = a1; a0 = a1; fillByte = (byte)~fillByte; @@ -217,7 +217,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.VerticalR3: a1 = b1 + 3; - scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte); + scanline[unpacked..a1].Fill(fillByte); unpacked = a1; a0 = a1; fillByte = (byte)~fillByte; @@ -226,7 +226,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.VerticalL1: a1 = b1 - 1; - scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte); + scanline[unpacked..a1].Fill(fillByte); unpacked = a1; a0 = a1; fillByte = (byte)~fillByte; @@ -235,7 +235,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.VerticalL2: a1 = b1 - 2; - scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte); + scanline[unpacked..a1].Fill(fillByte); unpacked = a1; a0 = a1; fillByte = (byte)~fillByte; @@ -244,7 +244,7 @@ private static void Decode2DScanline(T6BitReader bitReader, bool whiteIsZero, Cc case CcittTwoDimensionalCodeType.VerticalL3: a1 = b1 - 3; - scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte); + scanline[unpacked..a1].Fill(fillByte); unpacked = a1; a0 = a1; fillByte = (byte)~fillByte; diff --git a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs index db93406a0d..587d302c64 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs @@ -45,7 +45,7 @@ private static void CopyImageBytesToBuffer(Span buffer, Buffer2D pi { Span pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y); Span rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan); - rgbBytes.CopyTo(buffer.Slice(offset)); + rgbBytes.CopyTo(buffer[offset..]); offset += rgbBytes.Length; } } diff --git a/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs b/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs index ab8f51844c..406d6ef743 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs @@ -235,7 +235,7 @@ private static void UndoRgb24Bit(Span pixelBytes, int width) for (int y = 0; y < height; y++) { Span rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); - Span rowRgb = MemoryMarshal.Cast(rowBytes).Slice(0, width); + Span rowRgb = MemoryMarshal.Cast(rowBytes)[..width]; ref Rgb24 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb); byte r = rowRgbBase.R; byte g = rowRgbBase.G; @@ -260,7 +260,7 @@ private static void UndoRgba32Bit(Span pixelBytes, int width) for (int y = 0; y < height; y++) { Span rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); - Span rowRgb = MemoryMarshal.Cast(rowBytes).Slice(0, width); + Span rowRgb = MemoryMarshal.Cast(rowBytes)[..width]; ref Rgba32 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb); byte r = rowRgbBase.R; byte g = rowRgbBase.G; diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs index e9be797b4b..d68d70e9b1 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs @@ -31,7 +31,7 @@ public override void Decode(ReadOnlySpan data, Buffer2D pixels, in Span buffer = stackalloc byte[4]; int bufferStartIdx = this.isBigEndian ? 1 : 0; - Span bufferSpan = buffer.Slice(bufferStartIdx); + Span bufferSpan = buffer[bufferStartIdx..]; int offset = 0; for (int y = top; y < top + height; y++) { diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs index b74c43cebd..10c61a6d0e 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs @@ -32,7 +32,7 @@ public override void Decode(ReadOnlySpan data, Buffer2D pixels, in Span buffer = stackalloc byte[4]; int bufferStartIdx = this.isBigEndian ? 1 : 0; - Span bufferSpan = buffer.Slice(bufferStartIdx); + Span bufferSpan = buffer[bufferStartIdx..]; for (int y = top; y < top + height; y++) { Span pixelRow = pixels.DangerousGetRowSpan(y).Slice(left, width); diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs index 94ba69785e..0746610951 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs @@ -35,7 +35,7 @@ public override void Decode(IMemoryOwner[] data, Buffer2D pixels, Span redData = data[0].GetSpan(); Span greenData = data[1].GetSpan(); Span blueData = data[2].GetSpan(); - Span bufferSpan = buffer.Slice(bufferStartIdx); + Span bufferSpan = buffer[bufferStartIdx..]; int offset = 0; for (int y = top; y < top + height; y++) diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs index ab5a21ac2c..be10495e75 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs @@ -42,7 +42,7 @@ public override void Decode(ReadOnlySpan data, Buffer2D pixels, in Span buffer = stackalloc byte[4]; int bufferStartIdx = this.isBigEndian ? 1 : 0; - Span bufferSpan = buffer.Slice(bufferStartIdx); + Span bufferSpan = buffer[bufferStartIdx..]; for (int y = top; y < top + height; y++) { Span pixelRow = pixels.DangerousGetRowSpan(y).Slice(left, width); diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs index 47c2ae5ad3..45f530d627 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs @@ -43,7 +43,7 @@ public override void Decode(IMemoryOwner[] data, Buffer2D pixels, Span greenData = data[1].GetSpan(); Span blueData = data[2].GetSpan(); Span alphaData = data[3].GetSpan(); - Span bufferSpan = buffer.Slice(bufferStartIdx); + Span bufferSpan = buffer[bufferStartIdx..]; bool hasAssociatedAlpha = this.extraSamplesType.HasValue && this.extraSamplesType == TiffExtraSampleType.AssociatedAlphaData; int offset = 0; diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs index 2caede066a..36832a198a 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs @@ -32,7 +32,7 @@ public override void Decode(ReadOnlySpan data, Buffer2D pixels, in int bufferStartIdx = this.isBigEndian ? 1 : 0; const uint maxValue = 0xFFFFFF; - Span bufferSpan = buffer.Slice(bufferStartIdx); + Span bufferSpan = buffer[bufferStartIdx..]; int offset = 0; for (int y = top; y < top + height; y++) { diff --git a/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs b/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs index 2412d166b4..d277af9003 100644 --- a/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs +++ b/src/ImageSharp/Formats/Tiff/TiffBitsPerSample.cs @@ -10,31 +10,6 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// public readonly struct TiffBitsPerSample : IEquatable { - /// - /// The bits for the channel 0. - /// - public readonly ushort Channel0; - - /// - /// The bits for the channel 1. - /// - public readonly ushort Channel1; - - /// - /// The bits for the channel 2. - /// - public readonly ushort Channel2; - - /// - /// The bits for the alpha channel. - /// - public readonly ushort Channel3; - - /// - /// The number of channels. - /// - public readonly byte Channels; - /// /// Initializes a new instance of the struct. /// @@ -56,6 +31,53 @@ public TiffBitsPerSample(ushort channel0, ushort channel1, ushort channel2, usho this.Channels += (byte)(this.Channel3 != 0 ? 1 : 0); } + /// + /// Gets the bits for the channel 0. + /// + public readonly ushort Channel0 { get; } + + /// + /// Gets the bits for the channel 1. + /// + public readonly ushort Channel1 { get; } + + /// + /// Gets the bits for the channel 2. + /// + public readonly ushort Channel2 { get; } + + /// + /// Gets the bits for the alpha channel. + /// + public readonly ushort Channel3 { get; } + + /// + /// Gets the number of channels. + /// + public readonly byte Channels { get; } + + /// + /// Checks whether two structures are equal. + /// + /// The left hand operand. + /// The right hand operand. + /// + /// True if the parameter is equal to the parameter; + /// otherwise, false. + /// + public static bool operator ==(TiffBitsPerSample left, TiffBitsPerSample right) => left.Equals(right); + + /// + /// Checks whether two structures are not equal. + /// + /// The left hand operand. + /// The right hand operand. + /// + /// True if the parameter is not equal to the parameter; + /// otherwise, false. + /// + public static bool operator !=(TiffBitsPerSample left, TiffBitsPerSample right) => !(left == right); + /// /// Tries to parse a ushort array and convert it into a TiffBitsPerSample struct. /// diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index 16071001d5..9ccd4416fc 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -73,7 +73,7 @@ internal sealed class TiffEncoderCore : IImageEncoderInternals /// private const TiffPhotometricInterpretation DefaultPhotometricInterpretation = TiffPhotometricInterpretation.Rgb; - private readonly List<(long, uint)> frameMarkers = new List<(long, uint)>(); + private readonly List<(long, uint)> frameMarkers = new(); /// /// Initializes a new instance of the class. @@ -148,15 +148,15 @@ public void Encode(Image image, Stream stream, CancellationToken // Make sure, the Encoder options makes sense in combination with each other. this.SanitizeAndSetEncoderOptions(bitsPerPixel, image.PixelType.BitsPerPixel, photometricInterpretation, compression, predictor); - using var writer = new TiffStreamWriter(stream); - long ifdMarker = this.WriteHeader(writer); + using TiffStreamWriter writer = new(stream); + long ifdMarker = WriteHeader(writer); Image metadataImage = image; foreach (ImageFrame frame in image.Frames) { cancellationToken.ThrowIfCancellationRequested(); - var subfileType = (TiffNewSubfileType)(frame.Metadata.ExifProfile?.GetValue(ExifTag.SubfileType)?.Value ?? (int)TiffNewSubfileType.FullImage); + TiffNewSubfileType subfileType = (TiffNewSubfileType)(frame.Metadata.ExifProfile?.GetValue(ExifTag.SubfileType)?.Value ?? (int)TiffNewSubfileType.FullImage); ifdMarker = this.WriteFrame(writer, frame, image.Metadata, metadataImage, ifdMarker); metadataImage = null; @@ -178,7 +178,7 @@ public void Encode(Image image, Stream stream, CancellationToken /// /// The marker to write the first IFD offset. /// - public long WriteHeader(TiffStreamWriter writer) + public static long WriteHeader(TiffStreamWriter writer) { writer.Write(ByteOrderMarker); writer.Write(TiffConstants.HeaderMagicNumber); @@ -214,7 +214,7 @@ private long WriteFrame( this.compressionLevel, this.HorizontalPredictor == TiffPredictor.Horizontal ? this.HorizontalPredictor.Value : TiffPredictor.None); - var entriesCollector = new TiffEncoderEntriesCollector(); + TiffEncoderEntriesCollector entriesCollector = new(); using TiffBaseColorWriter colorWriter = TiffColorWriterFactory.Create( this.PhotometricInterpretation, frame, @@ -224,7 +224,7 @@ private long WriteFrame( entriesCollector, (int)this.BitsPerPixel); - int rowsPerStrip = this.CalcRowsPerStrip(frame.Height, colorWriter.BytesPerRow, this.CompressionType); + int rowsPerStrip = CalcRowsPerStrip(frame.Height, colorWriter.BytesPerRow, this.CompressionType); colorWriter.Write(compressor, rowsPerStrip); @@ -248,7 +248,7 @@ private long WriteFrame( /// The number of bytes per row. /// The compression used. /// Number of rows per strip. - private int CalcRowsPerStrip(int height, int bytesPerRow, TiffCompression? compression) + private static int CalcRowsPerStrip(int height, int bytesPerRow, TiffCompression? compression) { DebugGuard.MustBeGreaterThan(height, 0, nameof(height)); DebugGuard.MustBeGreaterThan(bytesPerRow, 0, nameof(bytesPerRow)); @@ -290,7 +290,7 @@ private long WriteIfd(TiffStreamWriter writer, List entries) } uint dataOffset = (uint)writer.Position + (uint)(6 + (entries.Count * 12)); - var largeDataBlocks = new List(); + List largeDataBlocks = new(); entries.Sort((a, b) => (ushort)a.Tag - (ushort)b.Tag); @@ -440,13 +440,6 @@ private void SetEncoderOptions(TiffBitsPerPixel? bitsPerPixel, TiffPhotometricIn } public static bool IsOneBitCompression(TiffCompression? compression) - { - if (compression is TiffCompression.Ccitt1D or TiffCompression.CcittGroup3Fax or TiffCompression.CcittGroup4Fax) - { - return true; - } - - return false; - } + => compression is TiffCompression.Ccitt1D or TiffCompression.CcittGroup3Fax or TiffCompression.CcittGroup4Fax; } } diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs index 8d9c6c2b4e..926dbf1c0f 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs @@ -55,7 +55,7 @@ protected override void EncodeStrip(int y, int height, TiffBaseCompressor compre grayRowIdx++; } - compressor.CompressStrip(pixelAsGraySpan.Slice(0, stripPixels), height); + compressor.CompressStrip(pixelAsGraySpan[..stripPixels], height); }); } else @@ -76,7 +76,7 @@ protected override void EncodeStrip(int y, int height, TiffBaseCompressor compre { int bitIndex = 0; int byteIndex = 0; - Span outputRow = rows.Slice(outputRowIdx * this.BytesPerRow); + Span outputRow = rows[(outputRowIdx * this.BytesPerRow)..]; Span pixelsBlackWhiteRow = blackWhiteBuffer.DangerousGetRowSpan(row); PixelOperations.Instance.ToL8Bytes(this.Configuration, pixelsBlackWhiteRow, pixelAsGraySpan, width); for (int x = 0; x < this.Image.Width; x++) diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs index 19b5e5f88a..5bb39771e7 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs @@ -31,7 +31,7 @@ protected override void EncodeStrip(int y, int height, TiffBaseCompressor compre this.rowBuffer.Clear(); - Span outputRowSpan = this.rowBuffer.GetSpan().Slice(0, this.BytesPerRow * height); + Span outputRowSpan = this.rowBuffer.GetSpan()[..(this.BytesPerRow * height)]; int width = this.Image.Width; using IMemoryOwner stripPixelBuffer = this.MemoryAllocator.Allocate(height * width); diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs index 8e123c22f9..19d071c9ed 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs @@ -83,7 +83,7 @@ protected override void EncodeStrip(int y, int height, TiffBaseCompressor compre } } - compressor.CompressStrip(rows4bit.Slice(0, idx4bitRows), height); + compressor.CompressStrip(rows4bit[..idx4bitRows], height); } else { @@ -99,7 +99,7 @@ protected override void EncodeStrip(int y, int height, TiffBaseCompressor compre indexedPixelsRowIdx++; } - compressor.CompressStrip(indexedPixels.Slice(0, stripPixels), height); + compressor.CompressStrip(indexedPixels[..stripPixels], height); } } @@ -119,7 +119,7 @@ private void AddColorMapTag() int quantizedColorBytes = quantizedColors.Length * 3 * 2; // In the ColorMap, black is represented by 0, 0, 0 and white is represented by 65535, 65535, 65535. - Span quantizedColorRgb48 = MemoryMarshal.Cast(colorPalette.Slice(0, quantizedColorBytes)); + Span quantizedColorRgb48 = MemoryMarshal.Cast(colorPalette[..quantizedColorBytes]); PixelOperations.Instance.ToRgb48(this.Configuration, quantizedColors, quantizedColorRgb48); // It can happen that the quantized colors are less than the expected maximum per channel. diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs index 667f75be43..d35d169488 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs @@ -28,7 +28,7 @@ internal sealed class TiffStreamWriter : IDisposable /// /// Gets a value indicating whether the architecture is little-endian. /// - public bool IsLittleEndian => BitConverter.IsLittleEndian; + public static bool IsLittleEndian => BitConverter.IsLittleEndian; /// /// Gets the current position within the stream. @@ -75,7 +75,7 @@ public long PlaceMarker() /// The two-byte unsigned integer to write. public void Write(ushort value) { - if (this.IsLittleEndian) + if (IsLittleEndian) { BinaryPrimitives.WriteUInt16LittleEndian(this.buffer, value); } @@ -93,7 +93,7 @@ public void Write(ushort value) /// The four-byte unsigned integer to write. public void Write(uint value) { - if (this.IsLittleEndian) + if (IsLittleEndian) { BinaryPrimitives.WriteUInt32LittleEndian(this.buffer, value); } diff --git a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs index 3a118fc0e9..a2628a1db4 100644 --- a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs +++ b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs @@ -6,13 +6,11 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; using SixLabors.ImageSharp.Formats.Webp.BitReader; using SixLabors.ImageSharp.Formats.Webp.Lossless; using SixLabors.ImageSharp.Memory; -#if SUPPORTS_RUNTIME_INTRINSICS -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp { @@ -143,7 +141,7 @@ public void Decode() Span alphaSpan = this.Alpha.Memory.Span; if (this.AlphaFilterType == WebpAlphaFilterType.None) { - dataSpan.Slice(0, pixelCount).CopyTo(alphaSpan); + dataSpan[..pixelCount].CopyTo(alphaSpan); return; } @@ -166,8 +164,8 @@ public void Decode() } prev = dst; - deltas = deltas.Slice(this.Width); - dst = dst.Slice(this.Width); + deltas = deltas[this.Width..]; + dst = dst[this.Width..]; } } else @@ -199,7 +197,7 @@ public void AlphaApplyFilter(int firstRow, int lastRow, Span dst, int stri } Span alphaSpan = this.Alpha.Memory.Span; - Span prev = this.PrevRow == 0 ? null : alphaSpan.Slice(this.Width * this.PrevRow); + Span prev = this.PrevRow == 0 ? null : alphaSpan[(this.Width * this.PrevRow)..]; for (int y = firstRow; y < lastRow; y++) { switch (this.AlphaFilterType) @@ -216,7 +214,7 @@ public void AlphaApplyFilter(int firstRow, int lastRow, Span dst, int stri } prev = dst; - dst = dst.Slice(stride); + dst = dst[stride..]; } this.PrevRow = lastRow - 1; @@ -234,8 +232,8 @@ public void ExtractPalettedAlphaRows(int lastRow) Span output = this.Alpha.Memory.Span; Span pixelData = this.Vp8LDec.Pixels.Memory.Span; Span pixelDataAsBytes = MemoryMarshal.Cast(pixelData); - Span dst = output.Slice(this.Width * firstRow); - Span input = pixelDataAsBytes.Slice(this.Vp8LDec.Width * firstRow); + Span dst = output[(this.Width * firstRow)..]; + Span input = pixelDataAsBytes[(this.Vp8LDec.Width * firstRow)..]; if (this.Vp8LDec.Transforms.Count == 0 || this.Vp8LDec.Transforms[0].TransformType != Vp8LTransformType.ColorIndexingTransform) { @@ -311,7 +309,6 @@ private static void ColorIndexInverseTransformAlpha( private static void HorizontalUnfilter(Span prev, Span input, Span dst, int width) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { dst[0] = (byte)(input[0] + (prev.IsEmpty ? 0 : prev[0])); @@ -345,7 +342,6 @@ private static void HorizontalUnfilter(Span prev, Span input, Span prev, Span input, Span prev, Span input, Span(bytesToRead); Span dataSpan = this.Data.Memory.Span; - input.Read(dataSpan.Slice(0, bytesToRead), 0, bytesToRead); + input.Read(dataSpan[..bytesToRead], 0, bytesToRead); } protected virtual void Dispose(bool disposing) diff --git a/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs b/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs index e1639b8990..24761213e8 100644 --- a/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs +++ b/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Buffers.Binary; using System.IO; +using System.Numerics; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Memory; @@ -111,7 +112,7 @@ public int GetBit(int prob) range = split + 1; } - int shift = 7 ^ Numerics.Log2(range); + int shift = 7 ^ BitOperations.Log2(range); range <<= shift; this.bits -= shift; @@ -132,7 +133,7 @@ public int GetSigned(int v) uint split = this.range >> 1; ulong value = this.value >> pos; ulong mask = (split - value) >> 31; // -1 or 0 - this.bits -= 1; + this.bits--; this.range = (this.range + (uint)mask) | 1; this.value -= ((split + 1) & mask) << pos; @@ -188,7 +189,7 @@ private void LoadNewBytes() { ulong inBits = BinaryPrimitives.ReadUInt64LittleEndian(this.Data.Memory.Span.Slice((int)this.pos, 8)); this.pos += BitsCount >> 3; - ulong bits = this.ByteSwap64(inBits); + ulong bits = ByteSwap64(inBits); bits >>= 64 - BitsCount; this.value = bits | (this.value << BitsCount); this.bits += BitsCount; @@ -220,7 +221,7 @@ private void LoadFinalBytes() } [MethodImpl(InliningOptions.ShortMethod)] - private ulong ByteSwap64(ulong x) + private static ulong ByteSwap64(ulong x) { x = ((x & 0xffffffff00000000ul) >> 32) | ((x & 0x00000000fffffffful) << 32); x = ((x & 0xffff0000ffff0000ul) >> 16) | ((x & 0x0000ffff0000fffful) << 16); diff --git a/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs b/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs index ecf87d8b53..ed41c29fe6 100644 --- a/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs +++ b/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs @@ -5,7 +5,6 @@ using System.Buffers.Binary; using System.IO; using SixLabors.ImageSharp.Metadata.Profiles.Exif; -using SixLabors.ImageSharp.Metadata.Profiles.Icc; using SixLabors.ImageSharp.Metadata.Profiles.Xmp; namespace SixLabors.ImageSharp.Formats.Webp.BitWriter @@ -38,6 +37,7 @@ internal abstract class BitWriterBase /// Initializes a new instance of the class. /// Used internally for cloning. /// + /// The byte buffer. private protected BitWriterBase(byte[] buffer) => this.buffer = buffer; public byte[] Buffer => this.buffer; @@ -102,12 +102,10 @@ protected void WriteRiffHeader(Stream stream, uint riffSize) /// /// The metadata profile bytes. /// The metadata chunk size in bytes. - protected uint MetadataChunkSize(byte[] metadataBytes) + protected static uint MetadataChunkSize(byte[] metadataBytes) { uint metaSize = (uint)metadataBytes.Length; - uint metaChunkSize = WebpConstants.ChunkHeaderSize + metaSize + (metaSize & 1); - - return metaChunkSize; + return WebpConstants.ChunkHeaderSize + metaSize + (metaSize & 1); } /// @@ -115,12 +113,10 @@ protected uint MetadataChunkSize(byte[] metadataBytes) /// /// The alpha chunk bytes. /// The alpha data chunk size in bytes. - protected uint AlphaChunkSize(Span alphaBytes) + protected static uint AlphaChunkSize(Span alphaBytes) { uint alphaSize = (uint)alphaBytes.Length + 1; - uint alphaChunkSize = WebpConstants.ChunkHeaderSize + alphaSize + (alphaSize & 1); - - return alphaChunkSize; + return WebpConstants.ChunkHeaderSize + alphaSize + (alphaSize & 1); } /// @@ -258,9 +254,9 @@ protected void WriteVp8XHeader(Stream stream, ExifProfile exifProfile, XmpProfil BinaryPrimitives.WriteUInt32LittleEndian(buf, flags); stream.Write(buf); BinaryPrimitives.WriteUInt32LittleEndian(buf, width - 1); - stream.Write(buf.Slice(0, 3)); + stream.Write(buf[..3]); BinaryPrimitives.WriteUInt32LittleEndian(buf, height - 1); - stream.Write(buf.Slice(0, 3)); + stream.Write(buf[..3]); } } } diff --git a/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs b/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs index 7b9a79a2e5..a218d50f4a 100644 --- a/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs +++ b/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs @@ -215,7 +215,7 @@ public void PutSegment(int s, Span p) { if (this.PutBit(s >= 2, p[0])) { - p = p.Slice(1); + p = p[1..]; } this.PutBit(s & 1, p[1]); @@ -433,27 +433,27 @@ public void WriteEncodedImageToStream( { isVp8X = true; exifBytes = exifProfile.ToByteArray(); - riffSize += this.MetadataChunkSize(exifBytes); + riffSize += MetadataChunkSize(exifBytes); } if (xmpProfile != null) { isVp8X = true; xmpBytes = xmpProfile.Data; - riffSize += this.MetadataChunkSize(xmpBytes); + riffSize += MetadataChunkSize(xmpBytes); } if (iccProfile != null) { isVp8X = true; iccProfileBytes = iccProfile.ToByteArray(); - riffSize += this.MetadataChunkSize(iccProfileBytes); + riffSize += MetadataChunkSize(iccProfileBytes); } if (hasAlpha) { isVp8X = true; - riffSize += this.AlphaChunkSize(alphaData); + riffSize += AlphaChunkSize(alphaData); } if (isVp8X) @@ -711,7 +711,7 @@ private void WriteVp8Header(Stream stream, uint size) Span vp8ChunkHeader = stackalloc byte[WebpConstants.ChunkHeaderSize]; WebpConstants.Vp8MagicBytes.AsSpan().CopyTo(vp8ChunkHeader); - BinaryPrimitives.WriteUInt32LittleEndian(vp8ChunkHeader.Slice(4), size); + BinaryPrimitives.WriteUInt32LittleEndian(vp8ChunkHeader[4..], size); stream.Write(vp8ChunkHeader); } diff --git a/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs b/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs index 78494004d3..cb4d6d6543 100644 --- a/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs +++ b/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs @@ -150,21 +150,21 @@ public void WriteEncodedImageToStream(Stream stream, ExifProfile exifProfile, Xm { isVp8X = true; exifBytes = exifProfile.ToByteArray(); - riffSize += this.MetadataChunkSize(exifBytes); + riffSize += MetadataChunkSize(exifBytes); } if (xmpProfile != null) { isVp8X = true; xmpBytes = xmpProfile.Data; - riffSize += this.MetadataChunkSize(xmpBytes); + riffSize += MetadataChunkSize(xmpBytes); } if (iccProfile != null) { isVp8X = true; iccBytes = iccProfile.ToByteArray(); - riffSize += this.MetadataChunkSize(iccBytes); + riffSize += MetadataChunkSize(iccBytes); } if (isVp8X) diff --git a/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs b/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs index 8c5aa43f5f..88d6261cfe 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs @@ -252,7 +252,7 @@ private static void BackwardReferencesTraceBackwards( BackwardReferencesHashChainDistanceOnly(xSize, ySize, memoryAllocator, bgra, cacheBits, hashChain, refsSrc, distArrayBuffer); int chosenPathSize = TraceBackwards(distArray, distArraySize); - Span chosenPath = distArray.Slice(distArraySize - chosenPathSize); + Span chosenPath = distArray[(distArraySize - chosenPathSize)..]; BackwardReferencesHashChainFollowChosenPath(bgra, cacheBits, chosenPath, chosenPathSize, hashChain, refsDst); } @@ -741,8 +741,8 @@ private static void BackwardReferencesRle(int xSize, int ySize, ReadOnlySpan= prevRowLen && rleLen >= MinLength) { refs.Add(PixOrCopy.CreateCopy(1, (ushort)rleLen)); diff --git a/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs index 06e3c88fc0..d80cdc2758 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossless { @@ -15,21 +13,20 @@ internal static class ColorSpaceTransformUtils { public static void CollectColorBlueTransforms(Span bgra, int stride, int tileWidth, int tileHeight, int greenToBlue, int redToBlue, Span histo) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && tileWidth >= 16) { const int span = 16; Span values = stackalloc ushort[span]; - Vector256 collectColorBlueTransformsShuffleLowMask256 = Vector256.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30, 255, 255, 255, 255, 255, 255, 255, 255); - Vector256 collectColorBlueTransformsShuffleHighMask256 = Vector256.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30); - Vector256 collectColorBlueTransformsGreenBlueMask256 = Vector256.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); - Vector256 collectColorBlueTransformsGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector256 collectColorBlueTransformsBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); - Vector256 multsr = Vector256.Create(LosslessUtils.Cst5b(redToBlue)); - Vector256 multsg = Vector256.Create(LosslessUtils.Cst5b(greenToBlue)); + var collectColorBlueTransformsShuffleLowMask256 = Vector256.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30, 255, 255, 255, 255, 255, 255, 255, 255); + var collectColorBlueTransformsShuffleHighMask256 = Vector256.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30); + var collectColorBlueTransformsGreenBlueMask256 = Vector256.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); + var collectColorBlueTransformsGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var collectColorBlueTransformsBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var multsr = Vector256.Create(LosslessUtils.Cst5b(redToBlue)); + var multsg = Vector256.Create(LosslessUtils.Cst5b(greenToBlue)); for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -63,23 +60,23 @@ public static void CollectColorBlueTransforms(Span bgra, int stride, int t int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorBlueTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); + CollectColorBlueTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); } } else if (Sse41.IsSupported) { const int span = 8; Span values = stackalloc ushort[span]; - Vector128 collectColorBlueTransformsShuffleLowMask = Vector128.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255); - Vector128 collectColorBlueTransformsShuffleHighMask = Vector128.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14); - Vector128 collectColorBlueTransformsGreenBlueMask = Vector128.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); - Vector128 collectColorBlueTransformsGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector128 collectColorBlueTransformsBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); - Vector128 multsr = Vector128.Create(LosslessUtils.Cst5b(redToBlue)); - Vector128 multsg = Vector128.Create(LosslessUtils.Cst5b(greenToBlue)); + var collectColorBlueTransformsShuffleLowMask = Vector128.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255); + var collectColorBlueTransformsShuffleHighMask = Vector128.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14); + var collectColorBlueTransformsGreenBlueMask = Vector128.Create(255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0); + var collectColorBlueTransformsGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var collectColorBlueTransformsBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var multsr = Vector128.Create(LosslessUtils.Cst5b(redToBlue)); + var multsg = Vector128.Create(LosslessUtils.Cst5b(greenToBlue)); for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -113,11 +110,10 @@ public static void CollectColorBlueTransforms(Span bgra, int stride, int t int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorBlueTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); + CollectColorBlueTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToBlue, redToBlue, histo); } } else -#endif { CollectColorBlueTransformsNoneVectorized(bgra, stride, tileWidth, tileHeight, greenToBlue, redToBlue, histo); } @@ -140,17 +136,16 @@ private static void CollectColorBlueTransformsNoneVectorized(Span bgra, in public static void CollectColorRedTransforms(Span bgra, int stride, int tileWidth, int tileHeight, int greenToRed, Span histo) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && tileWidth >= 16) { Vector256 collectColorRedTransformsGreenMask256 = Vector256.Create(0x00ff00).AsByte(); Vector256 collectColorRedTransformsAndMask256 = Vector256.Create((short)0xff).AsByte(); - Vector256 multsg = Vector256.Create(LosslessUtils.Cst5b(greenToRed)); + var multsg = Vector256.Create(LosslessUtils.Cst5b(greenToRed)); const int span = 16; Span values = stackalloc ushort[span]; for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -181,19 +176,19 @@ public static void CollectColorRedTransforms(Span bgra, int stride, int ti int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorRedTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToRed, histo); + CollectColorRedTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToRed, histo); } } else if (Sse41.IsSupported) { Vector128 collectColorRedTransformsGreenMask = Vector128.Create(0x00ff00).AsByte(); Vector128 collectColorRedTransformsAndMask = Vector128.Create((short)0xff).AsByte(); - Vector128 multsg = Vector128.Create(LosslessUtils.Cst5b(greenToRed)); + var multsg = Vector128.Create(LosslessUtils.Cst5b(greenToRed)); const int span = 8; Span values = stackalloc ushort[span]; for (int y = 0; y < tileHeight; y++) { - Span srcSpan = bgra.Slice(y * stride); + Span srcSpan = bgra[(y * stride)..]; ref uint inputRef = ref MemoryMarshal.GetReference(srcSpan); for (nint x = 0; x <= tileWidth - span; x += span) { @@ -224,11 +219,10 @@ public static void CollectColorRedTransforms(Span bgra, int stride, int ti int leftOver = tileWidth & (span - 1); if (leftOver > 0) { - CollectColorRedTransformsNoneVectorized(bgra.Slice(tileWidth - leftOver), stride, leftOver, tileHeight, greenToRed, histo); + CollectColorRedTransformsNoneVectorized(bgra[(tileWidth - leftOver)..], stride, leftOver, tileHeight, greenToRed, histo); } } else -#endif { CollectColorRedTransformsNoneVectorized(bgra, stride, tileWidth, tileHeight, greenToRed, histo); } diff --git a/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs index 7bd206391b..515ae7a7d9 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs @@ -402,7 +402,7 @@ public static int BuildHuffmanTable(Span table, int rootBits, int[] BitsUsed = len, Value = (uint)sorted[symbol++] }; - ReplicateValue(table.Slice(key), step, tableSize, huffmanCode); + ReplicateValue(table[key..], step, tableSize, huffmanCode); key = GetNextKey(key, len); } @@ -426,7 +426,7 @@ public static int BuildHuffmanTable(Span table, int rootBits, int[] { if ((key & mask) != low) { - tableSpan = tableSpan.Slice(tableSize); + tableSpan = tableSpan[tableSize..]; tablePos += tableSize; tableBits = NextTableBitSize(counts, len, rootBits); tableSize = 1 << tableBits; @@ -444,7 +444,7 @@ public static int BuildHuffmanTable(Span table, int rootBits, int[] BitsUsed = len - rootBits, Value = (uint)sorted[symbol++] }; - ReplicateValue(tableSpan.Slice(key >> rootBits), step, tableSize, huffmanCode); + ReplicateValue(tableSpan[(key >> rootBits)..], step, tableSize, huffmanCode); key = GetNextKey(key, len); } } @@ -576,8 +576,8 @@ private static void SetBitDepths(Span tree, Span pool, { if (tree[0].PoolIndexLeft >= 0) { - SetBitDepths(pool.Slice(tree[0].PoolIndexLeft), pool, bitDepths, level + 1); - SetBitDepths(pool.Slice(tree[0].PoolIndexRight), pool, bitDepths, level + 1); + SetBitDepths(pool[tree[0].PoolIndexLeft..], pool, bitDepths, level + 1); + SetBitDepths(pool[tree[0].PoolIndexRight..], pool, bitDepths, level + 1); } else { diff --git a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs index 23b355ca43..cb826f75d1 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs @@ -2,13 +2,12 @@ // Licensed under the Six Labors Split License. using System; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.Memory; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif +using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Formats.Webp.Lossless { @@ -68,9 +67,9 @@ public static int PrefixEncodeBits(int distance, ref int extraBits) { if (distance < PrefixLookupIdxMax) { - (int Code, int ExtraBits) prefixCode = WebpLookupTables.PrefixEncodeCode[distance]; - extraBits = prefixCode.ExtraBits; - return prefixCode.Code; + (int code, int bits) = WebpLookupTables.PrefixEncodeCode[distance]; + extraBits = bits; + return code; } return PrefixEncodeBitsNoLut(distance, ref extraBits); @@ -80,11 +79,11 @@ public static int PrefixEncode(int distance, ref int extraBits, ref int extraBit { if (distance < PrefixLookupIdxMax) { - (int Code, int ExtraBits) prefixCode = WebpLookupTables.PrefixEncodeCode[distance]; - extraBits = prefixCode.ExtraBits; + (int code, int bits) = WebpLookupTables.PrefixEncodeCode[distance]; + extraBits = bits; extraBitsValue = WebpLookupTables.PrefixEncodeExtraBitsValue[distance]; - return prefixCode.Code; + return code; } return PrefixEncodeNoLut(distance, ref extraBits, ref extraBitsValue); @@ -96,10 +95,9 @@ public static int PrefixEncode(int distance, ref int extraBits, ref int extraBit /// The pixel data to apply the transformation. public static void AddGreenToBlueAndRed(Span pixelData) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { - Vector256 addGreenToBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); + var addGreenToBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 8; i += 8) @@ -113,12 +111,12 @@ public static void AddGreenToBlueAndRed(Span pixelData) if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else if (Ssse3.IsSupported) { - Vector128 addGreenToBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); + var addGreenToBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 4; i += 4) @@ -132,7 +130,7 @@ public static void AddGreenToBlueAndRed(Span pixelData) if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else if (Sse2.IsSupported) @@ -154,11 +152,10 @@ public static void AddGreenToBlueAndRed(Span pixelData) if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else -#endif { AddGreenToBlueAndRedScalar(pixelData); } @@ -180,10 +177,9 @@ private static void AddGreenToBlueAndRedScalar(Span pixelData) public static void SubtractGreenFromBlueAndRed(Span pixelData) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { - Vector256 subtractGreenFromBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); + var subtractGreenFromBlueAndRedMaskAvx2 = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 8; i += 8) @@ -197,12 +193,12 @@ public static void SubtractGreenFromBlueAndRed(Span pixelData) if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else if (Ssse3.IsSupported) { - Vector128 subtractGreenFromBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); + var subtractGreenFromBlueAndRedMaskSsse3 = Vector128.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255); int numPixels = pixelData.Length; nint i; for (i = 0; i <= numPixels - 4; i += 4) @@ -216,7 +212,7 @@ public static void SubtractGreenFromBlueAndRed(Span pixelData) if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else if (Sse2.IsSupported) @@ -238,11 +234,10 @@ public static void SubtractGreenFromBlueAndRed(Span pixelData) if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else -#endif { SubtractGreenFromBlueAndRedScalar(pixelData); } @@ -375,11 +370,10 @@ public static void ColorSpaceInverseTransform(Vp8LTransform transform, SpanThe number of pixels to process. public static void TransformColor(Vp8LMultipliers m, Span pixelData, int numPixels) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && numPixels >= 8) { - Vector256 transformColorAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector256 transformColorRedBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var transformColorAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorRedBlueMask256 = Vector256.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); Vector256 multsrb = MkCst32(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector256 multsb2 = MkCst32(Cst5b(m.RedToBlue), 0); @@ -405,13 +399,13 @@ public static void TransformColor(Vp8LMultipliers m, Span pixelData, int n if (idx != numPixels) { - TransformColorScalar(m, pixelData.Slice((int)idx), numPixels - (int)idx); + TransformColorScalar(m, pixelData[(int)idx..], numPixels - (int)idx); } } else if (Sse2.IsSupported) { - Vector128 transformColorAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); - Vector128 transformColorRedBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); + var transformColorAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorRedBlueMask = Vector128.Create(255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0); Vector128 multsrb = MkCst16(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector128 multsb2 = MkCst16(Cst5b(m.RedToBlue), 0); nint idx; @@ -436,11 +430,10 @@ public static void TransformColor(Vp8LMultipliers m, Span pixelData, int n if (idx != numPixels) { - TransformColorScalar(m, pixelData.Slice((int)idx), numPixels - (int)idx); + TransformColorScalar(m, pixelData[(int)idx..], numPixels - (int)idx); } } else -#endif { TransformColorScalar(m, pixelData, numPixels); } @@ -471,10 +464,9 @@ private static void TransformColorScalar(Vp8LMultipliers m, Span data, int /// The pixel data to apply the inverse transform on. public static void TransformColorInverse(Vp8LMultipliers m, Span pixelData) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && pixelData.Length >= 8) { - Vector256 transformColorInverseAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorInverseAlphaGreenMask256 = Vector256.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); Vector256 multsrb = MkCst32(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector256 multsb2 = MkCst32(Cst5b(m.RedToBlue), 0); nint idx; @@ -500,12 +492,12 @@ public static void TransformColorInverse(Vp8LMultipliers m, Span pixelData if (idx != pixelData.Length) { - TransformColorInverseScalar(m, pixelData.Slice((int)idx)); + TransformColorInverseScalar(m, pixelData[(int)idx..]); } } else if (Sse2.IsSupported) { - Vector128 transformColorInverseAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); + var transformColorInverseAlphaGreenMask = Vector128.Create(0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255); Vector128 multsrb = MkCst16(Cst5b(m.GreenToRed), Cst5b(m.GreenToBlue)); Vector128 multsb2 = MkCst16(Cst5b(m.RedToBlue), 0); @@ -532,11 +524,10 @@ public static void TransformColorInverse(Vp8LMultipliers m, Span pixelData if (idx != pixelData.Length) { - TransformColorInverseScalar(m, pixelData.Slice((int)idx)); + TransformColorInverseScalar(m, pixelData[(int)idx..]); } } else -#endif { TransformColorInverseScalar(m, pixelData); } @@ -753,7 +744,6 @@ public static void BundleColorMap(Span row, int width, int xBits, SpanShanon entropy. public static float CombinedShannonEntropy(Span x, Span y) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { double retVal = 0.0d; @@ -906,7 +896,6 @@ public static float CombinedShannonEntropy(Span x, Span y) return (float)retVal; } else -#endif { double retVal = 0.0d; uint sumX = 0, sumXY = 0; @@ -1053,7 +1042,7 @@ private static float FastLog2Slow(uint v) /// private static int PrefixEncodeBitsNoLut(int distance, ref int extraBits) { - int highestBit = Numerics.Log2((uint)--distance); + int highestBit = BitOperations.Log2((uint)--distance); int secondHighestBit = (distance >> (highestBit - 1)) & 1; extraBits = highestBit - 1; int code = (2 * highestBit) + secondHighestBit; @@ -1062,7 +1051,7 @@ private static int PrefixEncodeBitsNoLut(int distance, ref int extraBits) private static int PrefixEncodeNoLut(int distance, ref int extraBits, ref int extraBitsValue) { - int highestBit = Numerics.Log2((uint)--distance); + int highestBit = BitOperations.Log2((uint)--distance); int secondHighestBit = (distance >> (highestBit - 1)) & 1; extraBits = highestBit - 1; extraBitsValue = distance & ((1 << extraBits) - 1); @@ -1406,7 +1395,6 @@ public static uint AddPixels(uint a, uint b) private static uint ClampedAddSubtractFull(uint c0, uint c1, uint c2) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { Vector128 c0Vec = Sse2.UnpackLow(Sse2.ConvertScalarToVector128UInt32(c0).AsByte(), Vector128.Zero); @@ -1415,10 +1403,9 @@ private static uint ClampedAddSubtractFull(uint c0, uint c1, uint c2) Vector128 v1 = Sse2.Add(c0Vec.AsInt16(), c1Vec.AsInt16()); Vector128 v2 = Sse2.Subtract(v1, c2Vec.AsInt16()); Vector128 b = Sse2.PackUnsignedSaturate(v2, v2); - uint output = Sse2.ConvertToUInt32(b.AsUInt32()); - return output; + return Sse2.ConvertToUInt32(b.AsUInt32()); } -#endif + { int a = AddSubtractComponentFull( (int)(c0 >> 24), @@ -1439,7 +1426,6 @@ private static uint ClampedAddSubtractFull(uint c0, uint c1, uint c2) private static uint ClampedAddSubtractHalf(uint c0, uint c1, uint c2) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { Vector128 c0Vec = Sse2.UnpackLow(Sse2.ConvertScalarToVector128UInt32(c0).AsByte(), Vector128.Zero); @@ -1453,10 +1439,9 @@ private static uint ClampedAddSubtractHalf(uint c0, uint c1, uint c2) Vector128 a3 = Sse2.ShiftRightArithmetic(a2, 1); Vector128 a4 = Sse2.Add(a0, a3).AsInt16(); Vector128 a5 = Sse2.PackUnsignedSaturate(a4, a4); - uint output = Sse2.ConvertToUInt32(a5.AsUInt32()); - return output; + return Sse2.ConvertToUInt32(a5.AsUInt32()); } -#endif + { uint ave = Average2(c0, c1); int a = AddSubtractComponentHalf((int)(ave >> 24), (int)(c2 >> 24)); @@ -1476,17 +1461,14 @@ private static uint ClampedAddSubtractHalf(uint c0, uint c1, uint c2) [MethodImpl(InliningOptions.ShortMethod)] private static uint Clip255(uint a) => a < 256 ? a : ~a >> 24; -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(InliningOptions.ShortMethod)] private static Vector128 MkCst16(int hi, int lo) => Vector128.Create((hi << 16) | (lo & 0xffff)); [MethodImpl(InliningOptions.ShortMethod)] private static Vector256 MkCst32(int hi, int lo) => Vector256.Create((hi << 16) | (lo & 0xffff)); -#endif private static uint Select(uint a, uint b, uint c, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { Span output = scratch; @@ -1510,7 +1492,6 @@ private static uint Select(uint a, uint b, uint c, Span scratch) } } else -#endif { int paMinusPb = Sub3((int)(a >> 24), (int)(b >> 24), (int)(c >> 24)) + diff --git a/src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs b/src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs index db1273f4e7..b2753ab223 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs @@ -44,7 +44,7 @@ private static void NearLossless(int xSize, int ySize, Span argbSrc, int s Span prevRow = copyBuffer; Span currRow = copyBuffer.Slice(xSize, xSize); Span nextRow = copyBuffer.Slice(xSize * 2, xSize); - argbSrc.Slice(0, xSize).CopyTo(currRow); + argbSrc[..xSize].CopyTo(currRow); argbSrc.Slice(xSize, xSize).CopyTo(nextRow); int srcOffset = 0; diff --git a/src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs b/src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs index e2dd8c644d..1383eba78d 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs @@ -230,8 +230,8 @@ private static int GetBestPredictorForTile( // to allow the top right pixel to point to the leftmost pixel of the next row // when at the right edge. Span upperRow = argbScratch; - Span currentRow = upperRow.Slice(width + 1); - Span maxDiffs = MemoryMarshal.Cast(currentRow.Slice(width + 1)); + Span currentRow = upperRow[(width + 1)..]; + Span maxDiffs = MemoryMarshal.Cast(currentRow[(width + 1)..]); float bestDiff = MaxDiffCost; int bestMode = 0; uint[] residuals = new uint[1 << WebpConstants.MaxTransformBits]; @@ -250,7 +250,7 @@ private static int GetBestPredictorForTile( // in all cases (wrapping to the leftmost pixel of the next row if it does // not exist). Span src = argb.Slice(((startY - 1) * width) + contextStartX, maxX + haveLeft + 1); - Span dst = currentRow.Slice(contextStartX); + Span dst = currentRow[contextStartX..]; src.CopyTo(dst); } @@ -267,14 +267,14 @@ private static int GetBestPredictorForTile( // not exist in the currentRow). int offset = (y * width) + contextStartX; Span src = argb.Slice(offset, maxX + haveLeft + (y + 1 < height ? 1 : 0)); - Span dst = currentRow.Slice(contextStartX); + Span dst = currentRow[contextStartX..]; src.CopyTo(dst); if (nearLossless) { if (maxQuantization > 1 && y >= 1 && y + 1 < height) { - MaxDiffsForRow(contextWidth, width, argb, offset, maxDiffs.Slice(contextStartX), usedSubtractGreen); + MaxDiffsForRow(contextWidth, width, argb, offset, maxDiffs[contextStartX..], usedSubtractGreen); } } @@ -589,10 +589,10 @@ private static void CopyImageWithPrediction( // to allow the top right pixel to point to the leftmost pixel of the next row // when at the right edge. Span upperRow = argbScratch; - Span currentRow = upperRow.Slice(width + 1); - Span currentMaxDiffs = MemoryMarshal.Cast(currentRow.Slice(width + 1)); + Span currentRow = upperRow[(width + 1)..]; + Span currentMaxDiffs = MemoryMarshal.Cast(currentRow[(width + 1)..]); - Span lowerMaxDiffs = currentMaxDiffs.Slice(width); + Span lowerMaxDiffs = currentMaxDiffs[width..]; Span scratch = stackalloc short[8]; for (int y = 0; y < height; y++) { @@ -604,7 +604,7 @@ private static void CopyImageWithPrediction( if (lowEffort) { - PredictBatch(PredLowEffort, 0, y, width, currentRow, upperRow, argb.Slice(y * width), scratch); + PredictBatch(PredLowEffort, 0, y, width, currentRow, upperRow, argb[(y * width)..], scratch); } else { @@ -645,7 +645,7 @@ private static void CopyImageWithPrediction( transparentColorMode, usedSubtractGreen, nearLossless, - argb.Slice((y * width) + x), + argb[((y * width) + x)..], scratch); x = xEnd; @@ -820,14 +820,14 @@ private static void CopyTileWithColorTransform(int xSize, int ySize, int tileX, { int xScan = GetMin(maxTileSize, xSize - tileX); int yScan = GetMin(maxTileSize, ySize - tileY); - argb = argb.Slice((tileY * xSize) + tileX); + argb = argb[((tileY * xSize) + tileX)..]; while (yScan-- > 0) { LosslessUtils.TransformColor(colorTransform, argb, xScan); if (argb.Length > xSize) { - argb = argb.Slice(xSize); + argb = argb[xSize..]; } } } @@ -853,7 +853,7 @@ private static Vp8LMultipliers GetBestColorTransformForTile( int allYMax = GetMin(tileYOffset + maxTileSize, ySize); int tileWidth = allXMax - tileXOffset; int tileHeight = allYMax - tileYOffset; - Span tileArgb = argb.Slice((tileYOffset * xSize) + tileXOffset); + Span tileArgb = argb[((tileYOffset * xSize) + tileXOffset)..]; var bestTx = default(Vp8LMultipliers); @@ -954,7 +954,7 @@ private static double GetPredictionCostCrossColorRed( int greenToRed, int[] accumulatedRedHisto) { - Span histo = scratch.Slice(0, 256); + Span histo = scratch[..256]; histo.Clear(); ColorSpaceTransformUtils.CollectColorRedTransforms(argb, stride, tileWidth, tileHeight, greenToRed, histo); @@ -992,7 +992,7 @@ private static double GetPredictionCostCrossColorBlue( int redToBlue, int[] accumulatedBlueHisto) { - Span histo = scratch.Slice(0, 256); + Span histo = scratch[..256]; histo.Clear(); ColorSpaceTransformUtils.CollectColorBlueTransforms(argb, stride, tileWidth, tileHeight, greenToBlue, redToBlue, histo); diff --git a/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs b/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs index f2b855a37b..6e7cbd5e82 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Formats.Webp.BitWriter; @@ -343,7 +344,7 @@ private void EncodeStream(Image image) foreach (CrunchConfig crunchConfig in crunchConfigs) { bgra.CopyTo(encodedData); - bool useCache = true; + const bool useCache = true; this.UsePalette = crunchConfig.EntropyIdx is EntropyIx.Palette or EntropyIx.PaletteAndSpatial; this.UseSubtractGreenTransform = crunchConfig.EntropyIdx is EntropyIx.SubGreen or EntropyIx.SpatialSubGreen; this.UsePredictorTransform = crunchConfig.EntropyIdx is EntropyIx.Spatial or EntropyIx.SpatialSubGreen; @@ -382,7 +383,7 @@ private void EncodeStream(Image image) // If using a color cache, do not have it bigger than the number of colors. if (useCache && this.PaletteSize < 1 << WebpConstants.MaxColorCacheBits) { - this.CacheBits = Numerics.Log2((uint)this.PaletteSize) + 1; + this.CacheBits = BitOperations.Log2((uint)this.PaletteSize) + 1; } } @@ -417,7 +418,7 @@ private void EncodeStream(Image image) if (isFirstConfig || this.bitWriter.NumBytes() < bestSize) { bestSize = this.bitWriter.NumBytes(); - this.BitWriterSwap(ref this.bitWriter, ref bitWriterBest); + BitWriterSwap(ref this.bitWriter, ref bitWriterBest); } // Reset the bit writer for the following iteration if any. @@ -429,7 +430,7 @@ private void EncodeStream(Image image) isFirstConfig = false; } - this.BitWriterSwap(ref bitWriterBest, ref this.bitWriter); + BitWriterSwap(ref bitWriterBest, ref this.bitWriter); } /// @@ -484,7 +485,7 @@ private CrunchConfig[] EncoderAnalyze(ReadOnlySpan bgra, int width, int he EntropyIx entropyIdx = this.AnalyzeEntropy(bgra, width, height, usePalette, this.PaletteSize, this.TransformBits, out redAndBlueAlwaysZero); bool doNotCache = false; - var crunchConfigs = new List(); + List crunchConfigs = new(); if (this.method == WebpEncodingMethod.BestQuality && this.quality == 100) { @@ -539,7 +540,7 @@ private void EncodeImage(int width, int height, bool useCache, CrunchConfig conf Span bgra = this.EncodedData.GetSpan(); int histogramImageXySize = LosslessUtils.SubSampleSize(width, this.HistoBits) * LosslessUtils.SubSampleSize(height, this.HistoBits); ushort[] histogramSymbols = new ushort[histogramImageXySize]; - var huffTree = new HuffmanTree[3 * WebpConstants.CodeLengthCodes]; + HuffmanTree[] huffTree = new HuffmanTree[3 * WebpConstants.CodeLengthCodes]; for (int i = 0; i < huffTree.Length; i++) { huffTree[i] = default; @@ -582,8 +583,8 @@ private void EncodeImage(int width, int height, bool useCache, CrunchConfig conf Vp8LBackwardRefs refsTmp = this.Refs[refsBest.Equals(this.Refs[0]) ? 1 : 0]; this.bitWriter.Reset(bwInit); - var tmpHisto = new Vp8LHistogram(cacheBits); - var histogramImage = new List(histogramImageXySize); + Vp8LHistogram tmpHisto = new(cacheBits); + List histogramImage = new(histogramImageXySize); for (int i = 0; i < histogramImageXySize; i++) { histogramImage.Add(new Vp8LHistogram(cacheBits)); @@ -595,7 +596,7 @@ private void EncodeImage(int width, int height, bool useCache, CrunchConfig conf // Create Huffman bit lengths and codes for each histogram image. int histogramImageSize = histogramImage.Count; int bitArraySize = 5 * histogramImageSize; - var huffmanCodes = new HuffmanTreeCode[bitArraySize]; + HuffmanTreeCode[] huffmanCodes = new HuffmanTreeCode[bitArraySize]; for (int i = 0; i < huffmanCodes.Length; i++) { huffmanCodes[i] = default; @@ -656,7 +657,7 @@ private void EncodeImage(int width, int height, bool useCache, CrunchConfig conf } } - var tokens = new HuffmanTreeToken[maxTokens]; + HuffmanTreeToken[] tokens = new HuffmanTreeToken[maxTokens]; for (int i = 0; i < tokens.Length; i++) { tokens[i] = new HuffmanTreeToken(); @@ -766,13 +767,13 @@ private void EncodeImageNoHuffman(Span bgra, Vp8LHashChain hashChain, Vp8L int cacheBits = 0; ushort[] histogramSymbols = new ushort[1]; // Only one tree, one symbol. - var huffmanCodes = new HuffmanTreeCode[5]; + HuffmanTreeCode[] huffmanCodes = new HuffmanTreeCode[5]; for (int i = 0; i < huffmanCodes.Length; i++) { huffmanCodes[i] = default; } - var huffTree = new HuffmanTree[3UL * WebpConstants.CodeLengthCodes]; + HuffmanTree[] huffTree = new HuffmanTree[3UL * WebpConstants.CodeLengthCodes]; for (int i = 0; i < huffTree.Length; i++) { huffTree[i] = default; @@ -793,7 +794,7 @@ private void EncodeImageNoHuffman(Span bgra, Vp8LHashChain hashChain, Vp8L refsTmp1, refsTmp2); - var histogramImage = new List() + List histogramImage = new() { new(cacheBits) }; @@ -818,7 +819,7 @@ private void EncodeImageNoHuffman(Span bgra, Vp8LHashChain hashChain, Vp8L } } - var tokens = new HuffmanTreeToken[maxTokens]; + HuffmanTreeToken[] tokens = new HuffmanTreeToken[maxTokens]; for (int i = 0; i < tokens.Length; i++) { tokens[i] = new HuffmanTreeToken(); @@ -841,8 +842,8 @@ private void StoreHuffmanCode(HuffmanTree[] huffTree, HuffmanTreeToken[] tokens, int count = 0; Span symbols = this.scratch.AsSpan(0, 2); symbols.Clear(); - int maxBits = 8; - int maxSymbol = 1 << maxBits; + const int maxBits = 8; + const int maxSymbol = 1 << maxBits; // Check whether it's a small tree. for (int i = 0; i < huffmanCode.NumSymbols && count < 3; i++) @@ -895,7 +896,7 @@ private void StoreFullHuffmanCode(HuffmanTree[] huffTree, HuffmanTreeToken[] tok int i; byte[] codeLengthBitDepth = new byte[WebpConstants.CodeLengthCodes]; short[] codeLengthBitDepthSymbols = new short[WebpConstants.CodeLengthCodes]; - var huffmanCode = new HuffmanTreeCode + HuffmanTreeCode huffmanCode = new() { NumSymbols = WebpConstants.CodeLengthCodes, CodeLengths = codeLengthBitDepth, @@ -951,7 +952,7 @@ private void StoreFullHuffmanCode(HuffmanTree[] huffTree, HuffmanTreeToken[] tok } else { - int nBits = Numerics.Log2((uint)trimmedLength - 2); + int nBits = BitOperations.Log2((uint)trimmedLength - 2); int nBitPairs = (nBits / 2) + 1; this.bitWriter.PutBits((uint)nBitPairs - 1, 3); this.bitWriter.PutBits((uint)trimmedLength - 2, nBitPairs * 2); @@ -1098,31 +1099,31 @@ private EntropyIx AnalyzeEntropy(ReadOnlySpan bgra, int width, int height, uint pix = currentRow[x]; uint pixDiff = LosslessUtils.SubPixels(pix, pixPrev); pixPrev = pix; - if (pixDiff == 0 || (prevRow != null && pix == prevRow[x])) + if (pixDiff == 0 || (prevRow.Length > 0 && pix == prevRow[x])) { continue; } AddSingle( pix, - histo.Slice((int)HistoIx.HistoAlpha * 256), - histo.Slice((int)HistoIx.HistoRed * 256), - histo.Slice((int)HistoIx.HistoGreen * 256), - histo.Slice((int)HistoIx.HistoBlue * 256)); + histo[..], + histo[((int)HistoIx.HistoRed * 256)..], + histo[((int)HistoIx.HistoGreen * 256)..], + histo[((int)HistoIx.HistoBlue * 256)..]); AddSingle( pixDiff, - histo.Slice((int)HistoIx.HistoAlphaPred * 256), - histo.Slice((int)HistoIx.HistoRedPred * 256), - histo.Slice((int)HistoIx.HistoGreenPred * 256), - histo.Slice((int)HistoIx.HistoBluePred * 256)); + histo[((int)HistoIx.HistoAlphaPred * 256)..], + histo[((int)HistoIx.HistoRedPred * 256)..], + histo[((int)HistoIx.HistoGreenPred * 256)..], + histo[((int)HistoIx.HistoBluePred * 256)..]); AddSingleSubGreen( pix, - histo.Slice((int)HistoIx.HistoRedSubGreen * 256), - histo.Slice((int)HistoIx.HistoBlueSubGreen * 256)); + histo[((int)HistoIx.HistoRedSubGreen * 256)..], + histo[((int)HistoIx.HistoBlueSubGreen * 256)..]); AddSingleSubGreen( pixDiff, - histo.Slice((int)HistoIx.HistoRedPredSubGreen * 256), - histo.Slice((int)HistoIx.HistoBluePredSubGreen * 256)); + histo[((int)HistoIx.HistoRedPredSubGreen * 256)..], + histo[((int)HistoIx.HistoBluePredSubGreen * 256)..]); // Approximate the palette by the entropy of the multiplicative hash. uint hash = HashPix(pix); @@ -1146,7 +1147,7 @@ private EntropyIx AnalyzeEntropy(ReadOnlySpan bgra, int width, int height, histo[(int)HistoIx.HistoBluePred * 256]++; histo[(int)HistoIx.HistoAlphaPred * 256]++; - var bitEntropy = new Vp8LBitEntropy(); + Vp8LBitEntropy bitEntropy = new(); for (int j = 0; j < (int)HistoIx.HistoTotal; j++) { bitEntropy.Init(); @@ -1213,8 +1214,8 @@ private EntropyIx AnalyzeEntropy(ReadOnlySpan bgra, int width, int height, new[] { (byte)HistoIx.HistoRedPredSubGreen, (byte)HistoIx.HistoBluePredSubGreen }, new[] { (byte)HistoIx.HistoRed, (byte)HistoIx.HistoBlue } }; - Span redHisto = histo.Slice(256 * histoPairs[(int)minEntropyIx][0]); - Span blueHisto = histo.Slice(256 * histoPairs[(int)minEntropyIx][1]); + Span redHisto = histo[(256 * histoPairs[(int)minEntropyIx][0])..]; + Span blueHisto = histo[(256 * histoPairs[(int)minEntropyIx][1])..]; for (int i = 1; i < 256; i++) { if ((redHisto[i] | blueHisto[i]) != 0) @@ -1238,21 +1239,15 @@ private EntropyIx AnalyzeEntropy(ReadOnlySpan bgra, int width, int height, private bool AnalyzeAndCreatePalette(ReadOnlySpan bgra, int width, int height) { Span palette = this.Palette.Memory.Span; - this.PaletteSize = this.GetColorPalette(bgra, width, height, palette); + this.PaletteSize = GetColorPalette(bgra, width, height, palette); if (this.PaletteSize > WebpConstants.MaxPaletteSize) { this.PaletteSize = 0; return false; } -#if NET5_0_OR_GREATER - var paletteSlice = palette.Slice(0, this.PaletteSize); + Span paletteSlice = palette[..this.PaletteSize]; paletteSlice.Sort(); -#else - uint[] paletteArray = palette.Slice(0, this.PaletteSize).ToArray(); - Array.Sort(paletteArray); - paletteArray.CopyTo(palette); -#endif if (PaletteHasNonMonotonousDeltas(palette, this.PaletteSize)) { @@ -1270,9 +1265,9 @@ private bool AnalyzeAndCreatePalette(ReadOnlySpan bgra, int width, int hei /// The image height. /// The span to store the palette into. /// The number of palette entries. - private int GetColorPalette(ReadOnlySpan bgra, int width, int height, Span palette) + private static int GetColorPalette(ReadOnlySpan bgra, int width, int height, Span palette) { - var colors = new HashSet(); + HashSet colors = new(); for (int y = 0; y < height; y++) { ReadOnlySpan bgraRow = bgra.Slice(y * width, width); @@ -1352,8 +1347,8 @@ private void ApplyPalette(Span src, int srcStride, Span dst, int dst } BundleColorMap(tmpRow, width, xBits, dst); - src = src.Slice(srcStride); - dst = dst.Slice(dstStride); + src = src[srcStride..]; + dst = dst[dstStride..]; } } else @@ -1449,8 +1444,8 @@ private static void ApplyPaletteFor(int width, int height, Span palette, i LosslessUtils.BundleColorMap(tmpRow, width, xBits, dst); - src = src.Slice(srcStride); - dst = dst.Slice(dstStride); + src = src[srcStride..]; + dst = dst[dstStride..]; } } @@ -1474,8 +1469,8 @@ private static void ApplyPaletteForWithIdxMap(int width, int height, Span LosslessUtils.BundleColorMap(tmpRow, width, xBits, dst); - src = src.Slice(srcStride); - dst = dst.Slice(dstStride); + src = src[srcStride..]; + dst = dst[dstStride..]; } } @@ -1484,7 +1479,7 @@ private static void ApplyPaletteForWithIdxMap(int width, int height, Span /// private static void PrepareMapToPalette(Span palette, int numColors, uint[] sorted, uint[] idxMap) { - palette.Slice(0, numColors).CopyTo(sorted); + palette[..numColors].CopyTo(sorted); Array.Sort(sorted, PaletteCompareColorsForSort); for (int i = 0; i < numColors; i++) { @@ -1552,7 +1547,7 @@ private static void ClearHuffmanTreeIfOnlyOneSymbol(HuffmanTreeCode huffmanCode) /// True, if the palette has no monotonous deltas. private static bool PaletteHasNonMonotonousDeltas(Span palette, int numColors) { - uint predict = 0x000000; + const uint predict = 0x000000; byte signFound = 0x00; for (int i = 0; i < numColors; i++) { @@ -1642,7 +1637,7 @@ private static void GetHuffBitLengthsAndCodes(List histogramImage // Create Huffman trees. bool[] bufRle = new bool[maxNumSymbols]; - var huffTree = new HuffmanTree[3 * maxNumSymbols]; + HuffmanTree[] huffTree = new HuffmanTree[3 * maxNumSymbols]; for (int i = 0; i < huffTree.Length; i++) { huffTree[i] = default; @@ -1670,7 +1665,7 @@ private static void GetHuffBitLengthsAndCodes(List histogramImage private static uint PaletteColorDistance(uint col1, uint col2) { uint diff = LosslessUtils.SubPixels(col1, col2); - uint moreWeightForRGBThanForAlpha = 9; + const uint moreWeightForRGBThanForAlpha = 9; uint score = PaletteComponentDistance((diff >> 0) & 0xff); score += PaletteComponentDistance((diff >> 8) & 0xff); score += PaletteComponentDistance((diff >> 16) & 0xff); @@ -1735,7 +1730,7 @@ private static void BundleColorMap(Span row, int width, int xBits, Span bgra, int quality, int xSize, int ySize, boo else { // Just move one pixel forward. - hashCode = GetPixPairHash64(bgra.Slice(pos)); + hashCode = GetPixPairHash64(bgra[pos..]); chain[pos] = hashToFirstIndex[(int)hashCode]; hashToFirstIndex[(int)hashCode] = pos++; bgraComp = bgraCompNext; @@ -133,7 +133,7 @@ public void Fill(ReadOnlySpan bgra, int quality, int xSize, int ySize, boo } // Process the penultimate pixel. - chain[pos] = hashToFirstIndex[(int)GetPixPairHash64(bgra.Slice(pos))]; + chain[pos] = hashToFirstIndex[(int)GetPixPairHash64(bgra[pos..])]; // Find the best match interval at each pixel, defined by an offset to the // pixel and a length. The right-most pixel cannot match anything to the right @@ -157,7 +157,7 @@ public void Fill(ReadOnlySpan bgra, int quality, int xSize, int ySize, boo // Heuristic: use the comparison with the above line as an initialization. if (basePosition >= (uint)xSize) { - currLength = LosslessUtils.FindMatchLength(bgra.Slice(bgraStart - xSize), bgra.Slice(bgraStart), bestLength, maxLen); + currLength = LosslessUtils.FindMatchLength(bgra[(bgraStart - xSize)..], bgra[bgraStart..], bestLength, maxLen); if (currLength > bestLength) { bestLength = currLength; @@ -168,7 +168,7 @@ public void Fill(ReadOnlySpan bgra, int quality, int xSize, int ySize, boo } // Heuristic: compare to the previous pixel. - currLength = LosslessUtils.FindMatchLength(bgra.Slice(bgraStart - 1), bgra.Slice(bgraStart), bestLength, maxLen); + currLength = LosslessUtils.FindMatchLength(bgra[(bgraStart - 1)..], bgra[bgraStart..], bestLength, maxLen); if (currLength > bestLength) { bestLength = currLength; @@ -184,7 +184,7 @@ public void Fill(ReadOnlySpan bgra, int quality, int xSize, int ySize, boo } } - uint bestBgra = bgra.Slice(bgraStart)[bestLength]; + uint bestBgra = bgra[bgraStart..][bestLength]; for (; pos >= minPos && (--iter > 0); pos = chain[pos]) { @@ -193,12 +193,12 @@ public void Fill(ReadOnlySpan bgra, int quality, int xSize, int ySize, boo continue; } - currLength = LosslessUtils.VectorMismatch(bgra.Slice(pos), bgra.Slice(bgraStart), maxLen); + currLength = LosslessUtils.VectorMismatch(bgra[pos..], bgra[bgraStart..], maxLen); if (bestLength < currLength) { bestLength = currLength; bestDistance = (uint)(basePosition - pos); - bestBgra = bgra.Slice(bgraStart)[bestLength]; + bestBgra = bgra[bgraStart..][bestLength]; // Stop if we have reached a good enough length. if (bestLength >= lengthMax) diff --git a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs index 0c9bed3661..dca239e85e 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs @@ -5,10 +5,8 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossless { @@ -517,7 +515,6 @@ private static void AddVector(Span a, Span b, Span output, int DebugGuard.MustBeGreaterThanOrEqualTo(b.Length, count, nameof(b.Length)); DebugGuard.MustBeGreaterThanOrEqualTo(output.Length, count, nameof(output.Length)); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { ref uint aRef = ref MemoryMarshal.GetReference(a); @@ -551,7 +548,6 @@ private static void AddVector(Span a, Span b, Span output, int } } else -#endif { for (int i = 0; i < count; i++) { diff --git a/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs b/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs index ff2b808dd7..b90dbf4dbb 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs @@ -96,7 +96,7 @@ public WebpLosslessDecoder(Vp8LBitReader bitReader, MemoryAllocator memoryAlloca public void Decode(Buffer2D pixels, int width, int height) where TPixel : unmanaged, IPixel { - using (var decoder = new Vp8LDecoder(width, height, this.memoryAllocator)) + using (Vp8LDecoder decoder = new(width, height, this.memoryAllocator)) { this.DecodeImageStream(decoder, width, height, true); this.DecodeImageData(decoder, decoder.Pixels.Memory.Span); @@ -169,7 +169,7 @@ public IMemoryOwner DecodeImageStream(Vp8LDecoder decoder, int xSize, int decoder.Metadata.ColorCacheSize = 0; } - this.UpdateDecoder(decoder, transformXSize, transformYSize); + UpdateDecoder(decoder, transformXSize, transformYSize); if (isLevel0) { // level 0 complete. @@ -199,15 +199,15 @@ private void DecodePixelValues(Vp8LDecoder decoder, Buffer2D pix Span pixelRow = pixels.DangerousGetRowSpan(y); PixelOperations.Instance.FromBgra32Bytes( this.configuration, - rowAsBytes.Slice(0, bytesPerRow), - pixelRow.Slice(0, width), + rowAsBytes[..bytesPerRow], + pixelRow[..width], width); } } public void DecodeImageData(Vp8LDecoder decoder, Span pixelData) { - int lastPixel = 0; + const int lastPixel = 0; int width = decoder.Width; int height = decoder.Height; int row = lastPixel / width; @@ -233,7 +233,7 @@ public void DecodeImageData(Vp8LDecoder decoder, Span pixelData) if (hTreeGroup[0].IsTrivialCode) { pixelData[decodedPixels] = hTreeGroup[0].LiteralArb; - this.AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); + AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); continue; } @@ -248,7 +248,7 @@ public void DecodeImageData(Vp8LDecoder decoder, Span pixelData) if (code == PackedNonLiteralCode) { - this.AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); + AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); continue; } } @@ -283,7 +283,7 @@ public void DecodeImageData(Vp8LDecoder decoder, Span pixelData) pixelData[decodedPixels] = (uint)(((byte)alpha << 24) | ((byte)red << 16) | ((byte)code << 8) | (byte)blue); } - this.AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); + AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); } else if (code < lenCodeLimit) { @@ -333,7 +333,7 @@ public void DecodeImageData(Vp8LDecoder decoder, Span pixelData) } pixelData[decodedPixels] = colorCache.Lookup(key); - this.AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); + AdvanceByOne(ref col, ref row, width, colorCache, ref decodedPixels, pixelData, ref lastCached); } else { @@ -342,7 +342,7 @@ public void DecodeImageData(Vp8LDecoder decoder, Span pixelData) } } - private void AdvanceByOne(ref int col, ref int row, int width, ColorCache colorCache, ref int decodedPixels, Span pixelData, ref int lastCached) + private static void AdvanceByOne(ref int col, ref int row, int width, ColorCache colorCache, ref int decodedPixels, Span pixelData, ref int lastCached) { col++; decodedPixels++; @@ -414,8 +414,8 @@ private void ReadHuffmanCodes(Vp8LDecoder decoder, int xSize, int ySize, int col } int tableSize = TableSize[colorCacheBits]; - var huffmanTables = new HuffmanCode[numHTreeGroups * tableSize]; - var hTreeGroups = new HTreeGroup[numHTreeGroups]; + HuffmanCode[] huffmanTables = new HuffmanCode[numHTreeGroups * tableSize]; + HTreeGroup[] hTreeGroups = new HTreeGroup[numHTreeGroups]; Span huffmanTable = huffmanTables.AsSpan(); int[] codeLengths = new int[maxAlphabetSize]; for (int i = 0; i < numHTreeGroupsMax; i++) @@ -441,7 +441,7 @@ private void ReadHuffmanCodes(Vp8LDecoder decoder, int xSize, int ySize, int col } // TODO: Avoid allocation. - hTreeGroup.HTrees.Add(huffmanTable.Slice(0, size).ToArray()); + hTreeGroup.HTrees.Add(huffmanTable[..size].ToArray()); HuffmanCode huffTableZero = huffmanTable[0]; if (isTrivialLiteral && LiteralMap[j] == 1) @@ -450,7 +450,7 @@ private void ReadHuffmanCodes(Vp8LDecoder decoder, int xSize, int ySize, int col } totalSize += huffTableZero.BitsUsed; - huffmanTable = huffmanTable.Slice(size); + huffmanTable = huffmanTable[size..]; if (j <= HuffIndex.Alpha) { @@ -488,7 +488,7 @@ private void ReadHuffmanCodes(Vp8LDecoder decoder, int xSize, int ySize, int col hTreeGroup.UsePackedTable = !hTreeGroup.IsTrivialCode && maxBits < HuffmanUtils.HuffmanPackedBits; if (hTreeGroup.UsePackedTable) { - this.BuildPackedTable(hTreeGroup); + BuildPackedTable(hTreeGroup); } } @@ -546,9 +546,7 @@ private int ReadHuffmanCode(int alphabetSize, int[] codeLengths, Span table, int[] codeLengthCodeLengths, int numSymbols, int[] codeLengths) @@ -622,8 +620,8 @@ private void ReadHuffmanCodeLengths(Span table, int[] codeLengthCod /// Vp8LDecoder where the transformations will be stored. private void ReadTransformation(int xSize, int ySize, Vp8LDecoder decoder) { - var transformType = (Vp8LTransformType)this.bitReader.ReadValue(2); - var transform = new Vp8LTransform(transformType, xSize, ySize); + Vp8LTransformType transformType = (Vp8LTransformType)this.bitReader.ReadValue(2); + Vp8LTransform transform = new(transformType, xSize, ySize); // Each transform is allowed to be used only once. foreach (Vp8LTransform decoderTransform in decoder.Transforms) @@ -643,11 +641,23 @@ private void ReadTransformation(int xSize, int ySize, Vp8LDecoder decoder) // The transform data contains color table size and the entries in the color table. // 8 bit value for color table size. uint numColors = this.bitReader.ReadValue(8) + 1; - int bits = numColors > 16 ? 0 - : numColors > 4 ? 1 - : numColors > 2 ? 2 - : 3; - transform.Bits = bits; + if (numColors > 16) + { + transform.Bits = 0; + } + else if (numColors > 4) + { + transform.Bits = 1; + } + else if (numColors > 2) + { + transform.Bits = 2; + } + else + { + transform.Bits = 3; + } + using (IMemoryOwner colorMap = this.DecodeImageStream(decoder, (int)numColors, 1, false)) { int finalNumColors = 1 << (8 >> transform.Bits); @@ -660,15 +670,13 @@ private void ReadTransformation(int xSize, int ySize, Vp8LDecoder decoder) case Vp8LTransformType.PredictorTransform: case Vp8LTransformType.CrossColorTransform: - { + // The first 3 bits of prediction data define the block width and height in number of bits. transform.Bits = (int)this.bitReader.ReadValue(3) + 2; int blockWidth = LosslessUtils.SubSampleSize(transform.XSize, transform.Bits); int blockHeight = LosslessUtils.SubSampleSize(transform.YSize, transform.Bits); - IMemoryOwner transformData = this.DecodeImageStream(decoder, blockWidth, blockHeight, false); - transform.Data = transformData; + transform.Data = this.DecodeImageStream(decoder, blockWidth, blockHeight, false); break; - } } decoder.Transforms.Add(transform); @@ -687,8 +695,7 @@ public static void ApplyInverseTransforms(Vp8LDecoder decoder, Span pixelD for (int i = transforms.Count - 1; i >= 0; i--) { Vp8LTransform transform = transforms[i]; - Vp8LTransformType transformType = transform.TransformType; - switch (transformType) + switch (transform.TransformType) { case Vp8LTransformType.PredictorTransform: using (IMemoryOwner output = memoryAllocator.Allocate(pixelData.Length, AllocationOptions.Clean)) @@ -806,7 +813,7 @@ public void DecodeAlphaData(AlphaDecoder dec) dec.ExtractPalettedAlphaRows(row > lastRow ? lastRow : row); } - private void UpdateDecoder(Vp8LDecoder decoder, int width, int height) + private static void UpdateDecoder(Vp8LDecoder decoder, int width, int height) { int numBits = decoder.Metadata.HuffmanSubSampleBits; decoder.Width = width; @@ -831,7 +838,7 @@ private uint ReadPackedSymbols(Span group, Span pixelData, int return code.Value; } - private void BuildPackedTable(HTreeGroup hTreeGroup) + private static void BuildPackedTable(HTreeGroup hTreeGroup) { for (uint code = 0; code < HuffmanUtils.HuffmanPackedTableSize; code++) { @@ -859,17 +866,18 @@ private void BuildPackedTable(HTreeGroup hTreeGroup) /// Decodes the next Huffman code from the bit-stream. /// FillBitWindow() needs to be called at minimum every second call to ReadSymbol, in order to pre-fetch enough bits. /// + /// The Huffman table. private uint ReadSymbol(Span table) { uint val = (uint)this.bitReader.PrefetchBits(); - Span tableSpan = table.Slice((int)(val & HuffmanUtils.HuffmanTableMask)); + Span tableSpan = table[(int)(val & HuffmanUtils.HuffmanTableMask)..]; int nBits = tableSpan[0].BitsUsed - HuffmanUtils.HuffmanTableBits; if (nBits > 0) { this.bitReader.AdvanceBitPosition(HuffmanUtils.HuffmanTableBits); val = (uint)this.bitReader.PrefetchBits(); - tableSpan = tableSpan.Slice((int)tableSpan[0].Value); - tableSpan = tableSpan.Slice((int)val & ((1 << nBits) - 1)); + tableSpan = tableSpan[(int)tableSpan[0].Value..]; + tableSpan = tableSpan[((int)val & ((1 << nBits) - 1))..]; } this.bitReader.AdvanceBitPosition(tableSpan[0].BitsUsed); @@ -949,14 +957,14 @@ private static void CopyBlock(Span pixelData, int decodedPixels, int dist, { // no overlap. Span src = pixelData.Slice(start, length); - Span dest = pixelData.Slice(decodedPixels); + Span dest = pixelData[decodedPixels..]; src.CopyTo(dest); } else { // There is overlap between the backward reference distance and the pixels to copy. - Span src = pixelData.Slice(start); - Span dest = pixelData.Slice(decodedPixels); + Span src = pixelData[start..]; + Span dest = pixelData[decodedPixels..]; for (int i = 0; i < length; i++) { dest[i] = src[i]; @@ -977,12 +985,12 @@ private static void CopyBlock8B(Span data, int pos, int dist, int length) if (dist >= length) { // no overlap. - data.Slice(pos - dist, length).CopyTo(data.Slice(pos)); + data.Slice(pos - dist, length).CopyTo(data[pos..]); } else { - Span dst = data.Slice(pos); - Span src = data.Slice(pos - dist); + Span dst = data[pos..]; + Span src = data[(pos - dist)..]; for (int i = 0; i < length; i++) { dst[i] = src[i]; diff --git a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs index e19a813a47..210125790c 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs @@ -5,10 +5,8 @@ using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Webp.Lossy @@ -19,7 +17,6 @@ internal static class LossyUtils [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8_Sse16X16(Span a, Span b) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { return Vp8_Sse16xN_Avx2(a, b, 4); @@ -29,17 +26,14 @@ public static int Vp8_Sse16X16(Span a, Span b) { return Vp8_Sse16xN_Sse2(a, b, 8); } -#endif - { - return Vp8_SseNxN(a, b, 16, 16); - } + + return Vp8_SseNxN(a, b, 16, 16); } // Note: method name in libwebp reference implementation is called VP8SSE16x8. [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8_Sse16X8(Span a, Span b) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { return Vp8_Sse16xN_Avx2(a, b, 2); @@ -49,17 +43,14 @@ public static int Vp8_Sse16X8(Span a, Span b) { return Vp8_Sse16xN_Sse2(a, b, 4); } -#endif - { - return Vp8_SseNxN(a, b, 16, 8); - } + + return Vp8_SseNxN(a, b, 16, 8); } // Note: method name in libwebp reference implementation is called VP8SSE4x4. [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8_Sse4X4(Span a, Span b) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { // Load values. @@ -128,10 +119,8 @@ public static int Vp8_Sse4X4(Span a, Span b) return Numerics.ReduceSum(sum); } -#endif - { - return Vp8_SseNxN(a, b, 4, 4); - } + + return Vp8_SseNxN(a, b, 4, 4); } [MethodImpl(InliningOptions.ShortMethod)] @@ -155,7 +144,6 @@ public static int Vp8_SseNxN(Span a, Span b, int w, int h) return count; } -#if SUPPORTS_RUNTIME_INTRINSICS [MethodImpl(InliningOptions.ShortMethod)] private static int Vp8_Sse16xN_Sse2(Span a, Span b, int numPairs) { @@ -251,7 +239,6 @@ private static Vector256 SubtractAndAccumulate(Vector256 a, Vector256 return Avx2.Add(sum1, sum2); } -#endif [MethodImpl(InliningOptions.ShortMethod)] public static void Vp8Copy4X4(Span src, Span dst) => Copy(src, dst, 4, 4); @@ -274,7 +261,7 @@ public static void Copy(Span src, Span dst, int w, int h) public static int Vp8Disto16X16(Span a, Span b, Span w, Span scratch) { int d = 0; - int dataSize = (4 * WebpConstants.Bps) - 16; + const int dataSize = (4 * WebpConstants.Bps) - 16; for (int y = 0; y < 16 * WebpConstants.Bps; y += 4 * WebpConstants.Bps) { for (int x = 0; x < 16; x += 4) @@ -289,14 +276,12 @@ public static int Vp8Disto16X16(Span a, Span b, Span w, Span [MethodImpl(InliningOptions.ShortMethod)] public static int Vp8Disto4X4(Span a, Span b, Span w, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported) { int diffSum = TTransformSse41(a, b, w); return Math.Abs(diffSum) >> 5; } else -#endif { int sum1 = TTransform(a, w, scratch); int sum2 = TTransform(b, w, scratch); @@ -328,7 +313,7 @@ public static void VE16(Span dst, Span yuv, int offset) for (int j = 0; j < 16; j++) { // memcpy(dst + j * BPS, dst - BPS, 16); - src.CopyTo(dst.Slice(j * WebpConstants.Bps)); + src.CopyTo(dst[(j * WebpConstants.Bps)..]); } } @@ -342,7 +327,7 @@ public static void HE16(Span dst, Span yuv, int offset) byte v = yuv[offset]; Memset(dst, v, 0, 16); offset += WebpConstants.Bps; - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } @@ -399,11 +384,11 @@ public static void VE8uv(Span dst, Span yuv, int offset) // vertical Span src = yuv.Slice(offset - WebpConstants.Bps, 8); - int endIdx = 8 * WebpConstants.Bps; + const int endIdx = 8 * WebpConstants.Bps; for (int j = 0; j < endIdx; j += WebpConstants.Bps) { // memcpy(dst + j * BPS, dst - BPS, 8); - src.CopyTo(dst.Slice(j)); + src.CopyTo(dst[j..]); } } @@ -417,7 +402,7 @@ public static void HE8uv(Span dst, Span yuv, int offset) // dst += BPS; byte v = yuv[offset]; Memset(dst, v, 0, 8); - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; offset += WebpConstants.Bps; } } @@ -427,7 +412,7 @@ public static void DC8uvNoTop(Span dst, Span yuv, int offset) // DC with no top samples. int dc0 = 4; int offsetMinusOne = offset - 1; - int endIdx = 8 * WebpConstants.Bps; + const int endIdx = 8 * WebpConstants.Bps; for (int i = 0; i < endIdx; i += WebpConstants.Bps) { // dc0 += dst[-1 + i * BPS]; @@ -466,7 +451,7 @@ public static void DC4(Span dst, Span yuv, int offset) } dc >>= 3; - int endIndx = 4 * WebpConstants.Bps; + const int endIndx = 4 * WebpConstants.Bps; for (int i = 0; i < endIndx; i += WebpConstants.Bps) { Memset(dst, (byte)dc, i, 4); @@ -484,10 +469,10 @@ public static void VE4(Span dst, Span yuv, int offset, Span va vals[1] = Avg3(yuv[topOffset], yuv[topOffset + 1], yuv[topOffset + 2]); vals[2] = Avg3(yuv[topOffset + 1], yuv[topOffset + 2], yuv[topOffset + 3]); vals[3] = Avg3(yuv[topOffset + 2], yuv[topOffset + 3], yuv[topOffset + 4]); - int endIdx = 4 * WebpConstants.Bps; + const int endIdx = 4 * WebpConstants.Bps; for (int i = 0; i < endIdx; i += WebpConstants.Bps) { - vals.CopyTo(dst.Slice(i)); + vals.CopyTo(dst[i..]); } } @@ -503,11 +488,11 @@ public static void HE4(Span dst, Span yuv, int offset) uint val = 0x01010101U * Avg3(a, b, c); BinaryPrimitives.WriteUInt32BigEndian(dst, val); val = 0x01010101U * Avg3(b, c, d); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[WebpConstants.Bps..], val); val = 0x01010101U * Avg3(c, d, e); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(2 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(2 * WebpConstants.Bps)..], val); val = 0x01010101U * Avg3(d, e, e); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(3 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(3 * WebpConstants.Bps)..], val); } public static void RD4(Span dst, Span yuv, int offset) @@ -726,7 +711,7 @@ public static void HU4(Span dst, Span yuv, int offset) /// public static void TransformWht(Span input, Span output, Span scratch) { - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; tmp.Clear(); for (int i = 0; i < 4; i++) { @@ -768,7 +753,7 @@ public static void TransformWht(Span input, Span output, Span public static int TTransform(Span input, Span w, Span scratch) { int sum = 0; - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; tmp.Clear(); // horizontal pass. @@ -807,13 +792,12 @@ public static int TTransform(Span input, Span w, Span scratch sum += w[8] * Math.Abs(b2); sum += w[12] * Math.Abs(b3); - w = w.Slice(1); + w = w[1..]; } return sum; } -#if SUPPORTS_RUNTIME_INTRINSICS /// /// Hadamard transform /// Returns the weighted sum of the absolute value of transformed coefficients. @@ -944,13 +928,11 @@ public static void Vp8Transpose_2_4x4_16b(Vector128 b0, Vector128 // a02 a12 a22 a32 b02 b12 b22 b32 // a03 a13 a23 a33 b03 b13 b23 b33 } -#endif // Transforms (Paragraph 14.4). // Does two transforms. public static void TransformTwo(Span src, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // This implementation makes use of 16-bit fixed point versions of two @@ -1002,8 +984,8 @@ public static void TransformTwo(Span src, Span dst, Span scrat Vector128 a = Sse2.Add(in0.AsInt16(), in2.AsInt16()); Vector128 b = Sse2.Subtract(in0.AsInt16(), in2.AsInt16()); - Vector128 k1 = Vector128.Create((short)20091); - Vector128 k2 = Vector128.Create((short)-30068); + var k1 = Vector128.Create((short)20091); + var k2 = Vector128.Create((short)-30068); // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3 Vector128 c1 = Sse2.MultiplyHigh(in1.AsInt16(), k2); @@ -1097,16 +1079,14 @@ public static void TransformTwo(Span src, Span dst, Span scrat Unsafe.As>(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = dst3.GetLower(); } else -#endif { TransformOne(src, dst, scratch); - TransformOne(src.Slice(16), dst.Slice(4), scratch); + TransformOne(src[16..], dst[4..], scratch); } } public static void TransformOne(Span src, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load and concatenate the transform coefficients. @@ -1126,8 +1106,8 @@ public static void TransformOne(Span src, Span dst, Span scrat Vector128 a = Sse2.Add(in0.AsInt16(), in2.AsInt16()); Vector128 b = Sse2.Subtract(in0.AsInt16(), in2.AsInt16()); - Vector128 k1 = Vector128.Create((short)20091); - Vector128 k2 = Vector128.Create((short)-30068); + var k1 = Vector128.Create((short)20091); + var k2 = Vector128.Create((short)-30068); // c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3 Vector128 c1 = Sse2.MultiplyHigh(in1.AsInt16(), k2); @@ -1225,9 +1205,8 @@ public static void TransformOne(Span src, Span dst, Span scrat Unsafe.As(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = output3; } else -#endif { - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; int tmpOffset = 0; for (int srcOffset = 0; srcOffset < 4; srcOffset++) { @@ -1263,10 +1242,10 @@ public static void TransformOne(Span src, Span dst, Span scrat int b = dc - tmp[tmpOffsetPlus8]; int c = Mul2(tmp[tmpOffsetPlus4]) - Mul1(tmp[tmpOffsetPlus12]); int d = Mul1(tmp[tmpOffsetPlus4]) + Mul2(tmp[tmpOffsetPlus12]); - Store(dst.Slice(dstOffset), 0, 0, a + d); - Store(dst.Slice(dstOffset), 1, 0, b + c); - Store(dst.Slice(dstOffset), 2, 0, b - c); - Store(dst.Slice(dstOffset), 3, 0, a - d); + Store(dst[dstOffset..], 0, 0, a + d); + Store(dst[dstOffset..], 1, 0, b + c); + Store(dst[dstOffset..], 2, 0, b - c); + Store(dst[dstOffset..], 3, 0, a - d); tmpOffset++; dstOffset += WebpConstants.Bps; @@ -1302,37 +1281,36 @@ public static void TransformAc3(Span src, Span dst) public static void TransformUv(Span src, Span dst, Span scratch) { - TransformTwo(src.Slice(0 * 16), dst, scratch); - TransformTwo(src.Slice(2 * 16), dst.Slice(4 * WebpConstants.Bps), scratch); + TransformTwo(src[..], dst, scratch); + TransformTwo(src[(2 * 16)..], dst[(4 * WebpConstants.Bps)..], scratch); } public static void TransformDcuv(Span src, Span dst) { if (src[0 * 16] != 0) { - TransformDc(src.Slice(0 * 16), dst); + TransformDc(src[..], dst); } if (src[1 * 16] != 0) { - TransformDc(src.Slice(1 * 16), dst.Slice(4)); + TransformDc(src[(1 * 16)..], dst[4..]); } if (src[2 * 16] != 0) { - TransformDc(src.Slice(2 * 16), dst.Slice(4 * WebpConstants.Bps)); + TransformDc(src[(2 * 16)..], dst[(4 * WebpConstants.Bps)..]); } if (src[3 * 16] != 0) { - TransformDc(src.Slice(3 * 16), dst.Slice((4 * WebpConstants.Bps) + 4)); + TransformDc(src[(3 * 16)..], dst[((4 * WebpConstants.Bps) + 4)..]); } } // Simple In-loop filtering (Paragraph 15.2) public static void SimpleVFilter16(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load. @@ -1351,7 +1329,6 @@ public static void SimpleVFilter16(Span p, int offset, int stride, int thr Unsafe.As>(ref outputRef) = q0.AsSByte(); } else -#endif { int thresh2 = (2 * thresh) + 1; int end = 16 + offset; @@ -1367,7 +1344,6 @@ public static void SimpleVFilter16(Span p, int offset, int stride, int thr public static void SimpleHFilter16(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Beginning of p1 @@ -1378,7 +1354,6 @@ public static void SimpleHFilter16(Span p, int offset, int stride, int thr Store16x4(p1, p0, q0, q1, ref pRef, ref Unsafe.Add(ref pRef, 8 * stride), stride); } else -#endif { int thresh2 = (2 * thresh) + 1; int end = offset + (16 * stride); @@ -1394,7 +1369,6 @@ public static void SimpleHFilter16(Span p, int offset, int stride, int thr public static void SimpleVFilter16i(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { for (int k = 3; k > 0; k--) @@ -1404,7 +1378,6 @@ public static void SimpleVFilter16i(Span p, int offset, int stride, int th } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1416,7 +1389,6 @@ public static void SimpleVFilter16i(Span p, int offset, int stride, int th public static void SimpleHFilter16i(Span p, int offset, int stride, int thresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { for (int k = 3; k > 0; k--) @@ -1426,7 +1398,6 @@ public static void SimpleHFilter16i(Span p, int offset, int stride, int th } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1440,7 +1411,6 @@ public static void SimpleHFilter16i(Span p, int offset, int stride, int th [MethodImpl(InliningOptions.ShortMethod)] public static void VFilter16(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1475,7 +1445,6 @@ public static void VFilter16(Span p, int offset, int stride, int thresh, i Unsafe.As>(ref Unsafe.Add(ref outputRef, offset + (2 * stride))) = q2.AsInt32(); } else -#endif { FilterLoop26(p, offset, stride, 1, 16, thresh, ithresh, hevThresh); } @@ -1484,7 +1453,6 @@ public static void VFilter16(Span p, int offset, int stride, int thresh, i [MethodImpl(InliningOptions.ShortMethod)] public static void HFilter16(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1508,7 +1476,6 @@ public static void HFilter16(Span p, int offset, int stride, int thresh, i Store16x4(q0, q1, q2, q3, ref Unsafe.Add(ref pRef, offset), ref Unsafe.Add(ref pRef, offset + (8 * stride)), stride); } else -#endif { FilterLoop26(p, offset, 1, stride, 16, thresh, ithresh, hevThresh); } @@ -1516,7 +1483,6 @@ public static void HFilter16(Span p, int offset, int stride, int thresh, i public static void VFilter16i(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1528,7 +1494,7 @@ public static void VFilter16i(Span p, int offset, int stride, int thresh, for (int k = 3; k > 0; k--) { // Beginning of p1. - Span b = p.Slice(offset + (2 * stride)); + Span b = p[(offset + (2 * stride))..]; offset += 4 * stride; Vector128 mask = Abs(p0, p1); @@ -1562,7 +1528,6 @@ public static void VFilter16i(Span p, int offset, int stride, int thresh, } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1574,7 +1539,6 @@ public static void VFilter16i(Span p, int offset, int stride, int thresh, public static void HFilter16i(Span p, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte pRef = ref MemoryMarshal.GetReference(p); @@ -1611,7 +1575,6 @@ public static void HFilter16i(Span p, int offset, int stride, int thresh, } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1625,7 +1588,6 @@ public static void HFilter16i(Span p, int offset, int stride, int thresh, [MethodImpl(InliningOptions.ShortMethod)] public static void VFilter8(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load uv h-edges. @@ -1661,7 +1623,6 @@ public static void VFilter8(Span u, Span v, int offset, int stride, StoreUv(q2, ref uRef, ref vRef, offset + (2 * stride)); } else -#endif { FilterLoop26(u, offset, stride, 1, 8, thresh, ithresh, hevThresh); FilterLoop26(v, offset, stride, 1, 8, thresh, ithresh, hevThresh); @@ -1671,7 +1632,6 @@ public static void VFilter8(Span u, Span v, int offset, int stride, [MethodImpl(InliningOptions.ShortMethod)] public static void HFilter8(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte uRef = ref MemoryMarshal.GetReference(u); @@ -1695,7 +1655,6 @@ public static void HFilter8(Span u, Span v, int offset, int stride, Store16x4(q0, q1, q2, q3, ref Unsafe.Add(ref uRef, offset), ref Unsafe.Add(ref vRef, offset), stride); } else -#endif { FilterLoop26(u, offset, 1, stride, 8, thresh, ithresh, hevThresh); FilterLoop26(v, offset, 1, stride, 8, thresh, ithresh, hevThresh); @@ -1705,7 +1664,6 @@ public static void HFilter8(Span u, Span v, int offset, int stride, [MethodImpl(InliningOptions.ShortMethod)] public static void VFilter8i(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load uv h-edges. @@ -1741,7 +1699,6 @@ public static void VFilter8i(Span u, Span v, int offset, int stride, StoreUv(q1, ref uRef, ref vRef, offset + stride); } else -#endif { int offset4mulstride = offset + (4 * stride); FilterLoop24(u, offset4mulstride, stride, 1, 8, thresh, ithresh, hevThresh); @@ -1752,7 +1709,6 @@ public static void VFilter8i(Span u, Span v, int offset, int stride, [MethodImpl(InliningOptions.ShortMethod)] public static void HFilter8i(Span u, Span v, int offset, int stride, int thresh, int ithresh, int hevThresh) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte uRef = ref MemoryMarshal.GetReference(u); @@ -1780,7 +1736,6 @@ public static void HFilter8i(Span u, Span v, int offset, int stride, Store16x4(p1, p0, q0, q1, ref Unsafe.Add(ref uRef, offset), ref Unsafe.Add(ref vRef, offset), stride); } else -#endif { int offsetPlus4 = offset + 4; FilterLoop24(u, offsetPlus4, 1, stride, 8, thresh, ithresh, hevThresh); @@ -1790,7 +1745,6 @@ public static void HFilter8i(Span u, Span v, int offset, int stride, public static void Mean16x4(Span input, Span dc) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Ssse3.IsSupported) { Vector128 mean16x4Mask = Vector128.Create((short)0x00ff).AsByte(); @@ -1821,7 +1775,6 @@ public static void Mean16x4(Span input, Span dc) Unsafe.As>(ref outputRef) = wide; } else -#endif { for (int k = 0; k < 4; k++) { @@ -1835,7 +1788,7 @@ public static void Mean16x4(Span input, Span dc) } dc[k] = avg; - input = input.Slice(4); // go to next 4x4 block. + input = input[4..]; // go to next 4x4 block. } } } @@ -1860,7 +1813,7 @@ private static void Put16(int v, Span dst) { for (int j = 0; j < 16; j++) { - Memset(dst.Slice(j * WebpConstants.Bps), (byte)v, 0, 16); + Memset(dst[(j * WebpConstants.Bps)..], (byte)v, 0, 16); } } @@ -1868,7 +1821,7 @@ private static void TrueMotion(Span dst, Span yuv, int offset, int s { // For information about how true motion works, see rfc6386, page 52. ff and section 20.14. int topOffset = offset - WebpConstants.Bps; - Span top = yuv.Slice(topOffset); + Span top = yuv[topOffset..]; byte p = yuv[topOffset - 1]; int leftOffset = offset - 1; byte left = yuv[leftOffset]; @@ -1881,7 +1834,7 @@ private static void TrueMotion(Span dst, Span yuv, int offset, int s leftOffset += WebpConstants.Bps; left = yuv[leftOffset]; - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } @@ -1959,11 +1912,10 @@ private static void DoFilter2(Span p, int offset, int step) p[offset] = WebpLookupTables.Clip1(q0 - a1); } -#if SUPPORTS_RUNTIME_INTRINSICS // Applies filter on 2 pixels (p0 and q0) private static void DoFilter2Sse2(ref Vector128 p1, ref Vector128 p0, ref Vector128 q0, ref Vector128 q1, int thresh) { - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); // Convert p1/q1 to byte (for GetBaseDelta). Vector128 p1s = Sse2.Xor(p1, signBit); @@ -1992,7 +1944,7 @@ private static void DoFilter4Sse2(ref Vector128 p1, ref Vector128 p0 // Compute hev mask. Vector128 notHev = GetNotHev(ref p1, ref p0, ref q0, ref q1, tresh); - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); // Convert to signed values. p1 = Sse2.Xor(p1, signBit); @@ -2036,7 +1988,7 @@ private static void DoFilter6Sse2(ref Vector128 p2, ref Vector128 p1 Vector128 notHev = GetNotHev(ref p1, ref p0, ref q0, ref q1, tresh); // Convert to signed values. - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); p1 = Sse2.Xor(p1, signBit); p0 = Sse2.Xor(p0, signBit); q0 = Sse2.Xor(q0, signBit); @@ -2057,11 +2009,11 @@ private static void DoFilter6Sse2(ref Vector128 p2, ref Vector128 p1 Vector128 flow = Sse2.UnpackLow(Vector128.Zero, f); Vector128 fhigh = Sse2.UnpackHigh(Vector128.Zero, f); - Vector128 nine = Vector128.Create((short)0x0900); + var nine = Vector128.Create((short)0x0900); Vector128 f9Low = Sse2.MultiplyHigh(flow.AsInt16(), nine); // Filter (lo) * 9 Vector128 f9High = Sse2.MultiplyHigh(fhigh.AsInt16(), nine); // Filter (hi) * 9 - Vector128 sixtyThree = Vector128.Create((short)63); + var sixtyThree = Vector128.Create((short)63); Vector128 a2Low = Sse2.Add(f9Low, sixtyThree); // Filter * 9 + 63 Vector128 a2High = Sse2.Add(f9High, sixtyThree); // Filter * 9 + 63 @@ -2100,7 +2052,6 @@ private static Vector128 GetNotHev(ref Vector128 p1, ref Vector128.Zero); } -#endif // Applies filter on 4 pixels (p1, p0, q0 and q1) private static void DoFilter4(Span p, int offset, int step) @@ -2180,7 +2131,6 @@ private static bool NeedsFilter2(Span p, int offset, int step, int t, int WebpLookupTables.Abs0(q2 - q1) <= it && WebpLookupTables.Abs0(q1 - q0) <= it; } -#if SUPPORTS_RUNTIME_INTRINSICS private static Vector128 NeedsFilter(Vector128 p1, Vector128 p0, Vector128 q0, Vector128 q1, int thresh) { var mthresh = Vector128.Create((byte)thresh); @@ -2345,7 +2295,7 @@ private static void ComplexMask(Vector128 p1, Vector128 p0, Vector12 // Pixels 'pi' and 'qi' are int8_t on input, uint8_t on output (sign flip). private static void Update2Pixels(ref Vector128 pi, ref Vector128 qi, Vector128 a0Low, Vector128 a0High) { - Vector128 signBit = Vector128.Create((byte)0x80); + var signBit = Vector128.Create((byte)0x80); Vector128 a1Low = Sse2.ShiftRightArithmetic(a0Low, 7); Vector128 a1High = Sse2.ShiftRightArithmetic(a0High, 7); Vector128 delta = Sse2.PackSignedSaturate(a1Low, a1High); @@ -2374,7 +2324,6 @@ private static void StoreUv(Vector128 x, ref byte uRef, ref byte vRef, int [MethodImpl(InliningOptions.ShortMethod)] private static Vector128 Abs(Vector128 p, Vector128 q) => Sse2.Or(Sse2.SubtractSaturate(q, p), Sse2.SubtractSaturate(p, q)); -#endif [MethodImpl(InliningOptions.ShortMethod)] private static bool Hev(Span p, int offset, int step, int thresh) @@ -2411,7 +2360,7 @@ private static void Store2(Span dst, int y, int dc, int d, int c) [MethodImpl(InliningOptions.ShortMethod)] private static void Put8x8uv(byte value, Span dst) { - int end = 8 * WebpConstants.Bps; + const int end = 8 * WebpConstants.Bps; for (int j = 0; j < end; j += WebpConstants.Bps) { // memset(dst + j * BPS, value, 8); diff --git a/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs b/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs index a191cbcf84..a8e3652709 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs @@ -4,10 +4,9 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif +using SixLabors.ImageSharp.Common.Helpers; namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -77,9 +76,7 @@ public static void PickBestIntra16(Vp8EncIterator it, ref Vp8ModeScore rd, Vp8Se if (mode == 0 || rdCur.Score < rdBest.Score) { - Vp8ModeScore tmp = rdCur; - rdCur = rdBest; - rdBest = tmp; + RuntimeUtility.Swap(ref rdBest, ref rdCur); it.SwapOut(); } } @@ -128,13 +125,13 @@ public static bool PickBestIntra4(Vp8EncIterator it, ref Vp8ModeScore rd, Vp8Seg Span tmpLevels = new short[16]; do { - int numBlocks = 1; + const int numBlocks = 1; rdi4.Clear(); int mode; int bestMode = -1; - Span src = src0.Slice(WebpLookupTables.Vp8Scan[it.I4]); + Span src = src0[WebpLookupTables.Vp8Scan[it.I4]..]; short[] modeCosts = it.GetCostModeI4(rd.ModesI4); - Span bestBlock = bestBlocks.Slice(WebpLookupTables.Vp8Scan[it.I4]); + Span bestBlock = bestBlocks[WebpLookupTables.Vp8Scan[it.I4]..]; Span tmpDst = it.Scratch.AsSpan(); tmpDst.Clear(); @@ -178,9 +175,8 @@ public static bool PickBestIntra4(Vp8EncIterator it, ref Vp8ModeScore rd, Vp8Seg { rdi4.CopyScore(rdTmp); bestMode = mode; - Span tmp = tmpDst; - tmpDst = bestBlock; - bestBlock = tmp; + + RuntimeUtility.Swap(ref tmpDst, ref bestBlock); tmpLevels.CopyTo(rdBest.YAcLevels.AsSpan(it.I4 * 16, 16)); } } @@ -199,7 +195,7 @@ public static bool PickBestIntra4(Vp8EncIterator it, ref Vp8ModeScore rd, Vp8Seg } // Copy selected samples to the right place. - LossyUtils.Vp8Copy4X4(bestBlock, bestBlocks.Slice(WebpLookupTables.Vp8Scan[it.I4])); + LossyUtils.Vp8Copy4X4(bestBlock, bestBlocks[WebpLookupTables.Vp8Scan[it.I4]..]); rd.ModesI4[it.I4] = (byte)bestMode; it.TopNz[it.I4 & 3] = it.LeftNz[it.I4 >> 2] = rdi4.Nz != 0 ? 1 : 0; @@ -262,9 +258,7 @@ public static void PickBestUv(Vp8EncIterator it, ref Vp8ModeScore rd, Vp8Segment rd.Derr[i, 2] = rdUv.Derr[i, 2]; } - Span tmp = dst; - dst = tmpDst; - tmpDst = tmp; + RuntimeUtility.Swap(ref tmpDst, ref dst); } } @@ -290,14 +284,14 @@ public static int ReconstructIntra16(Vp8EncIterator it, Vp8SegmentInfo dqm, Vp8M Span scratch = it.Scratch3.AsSpan(0, 16); shortScratchSpan.Clear(); scratch.Clear(); - Span dcTmp = shortScratchSpan.Slice(0, 16); + Span dcTmp = shortScratchSpan[..16]; Span tmp = shortScratchSpan.Slice(16, 16 * 16); for (n = 0; n < 16; n += 2) { Vp8Encoding.FTransform2( - src.Slice(WebpLookupTables.Vp8Scan[n]), - reference.Slice(WebpLookupTables.Vp8Scan[n]), + src[WebpLookupTables.Vp8Scan[n]..], + reference[WebpLookupTables.Vp8Scan[n]..], tmp.Slice(n * 16, 16), tmp.Slice((n + 1) * 16, 16), scratch); @@ -318,7 +312,7 @@ public static int ReconstructIntra16(Vp8EncIterator it, Vp8SegmentInfo dqm, Vp8M LossyUtils.TransformWht(dcTmp, tmp, scratch); for (n = 0; n < 16; n += 2) { - Vp8Encoding.ITransformTwo(reference.Slice(WebpLookupTables.Vp8Scan[n]), tmp.Slice(n * 16, 32), yuvOut.Slice(WebpLookupTables.Vp8Scan[n]), scratch); + Vp8Encoding.ITransformTwo(reference[WebpLookupTables.Vp8Scan[n]..], tmp.Slice(n * 16, 32), yuvOut[WebpLookupTables.Vp8Scan[n]..], scratch); } return nz; @@ -348,8 +342,8 @@ public static int ReconstructUv(Vp8EncIterator it, Vp8SegmentInfo dqm, Vp8ModeSc for (n = 0; n < 8; n += 2) { Vp8Encoding.FTransform2( - src.Slice(WebpLookupTables.Vp8ScanUv[n]), - reference.Slice(WebpLookupTables.Vp8ScanUv[n]), + src[WebpLookupTables.Vp8ScanUv[n]..], + reference[WebpLookupTables.Vp8ScanUv[n]..], tmp.Slice(n * 16, 16), tmp.Slice((n + 1) * 16, 16), scratch); @@ -364,7 +358,7 @@ public static int ReconstructUv(Vp8EncIterator it, Vp8SegmentInfo dqm, Vp8ModeSc for (n = 0; n < 8; n += 2) { - Vp8Encoding.ITransformTwo(reference.Slice(WebpLookupTables.Vp8ScanUv[n]), tmp.Slice(n * 16, 32), yuvOut.Slice(WebpLookupTables.Vp8ScanUv[n]), scratch); + Vp8Encoding.ITransformTwo(reference[WebpLookupTables.Vp8ScanUv[n]..], tmp.Slice(n * 16, 32), yuvOut[WebpLookupTables.Vp8ScanUv[n]..], scratch); } return nz << 16; @@ -512,14 +506,13 @@ public static void RefineUsingDistortion(Vp8EncIterator it, Vp8SegmentInfo[] seg [MethodImpl(InliningOptions.ShortMethod)] public static int Quantize2Blocks(Span input, Span output, ref Vp8Matrix mtx) { - int nz = QuantizeBlock(input.Slice(0, 16), output.Slice(0, 16), ref mtx) << 0; + int nz = QuantizeBlock(input[..16], output[..16], ref mtx) << 0; nz |= QuantizeBlock(input.Slice(1 * 16, 16), output.Slice(1 * 16, 16), ref mtx) << 1; return nz; } public static int QuantizeBlock(Span input, Span output, ref Vp8Matrix mtx) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { // Load all inputs. @@ -636,7 +629,7 @@ public static int QuantizeBlock(Span input, Span output, ref Vp8Ma Vector128 out8 = Sse2.PackSignedSaturate(out08.AsInt32(), out12.AsInt32()); // if (coeff > 2047) coeff = 2047 - Vector128 maxCoeff2047 = Vector128.Create((short)MaxLevel); + var maxCoeff2047 = Vector128.Create((short)MaxLevel); out0 = Sse2.Min(out0, maxCoeff2047); out8 = Sse2.Min(out8, maxCoeff2047); @@ -677,7 +670,6 @@ public static int QuantizeBlock(Span input, Span output, ref Vp8Ma return Sse2.MoveMask(cmpeq) != 0xffff ? 1 : 0; } else -#endif { int last = -1; int n; @@ -762,11 +754,11 @@ public static void CorrectDcValues(Vp8EncIterator it, ref Vp8Matrix mtx, Span> (DSHIFT - DSCALE)); int err0 = QuantizeSingle(c, ref mtx); c[1 * 16] += (short)(((C1 * top[1]) + (C2 * err0)) >> (DSHIFT - DSCALE)); - int err1 = QuantizeSingle(c.Slice(1 * 16), ref mtx); + int err1 = QuantizeSingle(c[(1 * 16)..], ref mtx); c[2 * 16] += (short)(((C1 * err0) + (C2 * left[1])) >> (DSHIFT - DSCALE)); - int err2 = QuantizeSingle(c.Slice(2 * 16), ref mtx); + int err2 = QuantizeSingle(c[(2 * 16)..], ref mtx); c[3 * 16] += (short)(((C1 * err1) + (C2 * err2)) >> (DSHIFT - DSCALE)); - int err3 = QuantizeSingle(c.Slice(3 * 16), ref mtx); + int err3 = QuantizeSingle(c[(3 * 16)..], ref mtx); rd.Derr[ch, 0] = err1; rd.Derr[ch, 1] = err2; @@ -781,13 +773,13 @@ private static bool IsFlatSource16(Span src) Span vSpan = BitConverter.GetBytes(v).AsSpan(); for (nint i = 0; i < 16; i++) { - if (!src.Slice(0, 4).SequenceEqual(vSpan) || !src.Slice(4, 4).SequenceEqual(vSpan) || + if (!src[..4].SequenceEqual(vSpan) || !src.Slice(4, 4).SequenceEqual(vSpan) || !src.Slice(8, 4).SequenceEqual(vSpan) || !src.Slice(12, 4).SequenceEqual(vSpan)) { return false; } - src = src.Slice(WebpConstants.Bps); + src = src[WebpConstants.Bps..]; } return true; diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs index 25894905a7..3092e01e33 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs @@ -34,7 +34,9 @@ internal class Vp8EncIterator /// private readonly int predsWidth; - // Array to record the position of the top sample to pass to the prediction functions. + /// + /// Array to record the position of the top sample to pass to the prediction functions. + /// private readonly byte[] vp8TopLeftI4 = { 17, 21, 25, 29, @@ -46,9 +48,6 @@ internal class Vp8EncIterator private int currentMbIdx; private int nzIdx; - - private int predIdx; - private int yTopIdx; private int uvTopIdx; @@ -69,7 +68,7 @@ public Vp8EncIterator(byte[] yTop, byte[] uvTop, uint[] nz, Vp8MacroBlockInfo[] this.yTopIdx = 0; this.uvTopIdx = 0; this.predsWidth = (4 * mbw) + 1; - this.predIdx = this.predsWidth; + this.PredIdx = this.predsWidth; this.YuvIn = new byte[WebpConstants.Bps * 16]; this.YuvOut = new byte[WebpConstants.Bps * 16]; this.YuvOut2 = new byte[WebpConstants.Bps * 16]; @@ -85,7 +84,7 @@ public Vp8EncIterator(byte[] yTop, byte[] uvTop, uint[] nz, Vp8MacroBlockInfo[] this.Scratch3 = new int[16]; // To match the C initial values of the reference implementation, initialize all with 204. - byte defaultInitVal = 204; + const byte defaultInitVal = 204; this.YuvIn.AsSpan().Fill(defaultInitVal); this.YuvOut.AsSpan().Fill(defaultInitVal); this.YuvOut2.AsSpan().Fill(defaultInitVal); @@ -160,7 +159,7 @@ public Vp8EncIterator(byte[] yTop, byte[] uvTop, uint[] nz, Vp8MacroBlockInfo[] /// /// Gets the current start index of the intra mode predictors. /// - public int PredIdx => this.predIdx; + public int PredIdx { get; private set; } /// /// Gets the non-zero pattern. @@ -238,7 +237,7 @@ public Vp8EncIterator(byte[] yTop, byte[] uvTop, uint[] nz, Vp8MacroBlockInfo[] public void Init() => this.Reset(); - public void InitFilter() + public static void InitFilter() { // TODO: add support for autofilter } @@ -288,9 +287,9 @@ public void Import(Span y, Span u, Span v, int yStride, int uv { int yStartIdx = ((this.Y * yStride) + this.X) * 16; int uvStartIdx = ((this.Y * uvStride) + this.X) * 8; - Span ySrc = y.Slice(yStartIdx); - Span uSrc = u.Slice(uvStartIdx); - Span vSrc = v.Slice(uvStartIdx); + Span ySrc = y[yStartIdx..]; + Span uSrc = u[uvStartIdx..]; + Span vSrc = v[uvStartIdx..]; int w = Math.Min(width - (this.X * 16), 16); int h = Math.Min(height - (this.Y * 16), 16); int uvw = (w + 1) >> 1; @@ -299,9 +298,9 @@ public void Import(Span y, Span u, Span v, int yStride, int uv Span yuvIn = this.YuvIn.AsSpan(YOffEnc); Span uIn = this.YuvIn.AsSpan(UOffEnc); Span vIn = this.YuvIn.AsSpan(VOffEnc); - this.ImportBlock(ySrc, yStride, yuvIn, w, h, 16); - this.ImportBlock(uSrc, uvStride, uIn, uvw, uvh, 8); - this.ImportBlock(vSrc, uvStride, vIn, uvw, uvh, 8); + ImportBlock(ySrc, yStride, yuvIn, w, h, 16); + ImportBlock(uSrc, uvStride, uIn, uvw, uvh, 8); + ImportBlock(vSrc, uvStride, vIn, uvw, uvh, 8); if (!importBoundarySamples) { @@ -331,9 +330,9 @@ public void Import(Span y, Span u, Span v, int yStride, int uv vLeft[0] = v[uvStartIdx - 1 - uvStride]; } - this.ImportLine(y.Slice(yStartIdx - 1), yStride, yLeft.Slice(1), h, 16); - this.ImportLine(u.Slice(uvStartIdx - 1), uvStride, uLeft.Slice(1), uvh, 8); - this.ImportLine(v.Slice(uvStartIdx - 1), uvStride, vLeft.Slice(1), uvh, 8); + ImportLine(y[(yStartIdx - 1)..], yStride, yLeft[1..], h, 16); + ImportLine(u[(uvStartIdx - 1)..], uvStride, uLeft[1..], uvh, 8); + ImportLine(v[(uvStartIdx - 1)..], uvStride, vLeft[1..], uvh, 8); } Span yTop = this.YTop.AsSpan(this.yTopIdx, 16); @@ -344,9 +343,9 @@ public void Import(Span y, Span u, Span v, int yStride, int uv } else { - this.ImportLine(y.Slice(yStartIdx - yStride), 1, yTop, w, 16); - this.ImportLine(u.Slice(uvStartIdx - uvStride), 1, this.UvTop.AsSpan(this.uvTopIdx, 8), uvw, 8); - this.ImportLine(v.Slice(uvStartIdx - uvStride), 1, this.UvTop.AsSpan(this.uvTopIdx + 8, 8), uvw, 8); + ImportLine(y[(yStartIdx - yStride)..], 1, yTop, w, 16); + ImportLine(u[(uvStartIdx - uvStride)..], 1, this.UvTop.AsSpan(this.uvTopIdx, 8), uvw, 8); + ImportLine(v[(uvStartIdx - uvStride)..], 1, this.UvTop.AsSpan(this.uvTopIdx + 8, 8), uvw, 8); } } @@ -386,7 +385,7 @@ public int FastMbAnalyze(int quality) public int MbAnalyzeBestIntra16Mode() { - int maxMode = MaxIntra16Mode; + const int maxMode = MaxIntra16Mode; int mode; int bestAlpha = DefaultAlpha; int bestMode = 0; @@ -394,7 +393,7 @@ public int MbAnalyzeBestIntra16Mode() this.MakeLuma16Preds(); for (mode = 0; mode < maxMode; mode++) { - var histo = new Vp8Histogram(); + Vp8Histogram histo = new(); histo.CollectHistogram(this.YuvIn.AsSpan(YOffEnc), this.YuvP.AsSpan(Vp8Encoding.Vp8I16ModeOffsets[mode]), 0, 16); int alpha = histo.GetAlpha(); if (alpha > bestAlpha) @@ -411,15 +410,15 @@ public int MbAnalyzeBestIntra16Mode() public int MbAnalyzeBestIntra4Mode(int bestAlpha) { byte[] modes = new byte[16]; - int maxMode = MaxIntra4Mode; - var totalHisto = new Vp8Histogram(); + const int maxMode = MaxIntra4Mode; + Vp8Histogram totalHisto = new(); int curHisto = 0; this.StartI4(); do { int mode; int bestModeAlpha = DefaultAlpha; - var histos = new Vp8Histogram[2]; + Vp8Histogram[] histos = new Vp8Histogram[2]; Span src = this.YuvIn.AsSpan(YOffEnc + WebpLookupTables.Vp8Scan[this.I4]); this.MakeIntra4Preds(); @@ -459,13 +458,13 @@ public int MbAnalyzeBestUvMode() int bestAlpha = DefaultAlpha; int smallestAlpha = 0; int bestMode = 0; - int maxMode = MaxUvMode; + const int maxMode = MaxUvMode; int mode; this.MakeChroma8Preds(); for (mode = 0; mode < maxMode; ++mode) { - var histo = new Vp8Histogram(); + Vp8Histogram histo = new(); histo.CollectHistogram(this.YuvIn.AsSpan(UOffEnc), this.YuvP.AsSpan(Vp8Encoding.Vp8UvModeOffsets[mode]), 16, 16 + 4 + 4); int alpha = histo.GetAlpha(); if (alpha > bestAlpha) @@ -487,11 +486,11 @@ public int MbAnalyzeBestUvMode() public void SetIntra16Mode(int mode) { - Span preds = this.Preds.AsSpan(this.predIdx); + Span preds = this.Preds.AsSpan(this.PredIdx); for (int y = 0; y < 4; y++) { - preds.Slice(0, 4).Fill((byte)mode); - preds = preds.Slice(this.predsWidth); + preds[..4].Fill((byte)mode); + preds = preds[this.predsWidth..]; } this.CurrentMacroBlockInfo.MacroBlockType = Vp8MacroBlockType.I16X16; @@ -500,7 +499,7 @@ public void SetIntra16Mode(int mode) public void SetIntra4Mode(byte[] modes) { int modesIdx = 0; - int predIdx = this.predIdx; + int predIdx = this.PredIdx; for (int y = 4; y > 0; y--) { modes.AsSpan(modesIdx, 4).CopyTo(this.Preds.AsSpan(predIdx)); @@ -542,7 +541,7 @@ public int GetCostLuma16(Vp8ModeScore rd, Vp8EncProba proba, Vp8Residual res) public short[] GetCostModeI4(byte[] modes) { int predsWidth = this.predsWidth; - int predIdx = this.predIdx; + int predIdx = this.PredIdx; int x = this.I4 & 3; int y = this.I4 >> 2; int left = x == 0 ? this.Preds[predIdx + (y * predsWidth) - 1] : modes[this.I4 - 1]; @@ -635,7 +634,7 @@ public bool Next() { this.currentMbIdx++; this.nzIdx++; - this.predIdx += 4; + this.PredIdx += 4; this.yTopIdx += 16; this.uvTopIdx += 16; } @@ -679,7 +678,7 @@ public void SaveBoundary() public bool RotateI4(Span yuvOut) { - Span blk = yuvOut.Slice(WebpLookupTables.Vp8Scan[this.I4]); + Span blk = yuvOut[WebpLookupTables.Vp8Scan[this.I4]..]; Span top = this.I4Boundary.AsSpan(); int topOffset = this.I4BoundaryIdx; int i; @@ -754,9 +753,12 @@ public void MakeChroma8Preds() public void SwapOut() { + // Tuple swap uses 2 more IL bytes +#pragma warning disable IDE0180 // Use tuple to swap values byte[] tmp = this.YuvOut; this.YuvOut = this.YuvOut2; this.YuvOut2 = tmp; +#pragma warning restore IDE0180 // Use tuple to swap values } public void NzToBytes() @@ -769,35 +771,35 @@ public void NzToBytes() Span leftNz = this.LeftNz; // Top-Y - topNz[0] = this.Bit(tnz, 12); - topNz[1] = this.Bit(tnz, 13); - topNz[2] = this.Bit(tnz, 14); - topNz[3] = this.Bit(tnz, 15); + topNz[0] = Bit(tnz, 12); + topNz[1] = Bit(tnz, 13); + topNz[2] = Bit(tnz, 14); + topNz[3] = Bit(tnz, 15); // Top-U - topNz[4] = this.Bit(tnz, 18); - topNz[5] = this.Bit(tnz, 19); + topNz[4] = Bit(tnz, 18); + topNz[5] = Bit(tnz, 19); // Top-V - topNz[6] = this.Bit(tnz, 22); - topNz[7] = this.Bit(tnz, 23); + topNz[6] = Bit(tnz, 22); + topNz[7] = Bit(tnz, 23); // DC - topNz[8] = this.Bit(tnz, 24); + topNz[8] = Bit(tnz, 24); // left-Y - leftNz[0] = this.Bit(lnz, 3); - leftNz[1] = this.Bit(lnz, 7); - leftNz[2] = this.Bit(lnz, 11); - leftNz[3] = this.Bit(lnz, 15); + leftNz[0] = Bit(lnz, 3); + leftNz[1] = Bit(lnz, 7); + leftNz[2] = Bit(lnz, 11); + leftNz[3] = Bit(lnz, 15); // left-U - leftNz[4] = this.Bit(lnz, 17); - leftNz[5] = this.Bit(lnz, 19); + leftNz[4] = Bit(lnz, 17); + leftNz[5] = Bit(lnz, 19); // left-V - leftNz[6] = this.Bit(lnz, 21); - leftNz[7] = this.Bit(lnz, 23); + leftNz[6] = Bit(lnz, 21); + leftNz[7] = Bit(lnz, 23); // left-DC is special, iterated separately. } @@ -823,14 +825,14 @@ public void BytesToNz() this.Nz[this.nzIdx] = nz; } - private void ImportBlock(Span src, int srcStride, Span dst, int w, int h, int size) + private static void ImportBlock(Span src, int srcStride, Span dst, int w, int h, int size) { int dstIdx = 0; int srcIdx = 0; for (int i = 0; i < h; i++) { // memcpy(dst, src, w); - src.Slice(srcIdx, w).CopyTo(dst.Slice(dstIdx)); + src.Slice(srcIdx, w).CopyTo(dst[dstIdx..]); if (w < size) { // memset(dst + w, dst[w - 1], size - w); @@ -844,12 +846,12 @@ private void ImportBlock(Span src, int srcStride, Span dst, int w, i for (int i = h; i < size; i++) { // memcpy(dst, dst - BPS, size); - dst.Slice(dstIdx - WebpConstants.Bps, size).CopyTo(dst.Slice(dstIdx)); + dst.Slice(dstIdx - WebpConstants.Bps, size).CopyTo(dst[dstIdx..]); dstIdx += WebpConstants.Bps; } } - private void ImportLine(Span src, int srcStride, Span dst, int len, int totalLen) + private static void ImportLine(Span src, int srcStride, Span dst, int len, int totalLen) { int i; int srcIdx = 0; @@ -889,7 +891,7 @@ private void SetRow(int y) this.nzIdx = 1; // note: in reference source nz starts at -1. this.yTopIdx = 0; this.uvTopIdx = 0; - this.predIdx = this.predsWidth + (y * 4 * this.predsWidth); + this.PredIdx = this.predsWidth + (y * 4 * this.predsWidth); this.InitLeft(); } @@ -928,7 +930,7 @@ private void InitTop() this.TopDerr.AsSpan().Clear(); } - private int Bit(uint nz, int n) => (nz & (1 << n)) != 0 ? 1 : 0; + private static int Bit(uint nz, int n) => (nz & (1 << n)) != 0 ? 1 : 0; /// /// Set count down. diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs index 8eaaeda7ac..12b2ea7dc2 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs @@ -123,10 +123,22 @@ public Vp8Encoder( this.filterStrength = Numerics.Clamp(filterStrength, 0, 100); this.spatialNoiseShaping = Numerics.Clamp(spatialNoiseShaping, 0, 100); this.alphaCompression = alphaCompression; - this.rdOptLevel = method is WebpEncodingMethod.BestQuality ? Vp8RdLevel.RdOptTrellisAll - : method >= WebpEncodingMethod.Level5 ? Vp8RdLevel.RdOptTrellis - : method >= WebpEncodingMethod.Level3 ? Vp8RdLevel.RdOptBasic - : Vp8RdLevel.RdOptNone; + if (method is WebpEncodingMethod.BestQuality) + { + this.rdOptLevel = Vp8RdLevel.RdOptTrellisAll; + } + else if (method >= WebpEncodingMethod.Level5) + { + this.rdOptLevel = Vp8RdLevel.RdOptTrellis; + } + else if (method >= WebpEncodingMethod.Level3) + { + this.rdOptLevel = Vp8RdLevel.RdOptBasic; + } + else + { + this.rdOptLevel = Vp8RdLevel.RdOptNone; + } int pixelCount = width * height; this.Mbw = (width + 15) >> 4; @@ -142,7 +154,7 @@ public Vp8Encoder( this.TopDerr = new sbyte[this.Mbw * 4]; // TODO: make partition_limit configurable? - int limit = 100; // original code: limit = 100 - config->partition_limit; + const int limit = 100; // original code: limit = 100 - config->partition_limit; this.maxI4HeaderBits = 256 * 16 * 16 * limit * limit / (100 * 100); // ... modulated with a quadratic curve. @@ -307,7 +319,7 @@ public void Encode(Image image, Stream stream) int yStride = width; int uvStride = (yStride + 1) >> 1; - var it = new Vp8EncIterator(this.YTop, this.UvTop, this.Nz, this.MbInfo, this.Preds, this.TopDerr, this.Mbw, this.Mbh); + Vp8EncIterator it = new(this.YTop, this.UvTop, this.Nz, this.MbInfo, this.Preds, this.TopDerr, this.Mbw, this.Mbh); int[] alphas = new int[WebpConstants.MaxAlpha + 1]; this.alpha = this.MacroBlockAnalysis(width, height, it, y, u, v, yStride, uvStride, alphas, out this.uvAlpha); int totalMb = this.Mbw * this.Mbw; @@ -327,7 +339,7 @@ public void Encode(Image image, Stream stream) // Extract and encode alpha channel data, if present. int alphaDataSize = 0; bool alphaCompressionSucceeded = false; - using var alphaEncoder = new AlphaEncoder(); + using AlphaEncoder alphaEncoder = new(); Span alphaData = Span.Empty; if (hasAlpha) { @@ -344,9 +356,9 @@ public void Encode(Image image, Stream stream) // Stats-collection loop. this.StatLoop(width, height, yStride, uvStride); it.Init(); - it.InitFilter(); - var info = new Vp8ModeScore(); - var residual = new Vp8Residual(); + Vp8EncIterator.InitFilter(); + Vp8ModeScore info = new(); + Vp8Residual residual = new(); do { bool dontUseSkip = !this.Proba.UseSkipProba; @@ -382,7 +394,7 @@ public void Encode(Image image, Stream stream) (uint)width, (uint)height, hasAlpha, - alphaData.Slice(0, alphaDataSize), + alphaData[..alphaDataSize], this.alphaCompression && alphaCompressionSucceeded); } @@ -399,17 +411,21 @@ public void Dispose() /// This is used for deciding optimal probabilities. It also modifies the /// quantizer value if some target (size, PSNR) was specified. /// + /// The image width. + /// The image height. + /// The y-luminance stride. + /// The uv stride. private void StatLoop(int width, int height, int yStride, int uvStride) { - int targetSize = 0; // TODO: target size is hardcoded. - float targetPsnr = 0.0f; // TODO: targetPsnr is hardcoded. - bool doSearch = targetSize > 0 || targetPsnr > 0; + const int targetSize = 0; // TODO: target size is hardcoded. + const float targetPsnr = 0.0f; // TODO: targetPsnr is hardcoded. + const bool doSearch = targetSize > 0 || targetPsnr > 0; bool fastProbe = (this.method == 0 || this.method == WebpEncodingMethod.Level3) && !doSearch; int numPassLeft = this.entropyPasses; Vp8RdLevel rdOpt = this.method >= WebpEncodingMethod.Level3 || doSearch ? Vp8RdLevel.RdOptBasic : Vp8RdLevel.RdOptNone; int nbMbs = this.Mbw * this.Mbh; - var stats = new PassStats(targetSize, targetPsnr, QMin, QMax, this.quality); + PassStats stats = new(targetSize, targetPsnr, QMin, QMax, this.quality); this.Proba.ResetTokenStats(); // Fast mode: quick analysis pass over few mbs. Better than nothing. @@ -450,7 +466,10 @@ private void StatLoop(int width, int height, int yStride, int uvStride) // If no target size: just do several pass without changing 'q' if (doSearch) { + // Unreachable due to hardcoding above. +#pragma warning disable CS0162 // Unreachable code detected stats.ComputeNextQ(); +#pragma warning restore CS0162 // Unreachable code detected if (MathF.Abs(stats.Dq) <= DqLimit) { break; @@ -474,7 +493,7 @@ private long OneStatPass(int width, int height, int yStride, int uvStride, Vp8Rd Span y = this.Y.GetSpan(); Span u = this.U.GetSpan(); Span v = this.V.GetSpan(); - var it = new Vp8EncIterator(this.YTop, this.UvTop, this.Nz, this.MbInfo, this.Preds, this.TopDerr, this.Mbw, this.Mbh); + Vp8EncIterator it = new(this.YTop, this.UvTop, this.Nz, this.MbInfo, this.Preds, this.TopDerr, this.Mbw, this.Mbh); long size = 0; long sizeP0 = 0; long distortion = 0; @@ -482,7 +501,7 @@ private long OneStatPass(int width, int height, int yStride, int uvStride, Vp8Rd it.Init(); this.SetLoopParams(stats.Q); - var info = new Vp8ModeScore(); + Vp8ModeScore info = new(); do { info.Clear(); @@ -540,7 +559,7 @@ private unsafe void AdjustFilterStrength() // this '>> 3' accounts for some inverse WHT scaling int delta = (dqm.MaxEdge * dqm.Y2.Q[1]) >> 3; - int level = this.FilterStrengthFromDelta(this.FilterHeader.Sharpness, delta); + int level = FilterStrengthFromDelta(this.FilterHeader.Sharpness, delta); if (level > dqm.FStrength) { dqm.FStrength = level; @@ -757,8 +776,8 @@ private void SetSegmentParams(float quality) private void SetupFilterStrength() { - int filterSharpness = 0; // TODO: filterSharpness is hardcoded - int filterType = 1; // TODO: filterType is hardcoded + const int filterSharpness = 0; // TODO: filterSharpness is hardcoded + const int filterType = 1; // TODO: filterType is hardcoded // level0 is in [0..500]. Using '-f 50' as filter_strength is mid-filtering. int level0 = 5 * this.filterStrength; @@ -768,11 +787,22 @@ private void SetupFilterStrength() // We focus on the quantization of AC coeffs. int qstep = WebpLookupTables.AcTable[Numerics.Clamp(m.Quant, 0, 127)] >> 2; - int baseStrength = this.FilterStrengthFromDelta(this.FilterHeader.Sharpness, qstep); + int baseStrength = FilterStrengthFromDelta(this.FilterHeader.Sharpness, qstep); // Segments with lower complexity ('beta') will be less filtered. int f = baseStrength * level0 / (256 + m.Beta); - m.FStrength = f < WebpConstants.FilterStrengthCutoff ? 0 : f > 63 ? 63 : f; + if (f < WebpConstants.FilterStrengthCutoff) + { + m.FStrength = 0; + } + else if (f > 63) + { + m.FStrength = 63; + } + else + { + m.FStrength = f; + } } // We record the initial strength (mainly for the case of 1-segment only). @@ -1027,10 +1057,12 @@ private void CodeResiduals(Vp8EncIterator it, Vp8ModeScore rd, Vp8Residual resid /// Same as CodeResiduals, but doesn't actually write anything. /// Instead, it just records the event distribution. /// + /// The iterator. + /// The score accumulator. private void RecordResiduals(Vp8EncIterator it, Vp8ModeScore rd) { int x, y, ch; - var residual = new Vp8Residual(); + Vp8Residual residual = new(); bool i16 = it.CurrentMacroBlockInfo.MacroBlockType == Vp8MacroBlockType.I16X16; it.NzToBytes(); @@ -1096,6 +1128,7 @@ private static int FinalAlphaValue(int alpha) /// is around q=75. Internally, our "good" middle is around c=50. So we /// map accordingly using linear piece-wise function /// + /// The compression level. [MethodImpl(InliningOptions.ShortMethod)] private static double QualityToCompression(double c) { @@ -1107,13 +1140,11 @@ private static double QualityToCompression(double c) // this power-law: quant ~= compression ^ 1/3. This law holds well for // low quant. Finer modeling for high-quant would make use of AcTable[] // more explicitly. - double v = Math.Pow(linearC, 1 / 3.0d); - - return v; + return (double)Math.Pow(linearC, 1 / 3.0d); } [MethodImpl(InliningOptions.ShortMethod)] - private int FilterStrengthFromDelta(int sharpness, int delta) + private static int FilterStrengthFromDelta(int sharpness, int delta) { int pos = delta < WebpConstants.MaxDelzaSize ? delta : WebpConstants.MaxDelzaSize - 1; return WebpLookupTables.LevelsFromDelta[sharpness, pos]; diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs index b98eea4152..32d96cba9e 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs @@ -5,10 +5,8 @@ using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -81,7 +79,6 @@ private static byte[] GetClip1() // Does two inverse transforms. public static void ITransformTwo(Span reference, Span input, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // This implementation makes use of 16-bit fixed point versions of two @@ -106,19 +103,19 @@ public static void ITransformTwo(Span reference, Span input, Span(ref inputRef), 0); - var in1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 4)), 0); - var in2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 8)), 0); - var in3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 12)), 0); + Vector128 in0 = Vector128.Create(Unsafe.As(ref inputRef), 0); + Vector128 in1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 4)), 0); + Vector128 in2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 8)), 0); + Vector128 in3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 12)), 0); // a00 a10 a20 a30 x x x x // a01 a11 a21 a31 x x x x // a02 a12 a22 a32 x x x x // a03 a13 a23 a33 x x x x - var inb0 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 16)), 0); - var inb1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 20)), 0); - var inb2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 24)), 0); - var inb3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 28)), 0); + Vector128 inb0 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 16)), 0); + Vector128 inb1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 20)), 0); + Vector128 inb2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 24)), 0); + Vector128 inb3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 28)), 0); in0 = Sse2.UnpackLow(in0, inb0); in1 = Sse2.UnpackLow(in1, inb1); @@ -184,16 +181,14 @@ public static void ITransformTwo(Span reference, Span input, Span>(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = ref3.GetLower(); } else -#endif { ITransformOne(reference, input, dst, scratch); - ITransformOne(reference.Slice(4), input.Slice(16), dst.Slice(4), scratch); + ITransformOne(reference[4..], input[16..], dst[4..], scratch); } } public static void ITransformOne(Span reference, Span input, Span dst, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { // Load and concatenate the transform coefficients (we'll do two inverse @@ -201,10 +196,10 @@ public static void ITransformOne(Span reference, Span input, Span(ref inputRef), 0); - var in1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 4)), 0); - var in2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 8)), 0); - var in3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 12)), 0); + Vector128 in0 = Vector128.Create(Unsafe.As(ref inputRef), 0); + Vector128 in1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 4)), 0); + Vector128 in2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 8)), 0); + Vector128 in3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref inputRef, 12)), 0); // a00 a10 a20 a30 x x x x // a01 a11 a21 a31 x x x x @@ -272,10 +267,9 @@ public static void ITransformOne(Span reference, Span input, Span(ref Unsafe.Add(ref outputRef, WebpConstants.Bps * 3)) = output3; } else -#endif { int i; - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; for (i = 0; i < 4; i++) { // vertical pass. @@ -287,8 +281,8 @@ public static void ITransformOne(Span reference, Span input, Span reference, Span input, Span in0, Vector128 in2, Vector128 in1, Vector128 in3, out Vector128 tmp0, out Vector128 tmp1, out Vector128 tmp2, out Vector128 tmp3) { Vector128 a = Sse2.Add(in0.AsInt16(), in2.AsInt16()); @@ -372,27 +365,25 @@ private static void InverseTransformHorizontalPass(Vector128 t0, Vector128 shifted2 = Sse2.ShiftRightArithmetic(tmp2, 3); shifted3 = Sse2.ShiftRightArithmetic(tmp3, 3); } -#endif public static void FTransform2(Span src, Span reference, Span output, Span output2, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte srcRef = ref MemoryMarshal.GetReference(src); ref byte referenceRef = ref MemoryMarshal.GetReference(reference); // Load src. - var src0 = Vector128.Create(Unsafe.As(ref srcRef), 0); - var src1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps)), 0); - var src2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 2)), 0); - var src3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 3)), 0); + Vector128 src0 = Vector128.Create(Unsafe.As(ref srcRef), 0); + Vector128 src1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps)), 0); + Vector128 src2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 2)), 0); + Vector128 src3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 3)), 0); // Load ref. - var ref0 = Vector128.Create(Unsafe.As(ref referenceRef), 0); - var ref1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps)), 0); - var ref2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 2)), 0); - var ref3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 3)), 0); + Vector128 ref0 = Vector128.Create(Unsafe.As(ref referenceRef), 0); + Vector128 ref1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps)), 0); + Vector128 ref2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 2)), 0); + Vector128 ref3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 3)), 0); // Convert both to 16 bit. Vector128 srcLow0 = Sse2.UnpackLow(src0.AsByte(), Vector128.Zero); @@ -429,32 +420,30 @@ public static void FTransform2(Span src, Span reference, Span FTransformPass2SSE2(v01h, v32h, output2); } else -#endif { FTransform(src, reference, output, scratch); - FTransform(src.Slice(4), reference.Slice(4), output2, scratch); + FTransform(src[4..], reference[4..], output2, scratch); } } public static void FTransform(Span src, Span reference, Span output, Span scratch) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref byte srcRef = ref MemoryMarshal.GetReference(src); ref byte referenceRef = ref MemoryMarshal.GetReference(reference); // Load src. - var src0 = Vector128.Create(Unsafe.As(ref srcRef), 0); - var src1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps)), 0); - var src2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 2)), 0); - var src3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 3)), 0); + Vector128 src0 = Vector128.Create(Unsafe.As(ref srcRef), 0); + Vector128 src1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps)), 0); + Vector128 src2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 2)), 0); + Vector128 src3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref srcRef, WebpConstants.Bps * 3)), 0); // Load ref. - var ref0 = Vector128.Create(Unsafe.As(ref referenceRef), 0); - var ref1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps)), 0); - var ref2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 2)), 0); - var ref3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 3)), 0); + Vector128 ref0 = Vector128.Create(Unsafe.As(ref referenceRef), 0); + Vector128 ref1 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps)), 0); + Vector128 ref2 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 2)), 0); + Vector128 ref3 = Vector128.Create(Unsafe.As(ref Unsafe.Add(ref referenceRef, WebpConstants.Bps * 3)), 0); // 00 01 02 03 * // 10 11 12 13 * @@ -486,10 +475,9 @@ public static void FTransform(Span src, Span reference, Span FTransformPass2SSE2(v01, v32, output); } else -#endif { int i; - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; int srcIdx = 0; int refIdx = 0; @@ -530,7 +518,6 @@ public static void FTransform(Span src, Span reference, Span } } -#if SUPPORTS_RUNTIME_INTRINSICS public static void FTransformPass1SSE2(Vector128 row01, Vector128 row23, out Vector128 out01, out Vector128 out32) { // *in01 = 00 01 10 11 02 03 12 13 @@ -621,11 +608,10 @@ public static void FTransformPass2SSE2(Vector128 v01, Vector128 v32, S Unsafe.As>(ref outputRef) = d0g1.AsInt16(); Unsafe.As>(ref Unsafe.Add(ref outputRef, 8)) = d2f3.AsInt16(); } -#endif public static void FTransformWht(Span input, Span output, Span scratch) { - Span tmp = scratch.Slice(0, 16); + Span tmp = scratch[..16]; int i; int inputIdx = 0; @@ -668,62 +654,62 @@ public static void FTransformWht(Span input, Span output, Span dst, Span left, Span top) { - DcMode(dst.Slice(I16DC16), left, top, 16, 16, 5); - VerticalPred(dst.Slice(I16VE16), top, 16); - HorizontalPred(dst.Slice(I16HE16), left, 16); - TrueMotion(dst.Slice(I16TM16), left, top, 16); + DcMode(dst, left, top, 16, 16, 5); + VerticalPred(dst[I16VE16..], top, 16); + HorizontalPred(dst[I16HE16..], left, 16); + TrueMotion(dst[I16TM16..], left, top, 16); } // Chroma 8x8 prediction (paragraph 12.2). public static void EncPredChroma8(Span dst, Span left, Span top) { // U block. - DcMode(dst.Slice(C8DC8), left, top, 8, 8, 4); - VerticalPred(dst.Slice(C8VE8), top, 8); - HorizontalPred(dst.Slice(C8HE8), left, 8); - TrueMotion(dst.Slice(C8TM8), left, top, 8); + DcMode(dst[C8DC8..], left, top, 8, 8, 4); + VerticalPred(dst[C8VE8..], top, 8); + HorizontalPred(dst[C8HE8..], left, 8); + TrueMotion(dst[C8TM8..], left, top, 8); // V block. - dst = dst.Slice(8); - if (top != null) + dst = dst[8..]; + if (top != default) { - top = top.Slice(8); + top = top[8..]; } - if (left != null) + if (left != default) { - left = left.Slice(16); + left = left[16..]; } - DcMode(dst.Slice(C8DC8), left, top, 8, 8, 4); - VerticalPred(dst.Slice(C8VE8), top, 8); - HorizontalPred(dst.Slice(C8HE8), left, 8); - TrueMotion(dst.Slice(C8TM8), left, top, 8); + DcMode(dst[C8DC8..], left, top, 8, 8, 4); + VerticalPred(dst[C8VE8..], top, 8); + HorizontalPred(dst[C8HE8..], left, 8); + TrueMotion(dst[C8TM8..], left, top, 8); } // Left samples are top[-5 .. -2], top_left is top[-1], top are // located at top[0..3], and top right is top[4..7] public static void EncPredLuma4(Span dst, Span top, int topOffset, Span vals) { - Dc4(dst.Slice(I4DC4), top, topOffset); - Tm4(dst.Slice(I4TM4), top, topOffset); - Ve4(dst.Slice(I4VE4), top, topOffset, vals); - He4(dst.Slice(I4HE4), top, topOffset); - Rd4(dst.Slice(I4RD4), top, topOffset); - Vr4(dst.Slice(I4VR4), top, topOffset); - Ld4(dst.Slice(I4LD4), top, topOffset); - Vl4(dst.Slice(I4VL4), top, topOffset); - Hd4(dst.Slice(I4HD4), top, topOffset); - Hu4(dst.Slice(I4HU4), top, topOffset); + Dc4(dst[I4DC4..], top, topOffset); + Tm4(dst[I4TM4..], top, topOffset); + Ve4(dst[I4VE4..], top, topOffset, vals); + He4(dst[I4HE4..], top, topOffset); + Rd4(dst[I4RD4..], top, topOffset); + Vr4(dst[I4VR4..], top, topOffset); + Ld4(dst[I4LD4..], top, topOffset); + Vl4(dst[I4VL4..], top, topOffset); + Hd4(dst[I4HD4..], top, topOffset); + Hu4(dst[I4HU4..], top, topOffset); } private static void VerticalPred(Span dst, Span top, int size) { - if (top != null) + if (top != default) { for (int j = 0; j < size; j++) { - top.Slice(0, size).CopyTo(dst.Slice(j * WebpConstants.Bps)); + top[..size].CopyTo(dst[(j * WebpConstants.Bps)..]); } } else @@ -734,9 +720,9 @@ private static void VerticalPred(Span dst, Span top, int size) public static void HorizontalPred(Span dst, Span left, int size) { - if (left != null) + if (left != default) { - left = left.Slice(1); // in the reference implementation, left starts at - 1. + left = left[1..]; // in the reference implementation, left starts at - 1. for (int j = 0; j < size; j++) { dst.Slice(j * WebpConstants.Bps, size).Fill(left[j]); @@ -750,20 +736,20 @@ public static void HorizontalPred(Span dst, Span left, int size) public static void TrueMotion(Span dst, Span left, Span top, int size) { - if (left != null) + if (left != default) { - if (top != null) + if (top != default) { Span clip = Clip1.AsSpan(255 - left[0]); // left [0] instead of left[-1], original left starts at -1 for (int y = 0; y < size; y++) { - Span clipTable = clip.Slice(left[y + 1]); // left[y] + Span clipTable = clip[left[y + 1]..]; // left[y] for (int x = 0; x < size; x++) { dst[x] = clipTable[top[x]]; } - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } else @@ -777,7 +763,7 @@ public static void TrueMotion(Span dst, Span left, Span top, i // is equivalent to VE prediction where you just copy the top samples. // Note that if top samples are not available, the default value is // then 129, and not 127 as in the VerticalPred case. - if (top != null) + if (top != default) { VerticalPred(dst, top, size); } @@ -792,17 +778,17 @@ private static void DcMode(Span dst, Span left, Span top, int { int dc = 0; int j; - if (top != null) + if (top != default) { for (j = 0; j < size; j++) { dc += top[j]; } - if (left != null) + if (left != default) { // top and left present. - left = left.Slice(1); // in the reference implementation, left starts at -1. + left = left[1..]; // in the reference implementation, left starts at -1. for (j = 0; j < size; j++) { dc += left[j]; @@ -816,10 +802,10 @@ private static void DcMode(Span dst, Span left, Span top, int dc = (dc + round) >> shift; } - else if (left != null) + else if (left != default) { // left but no top. - left = left.Slice(1); // in the reference implementation, left starts at -1. + left = left[1..]; // in the reference implementation, left starts at -1. for (j = 0; j < size; j++) { dc += left[j]; @@ -854,13 +840,13 @@ private static void Tm4(Span dst, Span top, int topOffset) Span clip = Clip1.AsSpan(255 - top[topOffset - 1]); for (int y = 0; y < 4; y++) { - Span clipTable = clip.Slice(top[topOffset - 2 - y]); + Span clipTable = clip[top[topOffset - 2 - y]..]; for (int x = 0; x < 4; x++) { dst[x] = clipTable[top[topOffset + x]]; } - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } @@ -873,7 +859,7 @@ private static void Ve4(Span dst, Span top, int topOffset, Span dst, Span top, int topOffset) uint val = 0x01010101U * LossyUtils.Avg3(x, i, j); BinaryPrimitives.WriteUInt32BigEndian(dst, val); val = 0x01010101U * LossyUtils.Avg3(i, j, k); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(1 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(1 * WebpConstants.Bps)..], val); val = 0x01010101U * LossyUtils.Avg3(j, k, l); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(2 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(2 * WebpConstants.Bps)..], val); val = 0x01010101U * LossyUtils.Avg3(k, l, l); - BinaryPrimitives.WriteUInt32BigEndian(dst.Slice(3 * WebpConstants.Bps), val); + BinaryPrimitives.WriteUInt32BigEndian(dst[(3 * WebpConstants.Bps)..], val); } private static void Rd4(Span dst, Span top, int topOffset) diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs index a52d9e90ab..1ba359d85d 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Histogram.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -54,10 +52,9 @@ public void CollectHistogram(Span reference, Span pred, int startBlo this.distribution.AsSpan().Clear(); for (j = startBlock; j < endBlock; j++) { - Vp8Encoding.FTransform(reference.Slice(WebpLookupTables.Vp8DspScan[j]), pred.Slice(WebpLookupTables.Vp8DspScan[j]), this.output, this.scratch); + Vp8Encoding.FTransform(reference[WebpLookupTables.Vp8DspScan[j]..], pred[WebpLookupTables.Vp8DspScan[j]..], this.output, this.scratch); // Convert coefficients to bin. -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { // Load. @@ -81,7 +78,6 @@ public void CollectHistogram(Span reference, Span pred, int startBlo } } else -#endif { for (int k = 0; k < 16; ++k) { diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index e3a5696e34..9541ee1f7b 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -2,12 +2,11 @@ // Licensed under the Six Labors Split License. using System; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Formats.Webp.Lossy { @@ -46,7 +45,6 @@ public void Init(int first, int coeffType, Vp8EncProba prob) public void SetCoeffs(Span coeffs) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref short coeffsRef = ref MemoryMarshal.GetReference(coeffs); @@ -65,10 +63,9 @@ public void SetCoeffs(Span coeffs) // The position of the most significant non-zero bit indicates the position of // the last non-zero value. - this.Last = mask != 0 ? Numerics.Log2(mask) : -1; + this.Last = mask != 0 ? BitOperations.Log2(mask) : -1; } else -#endif { int n; this.Last = -1; @@ -82,7 +79,7 @@ public void SetCoeffs(Span coeffs) } } - coeffs.Slice(0, 16).CopyTo(this.Coeffs); + coeffs[..16].CopyTo(this.Coeffs); } // Simulate block coding, but only record statistics. @@ -93,23 +90,23 @@ public int RecordCoeffs(int ctx) Vp8StatsArray s = this.Stats[n].Stats[ctx]; if (this.Last < 0) { - this.RecordStats(0, s, 0); + RecordStats(0, s, 0); return 0; } while (n <= this.Last) { int v; - this.RecordStats(1, s, 0); // order of record doesn't matter + RecordStats(1, s, 0); // order of record doesn't matter while ((v = this.Coeffs[n++]) == 0) { - this.RecordStats(0, s, 1); + RecordStats(0, s, 1); s = this.Stats[WebpConstants.Vp8EncBands[n]].Stats[0]; } - this.RecordStats(1, s, 1); + RecordStats(1, s, 1); bool bit = (uint)(v + 1) > 2u; - if (this.RecordStats(bit ? 1 : 0, s, 2) == 0) + if (RecordStats(bit ? 1 : 0, s, 2) == 0) { // v = -1 or 1 s = this.Stats[WebpConstants.Vp8EncBands[n]].Stats[1]; @@ -130,7 +127,7 @@ public int RecordCoeffs(int ctx) int mask = 2 << i; if ((pattern & 1) != 0) { - this.RecordStats((bits & mask) != 0 ? 1 : 0, s, 3 + i); + RecordStats((bits & mask) != 0 ? 1 : 0, s, 3 + i); } } @@ -140,7 +137,7 @@ public int RecordCoeffs(int ctx) if (n < 16) { - this.RecordStats(0, s, 0); + RecordStats(0, s, 0); } return 1; @@ -163,7 +160,6 @@ public int GetResidualCost(int ctx0) return LossyUtils.Vp8BitCost(0, (byte)p0); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Span ctxs = this.scratch.AsSpan(0, 16); @@ -211,7 +207,7 @@ public int GetResidualCost(int ctx0) return cost; } -#endif + { int v; for (; n < this.Last; ++n) @@ -241,7 +237,7 @@ public int GetResidualCost(int ctx0) private static int LevelCost(Span table, int level) => WebpLookupTables.Vp8LevelFixedCosts[level] + table[level > WebpConstants.MaxVariableLevel ? WebpConstants.MaxVariableLevel : level]; - private int RecordStats(int bit, Vp8StatsArray statsArr, int idx) + private static int RecordStats(int bit, Vp8StatsArray statsArr, int idx) { // An overflow is inbound. Note we handle this at 0xfffe0000u instead of // 0xffff0000u to make sure p + 1u does not overflow. diff --git a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs index 0e789060a2..e913e98989 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs @@ -72,7 +72,7 @@ public void Decode(Buffer2D pixels, int width, int height, WebpI // Paragraph 9.2: color space and clamp type follow. sbyte colorSpace = (sbyte)this.bitReader.ReadValue(1); sbyte clampType = (sbyte)this.bitReader.ReadValue(1); - var pictureHeader = new Vp8PictureHeader() + Vp8PictureHeader pictureHeader = new() { Width = (uint)width, Height = (uint)height, @@ -83,10 +83,10 @@ public void Decode(Buffer2D pixels, int width, int height, WebpI }; // Paragraph 9.3: Parse the segment header. - var proba = new Vp8Proba(); + Vp8Proba proba = new(); Vp8SegmentHeader vp8SegmentHeader = this.ParseSegmentHeader(proba); - using (var decoder = new Vp8Decoder(info.Vp8FrameHeader, pictureHeader, vp8SegmentHeader, proba, this.memoryAllocator)) + using (Vp8Decoder decoder = new(info.Vp8FrameHeader, pictureHeader, vp8SegmentHeader, proba, this.memoryAllocator)) { Vp8Io io = InitializeVp8Io(decoder, pictureHeader); @@ -111,7 +111,7 @@ public void Decode(Buffer2D pixels, int width, int height, WebpI if (info.Features?.Alpha == true) { - using (var alphaDecoder = new AlphaDecoder( + using (AlphaDecoder alphaDecoder = new( width, height, alphaData, @@ -120,7 +120,7 @@ public void Decode(Buffer2D pixels, int width, int height, WebpI this.configuration)) { alphaDecoder.Decode(); - this.DecodePixelValues(width, height, decoder.Pixels.Memory.Span, pixels, alphaDecoder.Alpha); + DecodePixelValues(width, height, decoder.Pixels.Memory.Span, pixels, alphaDecoder.Alpha); } } else @@ -146,7 +146,7 @@ private void DecodePixelValues(int width, int height, Span pixelDa } } - private void DecodePixelValues(int width, int height, Span pixelData, Buffer2D decodedPixels, IMemoryOwner alpha) + private static void DecodePixelValues(int width, int height, Span pixelData, Buffer2D decodedPixels, IMemoryOwner alpha) where TPixel : unmanaged, IPixel { TPixel color = default; @@ -187,7 +187,7 @@ private void ParseFrame(Vp8Decoder dec, Vp8Io io) } // Prepare for next scanline. - this.InitScanline(dec); + InitScanline(dec); // Reconstruct, filter and emit the row. this.ProcessRow(dec, io); @@ -222,9 +222,27 @@ private void ParseIntraMode(Vp8Decoder dec, int mbX) if (!block.IsI4x4) { // Hardcoded 16x16 intra-mode decision tree. - int yMode = this.bitReader.GetBit(156) != 0 ? - this.bitReader.GetBit(128) != 0 ? (int)IntraPredictionMode.TrueMotion : (int)IntraPredictionMode.HPrediction : - this.bitReader.GetBit(163) != 0 ? (int)IntraPredictionMode.VPrediction : (int)IntraPredictionMode.DcPrediction; + int yMode; + if (this.bitReader.GetBit(156) != 0) + { + if (this.bitReader.GetBit(128) != 0) + { + yMode = (int)IntraPredictionMode.TrueMotion; + } + else + { + yMode = (int)IntraPredictionMode.HPrediction; + } + } + else if (this.bitReader.GetBit(163) != 0) + { + yMode = (int)IntraPredictionMode.VPrediction; + } + else + { + yMode = (int)IntraPredictionMode.DcPrediction; + } + block.Modes[0] = (byte)yMode; for (int i = 0; i < left.Length; i++) { @@ -252,18 +270,35 @@ private void ParseIntraMode(Vp8Decoder dec, int mbX) } top.CopyTo(modes); - modes = modes.Slice(4); + modes = modes[4..]; left[y] = (byte)yMode; } } // Hardcoded UVMode decision tree. - block.UvMode = (byte)(this.bitReader.GetBit(142) == 0 ? 0 : - this.bitReader.GetBit(114) == 0 ? 2 : - this.bitReader.GetBit(183) != 0 ? 1 : 3); + if (this.bitReader.GetBit(142) == 0) + { + // Hardcoded UVMode decision tree. + block.UvMode = 0; + } + else if (this.bitReader.GetBit(114) == 0) + { + // Hardcoded UVMode decision tree. + block.UvMode = 2; + } + else if (this.bitReader.GetBit(183) != 0) + { + // Hardcoded UVMode decision tree. + block.UvMode = 1; + } + else + { + // Hardcoded UVMode decision tree. + block.UvMode = 3; + } } - private void InitScanline(Vp8Decoder dec) + private static void InitScanline(Vp8Decoder dec) { Vp8MacroBlock left = dec.LeftMacroBlock; left.NoneZeroAcDcCoeffs = 0; @@ -279,7 +314,7 @@ private void InitScanline(Vp8Decoder dec) private void ProcessRow(Vp8Decoder dec, Vp8Io io) { this.ReconstructRow(dec); - this.FinishRow(dec, io); + FinishRow(dec, io); } private void ReconstructRow(Vp8Decoder dec) @@ -290,9 +325,9 @@ private void ReconstructRow(Vp8Decoder dec) const int vOff = uOff + 16; Span yuv = dec.YuvBuffer.Memory.Span; - Span yDst = yuv.Slice(yOff); - Span uDst = yuv.Slice(uOff); - Span vDst = yuv.Slice(vOff); + Span yDst = yuv[yOff..]; + Span uDst = yuv[uOff..]; + Span vDst = yuv[vOff..]; // Initialize left-most block. int end = 16 * WebpConstants.Bps; @@ -349,17 +384,17 @@ private void ReconstructRow(Vp8Decoder dec) { int srcIdx = (i * WebpConstants.Bps) + 12 + yOff; int dstIdx = (i * WebpConstants.Bps) - 4 + yOff; - yuv.Slice(srcIdx, 4).CopyTo(yuv.Slice(dstIdx)); + yuv.Slice(srcIdx, 4).CopyTo(yuv[dstIdx..]); } for (int i = -1; i < 8; i++) { int srcIdx = (i * WebpConstants.Bps) + 4 + uOff; int dstIdx = (i * WebpConstants.Bps) - 4 + uOff; - yuv.Slice(srcIdx, 4).CopyTo(yuv.Slice(dstIdx)); + yuv.Slice(srcIdx, 4).CopyTo(yuv[dstIdx..]); srcIdx = (i * WebpConstants.Bps) + 4 + vOff; dstIdx = (i * WebpConstants.Bps) - 4 + vOff; - yuv.Slice(srcIdx, 4).CopyTo(yuv.Slice(dstIdx)); + yuv.Slice(srcIdx, 4).CopyTo(yuv[dstIdx..]); } } @@ -369,15 +404,15 @@ private void ReconstructRow(Vp8Decoder dec) uint bits = block.NonZeroY; if (mby > 0) { - topYuv.Y.CopyTo(yuv.Slice(yOff - WebpConstants.Bps)); - topYuv.U.CopyTo(yuv.Slice(uOff - WebpConstants.Bps)); - topYuv.V.CopyTo(yuv.Slice(vOff - WebpConstants.Bps)); + topYuv.Y.CopyTo(yuv[(yOff - WebpConstants.Bps)..]); + topYuv.U.CopyTo(yuv[(uOff - WebpConstants.Bps)..]); + topYuv.V.CopyTo(yuv[(vOff - WebpConstants.Bps)..]); } // Predict and add residuals. if (block.IsI4x4) { - Span topRight = yuv.Slice(yOff - WebpConstants.Bps + 16); + Span topRight = yuv[(yOff - WebpConstants.Bps + 16)..]; if (mby > 0) { if (mbx >= dec.MbWidth - 1) @@ -396,16 +431,15 @@ private void ReconstructRow(Vp8Decoder dec) } // Replicate the top-right pixels below. - Span topRightUint = MemoryMarshal.Cast(yuv.Slice(yOff - WebpConstants.Bps + 16)); + Span topRightUint = MemoryMarshal.Cast(yuv[(yOff - WebpConstants.Bps + 16)..]); topRightUint[WebpConstants.Bps] = topRightUint[2 * WebpConstants.Bps] = topRightUint[3 * WebpConstants.Bps] = topRightUint[0]; // Predict and add residuals for all 4x4 blocks in turn. for (int n = 0; n < 16; ++n, bits <<= 2) { int offset = yOff + WebpConstants.Scan[n]; - Span dst = yuv.Slice(offset); - byte lumaMode = block.Modes[n]; - switch (lumaMode) + Span dst = yuv[offset..]; + switch (block.Modes[n]) { case 0: LossyUtils.DC4(dst, yuv, offset); @@ -439,14 +473,13 @@ private void ReconstructRow(Vp8Decoder dec) break; } - this.DoTransform(bits, coeffs.AsSpan(n * 16), dst, this.scratch); + DoTransform(bits, coeffs.AsSpan(n * 16), dst, this.scratch); } } else { // 16x16 - int mode = CheckMode(mbx, mby, block.Modes[0]); - switch (mode) + switch (CheckMode(mbx, mby, block.Modes[0])) { case 0: LossyUtils.DC16(yDst, yuv, yOff); @@ -475,15 +508,14 @@ private void ReconstructRow(Vp8Decoder dec) { for (int n = 0; n < 16; ++n, bits <<= 2) { - this.DoTransform(bits, coeffs.AsSpan(n * 16), yDst.Slice(WebpConstants.Scan[n]), this.scratch); + DoTransform(bits, coeffs.AsSpan(n * 16), yDst[WebpConstants.Scan[n]..], this.scratch); } } } // Chroma uint bitsUv = block.NonZeroUv; - int chromaMode = CheckMode(mbx, mby, block.UvMode); - switch (chromaMode) + switch (CheckMode(mbx, mby, block.UvMode)) { case 0: LossyUtils.DC8uv(uDst, yuv, uOff); @@ -515,8 +547,8 @@ private void ReconstructRow(Vp8Decoder dec) break; } - this.DoUVTransform(bitsUv, coeffs.AsSpan(16 * 16), uDst, this.scratch); - this.DoUVTransform(bitsUv >> 8, coeffs.AsSpan(20 * 16), vDst, this.scratch); + DoUVTransform(bitsUv, coeffs.AsSpan(16 * 16), uDst, this.scratch); + DoUVTransform(bitsUv >> 8, coeffs.AsSpan(20 * 16), vDst, this.scratch); // Stash away top samples for next block. if (mby < dec.MbHeight - 1) @@ -527,33 +559,33 @@ private void ReconstructRow(Vp8Decoder dec) } // Transfer reconstructed samples from yuv_buffer cache to final destination. - Span yOut = dec.CacheY.Memory.Span.Slice(dec.CacheYOffset + (mbx * 16)); - Span uOut = dec.CacheU.Memory.Span.Slice(dec.CacheUvOffset + (mbx * 8)); - Span vOut = dec.CacheV.Memory.Span.Slice(dec.CacheUvOffset + (mbx * 8)); + Span yOut = dec.CacheY.Memory.Span[(dec.CacheYOffset + (mbx * 16))..]; + Span uOut = dec.CacheU.Memory.Span[(dec.CacheUvOffset + (mbx * 8))..]; + Span vOut = dec.CacheV.Memory.Span[(dec.CacheUvOffset + (mbx * 8))..]; for (int j = 0; j < 16; j++) { - yDst.Slice(j * WebpConstants.Bps, Math.Min(16, yOut.Length)).CopyTo(yOut.Slice(j * dec.CacheYStride)); + yDst.Slice(j * WebpConstants.Bps, Math.Min(16, yOut.Length)).CopyTo(yOut[(j * dec.CacheYStride)..]); } for (int j = 0; j < 8; j++) { int jUvStride = j * dec.CacheUvStride; - uDst.Slice(j * WebpConstants.Bps, Math.Min(8, uOut.Length)).CopyTo(uOut.Slice(jUvStride)); - vDst.Slice(j * WebpConstants.Bps, Math.Min(8, vOut.Length)).CopyTo(vOut.Slice(jUvStride)); + uDst.Slice(j * WebpConstants.Bps, Math.Min(8, uOut.Length)).CopyTo(uOut[jUvStride..]); + vDst.Slice(j * WebpConstants.Bps, Math.Min(8, vOut.Length)).CopyTo(vOut[jUvStride..]); } } } - private void FilterRow(Vp8Decoder dec) + private static void FilterRow(Vp8Decoder dec) { int mby = dec.MbY; for (int mbx = dec.TopLeftMbX; mbx < dec.BottomRightMbX; ++mbx) { - this.DoFilter(dec, mbx, mby); + DoFilter(dec, mbx, mby); } } - private void DoFilter(Vp8Decoder dec, int mbx, int mby) + private static void DoFilter(Vp8Decoder dec, int mbx, int mby) { int yBps = dec.CacheYStride; Vp8FilterInfo filterInfo = dec.FilterInfo[mbx]; @@ -620,7 +652,7 @@ private void DoFilter(Vp8Decoder dec, int mbx, int mby) } } - private void FinishRow(Vp8Decoder dec, Vp8Io io) + private static void FinishRow(Vp8Decoder dec, Vp8Io io) { int extraYRows = WebpConstants.FilterExtraRows[(int)dec.Filter]; int ySize = extraYRows * dec.CacheYStride; @@ -635,7 +667,7 @@ private void FinishRow(Vp8Decoder dec, Vp8Io io) if (filterRow) { - this.FilterRow(dec); + FilterRow(dec); } int yStart = mby * 16; @@ -649,9 +681,9 @@ private void FinishRow(Vp8Decoder dec, Vp8Io io) } else { - io.Y = dec.CacheY.Memory.Span.Slice(dec.CacheYOffset); - io.U = dec.CacheU.Memory.Span.Slice(dec.CacheUvOffset); - io.V = dec.CacheV.Memory.Span.Slice(dec.CacheUvOffset); + io.Y = dec.CacheY.Memory.Span[dec.CacheYOffset..]; + io.U = dec.CacheU.Memory.Span[dec.CacheUvOffset..]; + io.V = dec.CacheV.Memory.Span[dec.CacheUvOffset..]; } if (!isLastRow) @@ -669,7 +701,7 @@ private void FinishRow(Vp8Decoder dec, Vp8Io io) io.MbY = yStart; io.MbW = io.Width; io.MbH = yEnd - yStart; - this.EmitRgb(dec, io); + EmitRgb(dec, io); } // Rotate top samples if needed. @@ -681,7 +713,7 @@ private void FinishRow(Vp8Decoder dec, Vp8Io io) } } - private int EmitRgb(Vp8Decoder dec, Vp8Io io) + private static int EmitRgb(Vp8Decoder dec, Vp8Io io) { Span buf = dec.Pixels.Memory.Span; int numLinesOut = io.MbH; // a priori guess. @@ -693,10 +725,10 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io) Span tmpVBuffer = dec.TmpVBuffer.Memory.Span; Span topU = tmpUBuffer; Span topV = tmpVBuffer; - int bpp = 3; + const int bpp = 3; int bufferStride = bpp * io.Width; int dstStartIdx = io.MbY * bufferStride; - Span dst = buf.Slice(dstStartIdx); + Span dst = buf[dstStartIdx..]; int yEnd = io.MbY + io.MbH; int mbw = io.MbW; int uvw = (mbw + 1) / 2; @@ -711,7 +743,7 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io) else { // We can finish the left-over line from previous call. - YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw, uvBuffer); + YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf[(dstStartIdx - bufferStride)..], dst, mbw, uvBuffer); numLinesOut++; } @@ -722,21 +754,21 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io) { topU = curU; topV = curV; - curU = curU.Slice(io.UvStride); - curV = curV.Slice(io.UvStride); - YuvConversion.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw, uvBuffer); - curY = curY.Slice(ioStride2); - dst = dst.Slice(bufferStride2); + curU = curU[io.UvStride..]; + curV = curV[io.UvStride..]; + YuvConversion.UpSample(curY[io.YStride..], curY[ioStride2..], topU, topV, curU, curV, dst[bufferStride..], dst[bufferStride2..], mbw, uvBuffer); + curY = curY[ioStride2..]; + dst = dst[bufferStride2..]; } // Move to last row. - curY = curY.Slice(io.YStride); + curY = curY[io.YStride..]; if (yEnd < io.Height) { // Save the unfinished samples for next call (as we're not done yet). - curY.Slice(0, mbw).CopyTo(tmpYBuffer); - curU.Slice(0, uvw).CopyTo(tmpUBuffer); - curV.Slice(0, uvw).CopyTo(tmpVBuffer); + curY[..mbw].CopyTo(tmpYBuffer); + curU[..uvw].CopyTo(tmpUBuffer); + curV[..uvw].CopyTo(tmpVBuffer); // The upsampler leaves a row unfinished behind (except for the very last row). numLinesOut--; @@ -746,14 +778,14 @@ private int EmitRgb(Vp8Decoder dec, Vp8Io io) // Process the very last row of even-sized picture. if ((yEnd & 1) == 0) { - YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst.Slice(bufferStride), default, mbw, uvBuffer); + YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst[bufferStride..], default, mbw, uvBuffer); } } return numLinesOut; } - private void DoTransform(uint bits, Span src, Span dst, Span scratch) + private static void DoTransform(uint bits, Span src, Span dst, Span scratch) { switch (bits >> 30) { @@ -769,7 +801,7 @@ private void DoTransform(uint bits, Span src, Span dst, Span s } } - private void DoUVTransform(uint bits, Span src, Span dst, Span scratch) + private static void DoUVTransform(uint bits, Span src, Span dst, Span scratch) { // any non-zero coeff at all? if ((bits & 0xff) > 0) @@ -845,7 +877,7 @@ private bool ParseResiduals(Vp8Decoder dec, Vp8BitReader br, Vp8MacroBlock mb) // Parse DC short[] dc = new short[16]; int ctx = (int)(mb.NoneZeroDcCoeffs + leftMb.NoneZeroDcCoeffs); - int nz = this.GetCoeffs(br, bands[1], ctx, q.Y2Mat, 0, dc); + int nz = GetCoeffs(br, bands[1], ctx, q.Y2Mat, 0, dc); mb.NoneZeroDcCoeffs = leftMb.NoneZeroDcCoeffs = (uint)(nz > 0 ? 1 : 0); if (nz > 1) { @@ -876,7 +908,7 @@ private bool ParseResiduals(Vp8Decoder dec, Vp8BitReader br, Vp8MacroBlock mb) for (int x = 0; x < 4; x++) { int ctx = l + (tnz & 1); - int nz = this.GetCoeffs(br, acProba, ctx, q.Y1Mat, first, dst.AsSpan(dstOffset)); + int nz = GetCoeffs(br, acProba, ctx, q.Y1Mat, first, dst.AsSpan(dstOffset)); l = nz > first ? 1 : 0; tnz = (byte)((tnz >> 1) | (l << 7)); nzCoeffs = NzCodeBits(nzCoeffs, nz, dst[dstOffset] != 0 ? 1 : 0); @@ -903,7 +935,7 @@ private bool ParseResiduals(Vp8Decoder dec, Vp8BitReader br, Vp8MacroBlock mb) for (int x = 0; x < 2; x++) { int ctx = l + (tnz & 1); - int nz = this.GetCoeffs(br, bands[2], ctx, q.UvMat, 0, dst.AsSpan(dstOffset)); + int nz = GetCoeffs(br, bands[2], ctx, q.UvMat, 0, dst.AsSpan(dstOffset)); l = nz > 0 ? 1 : 0; tnz = (byte)((tnz >> 1) | (l << 3)); nzCoeffs = NzCodeBits(nzCoeffs, nz, dst[dstOffset] != 0 ? 1 : 0); @@ -929,7 +961,7 @@ private bool ParseResiduals(Vp8Decoder dec, Vp8BitReader br, Vp8MacroBlock mb) return (nonZeroY | nonZeroUv) == 0; } - private int GetCoeffs(Vp8BitReader br, Vp8BandProbas[] prob, int ctx, int[] dq, int n, Span coeffs) + private static int GetCoeffs(Vp8BitReader br, Vp8BandProbas[] prob, int ctx, int[] dq, int n, Span coeffs) { // Returns the position of the last non-zero coeff plus one. Vp8ProbaArray p = prob[n].Probabilities[ctx]; @@ -960,7 +992,7 @@ private int GetCoeffs(Vp8BitReader br, Vp8BandProbas[] prob, int ctx, int[] dq, } else { - v = this.GetLargeValue(br, p.Probabilities); + v = GetLargeValue(br, p.Probabilities); p = prob[n + 1].Probabilities[2]; } @@ -971,7 +1003,7 @@ private int GetCoeffs(Vp8BitReader br, Vp8BandProbas[] prob, int ctx, int[] dq, return 16; } - private int GetLargeValue(Vp8BitReader br, byte[] p) + private static int GetLargeValue(Vp8BitReader br, byte[] p) { // See section 13 - 2: http://tools.ietf.org/html/rfc6386#section-13.2 int v; @@ -986,53 +1018,50 @@ private int GetLargeValue(Vp8BitReader br, byte[] p) v = 3 + br.GetBit(p[5]); } } - else + else if (br.GetBit(p[6]) == 0) { - if (br.GetBit(p[6]) == 0) + if (br.GetBit(p[7]) == 0) { - if (br.GetBit(p[7]) == 0) - { - v = 5 + br.GetBit(159); - } - else - { - v = 7 + (2 * br.GetBit(165)); - v += br.GetBit(145); - } + v = 5 + br.GetBit(159); } else { - int bit1 = br.GetBit(p[8]); - int bit0 = br.GetBit(p[9 + bit1]); - int cat = (2 * bit1) + bit0; - v = 0; - byte[] tab = null; - switch (cat) - { - case 0: - tab = WebpConstants.Cat3; - break; - case 1: - tab = WebpConstants.Cat4; - break; - case 2: - tab = WebpConstants.Cat5; - break; - case 3: - tab = WebpConstants.Cat6; - break; - default: - WebpThrowHelper.ThrowImageFormatException("VP8 parsing error"); - break; - } - - for (int i = 0; i < tab.Length; i++) - { - v += v + br.GetBit(tab[i]); - } + v = 7 + (2 * br.GetBit(165)); + v += br.GetBit(145); + } + } + else + { + int bit1 = br.GetBit(p[8]); + int bit0 = br.GetBit(p[9 + bit1]); + int cat = (2 * bit1) + bit0; + v = 0; + byte[] tab = null; + switch (cat) + { + case 0: + tab = WebpConstants.Cat3; + break; + case 1: + tab = WebpConstants.Cat4; + break; + case 2: + tab = WebpConstants.Cat5; + break; + case 3: + tab = WebpConstants.Cat6; + break; + default: + WebpThrowHelper.ThrowImageFormatException("VP8 parsing error"); + break; + } - v += 3 + (8 << cat); + for (int i = 0; i < tab.Length; i++) + { + v += v + br.GetBit(tab[i]); } + + v += 3 + (8 << cat); } return v; @@ -1040,7 +1069,7 @@ private int GetLargeValue(Vp8BitReader br, byte[] p) private Vp8SegmentHeader ParseSegmentHeader(Vp8Proba proba) { - var vp8SegmentHeader = new Vp8SegmentHeader + Vp8SegmentHeader vp8SegmentHeader = new() { UseSegment = this.bitReader.ReadBool() }; @@ -1055,15 +1084,13 @@ private Vp8SegmentHeader ParseSegmentHeader(Vp8Proba proba) for (int i = 0; i < vp8SegmentHeader.Quantizer.Length; i++) { hasValue = this.bitReader.ReadBool(); - byte quantizeValue = (byte)(hasValue ? this.bitReader.ReadSignedValue(7) : 0); - vp8SegmentHeader.Quantizer[i] = quantizeValue; + vp8SegmentHeader.Quantizer[i] = (byte)(hasValue ? this.bitReader.ReadSignedValue(7) : 0); } for (int i = 0; i < vp8SegmentHeader.FilterStrength.Length; i++) { hasValue = this.bitReader.ReadBool(); - byte filterStrengthValue = (byte)(hasValue ? this.bitReader.ReadSignedValue(6) : 0); - vp8SegmentHeader.FilterStrength[i] = filterStrengthValue; + vp8SegmentHeader.FilterStrength[i] = (byte)(hasValue ? this.bitReader.ReadSignedValue(6) : 0); } if (vp8SegmentHeader.UpdateMap) @@ -1149,7 +1176,7 @@ private void ParsePartitions(Vp8Decoder dec) dec.Vp8BitReaders[p] = new Vp8BitReader(this.bitReader.Data, (uint)pSize, partStart); partStart += pSize; sizeLeft -= pSize; - sz = sz.Slice(3); + sz = sz[3..]; } dec.Vp8BitReaders[lastPart] = new Vp8BitReader(this.bitReader.Data, (uint)sizeLeft, partStart); @@ -1188,10 +1215,8 @@ private void ParseDequantizationIndices(Vp8Decoder decoder) decoder.DeQuantMatrices[i] = decoder.DeQuantMatrices[0]; continue; } - else - { - q = baseQ0; - } + + q = baseQ0; } Vp8QuantMatrix m = decoder.DeQuantMatrices[i]; @@ -1228,10 +1253,9 @@ private void ParseProbabilities(Vp8Decoder dec) for (int p = 0; p < WebpConstants.NumProbas; ++p) { byte prob = WebpLookupTables.CoeffsUpdateProba[t, b, c, p]; - byte v = (byte)(this.bitReader.GetBit(prob) != 0 + proba.Bands[t, b].Probabilities[c].Probabilities[p] = (byte)(this.bitReader.GetBit(prob) != 0 ? this.bitReader.ReadValue(8) : WebpLookupTables.DefaultCoeffsProba[t, b, c, p]); - proba.Bands[t, b].Probabilities[c].Probabilities[p] = v; } } } @@ -1251,7 +1275,7 @@ private void ParseProbabilities(Vp8Decoder dec) private static Vp8Io InitializeVp8Io(Vp8Decoder dec, Vp8PictureHeader pictureHeader) { - var io = default(Vp8Io); + Vp8Io io = default; io.Width = (int)pictureHeader.Width; io.Height = (int)pictureHeader.Height; io.UseScaling = false; @@ -1311,7 +1335,19 @@ private static Vp8Io InitializeVp8Io(Vp8Decoder dec, Vp8PictureHeader pictureHea private static uint NzCodeBits(uint nzCoeffs, int nz, int dcNz) { nzCoeffs <<= 2; - nzCoeffs |= (uint)(nz > 3 ? 3 : nz > 1 ? 2 : dcNz); + if (nz > 3) + { + nzCoeffs |= 3; + } + else if (nz > 1) + { + nzCoeffs |= 2; + } + else + { + nzCoeffs |= (uint)dcNz; + } + return nzCoeffs; } @@ -1337,6 +1373,6 @@ private static int CheckMode(int mbx, int mby, int mode) } [MethodImpl(InliningOptions.ShortMethod)] - private static int Clip(int value, int max) => value < 0 ? 0 : value > max ? max : value; + private static int Clip(int value, int max) => Math.Clamp(value, 0, max); } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs index 6e350e7dc6..ea2b82c2c4 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs @@ -5,10 +5,8 @@ using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -32,13 +30,11 @@ internal static class YuvConversion // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16 public static void UpSample(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len, byte[] uvBuffer) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse41.IsSupported) { UpSampleSse41(topY, bottomY, topU, topV, curU, curV, topDst, bottomDst, len, uvBuffer); } else -#endif { UpSampleScalar(topY, bottomY, topU, topV, curU, curV, topDst, bottomDst, len); } @@ -46,7 +42,7 @@ public static void UpSample(Span topY, Span bottomY, Span topU private static void UpSampleScalar(Span topY, Span bottomY, Span topU, Span topV, Span curU, Span curV, Span topDst, Span bottomDst, int len) { - int xStep = 3; + const int xStep = 3; int lastPixelPair = (len - 1) >> 1; uint tluv = LoadUv(topU[0], topV[0]); // top-left sample uint luv = LoadUv(curU[0], curV[0]); // left-sample @@ -71,15 +67,15 @@ private static void UpSampleScalar(Span topY, Span bottomY, Span> 1; uint uv1 = (diag03 + tuv) >> 1; int xMul2 = x * 2; - YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((xMul2 - 1) * xStep)); - YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst.Slice((xMul2 - 0) * xStep)); + YuvToBgr(topY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst[((xMul2 - 1) * xStep)..]); + YuvToBgr(topY[xMul2 - 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), topDst[((xMul2 - 0) * xStep)..]); if (bottomY != default) { uv0 = (diag03 + luv) >> 1; uv1 = (diag12 + uv) >> 1; - YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((xMul2 - 1) * xStep)); - YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst.Slice((xMul2 + 0) * xStep)); + YuvToBgr(bottomY[xMul2 - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst[((xMul2 - 1) * xStep)..]); + YuvToBgr(bottomY[xMul2 + 0], (int)(uv1 & 0xff), (int)(uv1 >> 16), bottomDst[((xMul2 + 0) * xStep)..]); } tluv = tuv; @@ -89,16 +85,15 @@ private static void UpSampleScalar(Span topY, Span bottomY, Span> 2; - YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst.Slice((len - 1) * xStep)); + YuvToBgr(topY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), topDst[((len - 1) * xStep)..]); if (bottomY != default) { uv0 = ((3 * luv) + tluv + 0x00020002u) >> 2; - YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst.Slice((len - 1) * xStep)); + YuvToBgr(bottomY[len - 1], (int)(uv0 & 0xff), (int)(uv0 >> 16), bottomDst[((len - 1) * xStep)..]); } } } -#if SUPPORTS_RUNTIME_INTRINSICS // We compute (9*a + 3*b + 3*c + d + 8) / 16 as follows // u = (9*a + 3*b + 3*c + d + 8) / 16 // = (a + (a + 3*b + 3*c + d) / 8 + 1) / 2 @@ -118,7 +113,7 @@ private static void UpSampleSse41(Span topY, Span bottomY, Span ru = uvBuffer.AsSpan(15); - Span rv = ru.Slice(32); + Span rv = ru[32..]; // Treat the first pixel in regular way. int uDiag = ((topU[0] + curU[0]) >> 1) + 1; @@ -140,7 +135,7 @@ private static void UpSampleSse41(Span topY, Span bottomY, Span topY, Span bottomY, Span 1) { int leftOver = ((len + 1) >> 1) - (pos >> 1); - Span tmpTopDst = ru.Slice(4 * 32); - Span tmpBottomDst = tmpTopDst.Slice(4 * 32); - Span tmpTop = tmpBottomDst.Slice(4 * 32); - Span tmpBottom = (bottomY == null) ? null : tmpTop.Slice(32); - UpSampleLastBlock(topU.Slice(uvPos), curU.Slice(uvPos), leftOver, ru); - UpSampleLastBlock(topV.Slice(uvPos), curV.Slice(uvPos), leftOver, rv); - - topY.Slice(pos, len - pos).CopyTo(tmpTop); + Span tmpTopDst = ru[(4 * 32)..]; + Span tmpBottomDst = tmpTopDst[(4 * 32)..]; + Span tmpTop = tmpBottomDst[(4 * 32)..]; + Span tmpBottom = (bottomY == default) ? null : tmpTop[32..]; + UpSampleLastBlock(topU[uvPos..], curU[uvPos..], leftOver, ru); + UpSampleLastBlock(topV[uvPos..], curV[uvPos..], leftOver, rv); + + topY[pos..len].CopyTo(tmpTop); if (bottomY != default) { - bottomY.Slice(pos, len - pos).CopyTo(tmpBottom); + bottomY[pos..len].CopyTo(tmpBottom); ConvertYuvToBgrWithBottomYSse41(tmpTop, tmpBottom, tmpTopDst, tmpBottomDst, ru, rv, 0, xStep); } else @@ -181,10 +176,10 @@ private static void UpSampleSse41(Span topY, Span bottomY, Span output // Pack the alternate pixels. PackAndStore(a, b, diag1, diag2, output); // store top. - PackAndStore(c, d, diag2, diag1, output.Slice(2 * 32)); + PackAndStore(c, d, diag2, diag1, output[(2 * 32)..]); } private static void UpSampleLastBlock(Span tb, Span bb, int numPixels, Span output) { Span r1 = stackalloc byte[17]; Span r2 = stackalloc byte[17]; - tb.Slice(0, numPixels).CopyTo(r1); - bb.Slice(0, numPixels).CopyTo(r2); + tb[..numPixels].CopyTo(r1); + bb[..numPixels].CopyTo(r2); // Replicate last byte. int length = 17 - numPixels; @@ -263,7 +258,6 @@ private static void PackAndStore(Vector128 a, Vector128 b, Vector128 Unsafe.As>(ref output0Ref) = t1; Unsafe.As>(ref output1Ref) = t2; } -#endif /// /// Converts the RGB values of the image to YUV. @@ -317,11 +311,11 @@ public static bool ConvertRgbToYuv(Image image, Configuration co AccumulateRgba(bgraRow0, bgraRow1, tmpRgbSpan, width); } - ConvertRgbaToUv(tmpRgbSpan, u.Slice(uvRowIndex * uvWidth), v.Slice(uvRowIndex * uvWidth), uvWidth); + ConvertRgbaToUv(tmpRgbSpan, u[(uvRowIndex * uvWidth)..], v[(uvRowIndex * uvWidth)..], uvWidth); uvRowIndex++; - ConvertRgbaToY(bgraRow0, y.Slice(rowIndex * width), width); - ConvertRgbaToY(bgraRow1, y.Slice((rowIndex + 1) * width), width); + ConvertRgbaToY(bgraRow0, y[(rowIndex * width)..], width); + ConvertRgbaToY(bgraRow1, y[((rowIndex + 1) * width)..], width); } // Extra last row. @@ -329,7 +323,7 @@ public static bool ConvertRgbToYuv(Image image, Configuration co { Span rowSpan = imageBuffer.DangerousGetRowSpan(rowIndex); PixelOperations.Instance.ToBgra32(configuration, rowSpan, bgraRow0); - ConvertRgbaToY(bgraRow0, y.Slice(rowIndex * width), width); + ConvertRgbaToY(bgraRow0, y[(rowIndex * width)..], width); if (!WebpCommonUtils.CheckNonOpaque(bgraRow0)) { @@ -341,7 +335,7 @@ public static bool ConvertRgbToYuv(Image image, Configuration co hasAlpha = true; } - ConvertRgbaToUv(tmpRgbSpan, u.Slice(uvRowIndex * uvWidth), v.Slice(uvRowIndex * uvWidth), uvWidth); + ConvertRgbaToUv(tmpRgbSpan, u[(uvRowIndex * uvWidth)..], v[(uvRowIndex * uvWidth)..], uvWidth); } return hasAlpha; @@ -569,16 +563,14 @@ public static void YuvToBgr(int y, int u, int v, Span bgr) bgr[0] = (byte)YuvToB(y, u); } -#if SUPPORTS_RUNTIME_INTRINSICS - [MethodImpl(InliningOptions.ShortMethod)] - private static void ConvertYuvToBgrSse41(Span topY, Span topDst, Span ru, Span rv, int curX, int step) => YuvToBgrSse41(topY.Slice(curX), ru, rv, topDst.Slice(curX * step)); + private static void ConvertYuvToBgrSse41(Span topY, Span topDst, Span ru, Span rv, int curX, int step) => YuvToBgrSse41(topY[curX..], ru, rv, topDst[(curX * step)..]); [MethodImpl(InliningOptions.ShortMethod)] private static void ConvertYuvToBgrWithBottomYSse41(Span topY, Span bottomY, Span topDst, Span bottomDst, Span ru, Span rv, int curX, int step) { - YuvToBgrSse41(topY.Slice(curX), ru, rv, topDst.Slice(curX * step)); - YuvToBgrSse41(bottomY.Slice(curX), ru.Slice(64), rv.Slice(64), bottomDst.Slice(curX * step)); + YuvToBgrSse41(topY[curX..], ru, rv, topDst[(curX * step)..]); + YuvToBgrSse41(bottomY[curX..], ru[64..], rv[64..], bottomDst[(curX * step)..]); } private static void YuvToBgrSse41(Span y, Span u, Span v, Span dst) @@ -718,9 +710,9 @@ private static void ConvertYuv444ToBgrSse41(ref byte y, ref byte u, ref byte v, // R = (19077 * y + 26149 * v - 14234) >> 6 // G = (19077 * y - 6419 * u - 13320 * v + 8708) >> 6 // B = (19077 * y + 33050 * u - 17685) >> 6 - Vector128 k19077 = Vector128.Create((ushort)19077); - Vector128 k26149 = Vector128.Create((ushort)26149); - Vector128 k14234 = Vector128.Create((ushort)14234); + var k19077 = Vector128.Create((ushort)19077); + var k26149 = Vector128.Create((ushort)26149); + var k14234 = Vector128.Create((ushort)14234); Vector128 y1 = Sse2.MultiplyHigh(y0.AsUInt16(), k19077); Vector128 r0 = Sse2.MultiplyHigh(v0.AsUInt16(), k26149); @@ -744,8 +736,6 @@ private static void ConvertYuv444ToBgrSse41(ref byte y, ref byte u, ref byte v, b = Sse2.ShiftRightLogical(b2.AsInt16(), 6); // range: [0, 34238] } -#endif - [MethodImpl(InliningOptions.ShortMethod)] public static int YuvToB(int y, int u) => Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685); @@ -761,7 +751,7 @@ private static void ConvertYuv444ToBgrSse41(ref byte y, ref byte u, ref byte v, [MethodImpl(InliningOptions.ShortMethod)] private static byte Clip8(int v) { - int yuvMask = (256 << 6) - 1; + const int yuvMask = (256 << 6) - 1; return (byte)((v & ~yuvMask) == 0 ? v >> 6 : v < 0 ? 0 : 255); } } diff --git a/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs b/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs index 57c01cac74..2be64492ee 100644 --- a/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs +++ b/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs @@ -147,7 +147,7 @@ private uint ReadFrame(BufferedReadStream stream, ref Image imag } WebpImageInfo webpInfo = null; - var features = new WebpFeatures(); + WebpFeatures features = new(); switch (chunkType) { case WebpChunkType.Vp8: @@ -169,7 +169,7 @@ private uint ReadFrame(BufferedReadStream stream, ref Image imag { image = new Image(this.configuration, (int)width, (int)height, backgroundColor.ToPixel(), this.metadata); - this.SetFrameMetadata(image.Frames.RootFrame.Metadata, frameData.Duration); + SetFrameMetadata(image.Frames.RootFrame.Metadata, frameData.Duration); imageFrame = image.Frames.RootFrame; } @@ -177,7 +177,7 @@ private uint ReadFrame(BufferedReadStream stream, ref Image imag { currentFrame = image.Frames.AddFrame(previousFrame); // This clones the frame and adds it the collection. - this.SetFrameMetadata(currentFrame.Metadata, frameData.Duration); + SetFrameMetadata(currentFrame.Metadata, frameData.Duration); imageFrame = currentFrame; } @@ -186,7 +186,7 @@ private uint ReadFrame(BufferedReadStream stream, ref Image imag int frameY = (int)(frameData.Y * 2); int frameWidth = (int)frameData.Width; int frameHeight = (int)frameData.Height; - var regionRectangle = Rectangle.FromLTRB(frameX, frameY, frameX + frameWidth, frameY + frameHeight); + Rectangle regionRectangle = Rectangle.FromLTRB(frameX, frameY, frameX + frameWidth, frameY + frameHeight); if (frameData.DisposalMethod is AnimationDisposalMethod.Dispose) { @@ -194,7 +194,7 @@ private uint ReadFrame(BufferedReadStream stream, ref Image imag } using Buffer2D decodedImage = this.DecodeImageData(frameData, webpInfo); - this.DrawDecodedImageOnCanvas(decodedImage, imageFrame, frameX, frameY, frameWidth, frameHeight); + DrawDecodedImageOnCanvas(decodedImage, imageFrame, frameX, frameY, frameWidth, frameHeight); if (previousFrame != null && frameData.BlendingMethod is AnimationBlendingMethod.AlphaBlending) { @@ -213,7 +213,7 @@ private uint ReadFrame(BufferedReadStream stream, ref Image imag /// The metadata. /// The frame duration. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SetFrameMetadata(ImageFrameMetadata meta, uint duration) + private static void SetFrameMetadata(ImageFrameMetadata meta, uint duration) { WebpFrameMetadata frameMetadata = meta.GetWebpMetadata(); frameMetadata.FrameDuration = duration; @@ -248,19 +248,19 @@ private byte ReadAlphaData(BufferedReadStream stream) private Buffer2D DecodeImageData(AnimationFrameData frameData, WebpImageInfo webpInfo) where TPixel : unmanaged, IPixel { - var decodedImage = new Image((int)frameData.Width, (int)frameData.Height); + Image decodedImage = new((int)frameData.Width, (int)frameData.Height); try { Buffer2D pixelBufferDecoded = decodedImage.Frames.RootFrame.PixelBuffer; if (webpInfo.IsLossless) { - var losslessDecoder = new WebpLosslessDecoder(webpInfo.Vp8LBitReader, this.memoryAllocator, this.configuration); + WebpLosslessDecoder losslessDecoder = new(webpInfo.Vp8LBitReader, this.memoryAllocator, this.configuration); losslessDecoder.Decode(pixelBufferDecoded, (int)webpInfo.Width, (int)webpInfo.Height); } else { - var lossyDecoder = new WebpLossyDecoder(webpInfo.Vp8BitReader, this.memoryAllocator, this.configuration); + WebpLossyDecoder lossyDecoder = new(webpInfo.Vp8BitReader, this.memoryAllocator, this.configuration); lossyDecoder.Decode(pixelBufferDecoded, (int)webpInfo.Width, (int)webpInfo.Height, webpInfo, this.alphaData); } @@ -278,7 +278,7 @@ private Buffer2D DecodeImageData(AnimationFrameData frameData, W } /// - /// Draws the decoded image on canvas. The decoded image can be smaller the the canvas. + /// Draws the decoded image on canvas. The decoded image can be smaller the canvas. /// /// The type of the pixel. /// The decoded image. @@ -287,7 +287,7 @@ private Buffer2D DecodeImageData(AnimationFrameData frameData, W /// The frame y coordinate. /// The width of the frame. /// The height of the frame. - private void DrawDecodedImageOnCanvas(Buffer2D decodedImage, ImageFrame imageFrame, int frameX, int frameY, int frameWidth, int frameHeight) + private static void DrawDecodedImageOnCanvas(Buffer2D decodedImage, ImageFrame imageFrame, int frameX, int frameY, int frameWidth, int frameHeight) where TPixel : unmanaged, IPixel { Buffer2D imageFramePixels = imageFrame.PixelBuffer; @@ -295,8 +295,8 @@ private void DrawDecodedImageOnCanvas(Buffer2D decodedImage, Ima for (int y = frameY; y < frameY + frameHeight; y++) { Span framePixelRow = imageFramePixels.DangerousGetRowSpan(y); - Span decodedPixelRow = decodedImage.DangerousGetRowSpan(decodedRowIdx++).Slice(0, frameWidth); - decodedPixelRow.TryCopyTo(framePixelRow.Slice(frameX)); + Span decodedPixelRow = decodedImage.DangerousGetRowSpan(decodedRowIdx++)[..frameWidth]; + decodedPixelRow.TryCopyTo(framePixelRow[frameX..]); } } @@ -341,7 +341,7 @@ private void RestoreToBackground(ImageFrame imageFrame, Color ba return; } - var interest = Rectangle.Intersect(imageFrame.Bounds(), this.restoreArea.Value); + Rectangle interest = Rectangle.Intersect(imageFrame.Bounds(), this.restoreArea.Value); Buffer2DRegion pixelRegion = imageFrame.PixelBuffer.GetRegion(interest); TPixel backgroundPixel = backgroundColor.ToPixel(); pixelRegion.Fill(backgroundPixel); @@ -354,25 +354,25 @@ private void RestoreToBackground(ImageFrame imageFrame, Color ba /// Animation frame data. private AnimationFrameData ReadFrameHeader(BufferedReadStream stream) { - var data = new AnimationFrameData + AnimationFrameData data = new() { - DataSize = WebpChunkParsingUtils.ReadChunkSize(stream, this.buffer) - }; + DataSize = WebpChunkParsingUtils.ReadChunkSize(stream, this.buffer), - // 3 bytes for the X coordinate of the upper left corner of the frame. - data.X = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer); + // 3 bytes for the X coordinate of the upper left corner of the frame. + X = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer), - // 3 bytes for the Y coordinate of the upper left corner of the frame. - data.Y = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer); + // 3 bytes for the Y coordinate of the upper left corner of the frame. + Y = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer), - // Frame width Minus One. - data.Width = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer) + 1; + // Frame width Minus One. + Width = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer) + 1, - // Frame height Minus One. - data.Height = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer) + 1; + // Frame height Minus One. + Height = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer) + 1, - // Frame duration. - data.Duration = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer); + // Frame duration. + Duration = WebpChunkParsingUtils.ReadUnsignedInt24Bit(stream, this.buffer) + }; byte flags = (byte)stream.ReadByte(); data.DisposalMethod = (flags & 1) == 1 ? AnimationDisposalMethod.Dispose : AnimationDisposalMethod.DoNotDispose; diff --git a/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs b/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs index bd862c41cb..c5d8c30ed4 100644 --- a/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs +++ b/src/ImageSharp/Formats/Webp/WebpCommonUtils.cs @@ -3,11 +3,9 @@ using System; using System.Runtime.InteropServices; -using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif +using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Webp { @@ -23,7 +21,6 @@ internal static class WebpCommonUtils /// Returns true if alpha has non-0xff values. public static unsafe bool CheckNonOpaque(Span row) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { ReadOnlySpan rowBytes = MemoryMarshal.AsBytes(row); @@ -31,7 +28,7 @@ public static unsafe bool CheckNonOpaque(Span row) int length = (row.Length * 4) - 3; fixed (byte* src = rowBytes) { - Vector256 alphaMaskVector256 = Vector256.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); + var alphaMaskVector256 = Vector256.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); Vector256 all0x80Vector256 = Vector256.Create((byte)0x80).AsByte(); for (; i + 128 <= length; i += 128) @@ -113,7 +110,6 @@ public static unsafe bool CheckNonOpaque(Span row) } } else -#endif { for (int x = 0; x < row.Length; x++) { @@ -127,10 +123,9 @@ public static unsafe bool CheckNonOpaque(Span row) return false; } -#if SUPPORTS_RUNTIME_INTRINSICS private static unsafe bool IsNoneOpaque64Bytes(byte* src, int i) { - Vector128 alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); + var alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); Vector128 a0 = Sse2.LoadVector128(src + i).AsByte(); Vector128 a1 = Sse2.LoadVector128(src + i + 16).AsByte(); @@ -145,17 +140,12 @@ private static unsafe bool IsNoneOpaque64Bytes(byte* src, int i) Vector128 d = Sse2.PackSignedSaturate(c0, c1).AsByte(); Vector128 bits = Sse2.CompareEqual(d, Vector128.Create((byte)0x80).AsByte()); int mask = Sse2.MoveMask(bits); - if (mask != 0xFFFF) - { - return true; - } - - return false; + return mask != 0xFFFF; } private static unsafe bool IsNoneOpaque32Bytes(byte* src, int i) { - Vector128 alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); + var alphaMask = Vector128.Create(0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255); Vector128 a0 = Sse2.LoadVector128(src + i).AsByte(); Vector128 a1 = Sse2.LoadVector128(src + i + 16).AsByte(); @@ -165,13 +155,7 @@ private static unsafe bool IsNoneOpaque32Bytes(byte* src, int i) Vector128 d = Sse2.PackSignedSaturate(c, c).AsByte(); Vector128 bits = Sse2.CompareEqual(d, Vector128.Create((byte)0x80).AsByte()); int mask = Sse2.MoveMask(bits); - if (mask != 0xFFFF) - { - return true; - } - - return false; + return mask != 0xFFFF; } -#endif } } diff --git a/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs b/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs index fa270b5281..cdb6e56627 100644 --- a/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs @@ -14,22 +14,26 @@ public sealed class WebpImageFormatDetector : IImageFormatDetector public int HeaderSize => 12; /// - public IImageFormat DetectFormat(ReadOnlySpan header) => this.IsSupportedFileFormat(header) ? WebpFormat.Instance : null; + public IImageFormat DetectFormat(ReadOnlySpan header) + => this.IsSupportedFileFormat(header) ? WebpFormat.Instance : null; - private bool IsSupportedFileFormat(ReadOnlySpan header) => header.Length >= this.HeaderSize && this.IsRiffContainer(header) && this.IsWebpFile(header); + private bool IsSupportedFileFormat(ReadOnlySpan header) + => header.Length >= this.HeaderSize && IsRiffContainer(header) && IsWebpFile(header); /// /// Checks, if the header starts with a valid RIFF FourCC. /// /// The header bytes. /// True, if its a valid RIFF FourCC. - private bool IsRiffContainer(ReadOnlySpan header) => header.Slice(0, 4).SequenceEqual(WebpConstants.RiffFourCc); + private static bool IsRiffContainer(ReadOnlySpan header) + => header[..4].SequenceEqual(WebpConstants.RiffFourCc); /// /// Checks if 'WEBP' is present in the header. /// /// The header bytes. /// True, if its a webp file. - private bool IsWebpFile(ReadOnlySpan header) => header.Slice(8, 4).SequenceEqual(WebpConstants.WebpHeader); + private static bool IsWebpFile(ReadOnlySpan header) + => header.Slice(8, 4).SequenceEqual(WebpConstants.WebpHeader); } } diff --git a/src/ImageSharp/Formats/Webp/WebpImageInfo.cs b/src/ImageSharp/Formats/Webp/WebpImageInfo.cs index 5b74de6803..3c9eea38c5 100644 --- a/src/ImageSharp/Formats/Webp/WebpImageInfo.cs +++ b/src/ImageSharp/Formats/Webp/WebpImageInfo.cs @@ -49,14 +49,14 @@ internal class WebpImageInfo : IDisposable public Vp8FrameHeader Vp8FrameHeader { get; set; } /// - /// Gets or sets the VP8L bitreader. Will be null, if its not a lossless image. + /// Gets or sets the VP8L bitreader. Will be , if its not a lossless image. /// - public Vp8LBitReader Vp8LBitReader { get; set; } = null; + public Vp8LBitReader Vp8LBitReader { get; set; } /// - /// Gets or sets the VP8 bitreader. Will be null, if its not a lossy image. + /// Gets or sets the VP8 bitreader. Will be , if its not a lossy image. /// - public Vp8BitReader Vp8BitReader { get; set; } = null; + public Vp8BitReader Vp8BitReader { get; set; } /// public void Dispose() diff --git a/src/ImageSharp/IO/BufferedReadStream.cs b/src/ImageSharp/IO/BufferedReadStream.cs index a117b7d110..e6aeadea23 100644 --- a/src/ImageSharp/IO/BufferedReadStream.cs +++ b/src/ImageSharp/IO/BufferedReadStream.cs @@ -112,7 +112,7 @@ public override long Position public override bool CanSeek { get; } = true; /// - public override bool CanWrite { get; } = false; + public override bool CanWrite { get; } /// /// Gets remaining byte count available to read. @@ -175,7 +175,6 @@ public override int Read(byte[] buffer, int offset, int count) return this.ReadToBufferViaCopyFast(buffer, offset, count); } -#if SUPPORTS_SPAN_STREAM /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int Read(Span buffer) @@ -196,7 +195,6 @@ public override int Read(Span buffer) return this.ReadToBufferViaCopyFast(buffer); } -#endif /// public override void Flush() @@ -354,7 +352,7 @@ private int ReadToBufferDirectSlow(Span buffer) int i; do { - i = baseStream.Read(buffer.Slice(n, count - n)); + i = baseStream.Read(buffer[n..count]); n += i; } while (n < count && i > 0); diff --git a/src/ImageSharp/IO/ChunkedMemoryStream.cs b/src/ImageSharp/IO/ChunkedMemoryStream.cs index 2bd8563aba..837af618ec 100644 --- a/src/ImageSharp/IO/ChunkedMemoryStream.cs +++ b/src/ImageSharp/IO/ChunkedMemoryStream.cs @@ -203,7 +203,7 @@ protected override void Dispose(bool disposing) this.isDisposed = true; if (disposing) { - this.ReleaseMemoryChunks(this.memoryChunk); + ReleaseMemoryChunks(this.memoryChunk); } this.memoryChunk = null; @@ -236,11 +236,9 @@ public override int Read(byte[] buffer, int offset, int count) return this.ReadImpl(buffer.AsSpan(offset, count)); } -#if SUPPORTS_SPAN_STREAM /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int Read(Span buffer) => this.ReadImpl(buffer); -#endif private int ReadImpl(Span buffer) { @@ -288,7 +286,7 @@ private int ReadImpl(Span buffer) } int readCount = Math.Min(count, chunkSize - this.readOffset); - chunkBuffer.Slice(this.readOffset, readCount).CopyTo(buffer.Slice(offset)); + chunkBuffer.Slice(this.readOffset, readCount).CopyTo(buffer[offset..]); offset += readCount; count -= readCount; this.readOffset += readCount; @@ -352,11 +350,9 @@ public override void Write(byte[] buffer, int offset, int count) this.WriteImpl(buffer.AsSpan(offset, count)); } -#if SUPPORTS_SPAN_STREAM /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override void Write(ReadOnlySpan buffer) => this.WriteImpl(buffer); -#endif private void WriteImpl(ReadOnlySpan buffer) { @@ -386,7 +382,7 @@ private void WriteImpl(ReadOnlySpan buffer) } int copyCount = Math.Min(count, chunkSize - this.writeOffset); - buffer.Slice(offset, copyCount).CopyTo(chunkBuffer.Slice(this.writeOffset)); + buffer.Slice(offset, copyCount).CopyTo(chunkBuffer[this.writeOffset..]); offset += copyCount; count -= copyCount; @@ -534,7 +530,7 @@ private MemoryChunk AllocateMemoryChunk() }; } - private void ReleaseMemoryChunks(MemoryChunk chunk) + private static void ReleaseMemoryChunks(MemoryChunk chunk) { while (chunk != null) { diff --git a/src/ImageSharp/Image.FromStream.cs b/src/ImageSharp/Image.FromStream.cs index 5c73590aa1..4d1b172313 100644 --- a/src/ImageSharp/Image.FromStream.cs +++ b/src/ImageSharp/Image.FromStream.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.IO; using System.Text; using System.Threading; @@ -546,7 +547,7 @@ internal static T WithSeekableStream( } // We want to be able to load images from things like HttpContext.Request.Body - using var memoryStream = new ChunkedMemoryStream(configuration.MemoryAllocator); + using ChunkedMemoryStream memoryStream = new(configuration.MemoryAllocator); stream.CopyTo(memoryStream, configuration.StreamProcessingBufferSize); memoryStream.Position = 0; @@ -562,6 +563,7 @@ internal static T WithSeekableStream( /// The action to perform. /// The cancellation token. /// The . + /// Cannot read from the stream. internal static async Task WithSeekableStreamAsync( DecoderOptions options, Stream stream, @@ -577,19 +579,16 @@ internal static async Task WithSeekableStreamAsync( } Configuration configuration = options.Configuration; - if (stream.CanSeek) + if (stream.CanSeek && configuration.ReadOrigin == ReadOrigin.Begin) { - if (configuration.ReadOrigin == ReadOrigin.Begin) - { - stream.Position = 0; - } + stream.Position = 0; // NOTE: We are explicitly not executing the action against the stream here as we do in WithSeekableStream() because that // would incur synchronous IO reads which must be avoided in this asynchronous method. Instead, we will *always* run the // code below to copy the stream to an in-memory buffer before invoking the action. } - using var memoryStream = new ChunkedMemoryStream(configuration.MemoryAllocator); + using ChunkedMemoryStream memoryStream = new(configuration.MemoryAllocator); await stream.CopyToAsync(memoryStream, configuration.StreamProcessingBufferSize, cancellationToken).ConfigureAwait(false); memoryStream.Position = 0; @@ -599,12 +598,12 @@ internal static async Task WithSeekableStreamAsync( [DoesNotReturn] private static void ThrowNotLoaded(DecoderOptions options) { - var sb = new StringBuilder(); + StringBuilder sb = new(); sb.AppendLine("Image cannot be loaded. Available decoders:"); foreach (KeyValuePair val in options.Configuration.ImageFormatsManager.ImageDecoders) { - sb.AppendFormat(" - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); + sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); } throw new UnknownImageFormatException(sb.ToString()); diff --git a/src/ImageSharp/Image.LoadPixelData.cs b/src/ImageSharp/Image.LoadPixelData.cs index a59f5a34ce..a8db3483dc 100644 --- a/src/ImageSharp/Image.LoadPixelData.cs +++ b/src/ImageSharp/Image.LoadPixelData.cs @@ -74,7 +74,7 @@ public static Image LoadPixelData(Configuration configuration, R Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data)); var image = new Image(configuration, width, height); - data = data.Slice(0, count); + data = data[..count]; data.CopyTo(image.Frames.RootFrame.PixelBuffer.FastMemoryGroup); return image; diff --git a/src/ImageSharp/Image.WrapMemory.cs b/src/ImageSharp/Image.WrapMemory.cs index 6646e43c28..9e68d901a6 100644 --- a/src/ImageSharp/Image.WrapMemory.cs +++ b/src/ImageSharp/Image.WrapMemory.cs @@ -53,7 +53,7 @@ public static Image WrapMemory( Guard.NotNull(metadata, nameof(metadata)); Guard.IsTrue(pixelMemory.Length >= width * height, nameof(pixelMemory), "The length of the input memory is less than the specified image size"); - var memorySource = MemoryGroup.Wrap(pixelMemory); + MemoryGroup memorySource = MemoryGroup.Wrap(pixelMemory); return new Image(configuration, memorySource, width, height, metadata); } @@ -148,7 +148,7 @@ public static Image WrapMemory( Guard.NotNull(metadata, nameof(metadata)); Guard.IsTrue(pixelMemoryOwner.Memory.Length >= width * height, nameof(pixelMemoryOwner), "The length of the input memory is less than the specified image size"); - var memorySource = MemoryGroup.Wrap(pixelMemoryOwner); + MemoryGroup memorySource = MemoryGroup.Wrap(pixelMemoryOwner); return new Image(configuration, memorySource, width, height, metadata); } @@ -231,11 +231,11 @@ public static Image WrapMemory( Guard.NotNull(configuration, nameof(configuration)); Guard.NotNull(metadata, nameof(metadata)); - var memoryManager = new ByteMemoryManager(byteMemory); + ByteMemoryManager memoryManager = new(byteMemory); Guard.IsTrue(memoryManager.Memory.Length >= width * height, nameof(byteMemory), "The length of the input memory is less than the specified image size"); - var memorySource = MemoryGroup.Wrap(memoryManager.Memory); + MemoryGroup memorySource = MemoryGroup.Wrap(memoryManager.Memory); return new Image(configuration, memorySource, width, height, metadata); } @@ -329,11 +329,11 @@ public static Image WrapMemory( Guard.NotNull(configuration, nameof(configuration)); Guard.NotNull(metadata, nameof(metadata)); - var pixelMemoryOwner = new ByteMemoryOwner(byteMemoryOwner); + ByteMemoryOwner pixelMemoryOwner = new(byteMemoryOwner); Guard.IsTrue(pixelMemoryOwner.Memory.Length >= (long)width * height, nameof(pixelMemoryOwner), "The length of the input memory is less than the specified image size"); - var memorySource = MemoryGroup.Wrap(pixelMemoryOwner); + MemoryGroup memorySource = MemoryGroup.Wrap(pixelMemoryOwner); return new Image(configuration, memorySource, width, height, metadata); } @@ -422,9 +422,9 @@ public static unsafe Image WrapMemory( Guard.NotNull(configuration, nameof(configuration)); Guard.NotNull(metadata, nameof(metadata)); - var memoryManager = new UnmanagedMemoryManager(pointer, width * height); + UnmanagedMemoryManager memoryManager = new(pointer, width * height); - var memorySource = MemoryGroup.Wrap(memoryManager.Memory); + MemoryGroup memorySource = MemoryGroup.Wrap(memoryManager.Memory); return new Image(configuration, memorySource, width, height, metadata); } diff --git a/src/ImageSharp/ImageExtensions.cs b/src/ImageSharp/ImageExtensions.cs index 182047aff7..9427c8d616 100644 --- a/src/ImageSharp/ImageExtensions.cs +++ b/src/ImageSharp/ImageExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Text; using System.Threading; @@ -106,12 +107,12 @@ public static void Save(this Image source, Stream stream, IImageFormat format) if (encoder is null) { - var sb = new StringBuilder(); + StringBuilder sb = new(); sb.AppendLine("No encoder was found for the provided mime type. Registered encoders include:"); foreach (KeyValuePair val in source.GetConfiguration().ImageFormatsManager.ImageEncoders) { - sb.AppendFormat(" - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); + sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); } throw new NotSupportedException(sb.ToString()); @@ -150,12 +151,12 @@ public static Task SaveAsync( if (encoder is null) { - var sb = new StringBuilder(); + StringBuilder sb = new(); sb.AppendLine("No encoder was found for the provided mime type. Registered encoders include:"); foreach (KeyValuePair val in source.GetConfiguration().ImageFormatsManager.ImageEncoders) { - sb.AppendFormat(" - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); + sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine); } throw new NotSupportedException(sb.ToString()); @@ -182,7 +183,7 @@ public static string ToBase64String(this Image source, IImageFormat format) { Guard.NotNull(format, nameof(format)); - using var stream = new MemoryStream(); + using MemoryStream stream = new(); source.Save(stream, format); // Always available. diff --git a/src/ImageSharp/ImageFrame.LoadPixelData.cs b/src/ImageSharp/ImageFrame.LoadPixelData.cs index f6432757ea..b1f2b14bdc 100644 --- a/src/ImageSharp/ImageFrame.LoadPixelData.cs +++ b/src/ImageSharp/ImageFrame.LoadPixelData.cs @@ -44,7 +44,7 @@ internal static ImageFrame LoadPixelData(Configuration configura var image = new ImageFrame(configuration, width, height); - data = data.Slice(0, count); + data = data[..count]; data.CopyTo(image.PixelBuffer.FastMemoryGroup); return image; diff --git a/src/ImageSharp/ImageSharp.csproj.DotSettings b/src/ImageSharp/ImageSharp.csproj.DotSettings deleted file mode 100644 index 6896e069c2..0000000000 --- a/src/ImageSharp/ImageSharp.csproj.DotSettings +++ /dev/null @@ -1,15 +0,0 @@ - - True - True - True - True - True - True - True - True - True - True - True - True - True - True \ No newline at end of file diff --git a/src/ImageSharp/ImageSharp.netstandard1.1.v3.ncrunchproject b/src/ImageSharp/ImageSharp.netstandard1.1.v3.ncrunchproject deleted file mode 100644 index 319cd523ce..0000000000 --- a/src/ImageSharp/ImageSharp.netstandard1.1.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file diff --git a/src/ImageSharp/IndexedImageFrame{TPixel}.cs b/src/ImageSharp/IndexedImageFrame{TPixel}.cs index 87bdbff698..2bd5099028 100644 --- a/src/ImageSharp/IndexedImageFrame{TPixel}.cs +++ b/src/ImageSharp/IndexedImageFrame{TPixel}.cs @@ -46,7 +46,7 @@ internal IndexedImageFrame(Configuration configuration, int width, int height, R // Copy the palette over. We want the lifetime of this frame to be independant of any palette source. this.paletteOwner = configuration.MemoryAllocator.Allocate(palette.Length); palette.Span.CopyTo(this.paletteOwner.GetSpan()); - this.Palette = this.paletteOwner.Memory.Slice(0, palette.Length); + this.Palette = this.paletteOwner.Memory[..palette.Length]; } /// diff --git a/src/ImageSharp/Memory/Allocators/Internals/Gen2GcCallback.cs b/src/ImageSharp/Memory/Allocators/Internals/Gen2GcCallback.cs index dd30efa066..54d8e17f01 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/Gen2GcCallback.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/Gen2GcCallback.cs @@ -1,9 +1,8 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. // Port of BCL internal utility: // https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/System.Private.CoreLib/src/System/Gen2GcCallback.cs -#if NETCOREAPP3_1_OR_GREATER using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; @@ -20,10 +19,7 @@ internal sealed class Gen2GcCallback : CriticalFinalizerObject private readonly Func callback1; private GCHandle weakTargetObj; - private Gen2GcCallback(Func callback) - { - this.callback0 = callback; - } + private Gen2GcCallback(Func callback) => this.callback0 = callback; private Gen2GcCallback(Func callback, object targetObj) { @@ -92,24 +88,24 @@ private Gen2GcCallback(Func callback, object targetObj) /// Schedule 'callback' to be called in the next GC. If the callback returns true it is /// rescheduled for the next Gen 2 GC. Otherwise the callbacks stop. /// - public static void Register(Func callback) - { + public static void Register(Func callback) => + // Create a unreachable object that remembers the callback function and target object. _ = new Gen2GcCallback(callback); - } /// + /// /// Schedule 'callback' to be called in the next GC. If the callback returns true it is /// rescheduled for the next Gen 2 GC. Otherwise the callbacks stop. - /// + /// + /// /// NOTE: This callback will be kept alive until either the callback function returns false, /// or the target object dies. + /// /// - public static void Register(Func callback, object targetObj) - { + public static void Register(Func callback, object targetObj) => + // Create a unreachable object that remembers the callback function and target object. _ = new Gen2GcCallback(callback, targetObj); - } } } -#endif diff --git a/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.cs b/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.cs index e960aef0db..756f5a9955 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -40,9 +40,7 @@ public UniformUnmanagedMemoryPool(int bufferLength, int capacity, TrimSettings t if (trimSettings.Enabled) { UpdateTimer(trimSettings, this); -#if NETCOREAPP3_1_OR_GREATER Gen2GcCallback.Register(s => ((UniformUnmanagedMemoryPool)s).Trim(), this); -#endif this.lastTrimTimestamp = Stopwatch.ElapsedMilliseconds; } } @@ -326,14 +324,8 @@ private bool TrimLowPressure(UnmanagedMemoryHandle[] buffersLocal) private bool IsHighMemoryPressure() { -#if NETCOREAPP3_1_OR_GREATER GCMemoryInfo memoryInfo = GC.GetGCMemoryInfo(); return memoryInfo.MemoryLoadBytes >= memoryInfo.HighMemoryLoadThresholdBytes * this.trimSettings.HighPressureThresholdRate; -#else - // We don't have high pressure detection triggering full trimming on other platforms, - // to counterpart this, the maximum pool size is small. - return false; -#endif } public class TrimSettings diff --git a/src/ImageSharp/Memory/Allocators/Internals/UnmanagedMemoryHandle.cs b/src/ImageSharp/Memory/Allocators/Internals/UnmanagedMemoryHandle.cs index 74a98ed1af..7933f3e13f 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/UnmanagedMemoryHandle.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/UnmanagedMemoryHandle.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -24,7 +24,7 @@ internal struct UnmanagedMemoryHandle : IEquatable // A Monitor to wait/signal when we are low on memory. private static object lowMemoryMonitor; - public static readonly UnmanagedMemoryHandle NullHandle = default; + public static readonly UnmanagedMemoryHandle NullHandle; private IntPtr handle; private int lengthInBytes; @@ -80,24 +80,17 @@ private static IntPtr AllocateHandle(int lengthInBytes) { handle = Marshal.AllocHGlobal(lengthInBytes); } - catch (OutOfMemoryException) + catch (OutOfMemoryException) when (counter < MaxAllocationAttempts) { // We are low on memory, but expect some memory to be freed soon. // Block the thread & retry to avoid OOM. - if (counter < MaxAllocationAttempts) - { - counter++; - Interlocked.Increment(ref totalOomRetries); - - Interlocked.CompareExchange(ref lowMemoryMonitor, new object(), null); - Monitor.Enter(lowMemoryMonitor); - Monitor.Wait(lowMemoryMonitor, millisecondsTimeout: 1); - Monitor.Exit(lowMemoryMonitor); - } - else - { - throw; - } + counter++; + Interlocked.Increment(ref totalOomRetries); + + Interlocked.CompareExchange(ref lowMemoryMonitor, new object(), null); + Monitor.Enter(lowMemoryMonitor); + Monitor.Wait(lowMemoryMonitor, millisecondsTimeout: 1); + Monitor.Exit(lowMemoryMonitor); } } diff --git a/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs b/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs index e79eb4967e..af04718e83 100644 --- a/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs +++ b/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs @@ -4,7 +4,6 @@ using System; using System.Buffers; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory.Internals; namespace SixLabors.ImageSharp.Memory @@ -73,11 +72,9 @@ internal UniformUnmanagedMemoryPoolMemoryAllocator( this.nonPoolAllocator = new UnmanagedMemoryAllocator(unmanagedBufferSizeInBytes); } -#if NETCOREAPP3_1_OR_GREATER // This delegate allows overriding the method returning the available system memory, // so we can test our workaround for https://github.com/dotnet/runtime/issues/65466 internal static Func GetTotalAvailableMemoryBytes { get; set; } = () => GC.GetGCMemoryInfo().TotalAvailableMemoryBytes; -#endif /// protected internal override int GetBufferCapacityInBytes() => this.poolBufferSizeInBytes; @@ -151,11 +148,9 @@ internal override MemoryGroup AllocateGroup( private static long GetDefaultMaxPoolSizeBytes() { -#if NETCOREAPP3_1_OR_GREATER - // On 64 bit .NET Core 3.1+, set the pool size to a portion of the total available memory. - // There is a bug in GC.GetGCMemoryInfo() on .NET 5 + 32 bit, making TotalAvailableMemoryBytes unreliable: + // On 64 bit set the pool size to a portion of the total available memory. // https://github.com/dotnet/runtime/issues/55126#issuecomment-876779327 - if (Environment.Is64BitProcess || !RuntimeInformation.FrameworkDescription.StartsWith(".NET 5.0")) + if (Environment.Is64BitProcess) { long total = GetTotalAvailableMemoryBytes(); @@ -165,7 +160,6 @@ private static long GetDefaultMaxPoolSizeBytes() return total / 8; } } -#endif // Stick to a conservative value of 128 Megabytes on other platforms and 32 bit .NET 5.0: return 128 * OneMegabyte; diff --git a/src/ImageSharp/Memory/Buffer2D{T}.cs b/src/ImageSharp/Memory/Buffer2D{T}.cs index f35ec9b617..c73b96ae60 100644 --- a/src/ImageSharp/Memory/Buffer2D{T}.cs +++ b/src/ImageSharp/Memory/Buffer2D{T}.cs @@ -120,7 +120,7 @@ internal bool DangerousTryGetPaddedRowSpan(int y, int padding, out Span padde return false; } - paddedSpan = slice.Slice(0, stride); + paddedSpan = slice[..stride]; return true; } diff --git a/src/ImageSharp/Memory/ByteMemoryManager{T}.cs b/src/ImageSharp/Memory/ByteMemoryManager{T}.cs index fd9a06db06..f6d79642a3 100644 --- a/src/ImageSharp/Memory/ByteMemoryManager{T}.cs +++ b/src/ImageSharp/Memory/ByteMemoryManager{T}.cs @@ -47,7 +47,7 @@ public override MemoryHandle Pin(int elementIndex = 0) // We need to adjust the offset into the wrapped byte segment, // as the input index refers to the target-cast memory of T. // We just have to shift this index by the byte size of T. - return this.memory.Slice(elementIndex * Unsafe.SizeOf()).Pin(); + return this.memory[(elementIndex * Unsafe.SizeOf())..].Pin(); } /// diff --git a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs index fc8e150d91..51774c8816 100644 --- a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs +++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs @@ -82,7 +82,7 @@ internal static void CopyTo(this IMemoryGroup source, Span target) cur.GetSpan(fwd).CopyTo(target); cur.Forward(fwd); - target = target.Slice(fwd); + target = target[fwd..]; position += fwd; } } @@ -102,9 +102,9 @@ internal static void CopyTo(this ReadOnlySpan source, IMemoryGroup targ while (!source.IsEmpty) { int fwd = Math.Min(cur.LookAhead(), source.Length); - source.Slice(0, fwd).CopyTo(cur.GetSpan(fwd)); + source[..fwd].CopyTo(cur.GetSpan(fwd)); cur.Forward(fwd); - source = source.Slice(fwd); + source = source[fwd..]; } } diff --git a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs index 18d80dd51f..f044e6cb9e 100644 --- a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs +++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Threading; using SixLabors.ImageSharp.Memory.Internals; namespace SixLabors.ImageSharp.Memory @@ -129,7 +128,7 @@ public static MemoryGroup Allocate( if (bufferCount > 0) { - buffers[buffers.Length - 1] = allocator.Allocate(sizeOfLastBuffer, options); + buffers[^1] = allocator.Allocate(sizeOfLastBuffer, options); } return new Owned(buffers, bufferLength, totalLengthInElements, true); @@ -214,12 +213,12 @@ public static MemoryGroup Wrap(params Memory[] source) } } - if (source.Length > 0 && source[source.Length - 1].Length > bufferLength) + if (source.Length > 0 && source[^1].Length > bufferLength) { throw new InvalidMemoryOperationException("Wrap: the last buffer is too large!"); } - long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[source.Length - 1].Length : 0; + long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[^1].Length : 0; return new Consumed(source, bufferLength, totalLength); } @@ -235,12 +234,12 @@ public static MemoryGroup Wrap(params IMemoryOwner[] source) } } - if (source.Length > 0 && source[source.Length - 1].Memory.Length > bufferLength) + if (source.Length > 0 && source[^1].Memory.Length > bufferLength) { throw new InvalidMemoryOperationException("Wrap: the last buffer is too large!"); } - long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[source.Length - 1].Memory.Length : 0; + long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[^1].Memory.Length : 0; return new Owned(source, bufferLength, totalLength, false); } @@ -252,15 +251,10 @@ public unsafe Span GetRowSpanCoreUnsafe(int y, int width) { case SpanCacheMode.SingleArray: { -#if SUPPORTS_CREATESPAN ref byte b0 = ref MemoryMarshal.GetReference(this.memoryGroupSpanCache.SingleArray); ref T e0 = ref Unsafe.As(ref b0); e0 = ref Unsafe.Add(ref e0, y * width); return MemoryMarshal.CreateSpan(ref e0, width); -#else - return MemoryMarshal.Cast(this.memoryGroupSpanCache.SingleArray).Slice(y * width, width); -#endif - } case SpanCacheMode.SinglePointer: @@ -291,7 +285,7 @@ public Span GetRemainingSliceOfBuffer(long start) { long bufferIdx = Math.DivRem(start, this.BufferLength, out long bufferStart); Memory memory = this[(int)bufferIdx]; - return memory.Span.Slice((int)bufferStart); + return memory.Span[(int)bufferStart..]; } public static bool CanSwapContent(MemoryGroup target, MemoryGroup source) => diff --git a/src/ImageSharp/Memory/MemoryOwnerExtensions.cs b/src/ImageSharp/Memory/MemoryOwnerExtensions.cs index 0c415806fb..8c3d49d1eb 100644 --- a/src/ImageSharp/Memory/MemoryOwnerExtensions.cs +++ b/src/ImageSharp/Memory/MemoryOwnerExtensions.cs @@ -44,7 +44,7 @@ public static int Length(this IMemoryOwner buffer) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span Slice(this IMemoryOwner buffer, int start) { - return buffer.GetSpan().Slice(start); + return buffer.GetSpan()[start..]; } /// diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs index 03f1566d24..f5f884f289 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs @@ -57,7 +57,7 @@ public static bool TryParse(ReadOnlySpan buffer, out EncodedString encoded { if (TryDetect(buffer, out CharacterCode code)) { - string text = GetEncoding(code).GetString(buffer.Slice(CharacterCodeBytesLength)); + string text = GetEncoding(code).GetString(buffer[CharacterCodeBytesLength..]); encodedString = new EncodedString(code, text); return true; } @@ -74,30 +74,13 @@ public static int Write(EncodedString encodedString, Span destination) GetCodeBytes(encodedString.Code).CopyTo(destination); string text = encodedString.Text; - int count = Write(GetEncoding(encodedString.Code), text, destination.Slice(CharacterCodeBytesLength)); + int count = Write(GetEncoding(encodedString.Code), text, destination[CharacterCodeBytesLength..]); return CharacterCodeBytesLength + count; } public static unsafe int Write(Encoding encoding, string value, Span destination) -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER || NET => encoding.GetBytes(value.AsSpan(), destination); -#else - { - if (value.Length == 0) - { - return 0; - } - - fixed (char* c = value) - { - fixed (byte* b = destination) - { - return encoding.GetBytes(c, value.Length, b, destination.Length); - } - } - } -#endif private static bool TryDetect(ReadOnlySpan buffer, out CharacterCode code) { diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs index dc6fad9094..722f59316f 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs @@ -7,7 +7,9 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; +using System.Globalization; using System.IO; +using System.Linq; using System.Runtime.CompilerServices; using System.Text; using SixLabors.ImageSharp.Memory; @@ -34,7 +36,7 @@ public ExifReader(byte[] exifData, MemoryAllocator allocator) /// public List ReadValues() { - var values = new List(); + List values = new(); // II == 0x4949 this.IsBigEndian = this.ReadUInt16() != 0x4949; @@ -64,11 +66,12 @@ private void GetThumbnail(uint offset) return; } - var values = new List(); + List values = new(); this.ReadValues(values, offset); - foreach (ExifValue value in values) + for (int i = 0; i < values.Count; i++) { + ExifValue value = (ExifValue)values[i]; if (value == ExifTag.JPEGInterchangeFormat) { this.ThumbnailOffset = ((ExifLong)value).Value; @@ -150,7 +153,7 @@ protected void ReadBigValues(List values) foreach ((ulong Offset, ExifDataType DataType, ulong NumberOfComponents, ExifValue Exif) tag in this.BigValues) { ulong size = tag.NumberOfComponents * ExifDataTypes.GetSize(tag.DataType); - this.ReadBigValue(values, tag, buf.Slice(0, (int)size)); + this.ReadBigValue(values, tag, buf[..(int)size]); } } else @@ -160,7 +163,7 @@ protected void ReadBigValues(List values) foreach ((ulong Offset, ExifDataType DataType, ulong NumberOfComponents, ExifValue Exif) tag in this.BigValues) { ulong size = tag.NumberOfComponents * ExifDataTypes.GetSize(tag.DataType); - this.ReadBigValue(values, tag, buf.Slice(0, (int)size)); + this.ReadBigValue(values, tag, buf[..(int)size]); } } @@ -229,7 +232,7 @@ private static TDataType[] ToArray(ExifDataType dataType, ReadOnlySpa int dataTypeSize = (int)ExifDataTypes.GetSize(dataType); int length = data.Length / dataTypeSize; - var result = new TDataType[length]; + TDataType[] result = new TDataType[length]; for (int i = 0; i < length; i++) { @@ -247,13 +250,13 @@ private static string ConvertToString(Encoding encoding, ReadOnlySpan buff if (nullCharIndex > -1) { - buffer = buffer.Slice(0, nullCharIndex); + buffer = buffer[..nullCharIndex]; } return encoding.GetString(buffer); } - private byte ConvertToByte(ReadOnlySpan buffer) => buffer[0]; + private static byte ConvertToByte(ReadOnlySpan buffer) => buffer[0]; private object ConvertValue(ExifDataType dataType, ReadOnlySpan buffer, bool isArray) { @@ -272,7 +275,7 @@ private object ConvertValue(ExifDataType dataType, ReadOnlySpan buffer, bo case ExifDataType.Undefined: if (!isArray) { - return this.ConvertToByte(buffer); + return ConvertToByte(buffer); } return buffer.ToArray(); @@ -370,7 +373,7 @@ private void ReadValue(List values, Span offsetBuffer) return; } - var tag = (ExifTagValue)this.ReadUInt16(); + ExifTagValue tag = (ExifTagValue)this.ReadUInt16(); ExifDataType dataType = EnumUtils.Parse(this.ReadUInt16(), ExifDataType.Unknown); uint numberOfComponents = this.ReadUInt32(); @@ -414,7 +417,7 @@ private void ReadValue(List values, Span offsetBuffer) } else { - object value = this.ConvertValue(dataType, offsetBuffer.Slice(0, (int)size), numberOfComponents > 1 || exifValue.IsArray); + object value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray); this.Add(values, exifValue, value); } } @@ -426,7 +429,7 @@ private void ReadValue64(List values, Span offsetBuffer) return; } - var tag = (ExifTagValue)this.ReadUInt16(); + ExifTagValue tag = (ExifTagValue)this.ReadUInt16(); ExifDataType dataType = EnumUtils.Parse(this.ReadUInt16(), ExifDataType.Unknown); ulong numberOfComponents = this.ReadUInt64(); @@ -443,31 +446,14 @@ private void ReadValue64(List values, Span offsetBuffer) numberOfComponents = 8 / ExifDataTypes.GetSize(dataType); } - // The StripOffsets, StripByteCounts, TileOffsets, and TileByteCounts tags are allowed to have the datatype TIFF_LONG8 in BigTIFF. - // Old datatypes TIFF_LONG, and TIFF_SHORT where allowed in the TIFF 6.0 specification, are still valid in BigTIFF, too. - // Likewise, tags that point to other IFDs, like e.g. the SubIFDs tag, are now allowed to have the datatype TIFF_IFD8 in BigTIFF. - // Again, the old datatypes TIFF_IFD, and the hardly recommendable TIFF_LONG, are still valid, too. - // https://www.awaresystems.be/imaging/tiff/bigtiff.html - ExifValue exifValue; - switch (tag) - { - case ExifTagValue.StripOffsets: - exifValue = new ExifLong8Array(ExifTagValue.StripOffsets); - break; - case ExifTagValue.StripByteCounts: - exifValue = new ExifLong8Array(ExifTagValue.StripByteCounts); - break; - case ExifTagValue.TileOffsets: - exifValue = new ExifLong8Array(ExifTagValue.TileOffsets); - break; - case ExifTagValue.TileByteCounts: - exifValue = new ExifLong8Array(ExifTagValue.TileByteCounts); - break; - default: - exifValue = ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents); - break; - } - + ExifValue exifValue = tag switch + { + ExifTagValue.StripOffsets => new ExifLong8Array(ExifTagValue.StripOffsets), + ExifTagValue.StripByteCounts => new ExifLong8Array(ExifTagValue.StripByteCounts), + ExifTagValue.TileOffsets => new ExifLong8Array(ExifTagValue.TileOffsets), + ExifTagValue.TileByteCounts => new ExifLong8Array(ExifTagValue.TileByteCounts), + _ => ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents), + }; if (exifValue is null) { this.AddInvalidTag(new UnkownExifTag(tag)); @@ -488,7 +474,7 @@ private void ReadValue64(List values, Span offsetBuffer) } else { - object value = this.ConvertValue(dataType, offsetBuffer.Slice(0, (int)size), numberOfComponents > 1 || exifValue.IsArray); + object value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray); this.Add(values, exifValue, value); } } @@ -528,7 +514,7 @@ private void AddInvalidTag(ExifTag tag) => (this.invalidTags ??= new List()).Add(tag); private void AddSubIfd(object val) - => (this.subIfds ??= new List()).Add(Convert.ToUInt64(val)); + => (this.subIfds ??= new List()).Add(Convert.ToUInt64(val, CultureInfo.InvariantCulture)); private void Seek(ulong pos) => this.data.Seek((long)pos, SeekOrigin.Begin); @@ -644,7 +630,7 @@ private Rational ToRational(ReadOnlySpan buffer) return default; } - uint numerator = this.ConvertToUInt32(buffer.Slice(0, 4)); + uint numerator = this.ConvertToUInt32(buffer[..4]); uint denominator = this.ConvertToUInt32(buffer.Slice(4, 4)); return new Rational(numerator, denominator, false); @@ -671,7 +657,7 @@ private SignedRational ToSignedRational(ReadOnlySpan buffer) return default; } - int numerator = this.ConvertToInt32(buffer.Slice(0, 4)); + int numerator = this.ConvertToInt32(buffer[..4]); int denominator = this.ConvertToInt32(buffer.Slice(4, 4)); return new SignedRational(numerator, denominator, false); diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs index 6e98128d5b..1212e16ccc 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs @@ -49,9 +49,9 @@ public byte[] GetData() IExifValue exifOffset = GetOffsetValue(this.ifdValues, this.exifValues, ExifTag.SubIFDOffset); IExifValue gpsOffset = GetOffsetValue(this.ifdValues, this.gpsValues, ExifTag.GPSIFDOffset); - uint ifdLength = this.GetLength(this.ifdValues); - uint exifLength = this.GetLength(this.exifValues); - uint gpsLength = this.GetLength(this.gpsValues); + uint ifdLength = GetLength(this.ifdValues); + uint exifLength = GetLength(this.exifValues); + uint gpsLength = GetLength(this.gpsValues); uint length = ifdLength + exifLength + gpsLength; @@ -100,14 +100,14 @@ public byte[] GetData() private static unsafe int WriteSingle(float value, Span destination, int offset) { - BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(offset, 4), *((int*)&value)); + BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(offset, 4), *(int*)&value); return offset + 4; } private static unsafe int WriteDouble(double value, Span destination, int offset) { - BinaryPrimitives.WriteInt64LittleEndian(destination.Slice(offset, 8), *((long*)&value)); + BinaryPrimitives.WriteInt64LittleEndian(destination.Slice(offset, 8), *(long*)&value); return offset + 8; } @@ -195,7 +195,7 @@ private static IExifValue GetOffsetValue(List ifdValues, List GetPartValues(ExifParts part) { - var result = new List(); + List result = new(); if (!EnumUtils.HasFlag(this.allowedParts, part)) { @@ -240,7 +240,7 @@ private static bool HasValue(IExifValue exifValue) return true; } - private uint GetLength(IList values) + private static uint GetLength(IList values) { if (values.Count == 0) { @@ -360,20 +360,18 @@ private int WriteHeaders(List values, Span destination, int of } // next IFD offset - newOffset = WriteUInt32(0, destination, newOffset); - - return newOffset; + return WriteUInt32(0, destination, newOffset); } private static void WriteRational(Span destination, in Rational value) { - BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(0, 4), value.Numerator); + BinaryPrimitives.WriteUInt32LittleEndian(destination[..4], value.Numerator); BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(4, 4), value.Denominator); } private static void WriteSignedRational(Span destination, in SignedRational value) { - BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(0, 4), value.Numerator); + BinaryPrimitives.WriteInt32LittleEndian(destination[..4], value.Numerator); BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(4, 4), value.Denominator); } @@ -413,7 +411,7 @@ private static int WriteValue(ExifDataType dataType, object value, Span de WriteRational(destination.Slice(offset, 8), (Rational)value); return offset + 8; case ExifDataType.SignedByte: - destination[offset] = unchecked((byte)((sbyte)value)); + destination[offset] = unchecked((byte)(sbyte)value); return offset + 1; case ExifDataType.SignedLong: return WriteInt32((int)value, destination, offset); @@ -435,11 +433,11 @@ internal static int WriteValue(IExifValue exifValue, Span destination, int if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag)) { - return offset + ExifUcs2StringHelpers.Write((string)value, destination.Slice(offset)); + return offset + ExifUcs2StringHelpers.Write((string)value, destination[offset..]); } else if (value is EncodedString encodedString) { - return offset + ExifEncodedStringHelpers.Write(encodedString, destination.Slice(offset)); + return offset + ExifEncodedStringHelpers.Write(encodedString, destination[offset..]); } if (exifValue.IsArray) diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs index 2209586abb..2af413cb95 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs @@ -79,6 +79,28 @@ public enum CharacterCode /// The to convert. public static explicit operator string(EncodedString encodedString) => encodedString.Text; + /// + /// Checks whether two structures are equal. + /// + /// The left hand operand. + /// The right hand operand. + /// + /// True if the parameter is equal to the parameter; + /// otherwise, false. + /// + public static bool operator ==(EncodedString left, EncodedString right) => left.Equals(right); + + /// + /// Checks whether two structures are not equal. + /// + /// The left hand operand. + /// The right hand operand. + /// + /// True if the parameter is not equal to the parameter; + /// otherwise, false. + /// + public static bool operator !=(EncodedString left, EncodedString right) => !(left == right); + /// public override bool Equals(object obj) => obj is EncodedString other && this.Equals(other); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs index a4603a02a0..6fa985eb2c 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -15,9 +15,7 @@ internal abstract class IccCurveSegment : IEquatable /// /// The signature of this segment protected IccCurveSegment(IccCurveSegmentSignature signature) - { - this.Signature = signature; - } + => this.Signature = signature; /// /// Gets the signature of this segment @@ -39,5 +37,11 @@ public virtual bool Equals(IccCurveSegment other) return this.Signature == other.Signature; } + + /// + public override bool Equals(object obj) => this.Equals(obj as IccCurveSegment); + + /// + public override int GetHashCode() => this.Signature.GetHashCode(); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs index a22c7dcde3..5ad61d4a04 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -85,9 +85,20 @@ public override bool Equals(IccCurveSegment other) } /// - public bool Equals(IccFormulaCurveElement other) - { - return this.Equals((IccCurveSegment)other); - } + public bool Equals(IccFormulaCurveElement other) => this.Equals((IccCurveSegment)other); + + /// + public override bool Equals(object obj) => this.Equals(obj as IccFormulaCurveElement); + + /// + public override int GetHashCode() + => HashCode.Combine( + this.Type, + this.Gamma, + this.A, + this.B, + this.C, + this.D, + this.E); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccOneDimensionalCurve.cs b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccOneDimensionalCurve.cs index 773140ab2f..d84a18f902 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccOneDimensionalCurve.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccOneDimensionalCurve.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -53,5 +53,13 @@ public bool Equals(IccOneDimensionalCurve other) return this.BreakPoints.AsSpan().SequenceEqual(other.BreakPoints) && this.Segments.AsSpan().SequenceEqual(other.Segments); } + + /// + public override bool Equals(object obj) + => this.Equals(obj as IccOneDimensionalCurve); + + /// + public override int GetHashCode() + => HashCode.Combine(this.BreakPoints, this.Segments); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccSampledCurveElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccSampledCurveElement.cs index 30b3dafa30..a305eea31d 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccSampledCurveElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccSampledCurveElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -41,8 +41,14 @@ public override bool Equals(IccCurveSegment other) /// public bool Equals(IccSampledCurveElement other) - { - return this.Equals((IccCurveSegment)other); - } + => this.Equals((IccCurveSegment)other); + + /// + public override bool Equals(object obj) + => this.Equals(obj as IccSampledCurveElement); + + /// + public override int GetHashCode() + => HashCode.Combine(base.GetHashCode(), this.CurveEntries); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs index c9f4bab45c..d63bb74491 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs @@ -108,7 +108,7 @@ public string ReadAsciiString(int length) int pos = value.IndexOf('\0'); if (pos >= 0) { - value = value.Substring(0, pos); + value = value[..pos]; } return value; diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs index f7c7d0a816..176c463353 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs @@ -230,7 +230,7 @@ public IccDataTagDataEntry ReadDataTagDataEntry(uint size) byte b = this.data[this.AddIndex(1)]; // last bit of 4th byte is either 0 = ASCII or 1 = binary - bool ascii = this.GetBit(b, 7); + bool ascii = GetBit(b, 7); int length = (int)size - 12; byte[] cdata = this.ReadBytes(length); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs index bd85cfbf47..35c8678274 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs @@ -25,9 +25,7 @@ internal sealed partial class IccDataReader /// /// The data to read public IccDataReader(byte[] data) - { - this.data = data ?? throw new ArgumentNullException(nameof(data)); - } + => this.data = data ?? throw new ArgumentNullException(nameof(data)); /// /// Gets the length in bytes of the raw data @@ -39,9 +37,7 @@ public IccDataReader(byte[] data) /// /// The new index position public void SetIndex(int index) - { - this.currentIndex = Numerics.Clamp(index, 0, this.data.Length); - } + => this.currentIndex = Numerics.Clamp(index, 0, this.data.Length); /// /// Returns the current without increment and adds the given increment @@ -59,9 +55,7 @@ private int AddIndex(int increment) /// Calculates the 4 byte padding and adds it to the variable /// private void AddPadding() - { - this.currentIndex += this.CalcPadding(); - } + => this.currentIndex += this.CalcPadding(); /// /// Calculates the 4 byte padding @@ -79,9 +73,7 @@ private int CalcPadding() /// The value from where the bit will be extracted /// Position of the bit. Zero based index from left to right. /// The bit value at specified position - private bool GetBit(byte value, int position) - { - return ((value >> (7 - position)) & 1) == 1; - } + private static bool GetBit(byte value, int position) + => ((value >> (7 - position)) & 1) == 1; } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs index 180fdba030..d3113b0140 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs @@ -213,7 +213,7 @@ public int WriteAsciiString(string value, int length, bool ensureNullTerminator) lengthAdjust = 1; } - value = value.Substring(0, Math.Min(length - lengthAdjust, value.Length)); + value = value[..Math.Min(length - lengthAdjust, value.Length)]; byte[] textData = Encoding.ASCII.GetBytes(value); int actualLength = Math.Min(length - lengthAdjust, textData.Length); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs index 411cdacece..8ff48bf134 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs @@ -34,116 +34,46 @@ public int WriteTagDataEntry(IccTagDataEntry entry) { int count = this.WriteTagDataEntryHeader(entry.Signature); - switch (entry.Signature) - { - case IccTypeSignature.Chromaticity: - count += this.WriteChromaticityTagDataEntry((IccChromaticityTagDataEntry)entry); - break; - case IccTypeSignature.ColorantOrder: - count += this.WriteColorantOrderTagDataEntry((IccColorantOrderTagDataEntry)entry); - break; - case IccTypeSignature.ColorantTable: - count += this.WriteColorantTableTagDataEntry((IccColorantTableTagDataEntry)entry); - break; - case IccTypeSignature.Curve: - count += this.WriteCurveTagDataEntry((IccCurveTagDataEntry)entry); - break; - case IccTypeSignature.Data: - count += this.WriteDataTagDataEntry((IccDataTagDataEntry)entry); - break; - case IccTypeSignature.DateTime: - count += this.WriteDateTimeTagDataEntry((IccDateTimeTagDataEntry)entry); - break; - case IccTypeSignature.Lut16: - count += this.WriteLut16TagDataEntry((IccLut16TagDataEntry)entry); - break; - case IccTypeSignature.Lut8: - count += this.WriteLut8TagDataEntry((IccLut8TagDataEntry)entry); - break; - case IccTypeSignature.LutAToB: - count += this.WriteLutAtoBTagDataEntry((IccLutAToBTagDataEntry)entry); - break; - case IccTypeSignature.LutBToA: - count += this.WriteLutBtoATagDataEntry((IccLutBToATagDataEntry)entry); - break; - case IccTypeSignature.Measurement: - count += this.WriteMeasurementTagDataEntry((IccMeasurementTagDataEntry)entry); - break; - case IccTypeSignature.MultiLocalizedUnicode: - count += this.WriteMultiLocalizedUnicodeTagDataEntry((IccMultiLocalizedUnicodeTagDataEntry)entry); - break; - case IccTypeSignature.MultiProcessElements: - count += this.WriteMultiProcessElementsTagDataEntry((IccMultiProcessElementsTagDataEntry)entry); - break; - case IccTypeSignature.NamedColor2: - count += this.WriteNamedColor2TagDataEntry((IccNamedColor2TagDataEntry)entry); - break; - case IccTypeSignature.ParametricCurve: - count += this.WriteParametricCurveTagDataEntry((IccParametricCurveTagDataEntry)entry); - break; - case IccTypeSignature.ProfileSequenceDesc: - count += this.WriteProfileSequenceDescTagDataEntry((IccProfileSequenceDescTagDataEntry)entry); - break; - case IccTypeSignature.ProfileSequenceIdentifier: - count += this.WriteProfileSequenceIdentifierTagDataEntry((IccProfileSequenceIdentifierTagDataEntry)entry); - break; - case IccTypeSignature.ResponseCurveSet16: - count += this.WriteResponseCurveSet16TagDataEntry((IccResponseCurveSet16TagDataEntry)entry); - break; - case IccTypeSignature.S15Fixed16Array: - count += this.WriteFix16ArrayTagDataEntry((IccFix16ArrayTagDataEntry)entry); - break; - case IccTypeSignature.Signature: - count += this.WriteSignatureTagDataEntry((IccSignatureTagDataEntry)entry); - break; - case IccTypeSignature.Text: - count += this.WriteTextTagDataEntry((IccTextTagDataEntry)entry); - break; - case IccTypeSignature.U16Fixed16Array: - count += this.WriteUFix16ArrayTagDataEntry((IccUFix16ArrayTagDataEntry)entry); - break; - case IccTypeSignature.UInt16Array: - count += this.WriteUInt16ArrayTagDataEntry((IccUInt16ArrayTagDataEntry)entry); - break; - case IccTypeSignature.UInt32Array: - count += this.WriteUInt32ArrayTagDataEntry((IccUInt32ArrayTagDataEntry)entry); - break; - case IccTypeSignature.UInt64Array: - count += this.WriteUInt64ArrayTagDataEntry((IccUInt64ArrayTagDataEntry)entry); - break; - case IccTypeSignature.UInt8Array: - count += this.WriteUInt8ArrayTagDataEntry((IccUInt8ArrayTagDataEntry)entry); - break; - case IccTypeSignature.ViewingConditions: - count += this.WriteViewingConditionsTagDataEntry((IccViewingConditionsTagDataEntry)entry); - break; - case IccTypeSignature.Xyz: - count += this.WriteXyzTagDataEntry((IccXyzTagDataEntry)entry); - break; + count += entry.Signature switch + { + IccTypeSignature.Chromaticity => this.WriteChromaticityTagDataEntry((IccChromaticityTagDataEntry)entry), + IccTypeSignature.ColorantOrder => this.WriteColorantOrderTagDataEntry((IccColorantOrderTagDataEntry)entry), + IccTypeSignature.ColorantTable => this.WriteColorantTableTagDataEntry((IccColorantTableTagDataEntry)entry), + IccTypeSignature.Curve => this.WriteCurveTagDataEntry((IccCurveTagDataEntry)entry), + IccTypeSignature.Data => this.WriteDataTagDataEntry((IccDataTagDataEntry)entry), + IccTypeSignature.DateTime => this.WriteDateTimeTagDataEntry((IccDateTimeTagDataEntry)entry), + IccTypeSignature.Lut16 => this.WriteLut16TagDataEntry((IccLut16TagDataEntry)entry), + IccTypeSignature.Lut8 => this.WriteLut8TagDataEntry((IccLut8TagDataEntry)entry), + IccTypeSignature.LutAToB => this.WriteLutAtoBTagDataEntry((IccLutAToBTagDataEntry)entry), + IccTypeSignature.LutBToA => this.WriteLutBtoATagDataEntry((IccLutBToATagDataEntry)entry), + IccTypeSignature.Measurement => this.WriteMeasurementTagDataEntry((IccMeasurementTagDataEntry)entry), + IccTypeSignature.MultiLocalizedUnicode => this.WriteMultiLocalizedUnicodeTagDataEntry((IccMultiLocalizedUnicodeTagDataEntry)entry), + IccTypeSignature.MultiProcessElements => this.WriteMultiProcessElementsTagDataEntry((IccMultiProcessElementsTagDataEntry)entry), + IccTypeSignature.NamedColor2 => this.WriteNamedColor2TagDataEntry((IccNamedColor2TagDataEntry)entry), + IccTypeSignature.ParametricCurve => this.WriteParametricCurveTagDataEntry((IccParametricCurveTagDataEntry)entry), + IccTypeSignature.ProfileSequenceDesc => this.WriteProfileSequenceDescTagDataEntry((IccProfileSequenceDescTagDataEntry)entry), + IccTypeSignature.ProfileSequenceIdentifier => this.WriteProfileSequenceIdentifierTagDataEntry((IccProfileSequenceIdentifierTagDataEntry)entry), + IccTypeSignature.ResponseCurveSet16 => this.WriteResponseCurveSet16TagDataEntry((IccResponseCurveSet16TagDataEntry)entry), + IccTypeSignature.S15Fixed16Array => this.WriteFix16ArrayTagDataEntry((IccFix16ArrayTagDataEntry)entry), + IccTypeSignature.Signature => this.WriteSignatureTagDataEntry((IccSignatureTagDataEntry)entry), + IccTypeSignature.Text => this.WriteTextTagDataEntry((IccTextTagDataEntry)entry), + IccTypeSignature.U16Fixed16Array => this.WriteUFix16ArrayTagDataEntry((IccUFix16ArrayTagDataEntry)entry), + IccTypeSignature.UInt16Array => this.WriteUInt16ArrayTagDataEntry((IccUInt16ArrayTagDataEntry)entry), + IccTypeSignature.UInt32Array => this.WriteUInt32ArrayTagDataEntry((IccUInt32ArrayTagDataEntry)entry), + IccTypeSignature.UInt64Array => this.WriteUInt64ArrayTagDataEntry((IccUInt64ArrayTagDataEntry)entry), + IccTypeSignature.UInt8Array => this.WriteUInt8ArrayTagDataEntry((IccUInt8ArrayTagDataEntry)entry), + IccTypeSignature.ViewingConditions => this.WriteViewingConditionsTagDataEntry((IccViewingConditionsTagDataEntry)entry), + IccTypeSignature.Xyz => this.WriteXyzTagDataEntry((IccXyzTagDataEntry)entry), // V2 Types: - case IccTypeSignature.TextDescription: - count += this.WriteTextDescriptionTagDataEntry((IccTextDescriptionTagDataEntry)entry); - break; - case IccTypeSignature.CrdInfo: - count += this.WriteCrdInfoTagDataEntry((IccCrdInfoTagDataEntry)entry); - break; - case IccTypeSignature.Screening: - count += this.WriteScreeningTagDataEntry((IccScreeningTagDataEntry)entry); - break; - case IccTypeSignature.UcrBg: - count += this.WriteUcrBgTagDataEntry((IccUcrBgTagDataEntry)entry); - break; + IccTypeSignature.TextDescription => this.WriteTextDescriptionTagDataEntry((IccTextDescriptionTagDataEntry)entry), + IccTypeSignature.CrdInfo => this.WriteCrdInfoTagDataEntry((IccCrdInfoTagDataEntry)entry), + IccTypeSignature.Screening => this.WriteScreeningTagDataEntry((IccScreeningTagDataEntry)entry), + IccTypeSignature.UcrBg => this.WriteUcrBgTagDataEntry((IccUcrBgTagDataEntry)entry), // Unsupported or unknown - case IccTypeSignature.DeviceSettings: - case IccTypeSignature.NamedColor: - case IccTypeSignature.Unknown: - default: - count += this.WriteUnknownTagDataEntry(entry as IccUnknownTagDataEntry); - break; - } - + _ => this.WriteUnknownTagDataEntry(entry as IccUnknownTagDataEntry), + }; return count; } @@ -153,10 +83,7 @@ public int WriteTagDataEntry(IccTagDataEntry entry) /// The signature of the entry /// The number of bytes written public int WriteTagDataEntryHeader(IccTypeSignature signature) - { - return this.WriteUInt32((uint)signature) - + this.WriteEmpty(4); - } + => this.WriteUInt32((uint)signature) + this.WriteEmpty(4); /// /// Writes a @@ -190,10 +117,8 @@ public int WriteChromaticityTagDataEntry(IccChromaticityTagDataEntry value) /// The entry to write /// The number of bytes written public int WriteColorantOrderTagDataEntry(IccColorantOrderTagDataEntry value) - { - return this.WriteUInt32((uint)value.ColorantNumber.Length) - + this.WriteArray(value.ColorantNumber); - } + => this.WriteUInt32((uint)value.ColorantNumber.Length) + + this.WriteArray(value.ColorantNumber); /// /// Writes a @@ -255,11 +180,9 @@ public int WriteCurveTagDataEntry(IccCurveTagDataEntry value) /// The entry to write /// The number of bytes written public int WriteDataTagDataEntry(IccDataTagDataEntry value) - { - return this.WriteEmpty(3) - + this.WriteByte((byte)(value.IsAscii ? 0x01 : 0x00)) - + this.WriteArray(value.Data); - } + => this.WriteEmpty(3) + + this.WriteByte((byte)(value.IsAscii ? 0x01 : 0x00)) + + this.WriteArray(value.Data); /// /// Writes a @@ -531,13 +454,11 @@ public int WriteLutBtoATagDataEntry(IccLutBToATagDataEntry value) /// The entry to write /// The number of bytes written public int WriteMeasurementTagDataEntry(IccMeasurementTagDataEntry value) - { - return this.WriteUInt32((uint)value.Observer) - + this.WriteXyzNumber(value.XyzBacking) - + this.WriteUInt32((uint)value.Geometry) - + this.WriteUFix16(value.Flare) - + this.WriteUInt32((uint)value.Illuminant); - } + => this.WriteUInt32((uint)value.Observer) + + this.WriteXyzNumber(value.XyzBacking) + + this.WriteUInt32((uint)value.Geometry) + + this.WriteUFix16(value.Flare) + + this.WriteUInt32((uint)value.Illuminant); /// /// Writes a @@ -560,8 +481,8 @@ public int WriteMultiLocalizedUnicodeTagDataEntry(IccMultiLocalizedUnicodeTagDat // TODO: Investigate cost of Linq GroupBy IGrouping[] texts = value.Texts.GroupBy(t => t.Text).ToArray(); - var offset = new uint[texts.Length]; - var lengths = new int[texts.Length]; + uint[] offset = new uint[texts.Length]; + int[] lengths = new int[texts.Length]; for (int i = 0; i < texts.Length; i++) { @@ -582,11 +503,11 @@ public int WriteMultiLocalizedUnicodeTagDataEntry(IccMultiLocalizedUnicodeTagDat count += this.WriteAsciiString("xx", 2, false); count += this.WriteAsciiString("\0\0", 2, false); } - else if (cultureName.Contains("-")) + else if (cultureName.Contains('-')) { string[] code = cultureName.Split('-'); - count += this.WriteAsciiString(code[0].ToLower(), 2, false); - count += this.WriteAsciiString(code[1].ToUpper(), 2, false); + count += this.WriteAsciiString(code[0].ToLower(localizedString.Culture), 2, false); + count += this.WriteAsciiString(code[1].ToUpper(localizedString.Culture), 2, false); } else { @@ -620,7 +541,7 @@ public int WriteMultiProcessElementsTagDataEntry(IccMultiProcessElementsTagDataE long tpos = this.dataStream.Position; this.dataStream.Position += value.Data.Length * 8; - var posTable = new IccPositionNumber[value.Data.Length]; + IccPositionNumber[] posTable = new IccPositionNumber[value.Data.Length]; for (int i = 0; i < value.Data.Length; i++) { uint offset = (uint)(this.dataStream.Position - start); @@ -704,7 +625,7 @@ public int WriteProfileSequenceIdentifierTagDataEntry(IccProfileSequenceIdentifi // Jump over position table long tablePosition = this.dataStream.Position; this.dataStream.Position += length * 8; - var table = new IccPositionNumber[length]; + IccPositionNumber[] table = new IccPositionNumber[length]; for (int i = 0; i < length; i++) { @@ -746,7 +667,7 @@ public int WriteResponseCurveSet16TagDataEntry(IccResponseCurveSet16TagDataEntry long tablePosition = this.dataStream.Position; this.dataStream.Position += value.Curves.Length * 4; - var offset = new uint[value.Curves.Length]; + uint[] offset = new uint[value.Curves.Length]; for (int i = 0; i < value.Curves.Length; i++) { @@ -844,11 +765,9 @@ public int WriteUFix16ArrayTagDataEntry(IccUFix16ArrayTagDataEntry value) /// The entry to write /// The number of bytes written public int WriteViewingConditionsTagDataEntry(IccViewingConditionsTagDataEntry value) - { - return this.WriteXyzNumber(value.IlluminantXyz) - + this.WriteXyzNumber(value.SurroundXyz) - + this.WriteUInt32((uint)value.Illuminant); - } + => this.WriteXyzNumber(value.IlluminantXyz) + + this.WriteXyzNumber(value.SurroundXyz) + + this.WriteUInt32((uint)value.Illuminant); /// /// Writes a diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccProfileFlag.cs b/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccProfileFlag.cs index 7807ea4dfd..8a0c73882a 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccProfileFlag.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccProfileFlag.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// the rest can be used for vendor specific values /// [Flags] - public enum IccProfileFlag : int + public enum IccProfileFlag { /// /// No flags (equivalent to NotEmbedded and Independent) @@ -24,7 +24,7 @@ public enum IccProfileFlag : int Embedded = 1 << 0, /// - /// Profile is embedded within another file + /// Profile is not embedded within another file /// NotEmbedded = 0, diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccScreeningFlag.cs b/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccScreeningFlag.cs index d76da63245..bcfc4f8c94 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccScreeningFlag.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccScreeningFlag.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// Screening flags. Can be combined with a logical OR. /// [Flags] - internal enum IccScreeningFlag : int + internal enum IccScreeningFlag { /// /// No flags (equivalent to NotDefaultScreens and UnitLinesPerCm) diff --git a/src/ImageSharp/Metadata/Profiles/ICC/ICC.1-2022-05.pdf b/src/ImageSharp/Metadata/Profiles/ICC/ICC.1-2022-05.pdf new file mode 100644 index 0000000000..6c488c874b Binary files /dev/null and b/src/ImageSharp/Metadata/Profiles/ICC/ICC.1-2022-05.pdf differ diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs index 2f1aa1952a..39b726f903 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs @@ -91,7 +91,7 @@ public IccTagDataEntry[] Entries } /// - public IccProfile DeepClone() => new IccProfile(this); + public IccProfile DeepClone() => new(this); /// /// Calculates the MD5 hash value of an ICC profile @@ -108,33 +108,32 @@ public static IccProfileId CalculateHash(byte[] data) const int profileIdPos = 84; // need to copy some values because they need to be zero for the hashing - var temp = new byte[24]; + byte[] temp = new byte[24]; Buffer.BlockCopy(data, profileFlagPos, temp, 0, 4); Buffer.BlockCopy(data, renderingIntentPos, temp, 4, 4); Buffer.BlockCopy(data, profileIdPos, temp, 8, 16); - using (var md5 = MD5.Create()) + try { - try - { - // Zero out some values - Array.Clear(data, profileFlagPos, 4); - Array.Clear(data, renderingIntentPos, 4); - Array.Clear(data, profileIdPos, 16); - - // Calculate hash - byte[] hash = md5.ComputeHash(data); - - // Read values from hash - var reader = new IccDataReader(hash); - return reader.ReadProfileId(); - } - finally - { - Buffer.BlockCopy(temp, 0, data, profileFlagPos, 4); - Buffer.BlockCopy(temp, 4, data, renderingIntentPos, 4); - Buffer.BlockCopy(temp, 8, data, profileIdPos, 16); - } + // Zero out some values + Array.Clear(data, profileFlagPos, 4); + Array.Clear(data, renderingIntentPos, 4); + Array.Clear(data, profileIdPos, 16); + + // Calculate hash +#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms + byte[] hash = MD5.HashData(data); +#pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms + + // Read values from hash + IccDataReader reader = new(hash); + return reader.ReadProfileId(); + } + finally + { + Buffer.BlockCopy(temp, 0, data, profileFlagPos, 4); + Buffer.BlockCopy(temp, 4, data, renderingIntentPos, 4); + Buffer.BlockCopy(temp, 8, data, profileIdPos, 16); } } @@ -171,15 +170,13 @@ public byte[] ToByteArray() { if (this.data != null) { - var copy = new byte[this.data.Length]; + byte[] copy = new byte[this.data.Length]; Buffer.BlockCopy(this.data, 0, copy, 0, copy.Length); return copy; } - else - { - var writer = new IccWriter(); - return writer.Write(this); - } + + IccWriter writer = new(); + return IccWriter.Write(this); } private void InitializeHeader() @@ -195,8 +192,8 @@ private void InitializeHeader() return; } - var reader = new IccReader(); - this.header = reader.ReadHeader(this.data); + IccReader reader = new(); + this.header = IccReader.ReadHeader(this.data); } private void InitializeEntries() @@ -212,8 +209,8 @@ private void InitializeEntries() return; } - var reader = new IccReader(); - this.entries = reader.ReadTagData(this.data); + IccReader reader = new(); + this.entries = IccReader.ReadTagData(this.data); } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs index 96a5e77a03..5e6e69fff6 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -16,14 +16,14 @@ internal sealed class IccReader /// /// The raw ICC data /// The read ICC profile - public IccProfile Read(byte[] data) + public static IccProfile Read(byte[] data) { Guard.NotNull(data, nameof(data)); Guard.IsTrue(data.Length >= 128, nameof(data), "Data length must be at least 128 to be a valid ICC profile"); - var reader = new IccDataReader(data); - IccProfileHeader header = this.ReadHeader(reader); - IccTagDataEntry[] tagData = this.ReadTagData(reader); + IccDataReader reader = new(data); + IccProfileHeader header = ReadHeader(reader); + IccTagDataEntry[] tagData = ReadTagData(reader); return new IccProfile(header, tagData); } @@ -33,13 +33,13 @@ public IccProfile Read(byte[] data) /// /// The raw ICC data /// The read ICC profile header - public IccProfileHeader ReadHeader(byte[] data) + public static IccProfileHeader ReadHeader(byte[] data) { Guard.NotNull(data, nameof(data)); Guard.IsTrue(data.Length >= 128, nameof(data), "Data length must be at least 128 to be a valid profile header"); - var reader = new IccDataReader(data); - return this.ReadHeader(reader); + IccDataReader reader = new(data); + return ReadHeader(reader); } /// @@ -47,16 +47,16 @@ public IccProfileHeader ReadHeader(byte[] data) /// /// The raw ICC data /// The read ICC profile tag data - public IccTagDataEntry[] ReadTagData(byte[] data) + public static IccTagDataEntry[] ReadTagData(byte[] data) { Guard.NotNull(data, nameof(data)); Guard.IsTrue(data.Length >= 128, nameof(data), "Data length must be at least 128 to be a valid ICC profile"); - var reader = new IccDataReader(data); - return this.ReadTagData(reader); + IccDataReader reader = new(data); + return ReadTagData(reader); } - private IccProfileHeader ReadHeader(IccDataReader reader) + private static IccProfileHeader ReadHeader(IccDataReader reader) { reader.SetIndex(0); @@ -82,11 +82,11 @@ private IccProfileHeader ReadHeader(IccDataReader reader) }; } - private IccTagDataEntry[] ReadTagData(IccDataReader reader) + private static IccTagDataEntry[] ReadTagData(IccDataReader reader) { - IccTagTableEntry[] tagTable = this.ReadTagTable(reader); - var entries = new List(tagTable.Length); - var store = new Dictionary(); + IccTagTableEntry[] tagTable = ReadTagTable(reader); + List entries = new(tagTable.Length); + Dictionary store = new(); foreach (IccTagTableEntry tag in tagTable) { @@ -117,7 +117,7 @@ private IccTagDataEntry[] ReadTagData(IccDataReader reader) return entries.ToArray(); } - private IccTagTableEntry[] ReadTagTable(IccDataReader reader) + private static IccTagTableEntry[] ReadTagTable(IccDataReader reader) { reader.SetIndex(128); // An ICC header is 128 bytes long @@ -130,7 +130,7 @@ private IccTagTableEntry[] ReadTagTable(IccDataReader reader) return Array.Empty(); } - var table = new List((int)tagCount); + List table = new((int)tagCount); for (int i = 0; i < tagCount; i++) { uint tagSignature = reader.ReadUInt32(); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs index 2adfbbc7e5..4bf8b5eb93 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Collections.Generic; @@ -16,20 +16,18 @@ internal sealed class IccWriter /// /// The ICC profile to write /// The ICC profile as a byte array - public byte[] Write(IccProfile profile) + public static byte[] Write(IccProfile profile) { Guard.NotNull(profile, nameof(profile)); - using (var writer = new IccDataWriter()) - { - IccTagTableEntry[] tagTable = this.WriteTagData(writer, profile.Entries); - this.WriteTagTable(writer, tagTable); - this.WriteHeader(writer, profile.Header); - return writer.GetData(); - } + using IccDataWriter writer = new(); + IccTagTableEntry[] tagTable = WriteTagData(writer, profile.Entries); + WriteTagTable(writer, tagTable); + WriteHeader(writer, profile.Header); + return writer.GetData(); } - private void WriteHeader(IccDataWriter writer, IccProfileHeader header) + private static void WriteHeader(IccDataWriter writer, IccProfileHeader header) { writer.SetIndex(0); @@ -54,7 +52,7 @@ private void WriteHeader(IccDataWriter writer, IccProfileHeader header) writer.WriteProfileId(id); } - private void WriteTagTable(IccDataWriter writer, IccTagTableEntry[] table) + private static void WriteTagTable(IccDataWriter writer, IccTagTableEntry[] table) { // 128 = size of ICC header writer.SetIndex(128); @@ -68,7 +66,7 @@ private void WriteTagTable(IccDataWriter writer, IccTagTableEntry[] table) } } - private IccTagTableEntry[] WriteTagData(IccDataWriter writer, IccTagDataEntry[] entries) + private static IccTagTableEntry[] WriteTagData(IccDataWriter writer, IccTagDataEntry[] entries) { // TODO: Investigate cost of Linq GroupBy IEnumerable> grouped = entries.GroupBy(t => t); @@ -76,7 +74,7 @@ private IccTagTableEntry[] WriteTagData(IccDataWriter writer, IccTagDataEntry[] // (Header size) + (entry count) + (nr of entries) * (size of table entry) writer.SetIndex(128 + 4 + (entries.Length * 12)); - var table = new List(); + List table = new(); foreach (IGrouping group in grouped) { writer.WriteTagDataEntry(group.Key, out IccTagTableEntry tableEntry); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccBAcsProcessElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccBAcsProcessElement.cs index d6882957ff..ef2e6eae0a 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccBAcsProcessElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccBAcsProcessElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -21,9 +21,12 @@ public IccBAcsProcessElement(int inChannelCount, int outChannelCount) } /// - public bool Equals(IccBAcsProcessElement other) - { - return base.Equals(other); - } + public bool Equals(IccBAcsProcessElement other) => base.Equals(other); + + /// + public override bool Equals(object obj) => this.Equals(obj as IccBAcsProcessElement); + + /// + public override int GetHashCode() => base.GetHashCode(); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccClutProcessElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccClutProcessElement.cs index e450362a5d..00183b6e85 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccClutProcessElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccClutProcessElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -16,9 +16,7 @@ internal sealed class IccClutProcessElement : IccMultiProcessElement, IEquatable /// The color lookup table of this element public IccClutProcessElement(IccClut clutValue) : base(IccMultiProcessElementSignature.Clut, clutValue?.InputChannelCount ?? 1, clutValue?.OutputChannelCount ?? 1) - { - this.ClutValue = clutValue ?? throw new ArgumentNullException(nameof(clutValue)); - } + => this.ClutValue = clutValue ?? throw new ArgumentNullException(nameof(clutValue)); /// /// Gets the color lookup table of this element @@ -37,9 +35,12 @@ public override bool Equals(IccMultiProcessElement other) } /// - public bool Equals(IccClutProcessElement other) - { - return this.Equals((IccMultiProcessElement)other); - } + public bool Equals(IccClutProcessElement other) => this.Equals((IccMultiProcessElement)other); + + /// + public override bool Equals(object obj) => this.Equals(obj as IccClutProcessElement); + + /// + public override int GetHashCode() => base.GetHashCode(); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs index 3ea707eec3..21b372ffa6 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -36,5 +36,11 @@ public override bool Equals(IccMultiProcessElement other) /// public bool Equals(IccCurveSetProcessElement other) => this.Equals((IccMultiProcessElement)other); + + /// + public override bool Equals(object obj) => this.Equals(obj as IccCurveSetProcessElement); + + /// + public override int GetHashCode() => base.GetHashCode(); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccEAcsProcessElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccEAcsProcessElement.cs index 67f25b5ceb..5ce56bd11e 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccEAcsProcessElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccEAcsProcessElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -21,9 +21,11 @@ public IccEAcsProcessElement(int inChannelCount, int outChannelCount) } /// - public bool Equals(IccEAcsProcessElement other) - { - return base.Equals(other); - } + public bool Equals(IccEAcsProcessElement other) => base.Equals(other); + + public override bool Equals(object obj) => this.Equals(obj as IccEAcsProcessElement); + + /// + public override int GetHashCode() => base.GetHashCode(); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMatrixProcessElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMatrixProcessElement.cs index b7bde3f791..c448a71cd7 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMatrixProcessElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMatrixProcessElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -52,13 +52,17 @@ public override bool Equals(IccMultiProcessElement other) /// public bool Equals(IccMatrixProcessElement other) - { - return this.Equals((IccMultiProcessElement)other); - } + => this.Equals((IccMultiProcessElement)other); + + /// + public override bool Equals(object obj) + => this.Equals(obj as IccMatrixProcessElement); + + /// + public override int GetHashCode() + => HashCode.Combine(base.GetHashCode(), this.MatrixIxO, this.MatrixOx1); private bool EqualsMatrix(IccMatrixProcessElement element) - { - return this.MatrixIxO.Equals(element.MatrixIxO); - } + => this.MatrixIxO.Equals(element.MatrixIxO); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMultiProcessElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMultiProcessElement.cs index 3921212592..84d399459c 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMultiProcessElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccMultiProcessElement.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -58,5 +58,11 @@ public virtual bool Equals(IccMultiProcessElement other) && this.InputChannelCount == other.InputChannelCount && this.OutputChannelCount == other.OutputChannelCount; } + + public override bool Equals(object obj) => this.Equals(obj as IccMultiProcessElement); + + /// + public override int GetHashCode() + => HashCode.Combine(this.Signature, this.InputChannelCount, this.OutputChannelCount); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs index 5d0bdabe7b..8b40dd7832 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -87,9 +87,7 @@ public IccCrdInfoTagDataEntry( /// public override bool Equals(IccTagDataEntry other) - { - return other is IccCrdInfoTagDataEntry entry && this.Equals(entry); - } + => other is IccCrdInfoTagDataEntry entry && this.Equals(entry); /// public bool Equals(IccCrdInfoTagDataEntry other) @@ -105,29 +103,25 @@ public bool Equals(IccCrdInfoTagDataEntry other) } return base.Equals(other) - && string.Equals(this.PostScriptProductName, other.PostScriptProductName) - && string.Equals(this.RenderingIntent0Crd, other.RenderingIntent0Crd) - && string.Equals(this.RenderingIntent1Crd, other.RenderingIntent1Crd) - && string.Equals(this.RenderingIntent2Crd, other.RenderingIntent2Crd) - && string.Equals(this.RenderingIntent3Crd, other.RenderingIntent3Crd); + && string.Equals(this.PostScriptProductName, other.PostScriptProductName, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.RenderingIntent0Crd, other.RenderingIntent0Crd, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.RenderingIntent1Crd, other.RenderingIntent1Crd, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.RenderingIntent2Crd, other.RenderingIntent2Crd, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.RenderingIntent3Crd, other.RenderingIntent3Crd, StringComparison.OrdinalIgnoreCase); } /// public override bool Equals(object obj) - { - return obj is IccCrdInfoTagDataEntry other && this.Equals(other); - } + => obj is IccCrdInfoTagDataEntry other && this.Equals(other); /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Signature, this.PostScriptProductName, this.RenderingIntent0Crd, this.RenderingIntent1Crd, this.RenderingIntent2Crd, this.RenderingIntent3Crd); - } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs index 1a178b89a7..e5f817e958 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -40,7 +40,7 @@ public IccDataTagDataEntry(byte[] data, bool isAscii) public IccDataTagDataEntry(byte[] data, bool isAscii, IccProfileTag tagSignature) : base(IccTypeSignature.Data, tagSignature) { - this.Data = data ?? throw new ArgumentException(nameof(data)); + this.Data = data ?? throw new ArgumentNullException(nameof(data)); this.IsAscii = isAscii; } @@ -62,9 +62,7 @@ public IccDataTagDataEntry(byte[] data, bool isAscii, IccProfileTag tagSignature /// public override bool Equals(IccTagDataEntry other) - { - return other is IccDataTagDataEntry entry && this.Equals(entry); - } + => other is IccDataTagDataEntry entry && this.Equals(entry); /// public bool Equals(IccDataTagDataEntry other) @@ -84,17 +82,13 @@ public bool Equals(IccDataTagDataEntry other) /// public override bool Equals(object obj) - { - return obj is IccDataTagDataEntry other && this.Equals(other); - } + => obj is IccDataTagDataEntry other && this.Equals(other); /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Signature, this.Data, this.IsAscii); - } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs index 35542c1b4d..aa63c3b350 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -71,7 +71,7 @@ public IccLut8TagDataEntry(float[,] matrix, IccLut[] inputValues, IccClut clutVa bool is3By3 = matrix.GetLength(0) == 3 && matrix.GetLength(1) == 3; Guard.IsTrue(is3By3, nameof(matrix), "Matrix must have a size of three by three"); - this.Matrix = this.CreateMatrix(matrix); + this.Matrix = CreateMatrix(matrix); this.InputValues = inputValues ?? throw new ArgumentNullException(nameof(inputValues)); this.ClutValues = clutValues ?? throw new ArgumentNullException(nameof(clutValues)); this.OutputValues = outputValues ?? throw new ArgumentNullException(nameof(outputValues)); @@ -141,18 +141,15 @@ public bool Equals(IccLut8TagDataEntry other) /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Signature, this.Matrix, this.InputValues, this.ClutValues, this.OutputValues); - } - private Matrix4x4 CreateMatrix(float[,] matrix) - { - return new Matrix4x4( + private static Matrix4x4 CreateMatrix(float[,] matrix) + => new( matrix[0, 0], matrix[0, 1], matrix[0, 2], @@ -169,6 +166,5 @@ private Matrix4x4 CreateMatrix(float[,] matrix) 0, 0, 1); - } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs index 21d46b0163..0c338dabd2 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs @@ -53,13 +53,13 @@ public IccLutAToBTagDataEntry( IccProfileTag tagSignature) : base(IccTypeSignature.LutAToB, tagSignature) { - this.VerifyMatrix(matrix3x3, matrix3x1); + VerifyMatrix(matrix3x3, matrix3x1); this.VerifyCurve(curveA, nameof(curveA)); this.VerifyCurve(curveB, nameof(curveB)); this.VerifyCurve(curveM, nameof(curveM)); - this.Matrix3x3 = this.CreateMatrix3x3(matrix3x3); - this.Matrix3x1 = this.CreateMatrix3x1(matrix3x1); + this.Matrix3x3 = CreateMatrix3x3(matrix3x3); + this.Matrix3x1 = CreateMatrix3x1(matrix3x1); this.CurveA = curveA; this.CurveB = curveB; this.CurveM = curveM; @@ -212,29 +212,23 @@ private static bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] } private bool IsAClutMMatrixB() - { - return this.CurveB != null - && this.Matrix3x3 != null - && this.Matrix3x1 != null - && this.CurveM != null - && this.ClutValues != null - && this.CurveA != null; - } + => this.CurveB != null + && this.Matrix3x3 != null + && this.Matrix3x1 != null + && this.CurveM != null + && this.ClutValues != null + && this.CurveA != null; private bool IsMMatrixB() - { - return this.CurveB != null - && this.Matrix3x3 != null - && this.Matrix3x1 != null - && this.CurveM != null; - } + => this.CurveB != null + && this.Matrix3x3 != null + && this.Matrix3x1 != null + && this.CurveM != null; private bool IsAClutB() - { - return this.CurveB != null - && this.ClutValues != null - && this.CurveA != null; - } + => this.CurveB != null + && this.ClutValues != null + && this.CurveA != null; private bool IsB() => this.CurveB != null; @@ -242,12 +236,12 @@ private void VerifyCurve(IccTagDataEntry[] curves, string name) { if (curves != null) { - bool isNotCurve = curves.Any(t => !(t is IccParametricCurveTagDataEntry) && !(t is IccCurveTagDataEntry)); + bool isNotCurve = curves.Any(t => t is not IccParametricCurveTagDataEntry and not IccCurveTagDataEntry); Guard.IsFalse(isNotCurve, nameof(name), $"{nameof(name)} must be of type {nameof(IccParametricCurveTagDataEntry)} or {nameof(IccCurveTagDataEntry)}"); } } - private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) + private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) { if (matrix3x1 != null) { @@ -261,7 +255,7 @@ private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) } } - private Vector3? CreateMatrix3x1(float[] matrix) + private static Vector3? CreateMatrix3x1(float[] matrix) { if (matrix is null) { @@ -271,7 +265,7 @@ private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) return new Vector3(matrix[0], matrix[1], matrix[2]); } - private Matrix4x4? CreateMatrix3x3(float[,] matrix) + private static Matrix4x4? CreateMatrix3x3(float[,] matrix) { if (matrix is null) { diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs index 89b0101800..2c4487bcab 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs @@ -53,13 +53,13 @@ public IccLutBToATagDataEntry( IccProfileTag tagSignature) : base(IccTypeSignature.LutBToA, tagSignature) { - this.VerifyMatrix(matrix3x3, matrix3x1); + VerifyMatrix(matrix3x3, matrix3x1); this.VerifyCurve(curveA, nameof(curveA)); this.VerifyCurve(curveB, nameof(curveB)); this.VerifyCurve(curveM, nameof(curveM)); - this.Matrix3x3 = this.CreateMatrix3x3(matrix3x3); - this.Matrix3x1 = this.CreateMatrix3x1(matrix3x1); + this.Matrix3x3 = CreateMatrix3x3(matrix3x3); + this.Matrix3x1 = CreateMatrix3x1(matrix3x1); this.CurveA = curveA; this.CurveB = curveB; this.CurveM = curveM; @@ -167,9 +167,9 @@ public bool Equals(IccLutBToATagDataEntry other) && this.Matrix3x3.Equals(other.Matrix3x3) && this.Matrix3x1.Equals(other.Matrix3x1) && this.ClutValues.Equals(other.ClutValues) - && this.EqualsCurve(this.CurveB, other.CurveB) - && this.EqualsCurve(this.CurveM, other.CurveM) - && this.EqualsCurve(this.CurveA, other.CurveA); + && EqualsCurve(this.CurveB, other.CurveB) + && EqualsCurve(this.CurveM, other.CurveM) + && EqualsCurve(this.CurveA, other.CurveA); } /// @@ -192,7 +192,7 @@ public override int GetHashCode() return hashCode.ToHashCode(); } - private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) + private static bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) { bool thisNull = thisCurves is null; bool entryNull = entryCurves is null; @@ -211,29 +211,13 @@ private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCu } private bool IsBMatrixMClutA() - { - return this.CurveB != null - && this.Matrix3x3 != null - && this.Matrix3x1 != null - && this.CurveM != null - && this.ClutValues != null - && this.CurveA != null; - } + => this.CurveB != null && this.Matrix3x3 != null && this.Matrix3x1 != null && this.CurveM != null && this.ClutValues != null && this.CurveA != null; private bool IsBMatrixM() - { - return this.CurveB != null - && this.Matrix3x3 != null - && this.Matrix3x1 != null - && this.CurveM != null; - } + => this.CurveB != null && this.Matrix3x3 != null && this.Matrix3x1 != null && this.CurveM != null; private bool IsBClutA() - { - return this.CurveB != null - && this.ClutValues != null - && this.CurveA != null; - } + => this.CurveB != null && this.ClutValues != null && this.CurveA != null; private bool IsB() => this.CurveB != null; @@ -241,12 +225,12 @@ private void VerifyCurve(IccTagDataEntry[] curves, string name) { if (curves != null) { - bool isNotCurve = curves.Any(t => !(t is IccParametricCurveTagDataEntry) && !(t is IccCurveTagDataEntry)); + bool isNotCurve = curves.Any(t => t is not IccParametricCurveTagDataEntry and not IccCurveTagDataEntry); Guard.IsFalse(isNotCurve, nameof(name), $"{nameof(name)} must be of type {nameof(IccParametricCurveTagDataEntry)} or {nameof(IccCurveTagDataEntry)}"); } } - private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) + private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) { if (matrix3x1 != null) { @@ -260,7 +244,7 @@ private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) } } - private Vector3? CreateMatrix3x1(float[] matrix) + private static Vector3? CreateMatrix3x1(float[] matrix) { if (matrix is null) { @@ -270,7 +254,7 @@ private void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) return new Vector3(matrix[0], matrix[1], matrix[2]); } - private Matrix4x4? CreateMatrix3x3(float[,] matrix) + private static Matrix4x4? CreateMatrix3x3(float[,] matrix) { if (matrix is null) { diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs index c2c959d296..8541d287d8 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -121,9 +121,7 @@ public IccNamedColor2TagDataEntry(int vendorFlags, string prefix, string suffix, /// public override bool Equals(IccTagDataEntry other) - { - return other is IccNamedColor2TagDataEntry entry && this.Equals(entry); - } + => other is IccNamedColor2TagDataEntry entry && this.Equals(entry); /// public bool Equals(IccNamedColor2TagDataEntry other) @@ -140,28 +138,24 @@ public bool Equals(IccNamedColor2TagDataEntry other) return base.Equals(other) && this.CoordinateCount == other.CoordinateCount - && string.Equals(this.Prefix, other.Prefix) - && string.Equals(this.Suffix, other.Suffix) + && string.Equals(this.Prefix, other.Prefix, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.Suffix, other.Suffix, StringComparison.OrdinalIgnoreCase) && this.VendorFlags == other.VendorFlags && this.Colors.AsSpan().SequenceEqual(other.Colors); } /// public override bool Equals(object obj) - { - return obj is IccNamedColor2TagDataEntry other && this.Equals(other); - } + => obj is IccNamedColor2TagDataEntry other && this.Equals(other); /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Signature, this.CoordinateCount, this.Prefix, this.Suffix, this.VendorFlags, this.Colors); - } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs index 148450de60..2924a5dc6a 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -27,9 +27,7 @@ public IccSignatureTagDataEntry(string signatureData) /// Tag Signature public IccSignatureTagDataEntry(string signatureData, IccProfileTag tagSignature) : base(IccTypeSignature.Signature, tagSignature) - { - this.SignatureData = signatureData ?? throw new ArgumentNullException(nameof(signatureData)); - } + => this.SignatureData = signatureData ?? throw new ArgumentNullException(nameof(signatureData)); /// /// Gets the signature data @@ -38,9 +36,7 @@ public IccSignatureTagDataEntry(string signatureData, IccProfileTag tagSignature /// public override bool Equals(IccTagDataEntry other) - { - return other is IccSignatureTagDataEntry entry && this.Equals(entry); - } + => other is IccSignatureTagDataEntry entry && this.Equals(entry); /// public bool Equals(IccSignatureTagDataEntry other) @@ -55,14 +51,13 @@ public bool Equals(IccSignatureTagDataEntry other) return true; } - return base.Equals(other) && string.Equals(this.SignatureData, other.SignatureData); + return base.Equals(other) + && string.Equals(this.SignatureData, other.SignatureData, StringComparison.OrdinalIgnoreCase); } /// public override bool Equals(object obj) - { - return obj is IccSignatureTagDataEntry other && this.Equals(other); - } + => obj is IccSignatureTagDataEntry other && this.Equals(other); /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.SignatureData); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs index 1d9da5398e..6fb2aca203 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs @@ -104,7 +104,7 @@ public static explicit operator IccMultiLocalizedUnicodeTagDataEntry(IccTextDesc return new IccMultiLocalizedUnicodeTagDataEntry(new[] { localString }, textEntry.TagSignature); - CultureInfo GetCulture(uint value) + static CultureInfo GetCulture(uint value) { if (value == 0) { @@ -122,7 +122,7 @@ CultureInfo GetCulture(uint value) && p3 >= 0x41 && p3 <= 0x5A && p4 >= 0x41 && p4 <= 0x5A) { - var culture = new string(new[] { (char)p1, (char)p2, '-', (char)p3, (char)p4 }); + string culture = new(new[] { (char)p1, (char)p2, '-', (char)p3, (char)p4 }); return new CultureInfo(culture); } @@ -132,9 +132,7 @@ CultureInfo GetCulture(uint value) /// public override bool Equals(IccTagDataEntry other) - { - return other is IccTextDescriptionTagDataEntry entry && this.Equals(entry); - } + => other is IccTextDescriptionTagDataEntry entry && this.Equals(entry); /// public bool Equals(IccTextDescriptionTagDataEntry other) @@ -150,29 +148,25 @@ public bool Equals(IccTextDescriptionTagDataEntry other) } return base.Equals(other) - && string.Equals(this.Ascii, other.Ascii) - && string.Equals(this.Unicode, other.Unicode) - && string.Equals(this.ScriptCode, other.ScriptCode) + && string.Equals(this.Ascii, other.Ascii, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.Unicode, other.Unicode, StringComparison.OrdinalIgnoreCase) + && string.Equals(this.ScriptCode, other.ScriptCode, StringComparison.OrdinalIgnoreCase) && this.UnicodeLanguageCode == other.UnicodeLanguageCode && this.ScriptCodeCode == other.ScriptCodeCode; } /// public override bool Equals(object obj) - { - return obj is IccTextDescriptionTagDataEntry other && this.Equals(other); - } + => obj is IccTextDescriptionTagDataEntry other && this.Equals(other); /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Signature, this.Ascii, this.Unicode, this.ScriptCode, this.UnicodeLanguageCode, this.ScriptCodeCode); - } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs index 4af43a1a8b..9463f665a8 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -26,9 +26,7 @@ public IccTextTagDataEntry(string text) /// Tag Signature public IccTextTagDataEntry(string text, IccProfileTag tagSignature) : base(IccTypeSignature.Text, tagSignature) - { - this.Text = text ?? throw new ArgumentNullException(nameof(text)); - } + => this.Text = text ?? throw new ArgumentNullException(nameof(text)); /// /// Gets the Text @@ -37,9 +35,7 @@ public IccTextTagDataEntry(string text, IccProfileTag tagSignature) /// public override bool Equals(IccTagDataEntry other) - { - return other is IccTextTagDataEntry entry && this.Equals(entry); - } + => other is IccTextTagDataEntry entry && this.Equals(entry); /// public bool Equals(IccTextTagDataEntry other) @@ -54,14 +50,12 @@ public bool Equals(IccTextTagDataEntry other) return true; } - return base.Equals(other) && string.Equals(this.Text, other.Text); + return base.Equals(other) && string.Equals(this.Text, other.Text, StringComparison.OrdinalIgnoreCase); } /// public override bool Equals(object obj) - { - return obj is IccTextTagDataEntry other && this.Equals(other); - } + => obj is IccTextTagDataEntry other && this.Equals(other); /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Text); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs index e48c9d3b3a..d806ca2a56 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -54,9 +54,7 @@ public IccUcrBgTagDataEntry(ushort[] ucrCurve, ushort[] bgCurve, string descript /// public override bool Equals(IccTagDataEntry other) - { - return other is IccUcrBgTagDataEntry entry && this.Equals(entry); - } + => other is IccUcrBgTagDataEntry entry && this.Equals(entry); /// public bool Equals(IccUcrBgTagDataEntry other) @@ -74,23 +72,19 @@ public bool Equals(IccUcrBgTagDataEntry other) return base.Equals(other) && this.UcrCurve.AsSpan().SequenceEqual(other.UcrCurve) && this.BgCurve.AsSpan().SequenceEqual(other.BgCurve) - && string.Equals(this.Description, other.Description); + && string.Equals(this.Description, other.Description, StringComparison.OrdinalIgnoreCase); } /// public override bool Equals(object obj) - { - return obj is IccUcrBgTagDataEntry other && this.Equals(other); - } + => obj is IccUcrBgTagDataEntry other && this.Equals(other); /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Signature, this.UcrCurve, this.BgCurve, this.Description); - } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccXyzTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccXyzTagDataEntry.cs index 319ea8fde5..8a30802406 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccXyzTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccXyzTagDataEntry.cs @@ -1,9 +1,8 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; using System.Numerics; -using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Metadata.Profiles.Icc { @@ -28,9 +27,7 @@ public IccXyzTagDataEntry(Vector3[] data) /// Tag Signature public IccXyzTagDataEntry(Vector3[] data, IccProfileTag tagSignature) : base(IccTypeSignature.Xyz, tagSignature) - { - this.Data = data ?? throw new ArgumentNullException(nameof(data)); - } + => this.Data = data ?? throw new ArgumentNullException(nameof(data)); /// /// Gets the XYZ numbers. @@ -50,8 +47,13 @@ public override bool Equals(IccTagDataEntry other) /// public bool Equals(IccXyzTagDataEntry other) - { - return this.Equals((IccTagDataEntry)other); - } + => this.Equals((IccTagDataEntry)other); + + /// + public override bool Equals(object obj) + => this.Equals(obj as IccXyzTagDataEntry); + + public override int GetHashCode() + => HashCode.Combine(base.GetHashCode(), this.Data); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLocalizedString.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLocalizedString.cs index 20ca0248ab..63f97d45c8 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLocalizedString.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLocalizedString.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -50,5 +50,11 @@ public bool Equals(IccLocalizedString other) => /// public override string ToString() => $"{this.Culture.Name}: {this.Text}"; + + public override bool Equals(object obj) + => obj is IccLocalizedString iccLocalizedString && this.Equals(iccLocalizedString); + + public override int GetHashCode() + => HashCode.Combine(this.Culture, this.Text); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLut.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLut.cs index dfe186d7d0..b5709db4d7 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLut.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccLut.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -15,9 +15,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// The LUT values public IccLut(float[] values) - { - this.Values = values ?? throw new ArgumentNullException(nameof(values)); - } + => this.Values = values ?? throw new ArgumentNullException(nameof(values)); /// /// Initializes a new instance of the struct. @@ -68,5 +66,13 @@ public bool Equals(IccLut other) return this.Values.AsSpan().SequenceEqual(other.Values); } + + /// + public override bool Equals(object obj) + => obj is IccLut iccLut && this.Equals(iccLut); + + /// + public override int GetHashCode() + => this.Values.GetHashCode(); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccNamedColor.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccNamedColor.cs index a0e767a7c9..8010f78bc0 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccNamedColor.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccNamedColor.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -71,20 +71,16 @@ public IccNamedColor(string name, ushort[] pcsCoordinates, ushort[] deviceCoordi /// public bool Equals(IccNamedColor other) - { - return this.Name.Equals(other.Name) - && this.PcsCoordinates.AsSpan().SequenceEqual(other.PcsCoordinates) - && this.DeviceCoordinates.AsSpan().SequenceEqual(other.DeviceCoordinates); - } + => this.Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase) + && this.PcsCoordinates.AsSpan().SequenceEqual(other.PcsCoordinates) + && this.DeviceCoordinates.AsSpan().SequenceEqual(other.DeviceCoordinates); /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Name, this.PcsCoordinates, this.DeviceCoordinates); - } /// public override string ToString() => this.Name; diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs index 6633d2a687..b4e6e573b3 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs @@ -1,7 +1,8 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; +using System.Globalization; namespace SixLabors.ImageSharp.Metadata.Profiles.Icc { @@ -13,7 +14,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// A profile ID with all values set to zero /// - public static readonly IccProfileId Zero = default; + public static readonly IccProfileId Zero; /// /// Initializes a new instance of the struct. @@ -67,10 +68,7 @@ public IccProfileId(uint p1, uint p2, uint p3, uint p4) /// /// True if the parameter is equal to the parameter; otherwise, false. /// - public static bool operator ==(IccProfileId left, IccProfileId right) - { - return left.Equals(right); - } + public static bool operator ==(IccProfileId left, IccProfileId right) => left.Equals(right); /// /// Compares two objects for equality. @@ -80,10 +78,7 @@ public IccProfileId(uint p1, uint p2, uint p3, uint p4) /// /// True if the parameter is not equal to the parameter; otherwise, false. /// - public static bool operator !=(IccProfileId left, IccProfileId right) - { - return !left.Equals(right); - } + public static bool operator !=(IccProfileId left, IccProfileId right) => !left.Equals(right); /// public override bool Equals(object obj) => obj is IccProfileId other && this.Equals(other); @@ -97,17 +92,15 @@ public bool Equals(IccProfileId other) => /// public override int GetHashCode() - { - return HashCode.Combine( + => HashCode.Combine( this.Part1, this.Part2, this.Part3, this.Part4); - } /// public override string ToString() => $"{ToHex(this.Part1)}-{ToHex(this.Part2)}-{ToHex(this.Part3)}-{ToHex(this.Part4)}"; - private static string ToHex(uint value) => value.ToString("X").PadLeft(8, '0'); + private static string ToHex(uint value) => value.ToString("X", CultureInfo.InvariantCulture).PadLeft(8, '0'); } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccVersion.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccVersion.cs index f8f2b653a6..4b8cb91f7e 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccVersion.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccVersion.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -38,6 +38,28 @@ public IccVersion(int major, int minor, int patch) /// public int Patch { get; } + /// + /// Returns a value indicating whether the two values are equal. + /// + /// The first value. + /// The second value. + /// if the two value are equal; otherwise, . + public static bool operator ==(IccVersion left, IccVersion right) + => left.Equals(right); + + /// + /// Returns a value indicating whether the two values are not equal. + /// + /// The first value. + /// The second value. + /// if the two value are not equal; otherwise, . + public static bool operator !=(IccVersion left, IccVersion right) + => !(left == right); + + /// + public override bool Equals(object obj) + => obj is IccVersion iccVersion && this.Equals(iccVersion); + /// public bool Equals(IccVersion other) => this.Major == other.Major && @@ -46,8 +68,10 @@ public bool Equals(IccVersion other) => /// public override string ToString() - { - return string.Join(".", this.Major, this.Minor, this.Patch); - } + => string.Join(".", this.Major, this.Minor, this.Patch); + + /// + public override int GetHashCode() + => HashCode.Combine(this.Major, this.Minor, this.Patch); } } diff --git a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs index ec3eed2650..bc94e95552 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs @@ -5,6 +5,7 @@ using System.Buffers.Binary; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Globalization; using System.Text; using SixLabors.ImageSharp.Metadata.Profiles.IPTC; @@ -102,7 +103,7 @@ public IEnumerable Values /// The values found with the specified tag. public List GetValues(IptcTag tag) { - var iptcValues = new List(); + List iptcValues = new(); foreach (IptcValue iptcValue in this.Values) { if (iptcValue.Tag == tag) @@ -149,7 +150,7 @@ public bool RemoveValue(IptcTag tag, string value) bool removed = false; for (int i = this.values.Count - 1; i >= 0; i--) { - if (this.values[i].Tag == tag && this.values[i].Value.Equals(value)) + if (this.values[i].Tag == tag && this.values[i].Value.Equals(value, StringComparison.OrdinalIgnoreCase)) { this.values.RemoveAt(i); removed = true; @@ -226,16 +227,17 @@ public void SetValue(IptcTag tag, Encoding encoding, string value, bool strict = /// /// The tag of the iptc value. /// The datetime. + /// Iptc tag is not a time or date type. public void SetDateTimeValue(IptcTag tag, DateTimeOffset dateTimeOffset) { if (!tag.IsDate() && !tag.IsTime()) { - throw new ArgumentException("iptc tag is not a time or date type"); + throw new ArgumentException("Iptc tag is not a time or date type."); } string formattedDate = tag.IsDate() - ? dateTimeOffset.ToString("yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture) - : dateTimeOffset.ToString("HHmmsszzzz", System.Globalization.CultureInfo.InvariantCulture) + ? dateTimeOffset.ToString("yyyyMMdd", CultureInfo.InvariantCulture) + : dateTimeOffset.ToString("HHmmsszzzz", CultureInfo.InvariantCulture) .Replace(":", string.Empty); this.SetValue(tag, Encoding.UTF8, formattedDate); @@ -329,7 +331,7 @@ private void Initialize() bool isValidTagMarker = this.Data[offset++] == IptcTagMarkerByte; byte recordNumber = this.Data[offset++]; bool isValidRecordNumber = recordNumber is >= 1 and <= 9; - var tag = (IptcTag)this.Data[offset++]; + IptcTag tag = (IptcTag)this.Data[offset++]; bool isValidEntry = isValidTagMarker && isValidRecordNumber; bool isApplicationRecord = recordNumber == (byte)IptcRecordNumber.Application; diff --git a/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs b/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs index f0d40a718c..1a74ea4183 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs @@ -101,7 +101,7 @@ public string Value byte[] valueBytes; if (this.Strict && value.Length > maxLength) { - string cappedValue = value.Substring(0, maxLength); + string cappedValue = value[..maxLength]; valueBytes = this.encoding.GetBytes(cappedValue); // It is still possible that the bytes of the string exceed the limit. diff --git a/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs b/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs index 06595b9911..095beb24af 100644 --- a/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs @@ -67,15 +67,15 @@ public XDocument GetDocument() } } - using var stream = new MemoryStream(byteArray, 0, count); - using var reader = new StreamReader(stream, Encoding.UTF8); + using MemoryStream stream = new(byteArray, 0, count); + using StreamReader reader = new(stream, Encoding.UTF8); return XDocument.Load(reader); } /// /// Convert the content of this into a byte array. /// - /// The + /// The public byte[] ToByteArray() { byte[] result = new byte[this.Data.Length]; diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs index 0a00fcf35a..4c9afecfd4 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs @@ -20,7 +20,7 @@ internal static partial class PorterDuffFunctions /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -35,7 +35,7 @@ public static Vector4 NormalSrc(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -50,7 +50,7 @@ public static Vector4 NormalSrcAtop(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -65,7 +65,7 @@ public static Vector4 NormalSrcOver(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -80,7 +80,7 @@ public static Vector4 NormalSrcIn(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -95,7 +95,7 @@ public static Vector4 NormalSrcOut(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -108,7 +108,7 @@ public static Vector4 NormalDest(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -123,7 +123,7 @@ public static Vector4 NormalDestAtop(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -138,7 +138,7 @@ public static Vector4 NormalDestOver(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -153,7 +153,7 @@ public static Vector4 NormalDestIn(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -168,7 +168,7 @@ public static Vector4 NormalDestOut(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -183,7 +183,7 @@ public static Vector4 NormalXor(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 NormalClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -425,7 +425,7 @@ public static TPixel NormalXor(TPixel backdrop, TPixel source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplySrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -440,7 +440,7 @@ public static Vector4 MultiplySrc(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplySrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -455,7 +455,7 @@ public static Vector4 MultiplySrcAtop(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplySrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -470,7 +470,7 @@ public static Vector4 MultiplySrcOver(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplySrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -485,7 +485,7 @@ public static Vector4 MultiplySrcIn(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplySrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -500,7 +500,7 @@ public static Vector4 MultiplySrcOut(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplyDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -513,7 +513,7 @@ public static Vector4 MultiplyDest(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplyDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -528,7 +528,7 @@ public static Vector4 MultiplyDestAtop(Vector4 backdrop, Vector4 source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplyDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -543,7 +543,7 @@ public static Vector4 MultiplyDestOver(Vector4 backdrop, Vector4 source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplyDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -558,7 +558,7 @@ public static Vector4 MultiplyDestIn(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplyDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -573,7 +573,7 @@ public static Vector4 MultiplyDestOut(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplyXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -588,7 +588,7 @@ public static Vector4 MultiplyXor(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MultiplyClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -830,7 +830,7 @@ public static TPixel MultiplyXor(TPixel backdrop, TPixel source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -845,7 +845,7 @@ public static Vector4 AddSrc(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -860,7 +860,7 @@ public static Vector4 AddSrcAtop(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -875,7 +875,7 @@ public static Vector4 AddSrcOver(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -890,7 +890,7 @@ public static Vector4 AddSrcIn(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -905,7 +905,7 @@ public static Vector4 AddSrcOut(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -918,7 +918,7 @@ public static Vector4 AddDest(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -933,7 +933,7 @@ public static Vector4 AddDestAtop(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -948,7 +948,7 @@ public static Vector4 AddDestOver(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -963,7 +963,7 @@ public static Vector4 AddDestIn(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -978,7 +978,7 @@ public static Vector4 AddDestOut(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -993,7 +993,7 @@ public static Vector4 AddXor(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 AddClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1235,7 +1235,7 @@ public static TPixel AddXor(TPixel backdrop, TPixel source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1250,7 +1250,7 @@ public static Vector4 SubtractSrc(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1265,7 +1265,7 @@ public static Vector4 SubtractSrcAtop(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1280,7 +1280,7 @@ public static Vector4 SubtractSrcOver(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1295,7 +1295,7 @@ public static Vector4 SubtractSrcIn(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1310,7 +1310,7 @@ public static Vector4 SubtractSrcOut(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -1323,7 +1323,7 @@ public static Vector4 SubtractDest(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1338,7 +1338,7 @@ public static Vector4 SubtractDestAtop(Vector4 backdrop, Vector4 source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1353,7 +1353,7 @@ public static Vector4 SubtractDestOver(Vector4 backdrop, Vector4 source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1368,7 +1368,7 @@ public static Vector4 SubtractDestIn(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1383,7 +1383,7 @@ public static Vector4 SubtractDestOut(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1398,7 +1398,7 @@ public static Vector4 SubtractXor(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 SubtractClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1640,7 +1640,7 @@ public static TPixel SubtractXor(TPixel backdrop, TPixel source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1655,7 +1655,7 @@ public static Vector4 ScreenSrc(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1670,7 +1670,7 @@ public static Vector4 ScreenSrcAtop(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1685,7 +1685,7 @@ public static Vector4 ScreenSrcOver(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1700,7 +1700,7 @@ public static Vector4 ScreenSrcIn(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1715,7 +1715,7 @@ public static Vector4 ScreenSrcOut(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -1728,7 +1728,7 @@ public static Vector4 ScreenDest(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1743,7 +1743,7 @@ public static Vector4 ScreenDestAtop(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1758,7 +1758,7 @@ public static Vector4 ScreenDestOver(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1773,7 +1773,7 @@ public static Vector4 ScreenDestIn(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1788,7 +1788,7 @@ public static Vector4 ScreenDestOut(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1803,7 +1803,7 @@ public static Vector4 ScreenXor(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 ScreenClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2045,7 +2045,7 @@ public static TPixel ScreenXor(TPixel backdrop, TPixel source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2060,7 +2060,7 @@ public static Vector4 DarkenSrc(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2075,7 +2075,7 @@ public static Vector4 DarkenSrcAtop(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2090,7 +2090,7 @@ public static Vector4 DarkenSrcOver(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2105,7 +2105,7 @@ public static Vector4 DarkenSrcIn(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2120,7 +2120,7 @@ public static Vector4 DarkenSrcOut(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -2133,7 +2133,7 @@ public static Vector4 DarkenDest(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2148,7 +2148,7 @@ public static Vector4 DarkenDestAtop(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2163,7 +2163,7 @@ public static Vector4 DarkenDestOver(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2178,7 +2178,7 @@ public static Vector4 DarkenDestIn(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2193,7 +2193,7 @@ public static Vector4 DarkenDestOut(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2208,7 +2208,7 @@ public static Vector4 DarkenXor(Vector4 backdrop, Vector4 source, float opacity) /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 DarkenClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2450,7 +2450,7 @@ public static TPixel DarkenXor(TPixel backdrop, TPixel source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2465,7 +2465,7 @@ public static Vector4 LightenSrc(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2480,7 +2480,7 @@ public static Vector4 LightenSrcAtop(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2495,7 +2495,7 @@ public static Vector4 LightenSrcOver(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2510,7 +2510,7 @@ public static Vector4 LightenSrcIn(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2525,7 +2525,7 @@ public static Vector4 LightenSrcOut(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -2538,7 +2538,7 @@ public static Vector4 LightenDest(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2553,7 +2553,7 @@ public static Vector4 LightenDestAtop(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2568,7 +2568,7 @@ public static Vector4 LightenDestOver(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2583,7 +2583,7 @@ public static Vector4 LightenDestIn(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2598,7 +2598,7 @@ public static Vector4 LightenDestOut(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2613,7 +2613,7 @@ public static Vector4 LightenXor(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LightenClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2855,7 +2855,7 @@ public static TPixel LightenXor(TPixel backdrop, TPixel source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlaySrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2870,7 +2870,7 @@ public static Vector4 OverlaySrc(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlaySrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2885,7 +2885,7 @@ public static Vector4 OverlaySrcAtop(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlaySrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2900,7 +2900,7 @@ public static Vector4 OverlaySrcOver(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlaySrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2915,7 +2915,7 @@ public static Vector4 OverlaySrcIn(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlaySrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2930,7 +2930,7 @@ public static Vector4 OverlaySrcOut(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlayDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -2943,7 +2943,7 @@ public static Vector4 OverlayDest(Vector4 backdrop, Vector4 source, float opacit /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlayDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2958,7 +2958,7 @@ public static Vector4 OverlayDestAtop(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlayDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2973,7 +2973,7 @@ public static Vector4 OverlayDestOver(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlayDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2988,7 +2988,7 @@ public static Vector4 OverlayDestIn(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlayDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3003,7 +3003,7 @@ public static Vector4 OverlayDestOut(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlayXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3018,7 +3018,7 @@ public static Vector4 OverlayXor(Vector4 backdrop, Vector4 source, float opacity /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 OverlayClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3260,7 +3260,7 @@ public static TPixel OverlayXor(TPixel backdrop, TPixel source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3275,7 +3275,7 @@ public static Vector4 HardLightSrc(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3290,7 +3290,7 @@ public static Vector4 HardLightSrcAtop(Vector4 backdrop, Vector4 source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3305,7 +3305,7 @@ public static Vector4 HardLightSrcOver(Vector4 backdrop, Vector4 source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3320,7 +3320,7 @@ public static Vector4 HardLightSrcIn(Vector4 backdrop, Vector4 source, float opa /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3335,7 +3335,7 @@ public static Vector4 HardLightSrcOut(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -3348,7 +3348,7 @@ public static Vector4 HardLightDest(Vector4 backdrop, Vector4 source, float opac /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3363,7 +3363,7 @@ public static Vector4 HardLightDestAtop(Vector4 backdrop, Vector4 source, float /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3378,7 +3378,7 @@ public static Vector4 HardLightDestOver(Vector4 backdrop, Vector4 source, float /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3393,7 +3393,7 @@ public static Vector4 HardLightDestIn(Vector4 backdrop, Vector4 source, float op /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3408,7 +3408,7 @@ public static Vector4 HardLightDestOut(Vector4 backdrop, Vector4 source, float o /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3423,7 +3423,7 @@ public static Vector4 HardLightXor(Vector4 backdrop, Vector4 source, float opaci /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 HardLightClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt index c651ab4a4d..0cd4e637c4 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt +++ b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.tt @@ -13,10 +13,6 @@ // -<# -// Note use of MethodImplOptions.NoInlining. We have tests that are failing on certain architectures when -// AggresiveInlining is used. Confirmed on Intel i7-6600U in 64bit. -#> using System.Numerics; using System.Runtime.CompilerServices; @@ -32,7 +28,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>Src(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -47,7 +43,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>SrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -62,7 +58,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>SrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -77,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>SrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -92,7 +88,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>SrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -107,7 +103,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>Dest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -120,7 +116,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>DestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -135,7 +131,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>DestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -150,7 +146,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>DestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -165,7 +161,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>DestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -180,7 +176,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>Xor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -195,7 +191,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders /// The source vector. /// The source opacity. Range 0..1 /// The . - [MethodImpl(MethodImplOptions.NoInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 <#=blender#>Clear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index fe9acd4aa9..43bcdf4261 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -47,27 +47,22 @@ public void Blend( float amount) where TPixelSrc : unmanaged, IPixel { - Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length)); - Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); + int maxLength = destination.Length; + Guard.MustBeGreaterThanOrEqualTo(background.Length, maxLength, nameof(background.Length)); + Guard.MustBeGreaterThanOrEqualTo(source.Length, maxLength, nameof(source.Length)); Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount)); - using (IMemoryOwner buffer = - configuration.MemoryAllocator.Allocate(destination.Length * 3)) - { - Span destinationSpan = buffer.Slice(0, destination.Length); - Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); - Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); + using IMemoryOwner buffer = configuration.MemoryAllocator.Allocate(maxLength * 3); + Span destinationVectors = buffer.Slice(0, maxLength); + Span backgroundVectors = buffer.Slice(maxLength, maxLength); + Span sourceVectors = buffer.Slice(maxLength * 2, maxLength); - ReadOnlySpan sourcePixels = background.Slice(0, background.Length); - PixelOperations.Instance.ToVector4(configuration, sourcePixels, backgroundSpan, PixelConversionModifiers.Scale); - ReadOnlySpan sourcePixels1 = source.Slice(0, background.Length); - PixelOperations.Instance.ToVector4(configuration, sourcePixels1, sourceSpan, PixelConversionModifiers.Scale); + PixelOperations.Instance.ToVector4(configuration, background[..maxLength], backgroundVectors, PixelConversionModifiers.Scale); + PixelOperations.Instance.ToVector4(configuration, source[..maxLength], sourceVectors, PixelConversionModifiers.Scale); - this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); + this.BlendFunction(destinationVectors, backgroundVectors, sourceVectors, amount); - Span sourceVectors = destinationSpan.Slice(0, background.Length); - PixelOperations.Instance.FromVector4Destructive(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); - } + PixelOperations.Instance.FromVector4Destructive(configuration, destinationVectors[..maxLength], destination, PixelConversionModifiers.Scale); } /// @@ -109,27 +104,22 @@ public void Blend( ReadOnlySpan amount) where TPixelSrc : unmanaged, IPixel { - Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length)); - Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); - Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); + int maxLength = destination.Length; + Guard.MustBeGreaterThanOrEqualTo(background.Length, maxLength, nameof(background.Length)); + Guard.MustBeGreaterThanOrEqualTo(source.Length, maxLength, nameof(source.Length)); + Guard.MustBeGreaterThanOrEqualTo(amount.Length, maxLength, nameof(amount.Length)); - using (IMemoryOwner buffer = - configuration.MemoryAllocator.Allocate(destination.Length * 3)) - { - Span destinationSpan = buffer.Slice(0, destination.Length); - Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); - Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); + using IMemoryOwner buffer = configuration.MemoryAllocator.Allocate(maxLength * 3); + Span destinationVectors = buffer.Slice(0, maxLength); + Span backgroundVectors = buffer.Slice(maxLength, maxLength); + Span sourceVectors = buffer.Slice(maxLength * 2, maxLength); - ReadOnlySpan sourcePixels = background.Slice(0, background.Length); - PixelOperations.Instance.ToVector4(configuration, sourcePixels, backgroundSpan, PixelConversionModifiers.Scale); - ReadOnlySpan sourcePixels1 = source.Slice(0, background.Length); - PixelOperations.Instance.ToVector4(configuration, sourcePixels1, sourceSpan, PixelConversionModifiers.Scale); + PixelOperations.Instance.ToVector4(configuration, background[..maxLength], backgroundVectors, PixelConversionModifiers.Scale); + PixelOperations.Instance.ToVector4(configuration, source[..maxLength], sourceVectors, PixelConversionModifiers.Scale); - this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); + this.BlendFunction(destinationVectors, backgroundVectors, sourceVectors, amount); - Span sourceVectors = destinationSpan.Slice(0, background.Length); - PixelOperations.Instance.FromVector4Destructive(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); - } + PixelOperations.Instance.FromVector4Destructive(configuration, destinationVectors[..maxLength], destination, PixelConversionModifiers.Scale); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs index a415f41cc5..84354a5c28 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs @@ -18,8 +18,8 @@ public partial struct HalfSingle : IPixel, IPackedVector /// /// Initializes a new instance of the struct. /// - /// The single component. - public HalfSingle(float single) => this.PackedValue = HalfTypeHelper.Pack(single); + /// The single component value. + public HalfSingle(float value) => this.PackedValue = HalfTypeHelper.Pack(value); /// public ushort PackedValue { get; set; } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs index 80b967dcbb..50ea3533bf 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs @@ -17,24 +17,22 @@ public partial struct Rgb24 internal partial class PixelOperations : PixelOperations { private static readonly Lazy LazyInfo = - new Lazy(() => PixelTypeInfo.Create(PixelAlphaRepresentation.None), true); + new(() => PixelTypeInfo.Create(PixelAlphaRepresentation.None), true); /// public override PixelTypeInfo GetPixelTypeInfo() => LazyInfo.Value; /// internal override void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, Span destination) { - Guard.NotNull(configuration, nameof(configuration)); int count = redChannel.Length; GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); - SimdUtils.PackFromRgbPlanes(configuration, redChannel, greenChannel, blueChannel, destination); + SimdUtils.PackFromRgbPlanes(redChannel, greenChannel, blueChannel, destination); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs index e553322282..ed3a53758b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs @@ -20,7 +20,7 @@ public partial struct Rgba32 internal partial class PixelOperations : PixelOperations { private static readonly Lazy LazyInfo = - new Lazy(() => PixelTypeInfo.Create(PixelAlphaRepresentation.Unassociated), true); + new(() => PixelTypeInfo.Create(PixelAlphaRepresentation.Unassociated), true); /// public override PixelTypeInfo GetPixelTypeInfo() => LazyInfo.Value; @@ -34,7 +34,7 @@ public override void ToVector4( { Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationVectors, nameof(destinationVectors)); - destinationVectors = destinationVectors.Slice(0, sourcePixels.Length); + destinationVectors = destinationVectors[..sourcePixels.Length]; SimdUtils.ByteToNormalizedFloat( MemoryMarshal.Cast(sourcePixels), MemoryMarshal.Cast(destinationVectors)); @@ -50,7 +50,7 @@ public override void FromVector4Destructive( { Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationPixels, nameof(destinationPixels)); - destinationPixels = destinationPixels.Slice(0, sourceVectors.Length); + destinationPixels = destinationPixels[..sourceVectors.Length]; Vector4Converters.ApplyBackwardConversionModifiers(sourceVectors, modifiers); SimdUtils.NormalizedFloatToByteSaturate( MemoryMarshal.Cast(sourceVectors), @@ -59,17 +59,15 @@ public override void FromVector4Destructive( /// internal override void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, Span destination) { - Guard.NotNull(configuration, nameof(configuration)); int count = redChannel.Length; GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); - SimdUtils.PackFromRgbPlanes(configuration, redChannel, greenChannel, blueChannel, destination); + SimdUtils.PackFromRgbPlanes(redChannel, greenChannel, blueChannel, destination); } } } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs index 96d4579c7f..240e85ff15 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs @@ -59,7 +59,7 @@ public Rgb24(byte r, byte g, byte b) /// The . /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Color(Rgb24 source) => new Color(source); + public static implicit operator Color(Rgb24 source) => new(source); /// /// Converts a to . @@ -210,17 +210,7 @@ public void FromLa32(La32 source) /// [MethodImpl(InliningOptions.ShortMethod)] - public void FromRgba32(Rgba32 source) - { -#if NETSTANDARD2_0 - // See https://github.com/SixLabors/ImageSharp/issues/1275 - this.R = source.R; - this.G = source.G; - this.B = source.B; -#else - this = source.Rgb; -#endif - } + public void FromRgba32(Rgba32 source) => this = source.Rgb; /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs index 599857961c..d15a46d698 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs @@ -240,6 +240,7 @@ public static implicit operator Rgba32(ColorSpaces.Rgb color) /// /// The . /// + /// Hexadecimal string is not in the correct format. [MethodImpl(InliningOptions.ShortMethod)] public static Rgba32 ParseHex(string hex) { @@ -432,7 +433,7 @@ public void FromRgba64(Rgba64 source) public readonly string ToHex() { uint hexOrder = (uint)((this.A << 0) | (this.B << 8) | (this.G << 16) | (this.R << 24)); - return hexOrder.ToString("X8"); + return hexOrder.ToString("X8", CultureInfo.InvariantCulture); } /// @@ -517,7 +518,7 @@ private static string ToRgbaHex(string hex) { if (hex[0] == '#') { - hex = hex.Substring(1); + hex = hex[1..]; } if (hex.Length == 8) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs index 93037fcbce..7973ee3dc9 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Globalization; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -188,7 +189,7 @@ public readonly string ToHex() Vector4 vector = this.ToVector4() * Max; vector += Half; uint hexOrder = (uint)((byte)vector.W | ((byte)vector.Z << 8) | ((byte)vector.Y << 16) | ((byte)vector.X << 24)); - return hexOrder.ToString("X8"); + return hexOrder.ToString("X8", CultureInfo.InvariantCulture); } /// diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index db8c98733c..0662ffb71a 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -20,11 +20,14 @@ public partial class PixelOperations where TPixel : unmanaged, IPixel { private static readonly Lazy LazyInfo = new(() => PixelTypeInfo.Create(), true); + private static readonly Lazy> LazyInstance = new(() => default(TPixel).CreatePixelOperations(), true); /// /// Gets the global instance for the pixel type /// - public static PixelOperations Instance { get; } = default(TPixel).CreatePixelOperations(); +#pragma warning disable CA1000 // Do not declare static members on generic types + public static PixelOperations Instance => LazyInstance.Value; +#pragma warning restore CA1000 // Do not declare static members on generic types /// /// Gets the pixel type info for the given . @@ -134,9 +137,9 @@ public virtual void From( int remainder = sourcePixels.Length - endOfCompleteSlices; if (remainder > 0) { - ReadOnlySpan s = sourcePixels.Slice(endOfCompleteSlices); - Span d = destinationPixels.Slice(endOfCompleteSlices); - vectorSpan = vectorSpan.Slice(0, remainder); + ReadOnlySpan s = sourcePixels[endOfCompleteSlices..]; + Span d = destinationPixels[endOfCompleteSlices..]; + vectorSpan = vectorSpan[..remainder]; PixelOperations.Instance.ToVector4(configuration, s, vectorSpan, PixelConversionModifiers.Scale); this.FromVector4Destructive(configuration, vectorSpan, d, PixelConversionModifiers.Scale); } @@ -166,20 +169,16 @@ public virtual void To( /// Bulk operation that packs 3 seperate RGB channels to . /// The destination must have a padding of 3. /// - /// A to configure internal operations. /// A to the red values. /// A to the green values. /// A to the blue values. /// A to the destination pixels. internal virtual void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, Span destination) { - Guard.NotNull(configuration, nameof(configuration)); - int count = redChannel.Length; GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs index 38250b24a5..92007732dc 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -56,7 +56,7 @@ internal static void ToVector4( // Using the last quarter of 'destVectors' as a temporary buffer to avoid allocation: int countWithoutLastItem = count - 1; - ReadOnlySpan reducedSource = sourcePixels.Slice(0, countWithoutLastItem); + ReadOnlySpan reducedSource = sourcePixels[..countWithoutLastItem]; Span lastQuarterOfDestBuffer = MemoryMarshal.Cast(destVectors).Slice((3 * count) + 1, countWithoutLastItem); pixelOperations.ToRgba32(configuration, reducedSource, lastQuarterOfDestBuffer); @@ -64,7 +64,7 @@ internal static void ToVector4( // but we are always reading/writing at different positions: SimdUtils.ByteToNormalizedFloat( MemoryMarshal.Cast(lastQuarterOfDestBuffer), - MemoryMarshal.Cast(destVectors.Slice(0, countWithoutLastItem))); + MemoryMarshal.Cast(destVectors[..countWithoutLastItem])); destVectors[countWithoutLastItem] = sourcePixels[countWithoutLastItem].ToVector4(); diff --git a/src/ImageSharp/Primitives/DenseMatrix{T}.cs b/src/ImageSharp/Primitives/DenseMatrix{T}.cs index 471e4f6b22..7eee4a1b08 100644 --- a/src/ImageSharp/Primitives/DenseMatrix{T}.cs +++ b/src/ImageSharp/Primitives/DenseMatrix{T}.cs @@ -16,31 +16,6 @@ namespace SixLabors.ImageSharp public readonly struct DenseMatrix : IEquatable> where T : struct, IEquatable { - /// - /// The 1D representation of the dense matrix. - /// - public readonly T[] Data; - - /// - /// Gets the number of columns in the dense matrix. - /// - public readonly int Columns; - - /// - /// Gets the number of rows in the dense matrix. - /// - public readonly int Rows; - - /// - /// Gets the size of the dense matrix. - /// - public readonly Size Size; - - /// - /// Gets the number of items in the array. - /// - public readonly int Count; - /// /// Initializes a new instance of the struct. /// @@ -96,10 +71,35 @@ public DenseMatrix(T[,] data) } } + /// + /// Gets the 1D representation of the dense matrix. + /// + public readonly T[] Data { get; } + + /// + /// Gets the number of columns in the dense matrix. + /// + public readonly int Columns { get; } + + /// + /// Gets the number of rows in the dense matrix. + /// + public readonly int Rows { get; } + + /// + /// Gets the size of the dense matrix. + /// + public readonly Size Size { get; } + + /// + /// Gets the number of items in the array. + /// + public readonly int Count { get; } + /// /// Gets a span wrapping the . /// - public Span Span => new Span(this.Data); + public Span Span => new(this.Data); /// /// Gets or sets the item at the specified position. @@ -125,7 +125,7 @@ public DenseMatrix(T[,] data) /// The representation on the source data. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator DenseMatrix(T[,] data) => new DenseMatrix(data); + public static implicit operator DenseMatrix(T[,] data) => new(data); /// /// Performs an implicit conversion from a to a . @@ -139,7 +139,7 @@ public DenseMatrix(T[,] data) public static implicit operator T[,](in DenseMatrix data) #pragma warning restore SA1008 // Opening parenthesis should be spaced correctly { - var result = new T[data.Rows, data.Columns]; + T[,] result = new T[data.Rows, data.Columns]; for (int y = 0; y < data.Rows; y++) { @@ -178,7 +178,7 @@ public DenseMatrix(T[,] data) [MethodImpl(MethodImplOptions.AggressiveInlining)] public DenseMatrix Transpose() { - var result = new DenseMatrix(this.Rows, this.Columns); + DenseMatrix result = new DenseMatrix(this.Rows, this.Columns); for (int y = 0; y < this.Rows; y++) { diff --git a/src/ImageSharp/Primitives/LongRational.cs b/src/ImageSharp/Primitives/LongRational.cs index a181084aa1..062036a57f 100644 --- a/src/ImageSharp/Primitives/LongRational.cs +++ b/src/ImageSharp/Primitives/LongRational.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; @@ -66,23 +66,21 @@ public LongRational(long numerator, long denominator) /// public bool IsZero => this.Denominator == 1 && this.Numerator == 0; + /// + public override bool Equals(object obj) + => obj is LongRational longRational && this.Equals(longRational); + /// public bool Equals(LongRational other) - { - return this.Numerator == other.Numerator && this.Denominator == other.Denominator; - } + => this.Numerator == other.Numerator && this.Denominator == other.Denominator; /// public override int GetHashCode() - { - return ((this.Numerator * 397) ^ this.Denominator).GetHashCode(); - } + => HashCode.Combine(this.Numerator, this.Denominator); /// public override string ToString() - { - return this.ToString(CultureInfo.InvariantCulture); - } + => this.ToString(CultureInfo.InvariantCulture); /// /// Converts the numeric value of this instance to its equivalent string representation using @@ -119,10 +117,11 @@ public string ToString(IFormatProvider provider) return this.Numerator.ToString(provider); } - var sb = new StringBuilder(); - sb.Append(this.Numerator.ToString(provider)); - sb.Append('/'); - sb.Append(this.Denominator.ToString(provider)); + StringBuilder sb = new(); + sb.Append(this.Numerator.ToString(provider)) + .Append('/') + .Append(this.Denominator.ToString(provider)); + return sb.ToString(); } diff --git a/src/ImageSharp/Primitives/Point.cs b/src/ImageSharp/Primitives/Point.cs index 89db9befbb..356595cb4d 100644 --- a/src/ImageSharp/Primitives/Point.cs +++ b/src/ImageSharp/Primitives/Point.cs @@ -21,7 +21,7 @@ public struct Point : IEquatable /// /// Represents a that has X and Y values set to zero. /// - public static readonly Point Empty = default; + public static readonly Point Empty; /// /// Initializes a new instance of the struct. @@ -77,28 +77,28 @@ public Point(Size size) /// /// The point. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator PointF(Point point) => new PointF(point.X, point.Y); + public static implicit operator PointF(Point point) => new(point.X, point.Y); /// /// Creates a with the coordinates of the specified . /// /// The point. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2(Point point) => new Vector2(point.X, point.Y); + public static implicit operator Vector2(Point point) => new(point.X, point.Y); /// /// Creates a with the coordinates of the specified . /// /// The point. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Size(Point point) => new Size(point.X, point.Y); + public static explicit operator Size(Point point) => new(point.X, point.Y); /// /// Negates the given point by multiplying all values by -1. /// /// The source point. /// The negated point. - public static Point operator -(Point value) => new Point(-value.X, -value.Y); + public static Point operator -(Point value) => new(-value.X, -value.Y); /// /// Translates a by a given . @@ -143,7 +143,7 @@ public Point(Size size) /// Divisor of type . /// Result of type . public static Point operator /(Point left, int right) - => new Point(left.X / right, left.Y / right); + => new(left.X / right, left.Y / right); /// /// Compares two objects for equality. @@ -174,7 +174,7 @@ public Point(Size size) /// The size on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Point Add(Point point, Size size) => new Point(unchecked(point.X + size.Width), unchecked(point.Y + size.Height)); + public static Point Add(Point point, Size size) => new(unchecked(point.X + size.Width), unchecked(point.Y + size.Height)); /// /// Translates a by the negative of a given value. @@ -183,7 +183,7 @@ public Point(Size size) /// The value on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Point Multiply(Point point, int value) => new Point(unchecked(point.X * value), unchecked(point.Y * value)); + public static Point Multiply(Point point, int value) => new(unchecked(point.X * value), unchecked(point.Y * value)); /// /// Translates a by the negative of a given . @@ -192,7 +192,7 @@ public Point(Size size) /// The size on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Point Subtract(Point point, Size size) => new Point(unchecked(point.X - size.Width), unchecked(point.Y - size.Height)); + public static Point Subtract(Point point, Size size) => new(unchecked(point.X - size.Width), unchecked(point.Y - size.Height)); /// /// Converts a to a by performing a ceiling operation on all the coordinates. @@ -200,7 +200,7 @@ public Point(Size size) /// The point. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Point Ceiling(PointF point) => new Point(unchecked((int)MathF.Ceiling(point.X)), unchecked((int)MathF.Ceiling(point.Y))); + public static Point Ceiling(PointF point) => new(unchecked((int)MathF.Ceiling(point.X)), unchecked((int)MathF.Ceiling(point.Y))); /// /// Converts a to a by performing a round operation on all the coordinates. @@ -208,7 +208,7 @@ public Point(Size size) /// The point. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Point Round(PointF point) => new Point(unchecked((int)MathF.Round(point.X)), unchecked((int)MathF.Round(point.Y))); + public static Point Round(PointF point) => new(unchecked((int)MathF.Round(point.X)), unchecked((int)MathF.Round(point.Y))); /// /// Converts a to a by performing a round operation on all the coordinates. @@ -216,7 +216,7 @@ public Point(Size size) /// The vector. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Point Round(Vector2 vector) => new Point(unchecked((int)MathF.Round(vector.X)), unchecked((int)MathF.Round(vector.Y))); + public static Point Round(Vector2 vector) => new(unchecked((int)MathF.Round(vector.X)), unchecked((int)MathF.Round(vector.Y))); /// /// Converts a to a by performing a truncate operation on all the coordinates. @@ -224,7 +224,7 @@ public Point(Size size) /// The point. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Point Truncate(PointF point) => new Point(unchecked((int)point.X), unchecked((int)point.Y)); + public static Point Truncate(PointF point) => new(unchecked((int)point.X), unchecked((int)point.Y)); /// /// Transforms a point by a specified 3x2 matrix. diff --git a/src/ImageSharp/Primitives/PointF.cs b/src/ImageSharp/Primitives/PointF.cs index 9817f04f3e..d701f3d541 100644 --- a/src/ImageSharp/Primitives/PointF.cs +++ b/src/ImageSharp/Primitives/PointF.cs @@ -21,7 +21,7 @@ public struct PointF : IEquatable /// /// Represents a that has X and Y values set to zero. /// - public static readonly PointF Empty = default; + public static readonly PointF Empty; /// /// Initializes a new instance of the struct. @@ -69,7 +69,7 @@ public PointF(SizeF size) /// The . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator PointF(Vector2 vector) => new PointF(vector.X, vector.Y); + public static implicit operator PointF(Vector2 vector) => new(vector.X, vector.Y); /// /// Creates a with the coordinates of the specified . @@ -79,7 +79,7 @@ public PointF(SizeF size) /// The . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2(PointF point) => new Vector2(point.X, point.Y); + public static implicit operator Vector2(PointF point) => new(point.X, point.Y); /// /// Creates a with the coordinates of the specified by truncating each of the coordinates. @@ -96,7 +96,7 @@ public PointF(SizeF size) /// /// The source point. /// The negated point. - public static PointF operator -(PointF value) => new PointF(-value.X, -value.Y); + public static PointF operator -(PointF value) => new(-value.X, -value.Y); /// /// Translates a by a given . @@ -161,7 +161,7 @@ public PointF(SizeF size) /// Divisor of type . /// Result of type . public static PointF operator /(PointF left, float right) - => new PointF(left.X / right, left.Y / right); + => new(left.X / right, left.Y / right); /// /// Compares two objects for equality. @@ -200,7 +200,7 @@ public PointF(SizeF size) /// The size on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PointF Add(PointF point, SizeF size) => new PointF(point.X + size.Width, point.Y + size.Height); + public static PointF Add(PointF point, SizeF size) => new(point.X + size.Width, point.Y + size.Height); /// /// Translates a by the given . @@ -209,7 +209,7 @@ public PointF(SizeF size) /// The point on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PointF Add(PointF point, PointF pointb) => new PointF(point.X + pointb.X, point.Y + pointb.Y); + public static PointF Add(PointF point, PointF pointb) => new(point.X + pointb.X, point.Y + pointb.Y); /// /// Translates a by the negative of a given . @@ -218,7 +218,7 @@ public PointF(SizeF size) /// The size on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PointF Subtract(PointF point, SizeF size) => new PointF(point.X - size.Width, point.Y - size.Height); + public static PointF Subtract(PointF point, SizeF size) => new(point.X - size.Width, point.Y - size.Height); /// /// Translates a by the negative of a given . @@ -227,7 +227,7 @@ public PointF(SizeF size) /// The point on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PointF Subtract(PointF point, PointF pointb) => new PointF(point.X - pointb.X, point.Y - pointb.Y); + public static PointF Subtract(PointF point, PointF pointb) => new(point.X - pointb.X, point.Y - pointb.Y); /// /// Translates a by the multiplying the X and Y by the given value. @@ -236,7 +236,7 @@ public PointF(SizeF size) /// The value on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PointF Multiply(PointF point, float right) => new PointF(point.X * right, point.Y * right); + public static PointF Multiply(PointF point, float right) => new(point.X * right, point.Y * right); /// /// Transforms a point by a specified 3x2 matrix. @@ -284,7 +284,7 @@ public void Offset(float dx, float dy) public override string ToString() => $"PointF [ X={this.X}, Y={this.Y} ]"; /// - public override bool Equals(object obj) => obj is PointF && this.Equals((PointF)obj); + public override bool Equals(object obj) => obj is PointF pointF && this.Equals(pointF); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ImageSharp/Primitives/Rectangle.cs b/src/ImageSharp/Primitives/Rectangle.cs index 4c70e0dd9a..b21aae1fe0 100644 --- a/src/ImageSharp/Primitives/Rectangle.cs +++ b/src/ImageSharp/Primitives/Rectangle.cs @@ -20,7 +20,7 @@ public struct Rectangle : IEquatable /// /// Represents a that has X, Y, Width, and Height values set to zero. /// - public static readonly Rectangle Empty = default; + public static readonly Rectangle Empty; /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Primitives/RectangleF.cs b/src/ImageSharp/Primitives/RectangleF.cs index aa6f4fc236..9719d2b7e3 100644 --- a/src/ImageSharp/Primitives/RectangleF.cs +++ b/src/ImageSharp/Primitives/RectangleF.cs @@ -20,7 +20,7 @@ public struct RectangleF : IEquatable /// /// Represents a that has X, Y, Width, and Height values set to zero. /// - public static readonly RectangleF Empty = default; + public static readonly RectangleF Empty; /// /// Initializes a new instance of the struct. @@ -81,7 +81,7 @@ public RectangleF(PointF point, SizeF size) public PointF Location { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new PointF(this.X, this.Y); + get => new(this.X, this.Y); [MethodImpl(MethodImplOptions.AggressiveInlining)] set @@ -98,7 +98,7 @@ public PointF Location public SizeF Size { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new SizeF(this.Width, this.Height); + get => new(this.Width, this.Height); [MethodImpl(MethodImplOptions.AggressiveInlining)] set @@ -181,7 +181,7 @@ public float Bottom [MethodImpl(MethodImplOptions.AggressiveInlining)] // ReSharper disable once InconsistentNaming - public static RectangleF FromLTRB(float left, float top, float right, float bottom) => new RectangleF(left, top, right - left, bottom - top); + public static RectangleF FromLTRB(float left, float top, float right, float bottom) => new(left, top, right - left, bottom - top); /// /// Returns the center point of the given . @@ -189,7 +189,7 @@ public float Bottom /// The rectangle. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static PointF Center(RectangleF rectangle) => new PointF(rectangle.Left + (rectangle.Width / 2), rectangle.Top + (rectangle.Height / 2)); + public static PointF Center(RectangleF rectangle) => new(rectangle.Left + (rectangle.Width / 2), rectangle.Top + (rectangle.Height / 2)); /// /// Creates a rectangle that represents the intersection between and @@ -372,15 +372,11 @@ public void Offset(float dx, float dy) /// public override int GetHashCode() - { - return HashCode.Combine(this.X, this.Y, this.Width, this.Height); - } + => HashCode.Combine(this.X, this.Y, this.Width, this.Height); /// public override string ToString() - { - return $"RectangleF [ X={this.X}, Y={this.Y}, Width={this.Width}, Height={this.Height} ]"; - } + => $"RectangleF [ X={this.X}, Y={this.Y}, Width={this.Width}, Height={this.Height} ]"; /// public override bool Equals(object obj) => obj is RectangleF other && this.Equals(other); diff --git a/src/ImageSharp/Primitives/Size.cs b/src/ImageSharp/Primitives/Size.cs index 83bd392139..0e55b6845e 100644 --- a/src/ImageSharp/Primitives/Size.cs +++ b/src/ImageSharp/Primitives/Size.cs @@ -20,7 +20,7 @@ public struct Size : IEquatable /// /// Represents a that has Width and Height values set to zero. /// - public static readonly Size Empty = default; + public static readonly Size Empty; /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Primitives/SizeF.cs b/src/ImageSharp/Primitives/SizeF.cs index 4e2fba4e9f..fed62e5120 100644 --- a/src/ImageSharp/Primitives/SizeF.cs +++ b/src/ImageSharp/Primitives/SizeF.cs @@ -20,7 +20,7 @@ public struct SizeF : IEquatable /// /// Represents a that has Width and Height values set to zero. /// - public static readonly SizeF Empty = default; + public static readonly SizeF Empty; /// /// Initializes a new instance of the struct. @@ -78,7 +78,7 @@ public SizeF(PointF point) /// The . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2(SizeF point) => new Vector2(point.Width, point.Height); + public static implicit operator Vector2(SizeF point) => new(point.Width, point.Height); /// /// Creates a with the dimensions of the specified by truncating each of the dimensions. @@ -88,14 +88,14 @@ public SizeF(PointF point) /// The . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator Size(SizeF size) => new Size(unchecked((int)size.Width), unchecked((int)size.Height)); + public static explicit operator Size(SizeF size) => new(unchecked((int)size.Width), unchecked((int)size.Height)); /// /// Converts the given into a . /// /// The size. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static explicit operator PointF(SizeF size) => new PointF(size.Width, size.Height); + public static explicit operator PointF(SizeF size) => new(size.Width, size.Height); /// /// Computes the sum of adding two sizes. @@ -142,7 +142,7 @@ public SizeF(PointF point) /// Divisor of type . /// Result of type . public static SizeF operator /(SizeF left, float right) - => new SizeF(left.Width / right, left.Height / right); + => new(left.Width / right, left.Height / right); /// /// Compares two objects for equality. @@ -173,7 +173,7 @@ public SizeF(PointF point) /// The size on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SizeF Add(SizeF left, SizeF right) => new SizeF(left.Width + right.Width, left.Height + right.Height); + public static SizeF Add(SizeF left, SizeF right) => new(left.Width + right.Width, left.Height + right.Height); /// /// Contracts a by another . @@ -182,7 +182,7 @@ public SizeF(PointF point) /// The size on the right hand of the operand. /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SizeF Subtract(SizeF left, SizeF right) => new SizeF(left.Width - right.Width, left.Height - right.Height); + public static SizeF Subtract(SizeF left, SizeF right) => new(left.Width - right.Width, left.Height - right.Height); /// /// Transforms a size by the given matrix. @@ -228,6 +228,6 @@ public void Deconstruct(out float width, out float height) /// Multiplier of type . /// Product of type SizeF. private static SizeF Multiply(SizeF size, float multiplier) => - new SizeF(size.Width * multiplier, size.Height * multiplier); + new(size.Width * multiplier, size.Height * multiplier); } } diff --git a/src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs index eb36183ad1..e0221f8152 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs @@ -295,8 +295,8 @@ public ApplyGammaExposureRowOperation( [MethodImpl(InliningOptions.ShortMethod)] public void Invoke(int y, Span span) { - Span targetRowSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X); - PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Premultiply); + Span targetRowSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..]; + PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan[..span.Length], span, PixelConversionModifiers.Premultiply); ref Vector4 baseRef = ref MemoryMarshal.GetReference(span); for (int x = 0; x < this.bounds.Width; x++) @@ -335,9 +335,9 @@ public ApplyGamma3ExposureRowOperation( [MethodImpl(InliningOptions.ShortMethod)] public void Invoke(int y, Span span) { - Span targetRowSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X); + Span targetRowSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..]; - PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Premultiply); + PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan[..span.Length], span, PixelConversionModifiers.Premultiply); Numerics.CubePowOnXYZ(span); @@ -378,8 +378,8 @@ public void Invoke(int y) Vector4 low = Vector4.Zero; var high = new Vector4(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); - Span targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X); - Span sourceRowSpan = this.sourceValues.DangerousGetRowSpan(y).Slice(this.bounds.X); + Span targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..]; + Span sourceRowSpan = this.sourceValues.DangerousGetRowSpan(y)[this.bounds.X..]; ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceRowSpan); for (int x = 0; x < this.bounds.Width; x++) @@ -391,7 +391,7 @@ public void Invoke(int y) v.Z = MathF.Pow(clamp.Z, this.inverseGamma); } - PixelOperations.Instance.FromVector4Destructive(this.configuration, sourceRowSpan.Slice(0, this.bounds.Width), targetPixelSpan, PixelConversionModifiers.Premultiply); + PixelOperations.Instance.FromVector4Destructive(this.configuration, sourceRowSpan[..this.bounds.Width], targetPixelSpan, PixelConversionModifiers.Premultiply); } } @@ -428,9 +428,9 @@ public unsafe void Invoke(int y) Numerics.Clamp(MemoryMarshal.Cast(sourceRowSpan), 0, float.PositiveInfinity); Numerics.CubeRootOnXYZ(sourceRowSpan); - Span targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X); + Span targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..]; - PixelOperations.Instance.FromVector4Destructive(this.configuration, sourceRowSpan.Slice(0, this.bounds.Width), targetPixelSpan, PixelConversionModifiers.Premultiply); + PixelOperations.Instance.FromVector4Destructive(this.configuration, sourceRowSpan[..this.bounds.Width], targetPixelSpan, PixelConversionModifiers.Premultiply); } } } diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs index 5ccaa77c47..8b4eaab801 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs @@ -67,7 +67,7 @@ private void Convolve3(int y, Span span) // Span is 3x bounds. int boundsX = this.bounds.X; int boundsWidth = this.bounds.Width; - Span sourceBuffer = span.Slice(0, boundsWidth); + Span sourceBuffer = span[..boundsWidth]; Span targetYBuffer = span.Slice(boundsWidth, boundsWidth); Span targetXBuffer = span.Slice(boundsWidth * 2, boundsWidth); @@ -133,7 +133,7 @@ private void Convolve4(int y, Span span) // Span is 3x bounds. int boundsX = this.bounds.X; int boundsWidth = this.bounds.Width; - Span sourceBuffer = span.Slice(0, boundsWidth); + Span sourceBuffer = span[..boundsWidth]; Span targetYBuffer = span.Slice(boundsWidth, boundsWidth); Span targetXBuffer = span.Slice(boundsWidth * 2, boundsWidth); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs index db9557124a..697351abc4 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs @@ -166,8 +166,8 @@ private void Convolve3(int y, Span span) int boundsWidth = this.bounds.Width; int kernelSize = this.kernel.Length; - Span sourceBuffer = span.Slice(0, this.bounds.Width); - Span targetBuffer = span.Slice(this.bounds.Width); + Span sourceBuffer = span[..this.bounds.Width]; + Span targetBuffer = span[this.bounds.Width..]; // Clear the target buffer for each row run. targetBuffer.Clear(); @@ -228,8 +228,8 @@ private void Convolve4(int y, Span span) int boundsWidth = this.bounds.Width; int kernelSize = this.kernel.Length; - Span sourceBuffer = span.Slice(0, this.bounds.Width); - Span targetBuffer = span.Slice(this.bounds.Width); + Span sourceBuffer = span[..this.bounds.Width]; + Span targetBuffer = span[this.bounds.Width..]; // Clear the target buffer for each row run. targetBuffer.Clear(); @@ -327,8 +327,8 @@ private void Convolve3(int y, Span span) int boundsWidth = this.bounds.Width; int kernelSize = this.kernel.Length; - Span sourceBuffer = span.Slice(0, this.bounds.Width); - Span targetBuffer = span.Slice(this.bounds.Width); + Span sourceBuffer = span[..this.bounds.Width]; + Span targetBuffer = span[this.bounds.Width..]; ref int sampleRowBase = ref Unsafe.Add(ref MemoryMarshal.GetReference(this.map.GetRowOffsetSpan()), (y - this.bounds.Y) * kernelSize); @@ -392,8 +392,8 @@ private void Convolve4(int y, Span span) int boundsWidth = this.bounds.Width; int kernelSize = this.kernel.Length; - Span sourceBuffer = span.Slice(0, this.bounds.Width); - Span targetBuffer = span.Slice(this.bounds.Width); + Span sourceBuffer = span[..this.bounds.Width]; + Span targetBuffer = span[this.bounds.Width..]; ref int sampleRowBase = ref Unsafe.Add(ref MemoryMarshal.GetReference(this.map.GetRowOffsetSpan()), (y - this.bounds.Y) * kernelSize); diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs index fa0a012296..ed8b63ab2e 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs @@ -114,8 +114,8 @@ public void Invoke(int y, Span span) // Span is 2x bounds. int boundsX = this.bounds.X; int boundsWidth = this.bounds.Width; - Span sourceBuffer = span.Slice(0, this.bounds.Width); - Span targetBuffer = span.Slice(this.bounds.Width); + Span sourceBuffer = span[..this.bounds.Width]; + Span targetBuffer = span[this.bounds.Width..]; ref Vector4 targetRowRef = ref MemoryMarshal.GetReference(span); Span targetRowSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(boundsX, boundsWidth); diff --git a/src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs b/src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs index 06d4a27556..a4ae9cb4c6 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs @@ -60,8 +60,8 @@ public void BuildSamplingOffsetMap(int kernelHeight, int kernelWidth, Rectangle int minX = bounds.X; int maxX = bounds.Right - 1; - this.BuildOffsets(this.yOffsets, bounds.Height, kernelHeight, minY, maxY, yBorderMode); - this.BuildOffsets(this.xOffsets, bounds.Width, kernelWidth, minX, maxX, xBorderMode); + BuildOffsets(this.yOffsets, bounds.Height, kernelHeight, minY, maxY, yBorderMode); + BuildOffsets(this.xOffsets, bounds.Width, kernelWidth, minX, maxX, xBorderMode); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -83,7 +83,7 @@ public void Dispose() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void BuildOffsets(IMemoryOwner offsets, int boundsSize, int kernelSize, int min, int max, BorderWrappingMode borderMode) + private static void BuildOffsets(IMemoryOwner offsets, int boundsSize, int kernelSize, int min, int max, BorderWrappingMode borderMode) { int radius = kernelSize >> 1; Span span = offsets.GetSpan(); @@ -97,37 +97,37 @@ private void BuildOffsets(IMemoryOwner offsets, int boundsSize, int kernelS } } - this.CorrectBorder(span, kernelSize, min, max, borderMode); + CorrectBorder(span, kernelSize, min, max, borderMode); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void CorrectBorder(Span span, int kernelSize, int min, int max, BorderWrappingMode borderMode) + private static void CorrectBorder(Span span, int kernelSize, int min, int max, BorderWrappingMode borderMode) { - var affectedSize = (kernelSize >> 1) * kernelSize; + int affectedSize = (kernelSize >> 1) * kernelSize; ref int spanBase = ref MemoryMarshal.GetReference(span); if (affectedSize > 0) { switch (borderMode) { case BorderWrappingMode.Repeat: - Numerics.Clamp(span.Slice(0, affectedSize), min, max); - Numerics.Clamp(span.Slice(span.Length - affectedSize), min, max); + Numerics.Clamp(span[..affectedSize], min, max); + Numerics.Clamp(span[^affectedSize..], min, max); break; case BorderWrappingMode.Mirror: - var min2dec = min + min - 1; + int min2dec = min + min - 1; for (int i = 0; i < affectedSize; i++) { - var value = span[i]; + int value = span[i]; if (value < min) { span[i] = min2dec - value; } } - var max2inc = max + max + 1; + int max2inc = max + max + 1; for (int i = span.Length - affectedSize; i < span.Length; i++) { - var value = span[i]; + int value = span[i]; if (value > max) { span[i] = max2inc - value; @@ -136,20 +136,20 @@ private void CorrectBorder(Span span, int kernelSize, int min, int max, Bor break; case BorderWrappingMode.Bounce: - var min2 = min + min; + int min2 = min + min; for (int i = 0; i < affectedSize; i++) { - var value = span[i]; + int value = span[i]; if (value < min) { span[i] = min2 - value; } } - var max2 = max + max; + int max2 = max + max; for (int i = span.Length - affectedSize; i < span.Length; i++) { - var value = span[i]; + int value = span[i]; if (value > max) { span[i] = max2 - value; @@ -158,10 +158,10 @@ private void CorrectBorder(Span span, int kernelSize, int min, int max, Bor break; case BorderWrappingMode.Wrap: - var diff = max - min + 1; + int diff = max - min + 1; for (int i = 0; i < affectedSize; i++) { - var value = span[i]; + int value = span[i]; if (value < min) { span[i] = diff + value; @@ -170,7 +170,7 @@ private void CorrectBorder(Span span, int kernelSize, int min, int max, Bor for (int i = span.Length - affectedSize; i < span.Length; i++) { - var value = span[i]; + int value = span[i]; if (value > max) { span[i] = value - diff; diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs index 90c2575fc2..ff1bba22d2 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetector2DKernel.cs @@ -13,30 +13,30 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// /// An edge detection kernel containing two Kayyali operators. /// - public static EdgeDetector2DKernel KayyaliKernel = new EdgeDetector2DKernel(KayyaliKernels.KayyaliX, KayyaliKernels.KayyaliY); + public static readonly EdgeDetector2DKernel KayyaliKernel = new(KayyaliKernels.KayyaliX, KayyaliKernels.KayyaliY); /// /// An edge detection kernel containing two Prewitt operators. /// . /// - public static EdgeDetector2DKernel PrewittKernel = new EdgeDetector2DKernel(PrewittKernels.PrewittX, PrewittKernels.PrewittY); + public static readonly EdgeDetector2DKernel PrewittKernel = new(PrewittKernels.PrewittX, PrewittKernels.PrewittY); /// /// An edge detection kernel containing two Roberts-Cross operators. /// . /// - public static EdgeDetector2DKernel RobertsCrossKernel = new EdgeDetector2DKernel(RobertsCrossKernels.RobertsCrossX, RobertsCrossKernels.RobertsCrossY); + public static readonly EdgeDetector2DKernel RobertsCrossKernel = new(RobertsCrossKernels.RobertsCrossX, RobertsCrossKernels.RobertsCrossY); /// /// An edge detection kernel containing two Scharr operators. /// - public static EdgeDetector2DKernel ScharrKernel = new EdgeDetector2DKernel(ScharrKernels.ScharrX, ScharrKernels.ScharrY); + public static readonly EdgeDetector2DKernel ScharrKernel = new(ScharrKernels.ScharrX, ScharrKernels.ScharrY); /// /// An edge detection kernel containing two Sobel operators. /// . /// - public static EdgeDetector2DKernel SobelKernel = new EdgeDetector2DKernel(SobelKernels.SobelX, SobelKernels.SobelY); + public static readonly EdgeDetector2DKernel SobelKernel = new(SobelKernels.SobelX, SobelKernels.SobelY); /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs index 002f35c3d3..41d3c8ad24 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorCompassKernel.cs @@ -14,8 +14,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// An edge detection kenel comprised of Kirsch gradient operators. /// . /// - public static EdgeDetectorCompassKernel Kirsch = - new EdgeDetectorCompassKernel( + public static readonly EdgeDetectorCompassKernel Kirsch = + new( KirschKernels.North, KirschKernels.NorthWest, KirschKernels.West, @@ -29,8 +29,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// An edge detection kenel comprised of Robinson gradient operators. /// /// - public static EdgeDetectorCompassKernel Robinson = - new EdgeDetectorCompassKernel( + public static readonly EdgeDetectorCompassKernel Robinson = + new( RobinsonKernels.North, RobinsonKernels.NorthWest, RobinsonKernels.West, diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs index 0640884324..25007846c9 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/EdgeDetectorKernel.cs @@ -14,19 +14,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// An edge detection kernel containing a 3x3 Laplacian operator. /// /// - public static EdgeDetectorKernel Laplacian3x3 = new EdgeDetectorKernel(LaplacianKernels.Laplacian3x3); + public static readonly EdgeDetectorKernel Laplacian3x3 = new(LaplacianKernels.Laplacian3x3); /// /// An edge detection kernel containing a 5x5 Laplacian operator. /// /// - public static EdgeDetectorKernel Laplacian5x5 = new EdgeDetectorKernel(LaplacianKernels.Laplacian5x5); + public static readonly EdgeDetectorKernel Laplacian5x5 = new(LaplacianKernels.Laplacian5x5); /// /// An edge detection kernel containing a Laplacian of Gaussian operator. /// . /// - public static EdgeDetectorKernel LaplacianOfGaussian = new EdgeDetectorKernel(LaplacianKernels.LaplacianOfGaussianXY); + public static readonly EdgeDetectorKernel LaplacianOfGaussian = new(LaplacianKernels.LaplacianOfGaussianXY); /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs b/src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs index 435cafb520..2c9ce24194 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs @@ -11,178 +11,178 @@ public readonly partial struct ErrorDither /// /// Applies error diffusion based dithering using the Atkinson image dithering algorithm. /// - public static ErrorDither Atkinson = CreateAtkinson(); + public static readonly ErrorDither Atkinson = CreateAtkinson(); /// /// Applies error diffusion based dithering using the Burks image dithering algorithm. /// - public static ErrorDither Burkes = CreateBurks(); + public static readonly ErrorDither Burkes = CreateBurks(); /// /// Applies error diffusion based dithering using the Floyd–Steinberg image dithering algorithm. /// - public static ErrorDither FloydSteinberg = CreateFloydSteinberg(); + public static readonly ErrorDither FloydSteinberg = CreateFloydSteinberg(); /// /// Applies error diffusion based dithering using the Jarvis, Judice, Ninke image dithering algorithm. /// - public static ErrorDither JarvisJudiceNinke = CreateJarvisJudiceNinke(); + public static readonly ErrorDither JarvisJudiceNinke = CreateJarvisJudiceNinke(); /// /// Applies error diffusion based dithering using the Sierra2 image dithering algorithm. /// - public static ErrorDither Sierra2 = CreateSierra2(); + public static readonly ErrorDither Sierra2 = CreateSierra2(); /// /// Applies error diffusion based dithering using the Sierra3 image dithering algorithm. /// - public static ErrorDither Sierra3 = CreateSierra3(); + public static readonly ErrorDither Sierra3 = CreateSierra3(); /// /// Applies error diffusion based dithering using the Sierra Lite image dithering algorithm. /// - public static ErrorDither SierraLite = CreateSierraLite(); + public static readonly ErrorDither SierraLite = CreateSierraLite(); /// /// Applies error diffusion based dithering using the Stevenson-Arce image dithering algorithm. /// - public static ErrorDither StevensonArce = CreateStevensonArce(); + public static readonly ErrorDither StevensonArce = CreateStevensonArce(); /// /// Applies error diffusion based dithering using the Stucki image dithering algorithm. /// - public static ErrorDither Stucki = CreateStucki(); + public static readonly ErrorDither Stucki = CreateStucki(); private static ErrorDither CreateAtkinson() { - const float Divisor = 8F; - const int Offset = 1; + const float divisor = 8F; + const int offset = 1; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 1 / Divisor, 1 / Divisor }, - { 1 / Divisor, 1 / Divisor, 1 / Divisor, 0 }, - { 0, 1 / Divisor, 0, 0 } + { 0, 0, 1 / divisor, 1 / divisor }, + { 1 / divisor, 1 / divisor, 1 / divisor, 0 }, + { 0, 1 / divisor, 0, 0 } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateBurks() { - const float Divisor = 32F; - const int Offset = 2; + const float divisor = 32F; + const int offset = 2; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 0, 8 / Divisor, 4 / Divisor }, - { 2 / Divisor, 4 / Divisor, 8 / Divisor, 4 / Divisor, 2 / Divisor } + { 0, 0, 0, 8 / divisor, 4 / divisor }, + { 2 / divisor, 4 / divisor, 8 / divisor, 4 / divisor, 2 / divisor } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateFloydSteinberg() { - const float Divisor = 16F; - const int Offset = 1; + const float divisor = 16F; + const int offset = 1; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 7 / Divisor }, - { 3 / Divisor, 5 / Divisor, 1 / Divisor } + { 0, 0, 7 / divisor }, + { 3 / divisor, 5 / divisor, 1 / divisor } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateJarvisJudiceNinke() { - const float Divisor = 48F; - const int Offset = 2; + const float divisor = 48F; + const int offset = 2; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 0, 7 / Divisor, 5 / Divisor }, - { 3 / Divisor, 5 / Divisor, 7 / Divisor, 5 / Divisor, 3 / Divisor }, - { 1 / Divisor, 3 / Divisor, 5 / Divisor, 3 / Divisor, 1 / Divisor } + { 0, 0, 0, 7 / divisor, 5 / divisor }, + { 3 / divisor, 5 / divisor, 7 / divisor, 5 / divisor, 3 / divisor }, + { 1 / divisor, 3 / divisor, 5 / divisor, 3 / divisor, 1 / divisor } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateSierra2() { - const float Divisor = 16F; - const int Offset = 2; + const float divisor = 16F; + const int offset = 2; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 0, 4 / Divisor, 3 / Divisor }, - { 1 / Divisor, 2 / Divisor, 3 / Divisor, 2 / Divisor, 1 / Divisor } + { 0, 0, 0, 4 / divisor, 3 / divisor }, + { 1 / divisor, 2 / divisor, 3 / divisor, 2 / divisor, 1 / divisor } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateSierra3() { - const float Divisor = 32F; - const int Offset = 2; + const float divisor = 32F; + const int offset = 2; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 0, 5 / Divisor, 3 / Divisor }, - { 2 / Divisor, 4 / Divisor, 5 / Divisor, 4 / Divisor, 2 / Divisor }, - { 0, 2 / Divisor, 3 / Divisor, 2 / Divisor, 0 } + { 0, 0, 0, 5 / divisor, 3 / divisor }, + { 2 / divisor, 4 / divisor, 5 / divisor, 4 / divisor, 2 / divisor }, + { 0, 2 / divisor, 3 / divisor, 2 / divisor, 0 } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateSierraLite() { - const float Divisor = 4F; - const int Offset = 1; + const float divisor = 4F; + const int offset = 1; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 2 / Divisor }, - { 1 / Divisor, 1 / Divisor, 0 } + { 0, 0, 2 / divisor }, + { 1 / divisor, 1 / divisor, 0 } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateStevensonArce() { - const float Divisor = 200F; - const int Offset = 3; + const float divisor = 200F; + const int offset = 3; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 0, 0, 0, 32 / Divisor, 0 }, - { 12 / Divisor, 0, 26 / Divisor, 0, 30 / Divisor, 0, 16 / Divisor }, - { 0, 12 / Divisor, 0, 26 / Divisor, 0, 12 / Divisor, 0 }, - { 5 / Divisor, 0, 12 / Divisor, 0, 12 / Divisor, 0, 5 / Divisor } + { 0, 0, 0, 0, 0, 32 / divisor, 0 }, + { 12 / divisor, 0, 26 / divisor, 0, 30 / divisor, 0, 16 / divisor }, + { 0, 12 / divisor, 0, 26 / divisor, 0, 12 / divisor, 0 }, + { 5 / divisor, 0, 12 / divisor, 0, 12 / divisor, 0, 5 / divisor } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } private static ErrorDither CreateStucki() { - const float Divisor = 42F; - const int Offset = 2; + const float divisor = 42F; + const int offset = 2; - var matrix = new float[,] + float[,] matrix = { - { 0, 0, 0, 8 / Divisor, 4 / Divisor }, - { 2 / Divisor, 4 / Divisor, 8 / Divisor, 4 / Divisor, 2 / Divisor }, - { 1 / Divisor, 2 / Divisor, 4 / Divisor, 2 / Divisor, 1 / Divisor } + { 0, 0, 0, 8 / divisor, 4 / divisor }, + { 2 / divisor, 4 / divisor, 8 / divisor, 4 / divisor, 2 / divisor }, + { 1 / divisor, 2 / divisor, 4 / divisor, 2 / divisor, 1 / divisor } }; - return new ErrorDither(matrix, Offset); + return new ErrorDither(matrix, offset); } } } diff --git a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs index a6838d246f..f036273c2e 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs @@ -11,26 +11,26 @@ public readonly partial struct OrderedDither /// /// Applies order dithering using the 2x2 Bayer dithering matrix. /// - public static OrderedDither Bayer2x2 = new OrderedDither(2); + public static readonly OrderedDither Bayer2x2 = new(2); /// /// Applies order dithering using the 4x4 Bayer dithering matrix. /// - public static OrderedDither Bayer4x4 = new OrderedDither(4); + public static readonly OrderedDither Bayer4x4 = new(4); /// /// Applies order dithering using the 8x8 Bayer dithering matrix. /// - public static OrderedDither Bayer8x8 = new OrderedDither(8); + public static readonly OrderedDither Bayer8x8 = new(8); /// /// Applies order dithering using the 16x16 Bayer dithering matrix. /// - public static OrderedDither Bayer16x16 = new OrderedDither(16); + public static readonly OrderedDither Bayer16x16 = new(16); /// /// Applies order dithering using the 3x3 ordered dithering matrix. /// - public static OrderedDither Ordered3x3 = new OrderedDither(3); + public static readonly OrderedDither Ordered3x3 = new(3); } } diff --git a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs index 0e85b20eab..4c6e8e043b 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs @@ -124,7 +124,7 @@ public void ApplyQuantizationDither( for (int y = bounds.Top; y < bounds.Bottom; y++) { ReadOnlySpan sourceRow = sourceBuffer.DangerousGetRowSpan(y).Slice(bounds.X, bounds.Width); - Span destRow = destination.GetWritablePixelRowSpanUnsafe(y - bounds.Y).Slice(0, sourceRow.Length); + Span destRow = destination.GetWritablePixelRowSpanUnsafe(y - bounds.Y)[..sourceRow.Length]; for (int x = 0; x < sourceRow.Length; x++) { diff --git a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs index 248c216410..5b336d78fe 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessor{TPixel}.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors.Quantization; @@ -46,7 +47,7 @@ public PaletteDitherProcessor(Configuration configuration, PaletteDitherProcesso /// protected override void OnFrameApply(ImageFrame source) { - var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); + Rectangle interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); this.dither.ApplyPaletteDither(in this.ditherProcessor, source, interest); } @@ -74,6 +75,10 @@ protected override void Dispose(bool disposing) /// . /// /// Internal for AOT + [SuppressMessage( + "Design", + "CA1001:Types that own disposable fields should be disposable", + Justification = "https://github.com/dotnet/roslyn-analyzers/issues/6151")] internal readonly struct DitherProcessor : IPaletteDitherImageProcessor, IDisposable { private readonly EuclideanPixelMap pixelMap; diff --git a/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs index cf56d03389..4d33b848b1 100644 --- a/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs @@ -30,24 +30,18 @@ internal class OilPaintingProcessor : ImageProcessor /// The source area to process for the current processor instance. public OilPaintingProcessor(Configuration configuration, OilPaintingProcessor definition, Image source, Rectangle sourceRectangle) : base(configuration, source, sourceRectangle) - { - this.definition = definition; - } + => this.definition = definition; /// protected override void OnFrameApply(ImageFrame source) { - int brushSize = this.definition.BrushSize; - if (brushSize <= 0 || brushSize > source.Height || brushSize > source.Width) - { - throw new ArgumentOutOfRangeException(nameof(brushSize)); - } + int brushSize = Math.Clamp(this.definition.BrushSize, 1, Math.Min(source.Width, source.Height)); using Buffer2D targetPixels = this.Configuration.MemoryAllocator.Allocate2D(source.Size()); source.CopyTo(targetPixels); - var operation = new RowIntervalOperation(this.SourceRectangle, targetPixels, source.PixelBuffer, this.Configuration, brushSize >> 1, this.definition.Levels); + RowIntervalOperation operation = new(this.SourceRectangle, targetPixels, source.PixelBuffer, this.Configuration, brushSize >> 1, this.definition.Levels); ParallelRowIterator.IterateRowIntervals( this.Configuration, this.SourceRectangle, @@ -147,7 +141,7 @@ public void Invoke(in RowInterval rows) int offsetX = x + fxr; offsetX = Numerics.Clamp(offsetX, 0, maxX); - var vector = sourceOffsetRow[offsetX].ToVector4(); + Vector4 vector = sourceOffsetRow[offsetX].ToVector4(); float sourceRed = vector.X; float sourceBlue = vector.Z; diff --git a/src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs index 5c1282666d..7cc115137d 100644 --- a/src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs @@ -51,8 +51,8 @@ public OpaqueRowOperation( [MethodImpl(InliningOptions.ShortMethod)] public void Invoke(int y, Span span) { - Span targetRowSpan = this.target.DangerousGetRowSpan(y).Slice(this.bounds.X); - PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Scale); + Span targetRowSpan = this.target.DangerousGetRowSpan(y)[this.bounds.X..]; + PixelOperations.Instance.ToVector4(this.configuration, targetRowSpan[..span.Length], span, PixelConversionModifiers.Scale); ref Vector4 baseRef = ref MemoryMarshal.GetReference(span); for (int x = 0; x < this.bounds.Width; x++) diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs index d6d69f1617..518b19c4ca 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs @@ -628,7 +628,7 @@ public void Invoke(in RowInterval rows) this.processor.ClipHistogram(histogram, this.processor.ClipLimit); } - cdfMinSpan[cdfX] += this.processor.CalculateCdf(ref cdfBase, ref histogramBase, histogram.Length - 1); + cdfMinSpan[cdfX] += CalculateCdf(ref cdfBase, ref histogramBase, histogram.Length - 1); cdfX++; } diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs index a2f346be01..b7e5819e0e 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs @@ -7,7 +7,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks; -using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -57,20 +56,21 @@ protected override void OnFrameApply(ImageFrame source) { MemoryAllocator memoryAllocator = this.Configuration.MemoryAllocator; - var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = this.Configuration.MaxDegreeOfParallelism }; + ParallelOptions parallelOptions = new() + { MaxDegreeOfParallelism = this.Configuration.MaxDegreeOfParallelism }; int tileWidth = source.Width / this.Tiles; int tileHeight = tileWidth; int pixelInTile = tileWidth * tileHeight; int halfTileHeight = tileHeight / 2; int halfTileWidth = halfTileHeight; - var slidingWindowInfos = new SlidingWindowInfos(tileWidth, tileHeight, halfTileWidth, halfTileHeight, pixelInTile); + SlidingWindowInfos slidingWindowInfos = new(tileWidth, tileHeight, halfTileWidth, halfTileHeight, pixelInTile); // TODO: If the process was able to be switched to operate in parallel rows instead of columns // then we could take advantage of batching and allocate per-row buffers only once per batch. using Buffer2D targetPixels = this.Configuration.MemoryAllocator.Allocate2D(source.Width, source.Height); // Process the inner tiles, which do not require to check the borders. - var innerOperation = new SlidingWindowOperation( + SlidingWindowOperation innerOperation = new( this.Configuration, this, source, @@ -88,7 +88,7 @@ protected override void OnFrameApply(ImageFrame source) innerOperation.Invoke); // Process the left border of the image. - var leftBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation leftBorderOperation = new( this.Configuration, this, source, @@ -106,7 +106,7 @@ protected override void OnFrameApply(ImageFrame source) leftBorderOperation.Invoke); // Process the right border of the image. - var rightBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation rightBorderOperation = new( this.Configuration, this, source, @@ -124,7 +124,7 @@ protected override void OnFrameApply(ImageFrame source) rightBorderOperation.Invoke); // Process the top border of the image. - var topBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation topBorderOperation = new( this.Configuration, this, source, @@ -142,7 +142,7 @@ protected override void OnFrameApply(ImageFrame source) topBorderOperation.Invoke); // Process the bottom border of the image. - var bottomBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation bottomBorderOperation = new( this.Configuration, this, source, @@ -171,7 +171,7 @@ protected override void OnFrameApply(ImageFrame source) /// The y position. /// The width in pixels of a tile. /// The configuration. - private void CopyPixelRow( + private static void CopyPixelRow( ImageFrame source, Span rowPixels, int x, @@ -224,7 +224,7 @@ private void CopyPixelRow( return; } - this.CopyPixelRowFast(source.PixelBuffer, rowPixels, x, y, tileWidth, configuration); + CopyPixelRowFast(source.PixelBuffer, rowPixels, x, y, tileWidth, configuration); } /// @@ -237,7 +237,7 @@ private void CopyPixelRow( /// The width in pixels of a tile. /// The configuration. [MethodImpl(InliningOptions.ShortMethod)] - private void CopyPixelRowFast( + private static void CopyPixelRowFast( Buffer2D source, Span rowPixels, int x, @@ -254,7 +254,7 @@ private void CopyPixelRowFast( /// The number of different luminance levels. /// The grey values span length. [MethodImpl(InliningOptions.ShortMethod)] - private void AddPixelsToHistogram(ref Vector4 greyValuesBase, ref int histogramBase, int luminanceLevels, int length) + private static void AddPixelsToHistogram(ref Vector4 greyValuesBase, ref int histogramBase, int luminanceLevels, int length) { for (nint idx = 0; idx < length; idx++) { @@ -271,7 +271,7 @@ private void AddPixelsToHistogram(ref Vector4 greyValuesBase, ref int histogramB /// The number of different luminance levels. /// The grey values span length. [MethodImpl(InliningOptions.ShortMethod)] - private void RemovePixelsFromHistogram(ref Vector4 greyValuesBase, ref int histogramBase, int luminanceLevels, int length) + private static void RemovePixelsFromHistogram(ref Vector4 greyValuesBase, ref int histogramBase, int luminanceLevels, int length) { for (int idx = 0; idx < length; idx++) { @@ -356,14 +356,14 @@ public void Invoke(int x) { if (this.useFastPath) { - this.processor.CopyPixelRowFast(this.source.PixelBuffer, pixelRow, x - this.swInfos.HalfTileWidth, dy, this.swInfos.TileWidth, this.configuration); + CopyPixelRowFast(this.source.PixelBuffer, pixelRow, x - this.swInfos.HalfTileWidth, dy, this.swInfos.TileWidth, this.configuration); } else { - this.processor.CopyPixelRow(this.source, pixelRow, x - this.swInfos.HalfTileWidth, dy, this.swInfos.TileWidth, this.configuration); + CopyPixelRow(this.source, pixelRow, x - this.swInfos.HalfTileWidth, dy, this.swInfos.TileWidth, this.configuration); } - this.processor.AddPixelsToHistogram(ref pixelRowBase, ref histogramBase, this.processor.LuminanceLevels, pixelRow.Length); + AddPixelsToHistogram(ref pixelRowBase, ref histogramBase, this.processor.LuminanceLevels, pixelRow.Length); } for (int y = this.yStart; y < this.yEnd; y++) @@ -377,8 +377,8 @@ public void Invoke(int x) // Calculate the cumulative distribution function, which will map each input pixel in the current tile to a new value. int cdfMin = this.processor.ClipHistogramEnabled - ? this.processor.CalculateCdf(ref cdfBase, ref histogramCopyBase, histogram.Length - 1) - : this.processor.CalculateCdf(ref cdfBase, ref histogramBase, histogram.Length - 1); + ? CalculateCdf(ref cdfBase, ref histogramCopyBase, histogram.Length - 1) + : CalculateCdf(ref cdfBase, ref histogramBase, histogram.Length - 1); float numberOfPixelsMinusCdfMin = this.swInfos.PixelInTile - cdfMin; @@ -390,26 +390,26 @@ public void Invoke(int x) // Remove top most row from the histogram, mirroring rows which exceeds the borders. if (this.useFastPath) { - this.processor.CopyPixelRowFast(this.source.PixelBuffer, pixelRow, x - this.swInfos.HalfTileWidth, y - this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); + CopyPixelRowFast(this.source.PixelBuffer, pixelRow, x - this.swInfos.HalfTileWidth, y - this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); } else { - this.processor.CopyPixelRow(this.source, pixelRow, x - this.swInfos.HalfTileWidth, y - this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); + CopyPixelRow(this.source, pixelRow, x - this.swInfos.HalfTileWidth, y - this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); } - this.processor.RemovePixelsFromHistogram(ref pixelRowBase, ref histogramBase, this.processor.LuminanceLevels, pixelRow.Length); + RemovePixelsFromHistogram(ref pixelRowBase, ref histogramBase, this.processor.LuminanceLevels, pixelRow.Length); // Add new bottom row to the histogram, mirroring rows which exceeds the borders. if (this.useFastPath) { - this.processor.CopyPixelRowFast(this.source.PixelBuffer, pixelRow, x - this.swInfos.HalfTileWidth, y + this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); + CopyPixelRowFast(this.source.PixelBuffer, pixelRow, x - this.swInfos.HalfTileWidth, y + this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); } else { - this.processor.CopyPixelRow(this.source, pixelRow, x - this.swInfos.HalfTileWidth, y + this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); + CopyPixelRow(this.source, pixelRow, x - this.swInfos.HalfTileWidth, y + this.swInfos.HalfTileWidth, this.swInfos.TileWidth, this.configuration); } - this.processor.AddPixelsToHistogram(ref pixelRowBase, ref histogramBase, this.processor.LuminanceLevels, pixelRow.Length); + AddPixelsToHistogram(ref pixelRowBase, ref histogramBase, this.processor.LuminanceLevels, pixelRow.Length); } } } diff --git a/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs index 433207562a..c4b925efed 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs @@ -68,7 +68,7 @@ protected override void OnFrameApply(ImageFrame source) using IMemoryOwner cdfBuffer = memoryAllocator.Allocate(this.LuminanceLevels, AllocationOptions.Clean); // Calculate the cumulative distribution function, which will map each input pixel to a new value. - int cdfMin = this.CalculateCdf( + int cdfMin = CalculateCdf( ref MemoryMarshal.GetReference(cdfBuffer.GetSpan()), ref MemoryMarshal.GetReference(histogram), histogram.Length - 1); @@ -107,12 +107,7 @@ public GrayscaleLevelsRowOperation( } /// -#if NETSTANDARD2_0 - // https://github.com/SixLabors/ImageSharp/issues/1204 - [MethodImpl(MethodImplOptions.NoOptimization)] -#else [MethodImpl(InliningOptions.ShortMethod)] -#endif public void Invoke(int y) { ref int histogramBase = ref MemoryMarshal.GetReference(this.histogramBuffer.GetSpan()); @@ -156,12 +151,7 @@ public CdfApplicationRowOperation( } /// -#if NETSTANDARD2_0 - // https://github.com/SixLabors/ImageSharp/issues/1204 - [MethodImpl(MethodImplOptions.NoOptimization)] -#else [MethodImpl(InliningOptions.ShortMethod)] -#endif public void Invoke(int y) { ref int cdfBase = ref MemoryMarshal.GetReference(this.cdfBuffer.GetSpan()); diff --git a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs index 71fbc6e5be..0e9bfa7e48 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs @@ -25,7 +25,7 @@ public class HistogramEqualizationOptions /// It is recommended to use clipping when the AdaptiveTileInterpolation method is used, to suppress artifacts which can occur on the borders of the tiles. /// Defaults to false. /// - public bool ClipHistogram { get; set; } = false; + public bool ClipHistogram { get; set; } /// /// Gets or sets the histogram clip limit. Adaptive histogram equalization may cause noise to be amplified in near constant diff --git a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs index 4c32c5fd92..0213799071 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.PixelFormats; @@ -67,7 +68,7 @@ protected HistogramEqualizationProcessor( /// The reference to the histogram of the input image. /// Index of the maximum of the histogram. /// The first none zero value of the cdf. - public int CalculateCdf(ref int cdfBase, ref int histogramBase, int maxIdx) + public static int CalculateCdf(ref int cdfBase, ref int histogramBase, int maxIdx) { int histSum = 0; int cdfMin = 0; @@ -142,7 +143,7 @@ public void ClipHistogram(Span histogram, int clipLimit) public static int GetLuminance(TPixel sourcePixel, int luminanceLevels) { // TODO: We need a bulk per span equivalent. - var vector = sourcePixel.ToVector4(); + Vector4 vector = sourcePixel.ToVector4(); return ColorNumerics.GetBT709Luminance(ref vector, luminanceLevels); } } diff --git a/src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs index 981e1cf607..d06661d07e 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs @@ -23,7 +23,9 @@ internal sealed class EuclideanPixelMap : IDisposable { private Rgba32[] rgbaPalette; - // Do not make this readonly! Struct value would be always copied on non-readonly method calls. + /// + /// Do not make this readonly! Struct value would be always copied on non-readonly method calls. + /// private ColorDistanceCache cache; private readonly Configuration configuration; diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs index 4e47b0ac54..b3aa58acf3 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -16,6 +17,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// /// The pixel format. + [SuppressMessage( + "Design", + "CA1001:Types that own disposable fields should be disposable", + Justification = "https://github.com/dotnet/roslyn-analyzers/issues/6151")] public struct OctreeQuantizer : IQuantizer where TPixel : unmanaged, IPixel { @@ -48,7 +53,7 @@ public OctreeQuantizer(Configuration configuration, QuantizerOptions options) this.paletteOwner = configuration.MemoryAllocator.Allocate(this.maxColors, AllocationOptions.Clean); this.pixelMap = default; this.palette = default; - this.isDithering = !(this.Options.Dither is null); + this.isDithering = this.Options.Dither is not null; this.isDisposed = false; } @@ -108,7 +113,7 @@ public void AddPaletteColors(Buffer2DRegion pixelRegion) } this.octree.Palletize(paletteSpan, max, ref paletteIndex); - ReadOnlyMemory result = this.paletteOwner.Memory.Slice(0, paletteSpan.Length); + ReadOnlyMemory result = this.paletteOwner.Memory[..paletteSpan.Length]; // When called multiple times by QuantizerUtilities.BuildPalette // this prevents memory churn caused by reallocation. @@ -473,7 +478,7 @@ public void ConstructPalette(Span palette, ref int index) if (this.leaf) { // Set the color of the palette entry - var vector = Vector3.Clamp( + Vector3 vector = Vector3.Clamp( new Vector3(this.red, this.green, this.blue) / this.pixelCount, Vector3.Zero, new Vector3(255)); diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs index ab0f1548f8..30043abfba 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs @@ -54,7 +54,7 @@ public IQuantizer CreatePixelSpecificQuantizer(Configuration con // since the palette is unchanging. This allows a reduction of memory usage across // multi frame gifs using a global palette. int length = Math.Min(this.colorPalette.Length, options.MaxColors); - var palette = new TPixel[length]; + TPixel[] palette = new TPixel[length]; Color.ToPixel(configuration, this.colorPalette.Span, palette.AsSpan()); return new PaletteQuantizer(configuration, options, palette); diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs index 5196070e4f..1fcdbc5b1f 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer{TPixel}.cs @@ -2,6 +2,7 @@ // Licensed under the Six Labors Split License. using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -13,6 +14,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// /// The pixel format. + [SuppressMessage( + "Design", + "CA1001:Types that own disposable fields should be disposable", + Justification = "https://github.com/dotnet/roslyn-analyzers/issues/6151")] internal struct PaletteQuantizer : IQuantizer where TPixel : unmanaged, IPixel { diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs index 576e34a269..5f04669b74 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -31,6 +32,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// /// The pixel format. + [SuppressMessage( + "Design", + "CA1001:Types that own disposable fields should be disposable", + Justification = "https://github.com/dotnet/roslyn-analyzers/issues/6151")] internal struct WuQuantizer : IQuantizer where TPixel : unmanaged, IPixel { @@ -97,7 +102,7 @@ public WuQuantizer(Configuration configuration, QuantizerOptions options) this.isDisposed = false; this.pixelMap = default; this.palette = default; - this.isDithering = this.isDithering = !(this.Options.Dither is null); + this.isDithering = this.isDithering = this.Options.Dither is not null; } /// @@ -127,7 +132,7 @@ public void AddPaletteColors(Buffer2DRegion pixelRegion) this.BuildCube(); // Slice again since maxColors has been updated since the buffer was created. - Span paletteSpan = this.paletteOwner.GetSpan().Slice(0, this.maxColors); + Span paletteSpan = this.paletteOwner.GetSpan()[..this.maxColors]; ReadOnlySpan momentsSpan = this.momentsOwner.GetSpan(); for (int k = 0; k < paletteSpan.Length; k++) { @@ -142,7 +147,7 @@ public void AddPaletteColors(Buffer2DRegion pixelRegion) } } - ReadOnlyMemory result = this.paletteOwner.Memory.Slice(0, paletteSpan.Length); + ReadOnlyMemory result = this.paletteOwner.Memory[..paletteSpan.Length]; if (this.isDithering) { // When called multiple times by QuantizerUtilities.BuildPalette @@ -256,58 +261,51 @@ private static Moment Volume(ref Box cube, ReadOnlySpan moments) /// The direction. /// The moment. /// The result. + /// Invalid direction. private static Moment Bottom(ref Box cube, int direction, ReadOnlySpan moments) - { - switch (direction) + => direction switch { // Red - case 3: - return -moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, cube.AMax)] - + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMax)] - - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMax)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMin)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMax)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)]; + 3 => -moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, cube.AMax)] + + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMax)] + - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMax)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMin)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMax)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)], // Green - case 2: - return -moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, cube.AMax)] - + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, cube.AMin)] - + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMax)] - - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMax)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMin)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMax)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)]; + 2 => -moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, cube.AMax)] + + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, cube.AMin)] + + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMax)] + - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMax)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMin)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMax)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)], // Blue - case 1: - return -moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, cube.AMax)] - + moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, cube.AMin)] - + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMax)] - - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMax)] - - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMin)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMax)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)]; + 1 => -moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, cube.AMax)] + + moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, cube.AMin)] + + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMax)] + - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMax)] + - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMin)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMax)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)], // Alpha - case 0: - return -moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMax, cube.AMin)] - + moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, cube.AMin)] - + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, cube.AMin)] - - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, cube.AMin)] - - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMin)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)]; - - default: - throw new ArgumentOutOfRangeException(nameof(direction)); - } - } + 0 => -moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMax, cube.AMin)] + + moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, cube.AMin)] + + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, cube.AMin)] + - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, cube.AMin)] + - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, cube.AMin)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)], + _ => throw new ArgumentOutOfRangeException(nameof(direction)), + }; /// /// Computes remainder of Volume(cube, moment), substituting position for RMax, GMax, BMax, or AMax (depending on direction). @@ -317,58 +315,51 @@ private static Moment Bottom(ref Box cube, int direction, ReadOnlySpan m /// The position. /// The moment. /// The result. + /// Invalid direction. private static Moment Top(ref Box cube, int direction, int position, ReadOnlySpan moments) - { - switch (direction) + => direction switch { // Red - case 3: - return moments[GetPaletteIndex(position, cube.GMax, cube.BMax, cube.AMax)] - - moments[GetPaletteIndex(position, cube.GMax, cube.BMax, cube.AMin)] - - moments[GetPaletteIndex(position, cube.GMax, cube.BMin, cube.AMax)] - + moments[GetPaletteIndex(position, cube.GMax, cube.BMin, cube.AMin)] - - moments[GetPaletteIndex(position, cube.GMin, cube.BMax, cube.AMax)] - + moments[GetPaletteIndex(position, cube.GMin, cube.BMax, cube.AMin)] - + moments[GetPaletteIndex(position, cube.GMin, cube.BMin, cube.AMax)] - - moments[GetPaletteIndex(position, cube.GMin, cube.BMin, cube.AMin)]; + 3 => moments[GetPaletteIndex(position, cube.GMax, cube.BMax, cube.AMax)] + - moments[GetPaletteIndex(position, cube.GMax, cube.BMax, cube.AMin)] + - moments[GetPaletteIndex(position, cube.GMax, cube.BMin, cube.AMax)] + + moments[GetPaletteIndex(position, cube.GMax, cube.BMin, cube.AMin)] + - moments[GetPaletteIndex(position, cube.GMin, cube.BMax, cube.AMax)] + + moments[GetPaletteIndex(position, cube.GMin, cube.BMax, cube.AMin)] + + moments[GetPaletteIndex(position, cube.GMin, cube.BMin, cube.AMax)] + - moments[GetPaletteIndex(position, cube.GMin, cube.BMin, cube.AMin)], // Green - case 2: - return moments[GetPaletteIndex(cube.RMax, position, cube.BMax, cube.AMax)] - - moments[GetPaletteIndex(cube.RMax, position, cube.BMax, cube.AMin)] - - moments[GetPaletteIndex(cube.RMax, position, cube.BMin, cube.AMax)] - + moments[GetPaletteIndex(cube.RMax, position, cube.BMin, cube.AMin)] - - moments[GetPaletteIndex(cube.RMin, position, cube.BMax, cube.AMax)] - + moments[GetPaletteIndex(cube.RMin, position, cube.BMax, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, position, cube.BMin, cube.AMax)] - - moments[GetPaletteIndex(cube.RMin, position, cube.BMin, cube.AMin)]; + 2 => moments[GetPaletteIndex(cube.RMax, position, cube.BMax, cube.AMax)] + - moments[GetPaletteIndex(cube.RMax, position, cube.BMax, cube.AMin)] + - moments[GetPaletteIndex(cube.RMax, position, cube.BMin, cube.AMax)] + + moments[GetPaletteIndex(cube.RMax, position, cube.BMin, cube.AMin)] + - moments[GetPaletteIndex(cube.RMin, position, cube.BMax, cube.AMax)] + + moments[GetPaletteIndex(cube.RMin, position, cube.BMax, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, position, cube.BMin, cube.AMax)] + - moments[GetPaletteIndex(cube.RMin, position, cube.BMin, cube.AMin)], // Blue - case 1: - return moments[GetPaletteIndex(cube.RMax, cube.GMax, position, cube.AMax)] - - moments[GetPaletteIndex(cube.RMax, cube.GMax, position, cube.AMin)] - - moments[GetPaletteIndex(cube.RMax, cube.GMin, position, cube.AMax)] - + moments[GetPaletteIndex(cube.RMax, cube.GMin, position, cube.AMin)] - - moments[GetPaletteIndex(cube.RMin, cube.GMax, position, cube.AMax)] - + moments[GetPaletteIndex(cube.RMin, cube.GMax, position, cube.AMin)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, position, cube.AMax)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, position, cube.AMin)]; + 1 => moments[GetPaletteIndex(cube.RMax, cube.GMax, position, cube.AMax)] + - moments[GetPaletteIndex(cube.RMax, cube.GMax, position, cube.AMin)] + - moments[GetPaletteIndex(cube.RMax, cube.GMin, position, cube.AMax)] + + moments[GetPaletteIndex(cube.RMax, cube.GMin, position, cube.AMin)] + - moments[GetPaletteIndex(cube.RMin, cube.GMax, position, cube.AMax)] + + moments[GetPaletteIndex(cube.RMin, cube.GMax, position, cube.AMin)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, position, cube.AMax)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, position, cube.AMin)], // Alpha - case 0: - return moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMax, position)] - - moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, position)] - - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, position)] - + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, position)] - - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, position)] - + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, position)] - + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, position)] - - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, position)]; - - default: - throw new ArgumentOutOfRangeException(nameof(direction)); - } - } + 0 => moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMax, position)] + - moments[GetPaletteIndex(cube.RMax, cube.GMax, cube.BMin, position)] + - moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMax, position)] + + moments[GetPaletteIndex(cube.RMax, cube.GMin, cube.BMin, position)] + - moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMax, position)] + + moments[GetPaletteIndex(cube.RMin, cube.GMax, cube.BMin, position)] + + moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMax, position)] + - moments[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, position)], + _ => throw new ArgumentOutOfRangeException(nameof(direction)), + }; /// /// Builds a 3-D color histogram of counts, r/g/b, c^2. @@ -498,7 +489,7 @@ private double Variance(ref Box cube) - momentSpan[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMax)] + momentSpan[GetPaletteIndex(cube.RMin, cube.GMin, cube.BMin, cube.AMin)]; - var vector = new Vector4(volume.R, volume.G, volume.B, volume.A); + Vector4 vector = new(volume.R, volume.G, volume.B, volume.A); return variance.Moment2 - (Vector4.Dot(vector, vector) / volume.Weight); } @@ -533,7 +524,7 @@ private float Maximize(ref Box cube, int direction, int first, int last, out int continue; } - var vector = new Vector4(half.R, half.G, half.B, half.A); + Vector4 vector = new(half.R, half.G, half.B, half.A); float temp = Vector4.Dot(vector, vector) / half.Weight; half = whole - half; @@ -816,7 +807,7 @@ private struct Moment x.A += y.A; x.Weight++; - var vector = new Vector4(y.R, y.G, y.B, y.A); + Vector4 vector = new(y.R, y.G, y.B, y.A); x.Moment2 += Vector4.Dot(vector, vector); return x; diff --git a/src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs index 92f3e8b98b..32c93c2812 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs @@ -86,9 +86,9 @@ public RowOperation(Rectangle bounds, Buffer2D source, Buffer2D [MethodImpl(InliningOptions.ShortMethod)] public void Invoke(int y) { - Span sourceRow = this.source.DangerousGetRowSpan(y).Slice(this.bounds.Left); + Span sourceRow = this.source.DangerousGetRowSpan(y)[this.bounds.Left..]; Span targetRow = this.destination.DangerousGetRowSpan(y - this.bounds.Top); - sourceRow.Slice(0, this.bounds.Width).CopyTo(targetRow); + sourceRow[..this.bounds.Width].CopyTo(targetRow); } } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs index 01de78198a..680ada1d36 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor{TPixel}.cs @@ -2,11 +2,8 @@ // Licensed under the Six Labors Split License. using System; -using System.Buffers; -using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -183,19 +180,6 @@ public AffineOperation( [MethodImpl(InliningOptions.ShortMethod)] public void Invoke(in RowInterval rows, Span span) { - if (RuntimeEnvironment.IsOSPlatform(OSPlatform.OSX) - && RuntimeEnvironment.IsNetCore) - { - // There's something wrong with the JIT in .NET Core 3.1 on certain - // macOS machines so we have to use different pipelines. - // It's: - // - Not reproducable locally - // - Doesn't seem to be triggered by the bulk Numerics.UnPremultiply method but by caller. - // https://github.com/SixLabors/ImageSharp/pull/1591 - this.InvokeMacOS(in rows, span); - return; - } - Matrix3x2 matrix = this.matrix; TResampler sampler = this.sampler; float yRadius = this.yRadius; @@ -256,71 +240,6 @@ public void Invoke(in RowInterval rows, Span span) PixelConversionModifiers.Scale); } } - - [ExcludeFromCodeCoverage] - [MethodImpl(InliningOptions.ShortMethod)] - private void InvokeMacOS(in RowInterval rows, Span span) - { - Matrix3x2 matrix = this.matrix; - TResampler sampler = this.sampler; - float yRadius = this.yRadius; - float xRadius = this.xRadius; - int minY = this.bounds.Y; - int maxY = this.bounds.Bottom - 1; - int minX = this.bounds.X; - int maxX = this.bounds.Right - 1; - - for (int y = rows.Min; y < rows.Max; y++) - { - Span rowSpan = this.destination.DangerousGetRowSpan(y); - PixelOperations.Instance.ToVector4( - this.configuration, - rowSpan, - span, - PixelConversionModifiers.Scale); - - for (int x = 0; x < span.Length; x++) - { - var point = Vector2.Transform(new Vector2(x, y), matrix); - float pY = point.Y; - float pX = point.X; - - int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY); - int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY); - int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX); - int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX); - - if (bottom == top || right == left) - { - continue; - } - - Vector4 sum = Vector4.Zero; - for (int yK = top; yK <= bottom; yK++) - { - float yWeight = sampler.GetValue(yK - pY); - - for (int xK = left; xK <= right; xK++) - { - float xWeight = sampler.GetValue(xK - pX); - - Vector4 current = this.source.GetElementUnsafe(xK, yK).ToScaledVector4(); - Numerics.Premultiply(ref current); - sum += current * xWeight * yWeight; - } - } - - Numerics.UnPremultiply(ref sum); - span[x] = sum; - } - - PixelOperations.Instance.FromVector4Destructive( - this.configuration, - span, - rowSpan, - PixelConversionModifiers.Scale); - } - } } } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs index 7dc8b7365e..3f4e18b8c7 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs @@ -27,10 +27,7 @@ internal class FlipProcessor : ImageProcessor /// The source for the current processor instance. /// The source area to process for the current processor instance. public FlipProcessor(Configuration configuration, FlipProcessor definition, Image source, Rectangle sourceRectangle) - : base(configuration, source, sourceRectangle) - { - this.definition = definition; - } + : base(configuration, source, sourceRectangle) => this.definition = definition; /// protected override void OnFrameApply(ImageFrame source) @@ -39,10 +36,10 @@ protected override void OnFrameApply(ImageFrame source) { // No default needed as we have already set the pixels. case FlipMode.Vertical: - this.FlipX(source.PixelBuffer, this.Configuration); + FlipX(source.PixelBuffer, this.Configuration); break; case FlipMode.Horizontal: - this.FlipY(source, this.Configuration); + FlipY(source, this.Configuration); break; } } @@ -52,7 +49,7 @@ protected override void OnFrameApply(ImageFrame source) /// /// The source image to apply the process to. /// The configuration. - private void FlipX(Buffer2D source, Configuration configuration) + private static void FlipX(Buffer2D source, Configuration configuration) { int height = source.Height; using IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(source.Width); @@ -74,7 +71,7 @@ private void FlipX(Buffer2D source, Configuration configuration) /// /// The source image to apply the process to. /// The configuration. - private void FlipY(ImageFrame source, Configuration configuration) + private static void FlipY(ImageFrame source, Configuration configuration) { var operation = new RowOperation(source.PixelBuffer); ParallelRowIterator.IterateRows( diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs index a379dfa8fd..9dbf4708fe 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/ProjectiveTransformProcessor{TPixel}.cs @@ -2,10 +2,8 @@ // Licensed under the Six Labors Split License. using System; -using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -182,19 +180,6 @@ public ProjectiveOperation( [MethodImpl(InliningOptions.ShortMethod)] public void Invoke(in RowInterval rows, Span span) { - if (RuntimeEnvironment.IsOSPlatform(OSPlatform.OSX) - && RuntimeEnvironment.IsNetCore) - { - // There's something wrong with the JIT in .NET Core 3.1 on certain - // macOS machines so we have to use different pipelines. - // It's: - // - Not reproducable locally - // - Doesn't seem to be triggered by the bulk Numerics.UnPremultiply method but by caller. - // https://github.com/SixLabors/ImageSharp/pull/1591 - this.InvokeMacOS(in rows, span); - return; - } - Matrix4x4 matrix = this.matrix; TResampler sampler = this.sampler; float yRadius = this.yRadius; @@ -255,71 +240,6 @@ public void Invoke(in RowInterval rows, Span span) PixelConversionModifiers.Scale); } } - - [ExcludeFromCodeCoverage] - [MethodImpl(InliningOptions.ShortMethod)] - public void InvokeMacOS(in RowInterval rows, Span span) - { - Matrix4x4 matrix = this.matrix; - TResampler sampler = this.sampler; - float yRadius = this.yRadius; - float xRadius = this.xRadius; - int minY = this.bounds.Y; - int maxY = this.bounds.Bottom - 1; - int minX = this.bounds.X; - int maxX = this.bounds.Right - 1; - - for (int y = rows.Min; y < rows.Max; y++) - { - Span rowSpan = this.destination.DangerousGetRowSpan(y); - PixelOperations.Instance.ToVector4( - this.configuration, - rowSpan, - span, - PixelConversionModifiers.Scale); - - for (int x = 0; x < span.Length; x++) - { - Vector2 point = TransformUtils.ProjectiveTransform2D(x, y, matrix); - float pY = point.Y; - float pX = point.X; - - int top = LinearTransformUtility.GetRangeStart(yRadius, pY, minY, maxY); - int bottom = LinearTransformUtility.GetRangeEnd(yRadius, pY, minY, maxY); - int left = LinearTransformUtility.GetRangeStart(xRadius, pX, minX, maxX); - int right = LinearTransformUtility.GetRangeEnd(xRadius, pX, minX, maxX); - - if (bottom <= top || right <= left) - { - continue; - } - - Vector4 sum = Vector4.Zero; - for (int yK = top; yK <= bottom; yK++) - { - float yWeight = sampler.GetValue(yK - pY); - - for (int xK = left; xK <= right; xK++) - { - float xWeight = sampler.GetValue(xK - pX); - - Vector4 current = this.source.GetElementUnsafe(xK, yK).ToScaledVector4(); - Numerics.Premultiply(ref current); - sum += current * xWeight * yWeight; - } - } - - Numerics.UnPremultiply(ref sum); - span[x] = sum; - } - - PixelOperations.Instance.FromVector4Destructive( - this.configuration, - span, - rowSpan, - PixelConversionModifiers.Scale); - } - } } } } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs index 8e26675d86..8f6ba28963 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs @@ -104,19 +104,19 @@ private bool OptimizedApply( if (MathF.Abs(degrees - 90) < Constants.Epsilon) { - this.Rotate90(source, destination, configuration); + Rotate90(source, destination, configuration); return true; } if (MathF.Abs(degrees - 180) < Constants.Epsilon) { - this.Rotate180(source, destination, configuration); + Rotate180(source, destination, configuration); return true; } if (MathF.Abs(degrees - 270) < Constants.Epsilon) { - this.Rotate270(source, destination, configuration); + Rotate270(source, destination, configuration); return true; } @@ -129,7 +129,7 @@ private bool OptimizedApply( /// The source image. /// The destination image. /// The configuration. - private void Rotate180(ImageFrame source, ImageFrame destination, Configuration configuration) + private static void Rotate180(ImageFrame source, ImageFrame destination, Configuration configuration) { var operation = new Rotate180RowOperation(source.Width, source.Height, source.PixelBuffer, destination.PixelBuffer); ParallelRowIterator.IterateRows( @@ -144,7 +144,7 @@ private void Rotate180(ImageFrame source, ImageFrame destination /// The source image. /// The destination image. /// The configuration. - private void Rotate270(ImageFrame source, ImageFrame destination, Configuration configuration) + private static void Rotate270(ImageFrame source, ImageFrame destination, Configuration configuration) { var operation = new Rotate270RowIntervalOperation(destination.Bounds(), source.Width, source.Height, source.PixelBuffer, destination.PixelBuffer); ParallelRowIterator.IterateRowIntervals( @@ -159,7 +159,7 @@ private void Rotate270(ImageFrame source, ImageFrame destination /// The source image. /// The destination image. /// The configuration. - private void Rotate90(ImageFrame source, ImageFrame destination, Configuration configuration) + private static void Rotate90(ImageFrame source, ImageFrame destination, Configuration configuration) { var operation = new Rotate90RowOperation(destination.Bounds(), source.Width, source.Height, source.PixelBuffer, destination.PixelBuffer); ParallelRowIterator.IterateRows( diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs index 4a87c1ea99..53dfb466f8 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs @@ -23,31 +23,31 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// This filter produces a reasonably sharp edge, but without a the pronounced gradient change on large /// scale image enlargements that a 'Lagrange' filter can produce. /// - public static CubicResampler CatmullRom = new CubicResampler(2, 0, .5F); + public static readonly CubicResampler CatmullRom = new(2, 0, .5F); /// /// The Hermite filter is type of smoothed triangular interpolation Filter, /// This filter rounds off strong edges while preserving flat 'color levels' in the original image. /// - public static CubicResampler Hermite = new CubicResampler(2, 0, 0); + public static readonly CubicResampler Hermite = new(2, 0, 0); /// /// The function implements the Mitchell-Netravali algorithm as described on /// Wikipedia /// - public static CubicResampler MitchellNetravali = new CubicResampler(2, .3333333F, .3333333F); + public static readonly CubicResampler MitchellNetravali = new(2, .3333333F, .3333333F); /// /// The function implements the Robidoux algorithm. /// /// - public static CubicResampler Robidoux = new CubicResampler(2, .37821575509399867F, .31089212245300067F); + public static readonly CubicResampler Robidoux = new(2, .37821575509399867F, .31089212245300067F); /// /// The function implements the Robidoux Sharp algorithm. /// /// - public static CubicResampler RobidouxSharp = new CubicResampler(2, .2620145123990142F, .3689927438004929F); + public static readonly CubicResampler RobidouxSharp = new(2, .2620145123990142F, .3689927438004929F); /// /// The function implements the spline algorithm. @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// The function implements the Robidoux Sharp algorithm. /// /// - public static CubicResampler Spline = new CubicResampler(2, 1, 0); + public static readonly CubicResampler Spline = new(2, 1, 0); /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs index 23d8efa624..30bc5b5def 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resamplers/LanczosResampler.cs @@ -15,22 +15,22 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// Implements the Lanczos kernel algorithm with a radius of 2. /// - public static LanczosResampler Lanczos2 = new LanczosResampler(2); + public static readonly LanczosResampler Lanczos2 = new(2); /// /// Implements the Lanczos kernel algorithm with a radius of 3. /// - public static LanczosResampler Lanczos3 = new LanczosResampler(3); + public static readonly LanczosResampler Lanczos3 = new(3); /// /// Implements the Lanczos kernel algorithm with a radius of 5. /// - public static LanczosResampler Lanczos5 = new LanczosResampler(5); + public static readonly LanczosResampler Lanczos5 = new(5); /// /// Implements the Lanczos kernel algorithm with a radius of 8. /// - public static LanczosResampler Lanczos8 = new LanczosResampler(8); + public static readonly LanczosResampler Lanczos8 = new(8); /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs index d6cfbc4cc6..73a75bf66f 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernel.cs @@ -4,11 +4,9 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif namespace SixLabors.ImageSharp.Processing.Processors.Transforms { @@ -56,7 +54,7 @@ public int Length public Span Values { [MethodImpl(InliningOptions.ShortMethod)] - get => new Span(this.bufferPtr, this.Length); + get => new(this.bufferPtr, this.Length); } /// @@ -71,7 +69,6 @@ public Vector4 Convolve(Span rowSpan) [MethodImpl(InliningOptions.ShortMethod)] public Vector4 ConvolveCore(ref Vector4 rowStartRef) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && Fma.IsSupported) { float* bufferStart = this.bufferPtr; @@ -141,7 +138,6 @@ public Vector4 ConvolveCore(ref Vector4 rowStartRef) return *(Vector4*)&result128; } else -#endif { // Destination color components Vector4 result = Vector4.Zero; @@ -167,7 +163,7 @@ public Vector4 ConvolveCore(ref Vector4 rowStartRef) /// [MethodImpl(InliningOptions.ShortMethod)] internal ResizeKernel AlterLeftValue(int left) - => new ResizeKernel(left, this.bufferPtr, this.Length); + => new(left, this.bufferPtr, this.Length); internal void Fill(Span values) { diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs index 888143af42..cb8b68b572 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs @@ -102,7 +102,7 @@ public void Dispose() [MethodImpl(InliningOptions.ShortMethod)] public Span GetColumnSpan(int x, int startY) - => this.transposedFirstPassBuffer.DangerousGetRowSpan(x).Slice(startY - this.currentWindow.Min); + => this.transposedFirstPassBuffer.DangerousGetRowSpan(x)[(startY - this.currentWindow.Min)..]; public void Initialize() => this.CalculateFirstPassValues(this.currentWindow); diff --git a/src/ImageSharp/Processing/ResizeOptions.cs b/src/ImageSharp/Processing/ResizeOptions.cs index 3c31c7628f..c7b862c1a5 100644 --- a/src/ImageSharp/Processing/ResizeOptions.cs +++ b/src/ImageSharp/Processing/ResizeOptions.cs @@ -39,7 +39,7 @@ public class ResizeOptions /// Gets or sets a value indicating whether to compress /// or expand individual pixel colors the value on processing. /// - public bool Compand { get; set; } = false; + public bool Compand { get; set; } /// /// Gets or sets the target rectangle to resize into. diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs index 5b2c8c05e5..ee196cbea2 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs @@ -5,10 +5,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; @@ -169,7 +167,6 @@ public void UseVector8_V3() Unsafe.As>(ref Unsafe.AddByteOffset(ref d, (IntPtr)(stride * 7))) = v3; } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void UseVector256_Avx2_Variant1() { @@ -319,7 +316,7 @@ public void UseVector256_Avx2_Variant3_WithLocalPinning() { fixed (Block8x8F* ss = &this.block) { - var s = (float*)ss; + float* s = (float*)ss; Vector256 v0 = Avx.LoadVector256(s); Vector256 v1 = Avx.LoadVector256(s + 8); Vector256 v2 = Avx.LoadVector256(s + (8 * 2)); @@ -345,8 +342,8 @@ public void UseVector256_Avx2_Variant3_WithLocalPinning() public void UseVector256_Avx2_Variant3_sbyte() { int stride = Width * 4; - var d = (sbyte*)this.bufferPtr; - var s = (sbyte*)this.blockPtr; + sbyte* d = (sbyte*)this.bufferPtr; + sbyte* s = (sbyte*)this.blockPtr; Vector256 v0 = Avx.LoadVector256(s); Vector256 v1 = Avx.LoadVector256(s + 32); @@ -366,7 +363,6 @@ public void UseVector256_Avx2_Variant3_sbyte() Avx.Store(d + (stride * 6), v2); Avx.Store(d + (stride * 7), v3); } -#endif // *** RESULTS 02/2020 *** // BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363 diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs index 6dc5702faf..1ff81d677c 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs @@ -5,10 +5,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; @@ -136,7 +134,6 @@ public void SimdUtils_FastRound_Vector8_Grouped() row3 = SimdUtils.FastRound(row3); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void Sse41_V1() { @@ -491,6 +488,5 @@ private static void Round8SseVectors(float* p0) Sse.StoreAligned(p6, v6); Sse.StoreAligned(p7, v7); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs index c0256caf6e..59fe2ed431 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs @@ -30,7 +30,6 @@ public void SimdVector8() new JpegColorConverterBase.CmykVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ public void SimdVectorAvx() new JpegColorConverterBase.CmykAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs index 25ca884c14..5f70787943 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs @@ -22,7 +22,6 @@ public void Scalar() new JpegColorConverterBase.GrayscaleScalar(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -30,6 +29,5 @@ public void SimdVectorAvx() new JpegColorConverterBase.GrayscaleAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs index 4cfe9534db..99b1f88107 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs @@ -30,7 +30,6 @@ public void SimdVector8() new JpegColorConverterBase.RgbVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ public void SimdVectorAvx() new JpegColorConverterBase.RgbAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs index a01c5d6e29..d528ea5ff4 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs @@ -30,7 +30,6 @@ public void SimdVector8() new JpegColorConverterBase.YCbCrVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ public void SimdVectorAvx() new JpegColorConverterBase.YCbCrAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs index c4f9633cae..cfc47bdc6e 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs @@ -30,7 +30,6 @@ public void SimdVector8() new JpegColorConverterBase.YccKVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx2() { @@ -38,6 +37,5 @@ public void SimdVectorAvx2() new JpegColorConverterBase.YccKAvx(8).ConvertToRgbInplace(values); } -#endif } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs index 9f7a988e18..bb2985ab71 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -6,10 +6,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -80,15 +78,6 @@ public void FallbackIntrinsics128() SimdUtils.FallbackIntrinsics128.NormalizedFloatToByteSaturate(sBytes, dFloats); } - [Benchmark] - public void BasicIntrinsics256() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - SimdUtils.BasicIntrinsics256.NormalizedFloatToByteSaturate(sBytes, dFloats); - } - [Benchmark] public void ExtendedIntrinsic() { @@ -98,7 +87,6 @@ public void ExtendedIntrinsic() SimdUtils.ExtendedIntrinsics.NormalizedFloatToByteSaturate(sBytes, dFloats); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void UseHwIntrinsics() { @@ -161,7 +149,6 @@ private static Vector256 ConvertToInt32(Vector256 vf, Vector256().ToVector4( + => new PixelOperations().ToVector4( this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); - } - - [Benchmark(Baseline = true)] - public void BasicIntrinsics256() - { - Span sBytes = MemoryMarshal.Cast(this.source.GetSpan()); - Span dFloats = MemoryMarshal.Cast(this.destination.GetSpan()); - - SimdUtils.BasicIntrinsics256.ByteToNormalizedFloat(sBytes, dFloats); - } [Benchmark] public void ExtendedIntrinsics() @@ -51,7 +40,6 @@ public void ExtendedIntrinsics() SimdUtils.ExtendedIntrinsics.ByteToNormalizedFloat(sBytes, dFloats); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void HwIntrinsics() { @@ -60,7 +48,6 @@ public void HwIntrinsics() SimdUtils.HwIntrinsics.ByteToNormalizedFloat(sBytes, dFloats); } -#endif // [Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() @@ -96,8 +83,8 @@ public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() { ref Vector dRef = ref Unsafe.Add(ref destBase, i); - Vector du = Vector.AsVectorInt32(dRef); - Vector v = Vector.ConvertToSingle(du); + var du = Vector.AsVectorInt32(dRef); + var v = Vector.ConvertToSingle(du); v *= scale; dRef = v; diff --git a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs index 16b016a7c8..4de745005f 100644 --- a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs +++ b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs @@ -1,9 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Environments; using BenchmarkDotNet.Jobs; @@ -58,26 +56,24 @@ public class HwIntrinsics_SSE_AVX : Config { public HwIntrinsics_SSE_AVX() { - this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) + this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core60) .WithEnvironmentVariables( new EnvironmentVariable(EnableHWIntrinsic, Off), new EnvironmentVariable(FeatureSIMD, Off)) .WithId("1. No HwIntrinsics").AsBaseline()); -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse.IsSupported) { - this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) + this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core60) .WithEnvironmentVariables(new EnvironmentVariable(EnableAVX, Off)) .WithId("2. SSE")); } if (Avx.IsSupported) { - this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) + this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core60) .WithId("3. AVX")); } -#endif } } } diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs index d0300b0573..252ff90589 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs @@ -4,10 +4,8 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -#endif using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; @@ -200,7 +198,6 @@ public void Rgb24_Scalar_PerElement_Batched4() } } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark(Baseline = true)] public void Rgba32_Avx2_Float() { @@ -261,7 +258,6 @@ public void Rgba32_Avx2_Bytes() Span rgb = this.rgbaBuf; SimdUtils.HwIntrinsics.PackFromRgbPlanesAvx2Reduce(ref r, ref g, ref b, ref rgb); } -#endif #pragma warning disable SA1132 private struct Byte8 diff --git a/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs b/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs index 063ba63cd6..6ecb606f53 100644 --- a/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs +++ b/tests/ImageSharp.Tests/Advanced/AdvancedImageExtensionsTests.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -50,7 +49,7 @@ public void OwnedMemory_DestructiveMutate_ShouldInvalidateMemoryGroup(Te image.Mutate(c => c.Resize(8, 8)); Assert.False(memoryGroup.IsValid); - Assert.ThrowsAny(() => _ = memoryGroup.First()); + Assert.ThrowsAny(() => _ = memoryGroup[0]); Assert.ThrowsAny(() => _ = memory.Span); } diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs index 10d18d63c6..0cd258bd9e 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs @@ -36,8 +36,8 @@ public void Convert_xyY_to_XYZ(float xyzX, float xyzY, float xyzZ, float x, floa Span actualSpan = new CieXyz[5]; // Act - var actual = Converter.ToCieXyz(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToCieXyz(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,8 +64,8 @@ public void Convert_XYZ_to_xyY(float xyzX, float xyzY, float xyzZ, float x, floa Span actualSpan = new CieXyy[5]; // Act - var actual = Converter.ToCieXyy(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToCieXyy(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs index 9e08d572fa..095b5e1255 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs @@ -34,8 +34,8 @@ public void Convert_Cmyk_to_Hsl(float c, float m, float y, float k, float h, flo Span actualSpan = new Hsl[5]; // Act - var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToHsl(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,8 +64,8 @@ public void Convert_Hsl_to_Cmyk(float h, float s, float l, float c, float m, flo Span actualSpan = new Cmyk[5]; // Act - var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToCmyk(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs index 44de7383a9..770840e9be 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs @@ -34,8 +34,8 @@ public void Convert_Cmyk_to_Hsv(float c, float m, float y, float k, float h, flo Span actualSpan = new Hsv[5]; // Act - var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToHsv(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); @@ -64,8 +64,8 @@ public void Convert_Hsv_to_Cmyk(float h, float s, float v, float c, float m, flo Span actualSpan = new Cmyk[5]; // Act - var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToCmyk(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs index 9c156b18d8..a67af332d7 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs @@ -34,8 +34,8 @@ public void Convert_Cmyk_to_YCbCr(float c, float m, float y, float k, float y2, Span actualSpan = new YCbCr[5]; // Act - var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToYCbCr(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs index 3f23866372..04abcf9788 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs @@ -40,8 +40,8 @@ public void Convert_Cmyk_To_Rgb(float c, float m, float y, float k, float r, flo Span actualSpan = new Rgb[5]; // Act - var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToRgb(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -72,8 +72,8 @@ public void Convert_Rgb_To_Cmyk(float r, float g, float b, float c, float m, flo Span actualSpan = new Cmyk[5]; // Act - var actual = Converter.ToCmyk(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToCmyk(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs index a5fd9ca770..f1075f8666 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs @@ -43,8 +43,8 @@ public void Convert_Hsl_To_Rgb(float h, float s, float l, float r, float g, floa Span actualSpan = new Rgb[5]; // Act - var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToRgb(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -78,8 +78,8 @@ public void Convert_Rgb_To_Hsl(float r, float g, float b, float h, float s, floa Span actualSpan = new Hsl[5]; // Act - var actual = Converter.ToHsl(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToHsl(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs index e7e95e7922..2d801b5405 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs @@ -42,8 +42,8 @@ public void Convert_Hsv_To_Rgb(float h, float s, float v, float r, float g, floa Span actualSpan = new Rgb[5]; // Act - var actual = Converter.ToRgb(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToRgb(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(Rgb.DefaultWorkingSpace, actual.WorkingSpace, ColorSpaceComparer); @@ -76,8 +76,8 @@ public void Convert_Rgb_To_Hsv(float r, float g, float b, float h, float s, floa Span actualSpan = new Hsv[5]; // Act - var actual = Converter.ToHsv(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToHsv(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs index 297b4ad138..0b4193c1ae 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs @@ -71,8 +71,8 @@ public void Convert_Rgb_To_YCbCr(float r, float g, float b, float y, float cb, f Span actualSpan = new YCbCr[5]; // Act - var actual = Converter.ToYCbCr(input); - Converter.Convert(inputSpan, actualSpan); + var actual = ColorSpaceConverter.ToYCbCr(input); + ColorSpaceConverter.Convert(inputSpan, actualSpan); // Assert Assert.Equal(expected, actual, ColorSpaceComparer); diff --git a/tests/ImageSharp.Tests/Common/NumericsTests.cs b/tests/ImageSharp.Tests/Common/NumericsTests.cs index e8643de279..6f5df43135 100644 --- a/tests/ImageSharp.Tests/Common/NumericsTests.cs +++ b/tests/ImageSharp.Tests/Common/NumericsTests.cs @@ -11,67 +11,10 @@ public class NumericsTests { private ITestOutputHelper Output { get; } - public NumericsTests(ITestOutputHelper output) - { - this.Output = output; - } + public NumericsTests(ITestOutputHelper output) => this.Output = output; public static TheoryData IsOutOfRangeTestData = new() { int.MinValue, -1, 0, 1, 6, 7, 8, 91, 92, 93, int.MaxValue }; - private static int Log2_ReferenceImplementation(uint value) - { - int n = 0; - while ((value >>= 1) != 0) - { - ++n; - } - - return n; - } - - [Fact] - public void Log2_ZeroConvention() - { - uint value = 0; - int expected = 0; - int actual = Numerics.Log2(value); - - Assert.Equal(expected, actual); - } - - [Fact] - public void Log2_PowersOfTwo() - { - for (int i = 0; i < sizeof(int) * 8; i++) - { - // from 2^0 to 2^32 - uint value = (uint)(1 << i); - int expected = i; - int actual = Numerics.Log2(value); - - Assert.Equal(expected, actual); - } - } - - [Theory] - [InlineData(1, 100)] - [InlineData(2, 100)] - public void Log2_RandomValues(int seed, int count) - { - var rng = new Random(seed); - byte[] bytes = new byte[4]; - - for (int i = 0; i < count; i++) - { - rng.NextBytes(bytes); - uint value = BitConverter.ToUInt32(bytes, 0); - int expected = Log2_ReferenceImplementation(value); - int actual = Numerics.Log2(value); - - Assert.Equal(expected, actual); - } - } - private static uint DivideCeil_ReferenceImplementation(uint value, uint divisor) => (uint)MathF.Ceiling((float)value / divisor); [Fact] diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 028cc56cd0..1ba3c64de9 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -5,9 +5,7 @@ using System.Linq; using System.Numerics; using System.Runtime.CompilerServices; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; @@ -43,7 +41,7 @@ public void PseudoRound(float x, float y, float z, float w) private static Vector CreateExactTestVector1() { - var data = new float[Vector.Count]; + float[] data = new float[Vector.Count]; data[0] = 0.1f; data[1] = 0.4f; @@ -113,53 +111,6 @@ private bool SkipOnNonAvx2([CallerMemberName] string testCaseName = null) return false; } - [Theory] - [InlineData(1, 0)] - [InlineData(1, 8)] - [InlineData(2, 16)] - [InlineData(3, 128)] - public void BasicIntrinsics256_BulkConvertNormalizedFloatToByte_WithRoundedData(int seed, int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - float[] orig = new Random(seed).GenerateRandomRoundedFloatArray(count, 0, 256); - float[] normalized = orig.Select(f => f / 255f).ToArray(); - - var dest = new byte[count]; - - SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByte(normalized, dest); - - byte[] expected = orig.Select(f => (byte)f).ToArray(); - - Assert.Equal(expected, dest); - } - - [Theory] - [InlineData(1, 0)] - [InlineData(1, 8)] - [InlineData(2, 16)] - [InlineData(3, 128)] - public void BasicIntrinsics256_BulkConvertNormalizedFloatToByte_WithNonRoundedData(int seed, int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - float[] source = new Random(seed).GenerateRandomFloatArray(count, 0, 1f); - - byte[] dest = new byte[count]; - - SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByte(source, dest); - - byte[] expected = source.Select(f => (byte)Math.Round(f * 255f)).ToArray(); - - Assert.Equal(expected, dest); - } - public static readonly TheoryData ArraySizesDivisibleBy8 = new() { 0, 8, 16, 1024 }; public static readonly TheoryData ArraySizesDivisibleBy4 = new() { 0, 4, 8, 28, 1020 }; public static readonly TheoryData ArraySizesDivisibleBy3 = new() { 0, 3, 9, 36, 957 }; @@ -173,27 +124,12 @@ public void FallbackIntrinsics128_BulkConvertByteToNormalizedFloat(int count) => count, (s, d) => SimdUtils.FallbackIntrinsics128.ByteToNormalizedFloat(s.Span, d.Span)); - [Theory] - [MemberData(nameof(ArraySizesDivisibleBy8))] - public void BasicIntrinsics256_BulkConvertByteToNormalizedFloat(int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - TestImpl_BulkConvertByteToNormalizedFloat( - count, - (s, d) => SimdUtils.BasicIntrinsics256.ByteToNormalizedFloat(s.Span, d.Span)); - } - [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int count) => TestImpl_BulkConvertByteToNormalizedFloat( count, (s, d) => SimdUtils.ExtendedIntrinsics.ByteToNormalizedFloat(s.Span, d.Span)); -#if SUPPORTS_RUNTIME_INTRINSICS [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void HwIntrinsics_BulkConvertByteToNormalizedFloat(int count) @@ -212,7 +148,6 @@ static void RunTest(string serialized) => TestImpl_BulkConvertByteToNormalizedFl count, HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE41); } -#endif [Theory] [MemberData(nameof(ArbitraryArraySizes))] @@ -239,18 +174,6 @@ public void FallbackIntrinsics128_BulkConvertNormalizedFloatToByteClampOverflows count, (s, d) => SimdUtils.FallbackIntrinsics128.NormalizedFloatToByteSaturate(s.Span, d.Span)); - [Theory] - [MemberData(nameof(ArraySizesDivisibleBy8))] - public void BasicIntrinsics256_BulkConvertNormalizedFloatToByteClampOverflows(int count) - { - if (this.SkipOnNonAvx2()) - { - return; - } - - TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, (s, d) => SimdUtils.BasicIntrinsics256.NormalizedFloatToByteSaturate(s.Span, d.Span)); - } - [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) => TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( @@ -278,8 +201,6 @@ public void ExtendedIntrinsics_ConvertToSingle(short scale) Assert.Equal(expected2, actual2); } -#if SUPPORTS_RUNTIME_INTRINSICS - [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void HwIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) @@ -299,8 +220,6 @@ static void RunTest(string serialized) => TestImpl_BulkConvertNormalizedFloatToB HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); } -#endif - [Theory] [MemberData(nameof(ArbitraryArraySizes))] public void BulkConvertNormalizedFloatToByteClampOverflows(int count) @@ -325,16 +244,15 @@ public void BulkConvertNormalizedFloatToByteClampOverflows(int count) public void PackFromRgbPlanes_Rgb24(int count) => TestPackFromRgbPlanes( count, (r, g, b, actual) => - SimdUtils.PackFromRgbPlanes(Configuration.Default, r, g, b, actual)); + SimdUtils.PackFromRgbPlanes(r, g, b, actual)); [Theory] [MemberData(nameof(ArbitraryArraySizes))] public void PackFromRgbPlanes_Rgba32(int count) => TestPackFromRgbPlanes( count, (r, g, b, actual) => - SimdUtils.PackFromRgbPlanes(Configuration.Default, r, g, b, actual)); + SimdUtils.PackFromRgbPlanes(r, g, b, actual)); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void PackFromRgbPlanesAvx2Reduce_Rgb24() { @@ -403,7 +321,6 @@ public void PackFromRgbPlanesAvx2Reduce_Rgba32() Assert.Equal(0, bb.Length); Assert.Equal(0, dd.Length); } -#endif internal static void TestPackFromRgbPlanes(int count, Action packMethod) where TPixel : unmanaged, IPixel @@ -422,7 +339,7 @@ internal static void TestPackFromRgbPlanes(int count, Action 0 ? seed : count; float[] source = new Random(seed).GenerateRandomFloatArray(count, -0.2f, 1.2f); byte[] expected = source.Select(NormalizedFloatToByte).ToArray(); - var actual = new byte[count]; + byte[] actual = new byte[count]; convert(source, actual); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs index 28cf92d10f..3d75d34481 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs @@ -4,9 +4,7 @@ // Uncomment this to turn unit tests into benchmarks: // #define BENCHMARKING using System; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; using SixLabors.ImageSharp.Tests.TestUtilities; @@ -424,7 +422,7 @@ public void EqualsToScalar_OneOffEachPosition(int equalsTo) static void RunTest(string serializedEqualsTo) { int equalsTo = FeatureTestRunner.Deserialize(serializedEqualsTo); - int offValue = 0; + const int offValue = 0; // Fill matrix with valid value Block8x8F block = default; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs index 70b921da2d..deeff0992a 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs @@ -22,7 +22,7 @@ public class JpegColorConverterTests private const int TestBufferLength = 40; - private static readonly HwIntrinsics IntrinsicsConfig = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX; + private const HwIntrinsics IntrinsicsConfig = HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX; private static readonly ApproximateColorSpaceComparer ColorSpaceComparer = new(epsilon: Precision); @@ -31,9 +31,7 @@ public class JpegColorConverterTests public static readonly TheoryData Seeds = new() { 1, 2, 3 }; public JpegColorConverterTests(ITestOutputHelper output) - { - this.Output = output; - } + => this.Output = output; private ITestOutputHelper Output { get; } @@ -41,7 +39,7 @@ public JpegColorConverterTests(ITestOutputHelper output) public void GetConverterThrowsExceptionOnInvalidColorSpace() { var invalidColorSpace = (JpegColorSpace)(-1); - Assert.Throws(() => JpegColorConverterBase.GetConverter(invalidColorSpace, 8)); + Assert.Throws(() => JpegColorConverterBase.GetConverter(invalidColorSpace, 8)); } [Fact] @@ -49,7 +47,7 @@ public void GetConverterThrowsExceptionOnInvalidPrecision() { // Valid precisions: 8 & 12 bit int invalidPrecision = 9; - Assert.Throws(() => JpegColorConverterBase.GetConverter(JpegColorSpace.YCbCr, invalidPrecision)); + Assert.Throws(() => JpegColorConverterBase.GetConverter(JpegColorSpace.YCbCr, invalidPrecision)); } [Theory] diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index 8a78ef6485..a3cf66eeb5 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Tests.TestUtilities; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; @@ -33,7 +32,6 @@ public partial class JpegEncoderTests { JpegEncodingColor.Rgb, 100, 0.0238f / 100 }, { JpegEncodingColor.Rgb, 80, 1.3044f / 100 }, { JpegEncodingColor.Rgb, 40, 2.9879f / 100 }, - { JpegEncodingColor.YCbCrRatio444, 100, 0.0780f / 100 }, { JpegEncodingColor.YCbCrRatio444, 80, 1.4585f / 100 }, { JpegEncodingColor.YCbCrRatio444, 40, 3.1413f / 100 }, @@ -44,15 +42,12 @@ public partial class JpegEncoderTests { JpegEncodingColor.YCbCrRatio422, 100, 0.4895f / 100 }, { JpegEncodingColor.YCbCrRatio422, 80, 1.6043f / 100 }, { JpegEncodingColor.YCbCrRatio422, 40, 3.1996f / 100 }, - { JpegEncodingColor.YCbCrRatio420, 100, 0.5790f / 100 }, { JpegEncodingColor.YCbCrRatio420, 80, 1.6692f / 100 }, { JpegEncodingColor.YCbCrRatio420, 40, 3.2324f / 100 }, - { JpegEncodingColor.YCbCrRatio411, 100, 0.6868f / 100 }, { JpegEncodingColor.YCbCrRatio411, 80, 1.7139f / 100 }, { JpegEncodingColor.YCbCrRatio411, 40, 3.2634f / 100 }, - { JpegEncodingColor.YCbCrRatio410, 100, 0.7357f / 100 }, { JpegEncodingColor.YCbCrRatio410, 80, 1.7495f / 100 }, { JpegEncodingColor.YCbCrRatio410, 40, 3.2911f / 100 }, diff --git a/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs b/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs index 0c91c9098a..9e13edeba0 100644 --- a/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs @@ -51,7 +51,6 @@ private static byte[] GetBuffer(int length) return data; } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void RunCalculateAdlerTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCalculateAdlerTest, HwIntrinsics.AllowAll); @@ -69,6 +68,5 @@ private static void RunCalculateAdlerTest() CalculateAdlerAndCompareToReference(testData[i]); } } -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs index a0f93ba297..df364ee50f 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs @@ -147,7 +147,6 @@ private static void RunPaethFilterTest() [Fact] public void PaethFilter_Works() => RunPaethFilterTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void AverageFilter_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAverageFilterTest, HwIntrinsics.AllowAll); @@ -174,6 +173,5 @@ private static void RunPaethFilterTest() [Fact] public void PaethFilter_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPaethFilterTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs index f0611e9c4d..7211d53673 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs @@ -340,7 +340,7 @@ public void WritesFileMarker(TestImageProvider provider) 0x0A, // Line ending CRLF 0x1A, // EOF 0x0A // LF - }; + }; Assert.Equal(expected, data); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs index bb26d182b7..9ce45d3f36 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs @@ -245,7 +245,7 @@ private static byte[] WriteIfdTags64Bit(List values) private static void WriteLong8(TiffStreamWriter writer, byte[] buffer, ulong value) { - if (writer.IsLittleEndian) + if (TiffStreamWriter.IsLittleEndian) { BinaryPrimitives.WriteUInt64LittleEndian(buffer, value); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs index 9e1004cecf..c9854c0227 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs @@ -30,7 +30,8 @@ public class BlackIsZeroTiffColorTests : PhotometricInterpretationTestBase 0b10010000 }; - private static readonly Rgba32[][] BilevelResult4X4 = { + private static readonly Rgba32[][] BilevelResult4X4 = + { new[] { Bit0, Bit1, Bit0, Bit1 }, new[] { Bit1, Bit1, Bit1, Bit1 }, new[] { Bit0, Bit1, Bit1, Bit1 }, @@ -154,41 +155,25 @@ public static IEnumerable Grayscale8_Data [MemberData(nameof(Grayscale4_Data))] [MemberData(nameof(Grayscale8_Data))] public void Decode_WritesPixelData(byte[] inputData, ushort bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZeroTiffColor(new TiffBitsPerSample(bitsPerSample, 0, 0)).Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode( + expectedResult, + pixels => new BlackIsZeroTiffColor(new TiffBitsPerSample(bitsPerSample, 0, 0)).Decode(inputData, pixels, left, top, width, height)); [Theory] [MemberData(nameof(BilevelData))] public void Decode_WritesPixelData_Bilevel(byte[] inputData, int bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZero1TiffColor().Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode(expectedResult, pixels => new BlackIsZero1TiffColor().Decode(inputData, pixels, left, top, width, height)); [Theory] [MemberData(nameof(Grayscale4_Data))] public void Decode_WritesPixelData_4Bit(byte[] inputData, int bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZero4TiffColor().Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode( + expectedResult, + pixels => new BlackIsZero4TiffColor().Decode(inputData, pixels, left, top, width, height)); [Theory] [MemberData(nameof(Grayscale8_Data))] public void Decode_WritesPixelData_8Bit(byte[] inputData, int bitsPerSample, int left, int top, int width, int height, Rgba32[][] expectedResult) - { - AssertDecode(expectedResult, pixels => - { - new BlackIsZero8TiffColor(Configuration.Default).Decode(inputData, pixels, left, top, width, height); - }); - } + => AssertDecode(expectedResult, pixels => new BlackIsZero8TiffColor(Configuration.Default).Decode(inputData, pixels, left, top, width, height)); } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs index 6874019a0d..2d594319e6 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs @@ -25,7 +25,7 @@ public void WriteHeader_WritesValidHeader() using (var writer = new TiffStreamWriter(stream)) { - long firstIfdMarker = encoder.WriteHeader(writer); + long firstIfdMarker = TiffEncoderCore.WriteHeader(writer); } Assert.Equal(new byte[] { 0x49, 0x49, 42, 0, 0x00, 0x00, 0x00, 0x00 }, stream.ToArray()); @@ -39,7 +39,7 @@ public void WriteHeader_ReturnsFirstIfdMarker() using (var writer = new TiffStreamWriter(stream)) { - long firstIfdMarker = encoder.WriteHeader(writer); + long firstIfdMarker = TiffEncoderCore.WriteHeader(writer); Assert.Equal(4, firstIfdMarker); } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs index cc32779819..253381985e 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs @@ -16,7 +16,7 @@ public void IsLittleEndian_IsTrueOnWindows() { using var stream = new MemoryStream(); using var writer = new TiffStreamWriter(stream); - Assert.True(writer.IsLittleEndian); + Assert.True(TiffStreamWriter.IsLittleEndian); } [Theory] diff --git a/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs index c06936c09e..013674cfed 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs @@ -68,7 +68,6 @@ private static void RunCollectColorRedTransformsTest() [Fact] public void CollectColorRedTransforms_Works() => RunCollectColorRedTransformsTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CollectColorBlueTransforms_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectColorBlueTransformsTest, HwIntrinsics.AllowAll); @@ -86,7 +85,5 @@ private static void RunCollectColorRedTransformsTest() [Fact] public void CollectColorRedTransforms_WithoutAvx2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectColorRedTransformsTest, HwIntrinsics.DisableAVX2); -#endif - } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs index c9c3ba5de0..eb7b4dc64b 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs @@ -14,7 +14,7 @@ private static void RunCombinedShannonEntropyTest() { int[] x = { 3, 5, 2, 5, 3, 1, 2, 2, 3, 3, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 1, 0, 0, 2, 1, 1, 0, 3, 1, 2, 3, 2, 3 }; int[] y = { 11, 12, 8, 3, 4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 1, 1, 2, 4, 6, 4 }; - float expected = 884.7585f; + const float expected = 884.7585f; float actual = LosslessUtils.CombinedShannonEntropy(x, y); @@ -147,9 +147,9 @@ private static void RunPredictor11Test() { // arrange uint[] topData = { 4278258949, 4278258949 }; - uint left = 4294839812; + const uint left = 4294839812; short[] scratch = new short[8]; - uint expectedResult = 4294839812; + const uint expectedResult = 4294839812; // act unsafe @@ -168,8 +168,8 @@ private static void RunPredictor12Test() { // arrange uint[] topData = { 4294844413, 4294779388 }; - uint left = 4294844413; - uint expectedResult = 4294779388; + const uint left = 4294844413; + const uint expectedResult = 4294779388; // act unsafe @@ -188,8 +188,8 @@ private static void RunPredictor13Test() { // arrange uint[] topData = { 4278193922, 4278193666 }; - uint left = 4278193410; - uint expectedResult = 4278193154; + const uint left = 4278193410; + const uint expectedResult = 4278193154; // act unsafe @@ -228,7 +228,6 @@ private static void RunPredictor13Test() [Fact] public void TransformColorInverse_Works() => RunTransformColorInverseTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CombinedShannonEntropy_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCombinedShannonEntropyTest, HwIntrinsics.AllowAll); @@ -288,6 +287,5 @@ private static void RunPredictor13Test() [Fact] public void TransformColorInverse_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.DisableAVX2); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs index 9248f37c6d..419d6e2665 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs @@ -301,7 +301,6 @@ private static void RunHadamardTransformTest() [Fact] public void HadamardTransform_Works() => RunHadamardTransformTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void TransformTwo_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformTwoTest, HwIntrinsics.AllowAll); @@ -352,6 +351,5 @@ private static void RunHadamardTransformTest() [Fact] public void HadamardTransform_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunHadamardTransformTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs index bbf35e51b5..d6c2f415e2 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs @@ -5,9 +5,7 @@ using System.IO; using SixLabors.ImageSharp.Formats.Webp.Lossless; using SixLabors.ImageSharp.PixelFormats; -#if SUPPORTS_RUNTIME_INTRINSICS using SixLabors.ImageSharp.Tests.TestUtilities; -#endif using Xunit; namespace SixLabors.ImageSharp.Tests.Formats.Webp @@ -23,7 +21,6 @@ public static void ColorSpaceTransform_WithBikeImage_ProducesExpectedData() public static void ColorSpaceTransform_WithPeakImage_ProducesExpectedData() => RunColorSpaceTransformTestWithPeakImage(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void ColorSpaceTransform_WithPeakImage_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithPeakImage_ProducesExpectedData, HwIntrinsics.AllowAll); @@ -43,7 +40,6 @@ public void ColorSpaceTransform_WithBikeImage_WithoutSSE41_Works() [Fact] public void ColorSpaceTransform_WithBikeImage_WithoutAvx2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithBikeImage_ProducesExpectedData, HwIntrinsics.DisableAVX2); -#endif // Test image: Input\Webp\peak.png private static void RunColorSpaceTransformTestWithPeakImage() @@ -90,7 +86,7 @@ private static void RunColorSpaceTransformTestWithPeakImage() using var image = Image.Load(imgBytes); uint[] bgra = ToBgra(image); - int colorTransformBits = 3; + const int colorTransformBits = 3; int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits); int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits); uint[] transformData = new uint[transformWidth * transformHeight]; @@ -120,7 +116,7 @@ private static void RunColorSpaceTransformTestWithBikeImage() using var image = Image.Load(imgBytes); uint[] bgra = ToBgra(image); - int colorTransformBits = 4; + const int colorTransformBits = 4; int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits); int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits); uint[] transformData = new uint[transformWidth * transformHeight]; diff --git a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs index 86f22d67ae..0e4630fdb7 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs @@ -42,7 +42,6 @@ private static unsafe void RunQuantizeBlockTest() [Fact] public void QuantizeBlock_Works() => RunQuantizeBlockTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void QuantizeBlock_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunQuantizeBlockTest, HwIntrinsics.AllowAll); @@ -51,6 +50,5 @@ private static unsafe void RunQuantizeBlockTest() [Fact] public void QuantizeBlock_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunQuantizeBlockTest, HwIntrinsics.DisableAVX2); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs index d8b4acaa15..2923d1aaa6 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs @@ -138,7 +138,6 @@ private static void RunTwoInverseTransformTest() [Fact] public void TwoInverseTransform_Works() => RunTwoInverseTransformTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void FTransform2_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunFTransform2Test, HwIntrinsics.AllowAll); @@ -162,6 +161,5 @@ private static void RunTwoInverseTransformTest() [Fact] public void TwoInverseTransform_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTwoInverseTransformTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs index 3d8a8dabdf..053f8304df 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs @@ -215,12 +215,10 @@ public void Merge_Works(byte[] reference, byte[] pred) Assert.Equal(1054, alpha); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CollectHistogramTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectHistogramTest, HwIntrinsics.AllowAll); [Fact] public void CollectHistogramTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCollectHistogramTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs index 8f56d831f0..4aa3c1a5b5 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs @@ -99,12 +99,10 @@ private static void RunAddVectorTest() [Fact] public void AddVector_Works() => RunAddVectorTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void AddVector_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddVectorTest, HwIntrinsics.AllowAll); [Fact] public void AddVector_WithoutAVX2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddVectorTest, HwIntrinsics.DisableAVX2); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index 976dc0cb31..5819320e82 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -26,12 +26,10 @@ private static void RunSetCoeffsTest() [Fact] public void RunSetCoeffsTest_Works() => RunSetCoeffsTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void RunSetCoeffsTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.AllowAll); [Fact] public void RunSetCoeffsTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs index b197d01054..1346964ec4 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs @@ -5,10 +5,8 @@ using System.Runtime.InteropServices; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.PixelFormats; -using Xunit; -#if SUPPORTS_RUNTIME_INTRINSICS using SixLabors.ImageSharp.Tests.TestUtilities; -#endif +using Xunit; namespace SixLabors.ImageSharp.Tests.Formats.Webp { @@ -21,7 +19,6 @@ public class WebpCommonUtilsTests [Fact] public void CheckNonOpaque_WithNoneOpaquePixels_Works() => RunCheckNoneOpaqueWithNoneOpaquePixelsTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CheckNonOpaque_WithOpaquePixels_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithOpaquePixelsTest, HwIntrinsics.AllowAll); @@ -45,7 +42,6 @@ public void CheckNonOpaque_WithNoneOpaquePixels_WithoutSse2_Works() [Fact] public void CheckNonOpaque_WithNoneOpaquePixels_WithoutAvx2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithNoneOpaquePixelsTest, HwIntrinsics.DisableAVX2); -#endif private static void RunCheckNoneOpaqueWithNoneOpaquePixelsTest() { @@ -200,7 +196,7 @@ private static void RunCheckNoneOpaqueWithOpaquePixelsTest() for (int length = 8; length < row.Length; length += 8) { // act - noneOpaque = WebpCommonUtils.CheckNonOpaque(row.Slice(0, length)); + noneOpaque = WebpCommonUtils.CheckNonOpaque(row[..length]); // assert Assert.False(noneOpaque); diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs index ac59189527..3f000467d0 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -401,7 +401,6 @@ public void WebpDecoder_ThrowImageFormatException_OnInvalidImages(TestIm } }); -#if SUPPORTS_RUNTIME_INTRINSICS private static void RunDecodeLossyWithHorizontalFilter() { var provider = TestImageProvider.File(TestImageLossyHorizontalFilterPath); @@ -445,6 +444,5 @@ private static void RunDecodeLossyWithComplexFilterTest() [Fact] public void DecodeLossyWithComplexFilterTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunDecodeLossyWithComplexFilterTest, HwIntrinsics.DisableHWIntrinsic); -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs index 27dccf84a5..f16f50b989 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs @@ -326,13 +326,11 @@ public static void RunEncodeLossy_WithPeakImage() image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.Tolerant(0.04f)); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void RunEncodeLossy_WithPeakImage_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunEncodeLossy_WithPeakImage, HwIntrinsics.AllowAll); [Fact] public void RunEncodeLossy_WithPeakImage_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunEncodeLossy_WithPeakImage, HwIntrinsics.DisableHWIntrinsic); -#endif private static ImageComparer GetComparer(int quality) { diff --git a/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs b/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs index 6b4b604914..718dd920fe 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs @@ -26,25 +26,20 @@ public class YuvConversionTests public static void RunUpSampleYuvToRgbTest() { var provider = TestImageProvider.File(TestImageLossyFullPath); - using (Image image = provider.GetImage(WebpDecoder)) - { - image.DebugSave(provider); - image.CompareToOriginal(provider, ReferenceDecoder); - } + using Image image = provider.GetImage(WebpDecoder); + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); } [Fact] public void UpSampleYuvToRgb_Works() => RunUpSampleYuvToRgbTest(); -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void UpSampleYuvToRgb_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunUpSampleYuvToRgbTest, HwIntrinsics.AllowAll); [Fact] public void UpSampleYuvToRgb_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunUpSampleYuvToRgbTest, HwIntrinsics.DisableSSE2); -#endif - [Theory] [WithFile(TestImages.Webp.Yuv, PixelTypes.Rgba32)] public void ConvertRgbToYuv_Works(TestImageProvider provider) @@ -157,8 +152,8 @@ public void ConvertRgbToYuv_Works(TestImageProvider provider) // assert Assert.True(expectedY.AsSpan().SequenceEqual(y)); - Assert.True(expectedU.AsSpan().SequenceEqual(u.Slice(0, expectedU.Length))); - Assert.True(expectedV.AsSpan().SequenceEqual(v.Slice(0, expectedV.Length))); + Assert.True(expectedU.AsSpan().SequenceEqual(u[..expectedU.Length])); + Assert.True(expectedV.AsSpan().SequenceEqual(v[..expectedV.Length])); } [Theory] @@ -263,8 +258,8 @@ public void ConvertRgbToYuv_WithAlpha_Works(TestImageProvider pr // assert Assert.True(expectedY.AsSpan().SequenceEqual(y)); - Assert.True(expectedU.AsSpan().SequenceEqual(u.Slice(0, expectedU.Length))); - Assert.True(expectedV.AsSpan().SequenceEqual(v.Slice(0, expectedV.Length))); + Assert.True(expectedU.AsSpan().SequenceEqual(u[..expectedU.Length])); + Assert.True(expectedV.AsSpan().SequenceEqual(v[..expectedV.Length])); } } } diff --git a/tests/ImageSharp.Tests/Helpers/RuntimeEnvironmentTests.cs b/tests/ImageSharp.Tests/Helpers/RuntimeEnvironmentTests.cs deleted file mode 100644 index 39a5dcccea..0000000000 --- a/tests/ImageSharp.Tests/Helpers/RuntimeEnvironmentTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.InteropServices; -using Xunit; - -#pragma warning disable IDE0022 // Use expression body for methods -namespace SixLabors.ImageSharp.Tests.Helpers -{ - public class RuntimeEnvironmentTests - { - [Fact] - public void CanDetectNetCore() - { -#if NET5_0_OR_GREATER - Assert.False(RuntimeEnvironment.IsNetCore); -#elif NETCOREAPP - Assert.True(RuntimeEnvironment.IsNetCore); -#else - Assert.False(RuntimeEnvironment.IsNetCore); -#endif - } - - [Fact] - public void CanDetectOSPlatform() - { - if (TestEnvironment.IsLinux) - { - Assert.True(RuntimeEnvironment.IsOSPlatform(OSPlatform.Linux)); - } - else if (TestEnvironment.IsMacOS) - { - Assert.True(RuntimeEnvironment.IsOSPlatform(OSPlatform.OSX)); - } - else if (TestEnvironment.IsWindows) - { - Assert.True(RuntimeEnvironment.IsOSPlatform(OSPlatform.Windows)); - } - } - } -} diff --git a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs index a65fd2325f..5b9d430af0 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs @@ -1,11 +1,9 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; using System.Collections.Generic; -using System.IO; using System.Runtime.CompilerServices; -using System.Text; using System.Threading; using Microsoft.DotNet.RemoteExecutor; using SixLabors.ImageSharp.Memory.Internals; @@ -109,7 +107,6 @@ static void LeakPoolInstance() } } -#if NETCOREAPP3_1_OR_GREATER public static readonly bool Is32BitProcess = !Environment.Is64BitProcess; private static readonly List PressureArrays = new(); @@ -121,21 +118,21 @@ public static void GC_Collect_OnHighLoad_TrimsEntirePool() static void RunTest() { Assert.False(Environment.Is64BitProcess); - const int OneMb = 1 << 20; + const int oneMb = 1 << 20; var trimSettings = new UniformUnmanagedMemoryPool.TrimSettings { HighPressureThresholdRate = 0.2f }; GCMemoryInfo memInfo = GC.GetGCMemoryInfo(); - int highLoadThreshold = (int)(memInfo.HighMemoryLoadThresholdBytes / OneMb); + int highLoadThreshold = (int)(memInfo.HighMemoryLoadThresholdBytes / oneMb); highLoadThreshold = (int)(trimSettings.HighPressureThresholdRate * highLoadThreshold); - var pool = new UniformUnmanagedMemoryPool(OneMb, 16, trimSettings); + var pool = new UniformUnmanagedMemoryPool(oneMb, 16, trimSettings); pool.Return(pool.Rent(16)); Assert.Equal(16, UnmanagedMemoryHandle.TotalOutstandingHandles); for (int i = 0; i < highLoadThreshold; i++) { - byte[] array = new byte[OneMb]; + byte[] array = new byte[oneMb]; TouchPage(array); PressureArrays.Add(array); } @@ -163,7 +160,6 @@ static void TouchPage(byte[] b) } } } -#endif } } } diff --git a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs index e002fcc8e2..2cd1c696da 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs @@ -380,7 +380,6 @@ private static void AllocateSingleAndForget(UniformUnmanagedMemoryPoolMemoryAllo } } -#if NETCOREAPP3_1_OR_GREATER [Fact] public void Issue2001_NegativeMemoryReportedByGc() { @@ -393,6 +392,5 @@ static void RunTest() _ = MemoryAllocator.Create(); } } -#endif } } diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs index a21a4f0493..184a6c42e9 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs @@ -14,7 +14,7 @@ public void ReadProfile_NoEntries() { IccReader reader = this.CreateReader(); - IccProfile output = reader.Read(IccTestDataProfiles.Header_Random_Array); + IccProfile output = IccReader.Read(IccTestDataProfiles.Header_Random_Array); Assert.Equal(0, output.Entries.Length); Assert.NotNull(output.Header); @@ -45,7 +45,7 @@ public void ReadProfile_DuplicateEntry() { IccReader reader = this.CreateReader(); - IccProfile output = reader.Read(IccTestDataProfiles.Profile_Random_Array); + IccProfile output = IccReader.Read(IccTestDataProfiles.Profile_Random_Array); Assert.Equal(2, output.Entries.Length); Assert.True(ReferenceEquals(output.Entries[0], output.Entries[1])); diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccWriterTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccWriterTests.cs index 7aa587a327..039d126630 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccWriterTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccWriterTests.cs @@ -18,7 +18,7 @@ public void WriteProfile_NoEntries() { Header = IccTestDataProfiles.Header_Random_Write }; - byte[] output = writer.Write(profile); + byte[] output = IccWriter.Write(profile); Assert.Equal(IccTestDataProfiles.Header_Random_Array, output); } @@ -28,7 +28,7 @@ public void WriteProfile_DuplicateEntry() { IccWriter writer = this.CreateWriter(); - byte[] output = writer.Write(IccTestDataProfiles.Profile_Random_Val); + byte[] output = IccWriter.Write(IccTestDataProfiles.Profile_Random_Val); Assert.Equal(IccTestDataProfiles.Profile_Random_Array, output); } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index c22b5dbcd0..6f11e7aecb 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -20,13 +20,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations [Trait("Category", "PixelFormats")] public partial class PixelOperationsTests { -#pragma warning disable SA1313 // Parameter names should begin with lower-case letter [Theory] [WithBlankImages(1, 1, PixelTypes.All)] public void GetGlobalInstance(TestImageProvider _) where T : unmanaged, IPixel => Assert.NotNull(PixelOperations.Instance); } -#pragma warning restore SA1313 // Parameter names should begin with lower-case letter public abstract class PixelOperationsTests : MeasureFixture where TPixel : unmanaged, IPixel @@ -1059,7 +1057,7 @@ public void ToRgba64Bytes(int count) public void PackFromRgbPlanes(int count) => SimdUtilsTests.TestPackFromRgbPlanes( count, - (r, g, b, actual) => PixelOperations.Instance.PackFromRgbPlanes(this.Configuration, r, g, b, actual)); + (r, g, b, actual) => PixelOperations.Instance.PackFromRgbPlanes(r, g, b, actual)); public delegate void RefAction(ref T1 arg1); diff --git a/tests/ImageSharp.Tests/Primitives/ColorMatrixTests.cs b/tests/ImageSharp.Tests/Primitives/ColorMatrixTests.cs index c214a4caab..2e418c5a7a 100644 --- a/tests/ImageSharp.Tests/Primitives/ColorMatrixTests.cs +++ b/tests/ImageSharp.Tests/Primitives/ColorMatrixTests.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Tests.Primitives { public class ColorMatrixTests { - private readonly ApproximateFloatComparer approximateFloatComparer = new ApproximateFloatComparer(1e-6f); + private readonly ApproximateFloatComparer approximateFloatComparer = new(1e-6f); [Fact] public void ColorMatrixIdentityIsCorrect() @@ -47,8 +47,8 @@ public void ColorMatrixEquality() [Fact] public void ColorMatrixMultiply() { - ColorMatrix value1 = this.CreateAllTwos(); - ColorMatrix value2 = this.CreateAllThrees(); + ColorMatrix value1 = CreateAllTwos(); + ColorMatrix value2 = CreateAllThrees(); var m = default(ColorMatrix); @@ -88,35 +88,34 @@ public void ColorMatrixMultiply() [Fact] public void ColorMatrixMultiplyScalar() { - ColorMatrix m = this.CreateAllTwos(); - Assert.Equal(this.CreateAllFours(), m * 2, this.approximateFloatComparer); + ColorMatrix m = CreateAllTwos(); + Assert.Equal(CreateAllFours(), m * 2, this.approximateFloatComparer); } [Fact] public void ColorMatrixSubtract() { - ColorMatrix m = this.CreateAllOnes() + this.CreateAllTwos(); - Assert.Equal(this.CreateAllThrees(), m); + ColorMatrix m = CreateAllOnes() + CreateAllTwos(); + Assert.Equal(CreateAllThrees(), m); } [Fact] public void ColorMatrixNegate() { - ColorMatrix m = this.CreateAllOnes() * -1F; - Assert.Equal(m, -this.CreateAllOnes()); + ColorMatrix m = CreateAllOnes() * -1F; + Assert.Equal(m, -CreateAllOnes()); } [Fact] public void ColorMatrixAdd() { - ColorMatrix m = this.CreateAllOnes() + this.CreateAllTwos(); - Assert.Equal(this.CreateAllThrees(), m); + ColorMatrix m = CreateAllOnes() + CreateAllTwos(); + Assert.Equal(CreateAllThrees(), m); } [Fact] public void ColorMatrixHashCode() { -#if NETCOREAPP2_1 ColorMatrix m = KnownFilterMatrices.CreateBrightnessFilter(.5F); HashCode hash = default; hash.Add(m.M11); @@ -141,7 +140,6 @@ public void ColorMatrixHashCode() hash.Add(m.M54); Assert.Equal(hash.ToHashCode(), m.GetHashCode()); -#endif } [Fact] @@ -163,9 +161,8 @@ public void ColorMatrixToString() Assert.Equal(expected, m.ToString()); } - private ColorMatrix CreateAllOnes() - { - return new ColorMatrix + private static ColorMatrix CreateAllOnes() + => new() { M11 = 1F, M12 = 1F, @@ -188,11 +185,9 @@ private ColorMatrix CreateAllOnes() M53 = 1F, M54 = 1F }; - } - private ColorMatrix CreateAllTwos() - { - return new ColorMatrix + private static ColorMatrix CreateAllTwos() + => new() { M11 = 2F, M12 = 2F, @@ -215,11 +210,9 @@ private ColorMatrix CreateAllTwos() M53 = 2F, M54 = 2F }; - } - private ColorMatrix CreateAllThrees() - { - return new ColorMatrix + private static ColorMatrix CreateAllThrees() + => new() { M11 = 3F, M12 = 3F, @@ -242,11 +235,9 @@ private ColorMatrix CreateAllThrees() M53 = 3F, M54 = 3F }; - } - private ColorMatrix CreateAllFours() - { - return new ColorMatrix + private static ColorMatrix CreateAllFours() + => new() { M11 = 4F, M12 = 4F, @@ -269,6 +260,5 @@ private ColorMatrix CreateAllFours() M53 = 4F, M54 = 4F }; - } } } diff --git a/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs index b8668b2117..9e0fd2d938 100644 --- a/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs +++ b/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Convolution; using Xunit; @@ -9,7 +8,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution { [Trait("Category", "Processors")] - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "OK. Used for TheoryData compatibility.")] public class DetectEdgesTest : BaseImageOperationsExtensionTest { [Fact] @@ -32,8 +30,8 @@ public void DetectEdges_Rect_EdgeDetector2DProcessorDefaultsSet() Assert.Equal(KnownEdgeDetectorKernels.Sobel, processor.Kernel); } - public static TheoryData EdgeDetector2DKernelData = - new TheoryData + public static TheoryData EdgeDetector2DKernelData { get; } = + new() { { KnownEdgeDetectorKernels.Kayyali, true }, { KnownEdgeDetectorKernels.Kayyali, false }, @@ -91,8 +89,8 @@ public void DetectEdges_Rect_EdgeDetector2DProcessorSet(EdgeDetector2DKernel ker Assert.Equal(kernel, processor.Kernel); } - public static TheoryData EdgeDetectorKernelData = - new TheoryData + public static TheoryData EdgeDetectorKernelData { get; } = + new() { { KnownEdgeDetectorKernels.Laplacian3x3, true }, { KnownEdgeDetectorKernels.Laplacian3x3, false }, @@ -146,8 +144,8 @@ public void DetectEdges_Rect_EdgeDetectorProcessorSet(EdgeDetectorKernel kernel, Assert.Equal(kernel, processor.Kernel); } - public static TheoryData EdgeDetectorCompassKernelData = - new TheoryData + public static TheoryData EdgeDetectorCompassKernelData { get; } = + new() { { KnownEdgeDetectorKernels.Kirsch, true }, { KnownEdgeDetectorKernels.Kirsch, false }, diff --git a/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs index 90f4074845..02bdb82678 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Convolution/DetectEdgesTest.cs @@ -13,7 +13,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution { [Trait("Category", "Processors")] [GroupOutput("Convolution")] - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "OK. Used for TheoryData compatibility.")] public class DetectEdgesTest { private static readonly ImageComparer OpaqueComparer = ImageComparer.TolerantPercentage(0.01F); diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs index 306121fb0e..3d084df079 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs @@ -89,7 +89,6 @@ public void ResizeWithOptions() Assert.Equal(mode, resizeOptions.Mode); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void HwIntrinsics_Resize() { @@ -106,6 +105,5 @@ static void RunTest() RunTest, HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableFMA); } -#endif } } diff --git a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataCurves.cs b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataCurves.cs index d79880d8cc..1b91a11b59 100644 --- a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataCurves.cs +++ b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataCurves.cs @@ -8,7 +8,6 @@ namespace SixLabors.ImageSharp.Tests { internal static class IccTestDataCurves { -#pragma warning disable SA1118 // Parameter should not span multiple lines /// /// Channels: 3 /// @@ -26,7 +25,6 @@ internal static class IccTestDataCurves new IccResponseNumber[] { IccTestDataNonPrimitives.ResponseNumber_Val3, IccTestDataNonPrimitives.ResponseNumber_Val4 }, new IccResponseNumber[] { IccTestDataNonPrimitives.ResponseNumber_Val5, IccTestDataNonPrimitives.ResponseNumber_Val6 }, }); -#pragma warning restore SA1118 // Parameter should not span multiple lines /// /// Channels: 3 diff --git a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs index 1710dba9ae..feabf0e194 100644 --- a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs +++ b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs @@ -78,7 +78,6 @@ public static byte[] CreateHeaderRandomArray(uint size, uint nrOfEntries, byte[] 0x64, 0x63, 0x62, 0x61, // CreatorSignature }, profileId, -#pragma warning disable SA1118 // Parameter should not span multiple lines new byte[] { // Padding @@ -93,12 +92,10 @@ public static byte[] CreateHeaderRandomArray(uint size, uint nrOfEntries, byte[] (byte)(nrOfEntries >> 8), (byte)nrOfEntries }); -#pragma warning restore SA1118 // Parameter should not span multiple lines } public static readonly byte[] Profile_Random_Array = ArrayHelper.Concat( CreateHeaderRandomArray(168, 2, Profile_Random_Id_Array), -#pragma warning disable SA1118 // Parameter should not span multiple lines new byte[] { 0x00, 0x00, 0x00, 0x00, // tag signature (Unknown) @@ -108,7 +105,6 @@ public static byte[] CreateHeaderRandomArray(uint size, uint nrOfEntries, byte[] 0x00, 0x00, 0x00, 0x9C, // tag offset (156) 0x00, 0x00, 0x00, 0x0C, // tag size (12) }, -#pragma warning restore SA1118 // Parameter should not span multiple lines IccTestDataTagDataEntry.TagDataEntryHeader_UnknownArr, IccTestDataTagDataEntry.Unknown_Arr); diff --git a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataTagDataEntry.cs b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataTagDataEntry.cs index 9cbf4e1206..f6d5aadac4 100644 --- a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataTagDataEntry.cs +++ b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataTagDataEntry.cs @@ -37,7 +37,8 @@ internal static class IccTestDataTagDataEntry new object[] { TagDataEntryHeader_CurveArr, TagDataEntryHeader_CurveVal }, }; - public static readonly IccUnknownTagDataEntry Unknown_Val = new IccUnknownTagDataEntry(new byte[] { 0x00, 0x01, 0x02, 0x03 }); + public static readonly IccUnknownTagDataEntry Unknown_Val = new(new byte[] { 0x00, 0x01, 0x02, 0x03 }); + public static readonly byte[] Unknown_Arr = { 0x00, 0x01, 0x02, 0x03 }; public static readonly object[][] UnknownTagDataEntryTestData = @@ -45,7 +46,7 @@ internal static class IccTestDataTagDataEntry new object[] { Unknown_Arr, Unknown_Val, 12u }, }; - public static readonly IccChromaticityTagDataEntry Chromaticity_Val1 = new IccChromaticityTagDataEntry(IccColorantEncoding.ItuRBt709_2); + public static readonly IccChromaticityTagDataEntry Chromaticity_Val1 = new(IccColorantEncoding.ItuRBt709_2); public static readonly byte[] Chromaticity_Arr1 = ArrayHelper.Concat( IccTestDataPrimitives.UInt16_3, IccTestDataPrimitives.UInt16_1, @@ -56,7 +57,7 @@ internal static class IccTestDataTagDataEntry new byte[] { 0x00, 0x00, 0x26, 0x66 }, // 0.150 new byte[] { 0x00, 0x00, 0x0F, 0x5C }); // 0.060 - public static readonly IccChromaticityTagDataEntry Chromaticity_Val2 = new IccChromaticityTagDataEntry( + public static readonly IccChromaticityTagDataEntry Chromaticity_Val2 = new( new double[][] { new double[] { 1, 2 }, @@ -91,7 +92,7 @@ internal static class IccTestDataTagDataEntry new object[] { Chromaticity_Arr2, Chromaticity_Val2 }, }; - public static readonly IccColorantOrderTagDataEntry ColorantOrder_Val = new IccColorantOrderTagDataEntry(new byte[] { 0x00, 0x01, 0x02 }); + public static readonly IccColorantOrderTagDataEntry ColorantOrder_Val = new(new byte[] { 0x00, 0x01, 0x02 }); public static readonly byte[] ColorantOrder_Arr = ArrayHelper.Concat(IccTestDataPrimitives.UInt32_3, new byte[] { 0x00, 0x01, 0x02 }); public static readonly object[][] ColorantOrderTagDataEntryTestData = @@ -99,7 +100,7 @@ internal static class IccTestDataTagDataEntry new object[] { ColorantOrder_Arr, ColorantOrder_Val }, }; - public static readonly IccColorantTableTagDataEntry ColorantTable_Val = new IccColorantTableTagDataEntry( + public static readonly IccColorantTableTagDataEntry ColorantTable_Val = new( new IccColorantTableEntry[] { IccTestDataNonPrimitives.ColorantTableEntry_ValRand1, @@ -116,15 +117,15 @@ internal static class IccTestDataTagDataEntry new object[] { ColorantTable_Arr, ColorantTable_Val }, }; - public static readonly IccCurveTagDataEntry Curve_Val_0 = new IccCurveTagDataEntry(); + public static readonly IccCurveTagDataEntry Curve_Val_0 = new(); public static readonly byte[] Curve_Arr_0 = IccTestDataPrimitives.UInt32_0; - public static readonly IccCurveTagDataEntry Curve_Val_1 = new IccCurveTagDataEntry(1f); + public static readonly IccCurveTagDataEntry Curve_Val_1 = new(1f); public static readonly byte[] Curve_Arr_1 = ArrayHelper.Concat( IccTestDataPrimitives.UInt32_1, IccTestDataPrimitives.UFix8_1); - public static readonly IccCurveTagDataEntry Curve_Val_2 = new IccCurveTagDataEntry(new float[] { 1 / 65535f, 2 / 65535f, 3 / 65535f }); + public static readonly IccCurveTagDataEntry Curve_Val_2 = new(new float[] { 1 / 65535f, 2 / 65535f, 3 / 65535f }); public static readonly byte[] Curve_Arr_2 = ArrayHelper.Concat( IccTestDataPrimitives.UInt32_3, IccTestDataPrimitives.UInt16_1, @@ -138,7 +139,7 @@ internal static class IccTestDataTagDataEntry new object[] { Curve_Arr_2, Curve_Val_2 }, }; - public static readonly IccDataTagDataEntry Data_ValNoASCII = new IccDataTagDataEntry( + public static readonly IccDataTagDataEntry Data_ValNoASCII = new( new byte[] { 0x01, 0x02, 0x03, 0x04 }, false); @@ -148,7 +149,7 @@ internal static class IccTestDataTagDataEntry 0x01, 0x02, 0x03, 0x04 }; - public static readonly IccDataTagDataEntry Data_ValASCII = new IccDataTagDataEntry( + public static readonly IccDataTagDataEntry Data_ValASCII = new( new byte[] { (byte)'A', (byte)'S', (byte)'C', (byte)'I', (byte)'I' }, true); @@ -164,7 +165,7 @@ internal static class IccTestDataTagDataEntry new object[] { Data_ArrASCII, Data_ValASCII, 17u }, }; - public static readonly IccDateTimeTagDataEntry DateTime_Val = new IccDateTimeTagDataEntry(IccTestDataNonPrimitives.DateTime_ValRand1); + public static readonly IccDateTimeTagDataEntry DateTime_Val = new(IccTestDataNonPrimitives.DateTime_ValRand1); public static readonly byte[] DateTime_Arr = IccTestDataNonPrimitives.DateTime_Rand1; public static readonly object[][] DateTimeTagDataEntryTestData = @@ -172,7 +173,7 @@ internal static class IccTestDataTagDataEntry new object[] { DateTime_Arr, DateTime_Val }, }; - public static readonly IccLut16TagDataEntry Lut16_Val = new IccLut16TagDataEntry( + public static readonly IccLut16TagDataEntry Lut16_Val = new( new IccLut[] { IccTestDataLut.LUT16_ValGrad, IccTestDataLut.LUT16_ValGrad }, IccTestDataLut.CLUT16_ValGrad, new IccLut[] { IccTestDataLut.LUT16_ValGrad, IccTestDataLut.LUT16_ValGrad, IccTestDataLut.LUT16_ValGrad }); @@ -193,7 +194,7 @@ internal static class IccTestDataTagDataEntry new object[] { Lut16_Arr, Lut16_Val }, }; - public static readonly IccLut8TagDataEntry Lut8_Val = new IccLut8TagDataEntry( + public static readonly IccLut8TagDataEntry Lut8_Val = new( new IccLut[] { IccTestDataLut.LUT8_ValGrad, IccTestDataLut.LUT8_ValGrad }, IccTestDataLut.CLUT8_ValGrad, new IccLut[] { IccTestDataLut.LUT8_ValGrad, IccTestDataLut.LUT8_ValGrad, IccTestDataLut.LUT8_ValGrad }); @@ -225,20 +226,20 @@ internal static class IccTestDataTagDataEntry TagDataEntryHeader_CurveArr, Curve_Arr_2); - public static readonly IccLutAToBTagDataEntry LutAToB_Val = new IccLutAToBTagDataEntry( - new IccCurveTagDataEntry[] + public static readonly IccLutAToBTagDataEntry LutAToB_Val + = new( + new IccCurveTagDataEntry[] { Curve_Val_0, Curve_Val_1, Curve_Val_2, }, - IccTestDataMatrix.Single_2DArray_ValGrad, - IccTestDataMatrix.Single_1DArray_ValGrad, - new IccCurveTagDataEntry[] { Curve_Val_1, Curve_Val_2, Curve_Val_0 }, - IccTestDataLut.CLUT_Val16, - new IccCurveTagDataEntry[] { Curve_Val_2, Curve_Val_1 }); + IccTestDataMatrix.Single_2DArray_ValGrad, + IccTestDataMatrix.Single_1DArray_ValGrad, + new IccCurveTagDataEntry[] { Curve_Val_1, Curve_Val_2, Curve_Val_0 }, + IccTestDataLut.CLUT_Val16, + new IccCurveTagDataEntry[] { Curve_Val_2, Curve_Val_1 }); -#pragma warning disable SA1115 // Parameter should follow comma public static readonly byte[] LutAToB_Arr = ArrayHelper.Concat( new byte[] { 0x02, 0x03, 0x00, 0x00 }, new byte[] { 0x00, 0x00, 0x00, 0x20 }, // b: 32 @@ -275,14 +276,12 @@ internal static class IccTestDataTagDataEntry CurveFull_1, // 14 bytes new byte[] { 0x00, 0x00 }); // Padding -#pragma warning restore SA1115 // Parameter should follow comma - public static readonly object[][] LutAToBTagDataEntryTestData = { new object[] { LutAToB_Arr, LutAToB_Val }, }; - public static readonly IccLutBToATagDataEntry LutBToA_Val = new IccLutBToATagDataEntry( + public static readonly IccLutBToATagDataEntry LutBToA_Val = new( new[] { Curve_Val_0, @@ -294,10 +293,8 @@ internal static class IccTestDataTagDataEntry IccTestDataLut.CLUT_Val16, new[] { Curve_Val_2, Curve_Val_1, Curve_Val_0 }); -#pragma warning disable SA1115 // Parameter should follow comma public static readonly byte[] LutBToA_Arr = ArrayHelper.Concat( new byte[] { 0x02, 0x03, 0x00, 0x00 }, - new byte[] { 0x00, 0x00, 0x00, 0x20 }, // b: 32 new byte[] { 0x00, 0x00, 0x00, 0x00 }, // matrix: 0 new byte[] { 0x00, 0x00, 0x00, 0x00 }, // m: 0 @@ -320,14 +317,12 @@ internal static class IccTestDataTagDataEntry new byte[] { 0x00, 0x00 }, // Padding CurveFull_0); // 12 bytes -#pragma warning restore SA1115 // Parameter should follow comma - public static readonly object[][] LutBToATagDataEntryTestData = { new object[] { LutBToA_Arr, LutBToA_Val }, }; - public static readonly IccMeasurementTagDataEntry Measurement_Val = new IccMeasurementTagDataEntry( + public static readonly IccMeasurementTagDataEntry Measurement_Val = new( IccStandardObserver.Cie1931Observer, IccTestDataNonPrimitives.XyzNumber_ValVar1, IccMeasurementGeometry.Degree0ToDOrDTo0, @@ -352,7 +347,7 @@ internal static class IccTestDataTagDataEntry private static readonly IccLocalizedString LocalizedString_Rand2_esXL = CreateLocalizedString("es", "XL", IccTestDataPrimitives.Unicode_ValRand2); private static readonly IccLocalizedString LocalizedString_Rand2_xyXL = CreateLocalizedString("xy", "XL", IccTestDataPrimitives.Unicode_ValRand2); private static readonly IccLocalizedString LocalizedString_Rand_en = CreateLocalizedString("en", null, IccTestDataPrimitives.Unicode_ValRand2); - private static readonly IccLocalizedString LocalizedString_Rand_Invariant = new IccLocalizedString(CultureInfo.InvariantCulture, IccTestDataPrimitives.Unicode_ValRand3); + private static readonly IccLocalizedString LocalizedString_Rand_Invariant = new(CultureInfo.InvariantCulture, IccTestDataPrimitives.Unicode_ValRand3); private static IccLocalizedString CreateLocalizedString(string language, string country, string text) { @@ -403,7 +398,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string LocalizedString_Rand2_xyXL, }; - public static readonly IccMultiLocalizedUnicodeTagDataEntry MultiLocalizedUnicode_Val = new IccMultiLocalizedUnicodeTagDataEntry(LocalizedString_RandArr_enUS_deDE); + public static readonly IccMultiLocalizedUnicodeTagDataEntry MultiLocalizedUnicode_Val = new(LocalizedString_RandArr_enUS_deDE); public static readonly byte[] MultiLocalizedUnicode_Arr = ArrayHelper.Concat( IccTestDataPrimitives.UInt32_2, new byte[] { 0x00, 0x00, 0x00, 0x0C }, // 12 @@ -416,7 +411,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string IccTestDataPrimitives.Unicode_Rand2, IccTestDataPrimitives.Unicode_Rand3); - public static readonly IccMultiLocalizedUnicodeTagDataEntry MultiLocalizedUnicode_Val2 = new IccMultiLocalizedUnicodeTagDataEntry(LocalizedString_RandArr_en_Invariant); + public static readonly IccMultiLocalizedUnicodeTagDataEntry MultiLocalizedUnicode_Val2 = new(LocalizedString_RandArr_en_Invariant); public static readonly byte[] MultiLocalizedUnicode_Arr2_Read = ArrayHelper.Concat( IccTestDataPrimitives.UInt32_2, new byte[] { 0x00, 0x00, 0x00, 0x0C }, // 12 @@ -441,7 +436,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string IccTestDataPrimitives.Unicode_Rand2, IccTestDataPrimitives.Unicode_Rand3); - public static readonly IccMultiLocalizedUnicodeTagDataEntry MultiLocalizedUnicode_Val3 = new IccMultiLocalizedUnicodeTagDataEntry(LocalizedString_SameArr_enUS_deDE_esXL_xyXL); + public static readonly IccMultiLocalizedUnicodeTagDataEntry MultiLocalizedUnicode_Val3 = new(LocalizedString_SameArr_enUS_deDE_esXL_xyXL); public static readonly byte[] MultiLocalizedUnicode_Arr3 = ArrayHelper.Concat( IccTestDataPrimitives.UInt32_4, new byte[] { 0x00, 0x00, 0x00, 0x0C }, // 12 @@ -473,7 +468,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { MultiLocalizedUnicode_Arr3, MultiLocalizedUnicode_Val3 }, }; - public static readonly IccMultiProcessElementsTagDataEntry MultiProcessElements_Val = new IccMultiProcessElementsTagDataEntry( + public static readonly IccMultiProcessElementsTagDataEntry MultiProcessElements_Val = new( new IccMultiProcessElement[] { IccTestDataMultiProcessElements.MPE_ValCLUT, @@ -496,11 +491,11 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { MultiProcessElements_Arr, MultiProcessElements_Val }, }; - public static readonly IccNamedColor2TagDataEntry NamedColor2_Val = new IccNamedColor2TagDataEntry( + public static readonly IccNamedColor2TagDataEntry NamedColor2_Val = new( 16909060, ArrayHelper.Fill('A', 31), ArrayHelper.Fill('4', 31), - new IccNamedColor[] { IccTestDataNonPrimitives.NamedColor_ValMin, IccTestDataNonPrimitives.NamedColor_ValMin }); + new IccNamedColor[] { IccTestDataNonPrimitives.NamedColor_ValMin, IccTestDataNonPrimitives.NamedColor_ValMin }); public static readonly byte[] NamedColor2_Arr = ArrayHelper.Concat( new byte[] { 0x01, 0x02, 0x03, 0x04 }, @@ -518,7 +513,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { NamedColor2_Arr, NamedColor2_Val }, }; - public static readonly IccParametricCurveTagDataEntry ParametricCurve_Val = new IccParametricCurveTagDataEntry(IccTestDataCurves.Parametric_ValVar1); + public static readonly IccParametricCurveTagDataEntry ParametricCurve_Val = new(IccTestDataCurves.Parametric_ValVar1); public static readonly byte[] ParametricCurve_Arr = IccTestDataCurves.Parametric_Var1; public static readonly object[][] ParametricCurveTagDataEntryTestData = @@ -526,7 +521,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { ParametricCurve_Arr, ParametricCurve_Val }, }; - public static readonly IccProfileSequenceDescTagDataEntry ProfileSequenceDesc_Val = new IccProfileSequenceDescTagDataEntry( + public static readonly IccProfileSequenceDescTagDataEntry ProfileSequenceDesc_Val = new( new IccProfileDescription[] { IccTestDataNonPrimitives.ProfileDescription_ValRand1, @@ -543,7 +538,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { ProfileSequenceDesc_Arr, ProfileSequenceDesc_Val }, }; - public static readonly IccProfileSequenceIdentifierTagDataEntry ProfileSequenceIdentifier_Val = new IccProfileSequenceIdentifierTagDataEntry( + public static readonly IccProfileSequenceIdentifierTagDataEntry ProfileSequenceIdentifier_Val = new( new IccProfileSequenceIdentifier[] { new IccProfileSequenceIdentifier(IccTestDataNonPrimitives.ProfileId_ValRand, LocalizedString_RandArr_enUS_deDE), @@ -570,7 +565,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { ProfileSequenceIdentifier_Arr, ProfileSequenceIdentifier_Val }, }; - public static readonly IccResponseCurveSet16TagDataEntry ResponseCurveSet16_Val = new IccResponseCurveSet16TagDataEntry( + public static readonly IccResponseCurveSet16TagDataEntry ResponseCurveSet16_Val = new( new IccResponseCurve[] { IccTestDataCurves.Response_ValGrad, @@ -590,7 +585,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { ResponseCurveSet16_Arr, ResponseCurveSet16_Val }, }; - public static readonly IccFix16ArrayTagDataEntry Fix16Array_Val = new IccFix16ArrayTagDataEntry(new float[] { 1 / 256f, 2 / 256f, 3 / 256f }); + public static readonly IccFix16ArrayTagDataEntry Fix16Array_Val = new(new float[] { 1 / 256f, 2 / 256f, 3 / 256f }); public static readonly byte[] Fix16Array_Arr = ArrayHelper.Concat( IccTestDataPrimitives.Fix16_1, IccTestDataPrimitives.Fix16_2, @@ -601,7 +596,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { Fix16Array_Arr, Fix16Array_Val, 20u }, }; - public static readonly IccSignatureTagDataEntry Signature_Val = new IccSignatureTagDataEntry("ABCD"); + public static readonly IccSignatureTagDataEntry Signature_Val = new("ABCD"); public static readonly byte[] Signature_Arr = { 0x41, 0x42, 0x43, 0x44, }; public static readonly object[][] SignatureTagDataEntryTestData = @@ -609,7 +604,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { Signature_Arr, Signature_Val }, }; - public static readonly IccTextTagDataEntry Text_Val = new IccTextTagDataEntry("ABCD"); + public static readonly IccTextTagDataEntry Text_Val = new("ABCD"); public static readonly byte[] Text_Arr = { 0x41, 0x42, 0x43, 0x44 }; public static readonly object[][] TextTagDataEntryTestData = @@ -617,7 +612,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { Text_Arr, Text_Val, 12u }, }; - public static readonly IccUFix16ArrayTagDataEntry UFix16Array_Val = new IccUFix16ArrayTagDataEntry(new float[] { 1, 2, 3 }); + public static readonly IccUFix16ArrayTagDataEntry UFix16Array_Val = new(new float[] { 1, 2, 3 }); public static readonly byte[] UFix16Array_Arr = ArrayHelper.Concat( IccTestDataPrimitives.UFix16_1, IccTestDataPrimitives.UFix16_2, @@ -628,7 +623,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { UFix16Array_Arr, UFix16Array_Val, 20u }, }; - public static readonly IccUInt16ArrayTagDataEntry UInt16Array_Val = new IccUInt16ArrayTagDataEntry(new ushort[] { 1, 2, 3 }); + public static readonly IccUInt16ArrayTagDataEntry UInt16Array_Val = new(new ushort[] { 1, 2, 3 }); public static readonly byte[] UInt16Array_Arr = ArrayHelper.Concat( IccTestDataPrimitives.UInt16_1, IccTestDataPrimitives.UInt16_2, @@ -639,7 +634,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { UInt16Array_Arr, UInt16Array_Val, 14u }, }; - public static readonly IccUInt32ArrayTagDataEntry UInt32Array_Val = new IccUInt32ArrayTagDataEntry(new uint[] { 1, 2, 3 }); + public static readonly IccUInt32ArrayTagDataEntry UInt32Array_Val = new(new uint[] { 1, 2, 3 }); public static readonly byte[] UInt32Array_Arr = ArrayHelper.Concat( IccTestDataPrimitives.UInt32_1, IccTestDataPrimitives.UInt32_2, @@ -650,7 +645,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { UInt32Array_Arr, UInt32Array_Val, 20u }, }; - public static readonly IccUInt64ArrayTagDataEntry UInt64Array_Val = new IccUInt64ArrayTagDataEntry(new ulong[] { 1, 2, 3 }); + public static readonly IccUInt64ArrayTagDataEntry UInt64Array_Val = new(new ulong[] { 1, 2, 3 }); public static readonly byte[] UInt64Array_Arr = ArrayHelper.Concat( IccTestDataPrimitives.UInt64_1, IccTestDataPrimitives.UInt64_2, @@ -661,7 +656,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { UInt64Array_Arr, UInt64Array_Val, 32u }, }; - public static readonly IccUInt8ArrayTagDataEntry UInt8Array_Val = new IccUInt8ArrayTagDataEntry(new byte[] { 1, 2, 3 }); + public static readonly IccUInt8ArrayTagDataEntry UInt8Array_Val = new(new byte[] { 1, 2, 3 }); public static readonly byte[] UInt8Array_Arr = { 1, 2, 3 }; public static readonly object[][] UInt8ArrayTagDataEntryTestData = @@ -669,7 +664,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { UInt8Array_Arr, UInt8Array_Val, 11u }, }; - public static readonly IccViewingConditionsTagDataEntry ViewingConditions_Val = new IccViewingConditionsTagDataEntry( + public static readonly IccViewingConditionsTagDataEntry ViewingConditions_Val = new( IccTestDataNonPrimitives.XyzNumber_ValVar1, IccTestDataNonPrimitives.XyzNumber_ValVar2, IccStandardIlluminant.D50); @@ -684,7 +679,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { ViewingConditions_Arr, ViewingConditions_Val }, }; - public static readonly IccXyzTagDataEntry XYZ_Val = new IccXyzTagDataEntry(new Vector3[] + public static readonly IccXyzTagDataEntry XYZ_Val = new(new Vector3[] { IccTestDataNonPrimitives.XyzNumber_ValVar1, IccTestDataNonPrimitives.XyzNumber_ValVar2, @@ -701,7 +696,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { XYZ_Arr, XYZ_Val, 44u }, }; - public static readonly IccTextDescriptionTagDataEntry TextDescription_Val1 = new IccTextDescriptionTagDataEntry( + public static readonly IccTextDescriptionTagDataEntry TextDescription_Val1 = new( IccTestDataPrimitives.Ascii_ValRand, IccTestDataPrimitives.Unicode_ValRand1, ArrayHelper.Fill('A', 66), @@ -720,7 +715,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string ArrayHelper.Fill((byte)0x41, 66), new byte[] { 0x00 }); // Null terminator - public static readonly IccTextDescriptionTagDataEntry TextDescription_Val2 = new IccTextDescriptionTagDataEntry(IccTestDataPrimitives.Ascii_ValRand, null, null, 0, 0); + public static readonly IccTextDescriptionTagDataEntry TextDescription_Val2 = new(IccTestDataPrimitives.Ascii_ValRand, null, null, 0, 0); public static readonly byte[] TextDescription_Arr2 = ArrayHelper.Concat( new byte[] { 0x00, 0x00, 0x00, 0x0B }, // 11 IccTestDataPrimitives.Ascii_Rand, @@ -736,7 +731,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { TextDescription_Arr2, TextDescription_Val2 }, }; - public static readonly IccCrdInfoTagDataEntry CrdInfo_Val = new IccCrdInfoTagDataEntry( + public static readonly IccCrdInfoTagDataEntry CrdInfo_Val = new( IccTestDataPrimitives.Ascii_ValRand4, IccTestDataPrimitives.Ascii_ValRand1, IccTestDataPrimitives.Ascii_ValRand2, @@ -765,7 +760,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { CrdInfo_Arr, CrdInfo_Val }, }; - public static readonly IccScreeningTagDataEntry Screening_Val = new IccScreeningTagDataEntry( + public static readonly IccScreeningTagDataEntry Screening_Val = new( IccScreeningFlag.DefaultScreens | IccScreeningFlag.UnitLinesPerCm, new IccScreeningChannel[] { IccTestDataNonPrimitives.ScreeningChannel_ValRand1, IccTestDataNonPrimitives.ScreeningChannel_ValRand2 }); @@ -780,7 +775,7 @@ private static IccLocalizedString CreateLocalizedString(string language, string new object[] { Screening_Arr, Screening_Val }, }; - public static readonly IccUcrBgTagDataEntry UcrBg_Val = new IccUcrBgTagDataEntry( + public static readonly IccUcrBgTagDataEntry UcrBg_Val = new( new ushort[] { 3, 4, 6 }, new ushort[] { 9, 7, 2, 5 }, IccTestDataPrimitives.Ascii_ValRand); @@ -815,12 +810,12 @@ private static IccLocalizedString CreateLocalizedString(string language, string MultiLocalizedUnicode_Arr, new byte[] { 0x00, 0x00 }); // padding - public static readonly IccTagTableEntry TagDataEntry_MultiLocalizedUnicodeTable = new IccTagTableEntry( + public static readonly IccTagTableEntry TagDataEntry_MultiLocalizedUnicodeTable = new( IccProfileTag.Unknown, 0, (uint)TagDataEntry_MultiLocalizedUnicodeArr.Length - 2); - public static readonly IccTagTableEntry TagDataEntry_CurveTable = new IccTagTableEntry(IccProfileTag.Unknown, 0, (uint)TagDataEntry_CurveArr.Length - 2); + public static readonly IccTagTableEntry TagDataEntry_CurveTable = new(IccProfileTag.Unknown, 0, (uint)TagDataEntry_CurveArr.Length - 2); public static readonly object[][] TagDataEntryTestData = { diff --git a/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs b/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs index 4dd1e010fc..511b2cef5e 100644 --- a/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs +++ b/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs @@ -122,7 +122,6 @@ public PausedStream(string filePath) protected override void Dispose(bool disposing) => this.innerStream.Dispose(); -#if NETCOREAPP public override void CopyTo(Stream destination, int bufferSize) => this.Await(() => this.innerStream.CopyTo(destination, bufferSize)); public override int Read(Span buffer) @@ -140,6 +139,5 @@ public override void Write(ReadOnlySpan buffer) } public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => this.Await(() => this.innerStream.WriteAsync(buffer, cancellationToken)); -#endif } } diff --git a/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs b/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs index e78659aa6a..e0a6ec860c 100644 --- a/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs +++ b/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs @@ -12,7 +12,6 @@ namespace SixLabors.ImageSharp.Tests [Flags] public enum PixelTypes { -#pragma warning disable SA1602 // Enumeration items should be documented Undefined = 0, A8 = 1 << 0, @@ -75,7 +74,5 @@ public enum PixelTypes // "All" is handled as a separate, individual case instead of using bitwise OR All = 30 - -#pragma warning restore SA1602 // Enumeration items should be documented } } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index a4956ffb7d..7d3a536c88 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -781,7 +781,6 @@ public void Invoke(in RowInterval rows, Span span) internal class AllocatorBufferCapacityConfigurator { -#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete private readonly TestMemoryAllocator allocator; private readonly int pixelSizeInBytes; @@ -790,7 +789,6 @@ public AllocatorBufferCapacityConfigurator(TestMemoryAllocator allocator, int pi this.allocator = allocator; this.pixelSizeInBytes = pixelSizeInBytes; } -#pragma warning restore CS0618 public void InBytes(int totalBytes) => this.allocator.BufferCapacityInBytes = totalBytes; diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs index e660bb1538..fc8ca6c452 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs @@ -5,9 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; -#if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; -#endif using Xunit; using Xunit.Abstractions; @@ -55,7 +53,6 @@ public void AllowsAllHwIntrinsicFeatures() HwIntrinsics.AllowAll); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CanLimitHwIntrinsicBaseFeatures() { @@ -82,7 +79,6 @@ static void AssertDisabled() AssertDisabled, HwIntrinsics.DisableHWIntrinsic); } -#endif [Fact] public void CanLimitHwIntrinsicFeaturesWithIntrinsicsParam() @@ -91,9 +87,8 @@ static void AssertHwIntrinsicsFeatureDisabled(string intrinsic) { Assert.NotNull(intrinsic); - switch ((HwIntrinsics)Enum.Parse(typeof(HwIntrinsics), intrinsic)) + switch (Enum.Parse(intrinsic)) { -#if SUPPORTS_RUNTIME_INTRINSICS case HwIntrinsics.DisableHWIntrinsic: Assert.False(Sse.IsSupported); Assert.False(Sse2.IsSupported); @@ -156,11 +151,10 @@ static void AssertHwIntrinsicsFeatureDisabled(string intrinsic) case HwIntrinsics.DisableLZCNT: Assert.False(Lzcnt.IsSupported); break; -#endif } } - foreach (HwIntrinsics intrinsic in (HwIntrinsics[])Enum.GetValues(typeof(HwIntrinsics))) + foreach (HwIntrinsics intrinsic in Enum.GetValues()) { FeatureTestRunner.RunWithHwIntrinsicsFeature(AssertHwIntrinsicsFeatureDisabled, intrinsic); } @@ -173,10 +167,7 @@ static void AssertHwIntrinsicsFeatureDisabled(string serializable) { Assert.NotNull(serializable); Assert.NotNull(FeatureTestRunner.DeserializeForXunit(serializable)); - -#if SUPPORTS_RUNTIME_INTRINSICS Assert.False(Sse.IsSupported); -#endif } FeatureTestRunner.RunWithHwIntrinsicsFeature( @@ -193,9 +184,8 @@ static void AssertHwIntrinsicsFeatureDisabled(string serializable, string intrin Assert.NotNull(serializable); Assert.NotNull(FeatureTestRunner.DeserializeForXunit(serializable)); - switch ((HwIntrinsics)Enum.Parse(typeof(HwIntrinsics), intrinsic)) + switch (Enum.Parse(intrinsic)) { -#if SUPPORTS_RUNTIME_INTRINSICS case HwIntrinsics.DisableHWIntrinsic: Assert.False(Sse.IsSupported); Assert.False(Sse2.IsSupported); @@ -258,7 +248,6 @@ static void AssertHwIntrinsicsFeatureDisabled(string serializable, string intrin case HwIntrinsics.DisableLZCNT: Assert.False(Lzcnt.IsSupported); break; -#endif } } diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index 46e8b34bc1..f37e89c415 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -369,14 +369,14 @@ public static void DoTestThreadSafe(Action action) } public IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode((TestDecoderOptions)(new() { GeneralOptions = options }), stream, cancellationToken); + => this.Decode((TestDecoderOptions)new() { GeneralOptions = options }, stream, cancellationToken); public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel - => this.Decode((TestDecoderOptions)(new() { GeneralOptions = options }), stream, cancellationToken); + => this.Decode((TestDecoderOptions)new() { GeneralOptions = options }, stream, cancellationToken); public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode((TestDecoderOptions)(new() { GeneralOptions = options }), stream, cancellationToken); + => this.Decode((TestDecoderOptions)new() { GeneralOptions = options }, stream, cancellationToken); public Image Decode(TestDecoderOptions options, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel @@ -414,14 +414,14 @@ public static void DoTestThreadSafe(Action action) } public IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode((TestDecoderWithParametersOptions)(new() { GeneralOptions = options }), stream, cancellationToken); + => this.Decode((TestDecoderWithParametersOptions)new() { GeneralOptions = options }, stream, cancellationToken); public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel - => this.Decode((TestDecoderWithParametersOptions)(new() { GeneralOptions = options }), stream, cancellationToken); + => this.Decode((TestDecoderWithParametersOptions)new() { GeneralOptions = options }, stream, cancellationToken); public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) - => this.Decode((TestDecoderWithParametersOptions)(new() { GeneralOptions = options }), stream, cancellationToken); + => this.Decode((TestDecoderWithParametersOptions)new() { GeneralOptions = options }, stream, cancellationToken); public Image Decode(TestDecoderWithParametersOptions options, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel