diff --git a/.editorconfig b/.editorconfig index 753a4dbc2..f84e6de2a 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 c0e0353c1..5eb77e2d9 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 faa29865f..cfc3d8222 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 000000000..e88c43f83 --- /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 8a7046c9a..2fbb42995 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 @@ namespace SixLabors.ImageSharp.Advanced 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 @@ namespace SixLabors.ImageSharp.Advanced 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 @@ namespace SixLabors.ImageSharp.Advanced /// 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 @@ namespace SixLabors.ImageSharp.Advanced /// 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 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 @@ namespace SixLabors.ImageSharp.Advanced } /// - /// 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 d543a043c..5e3a71270 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 d8fb34891..9cff680e4 100644 --- a/src/ImageSharp/Color/Color.cs +++ b/src/ImageSharp/Color/Color.cs @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp /// /// The . /// + /// Input string is not in the correct format. public static Color Parse(string input) { Guard.NotNull(input, nameof(input)); @@ -241,7 +242,7 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 b72a2eecd..bc84342de 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 899c7d8db..0c46e9b7c 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 2a41fd490..2227b6022 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 a45042ba8..32481bcb5 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 9306606db..6bbcad075 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 e52904c55..b76712843 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 cd2899ee7..fad331101 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 1337af702..82e9a123b 100644 --- a/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs +++ b/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs @@ -5,10 +5,8 @@ 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.ColorSpaces.Companding { @@ -25,10 +23,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding }, 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding [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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding [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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding } } } -#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 60ae18b5c..d200aa83e 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Adapt.cs @@ -150,9 +150,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion 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 1a7c627db..c3dd3b473 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public CieLab ToCieLab(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCieLab(xyzColor); } @@ -190,7 +185,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 06ff11b1e..ec7d48b78 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 5752cb9b1..52c092a2e 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public CieLchuv ToCieLchuv(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCieLchuv(xyzColor); } @@ -156,7 +151,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 486924b9a..572d8875d 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public CieLuv ToCieLuv(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCieLuv(xyzColor); } @@ -187,7 +185,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 603308751..b5d655e68 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 242392acc..d1f0ca489 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public CieXyz ToCieXyz(in Cmyk color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return this.ToCieXyz(rgb); } @@ -233,7 +227,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public CieXyz ToCieXyz(in Hsl color) { - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return this.ToCieXyz(rgb); } @@ -267,7 +261,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion public CieXyz ToCieXyz(in Hsv color) { // Conversion - var rgb = this.ToRgb(color); + Rgb rgb = ToRgb(color); return this.ToCieXyz(rgb); } @@ -367,9 +361,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 664511be9..152a7f7fc 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public Cmyk ToCmyk(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToCmyk(xyzColor); } @@ -186,7 +184,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 666a6b03c..19e1bef0d 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public Hsl ToHsl(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -186,7 +184,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public Hsl ToHsl(Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsl(xyzColor); } @@ -382,14 +380,14 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 615a26e36..c6a3a68d7 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public Hsv ToHsv(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -186,7 +184,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public Hsv ToHsv(Lms color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = this.ToCieXyz(color); return this.ToHsv(xyzColor); } @@ -382,14 +380,14 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 ad2fbd626..0e880ed59 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs @@ -336,7 +336,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 c317c8e8b..c5801b0b4 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public LinearRgb ToLinearRgb(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToLinearRgb(xyzColor); } @@ -361,10 +359,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 be36c46dc..dbaaa4dd0 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs @@ -336,7 +336,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 cfb6d3b76..461ce8c21 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public Rgb ToRgb(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToRgb(xyzColor); } @@ -350,10 +348,10 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 db6dc2133..48bb8ebd6 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// The public YCbCr ToYCbCr(in CieXyy color) { - var xyzColor = this.ToCieXyz(color); + CieXyz xyzColor = ToCieXyz(color); return this.ToYCbCr(xyzColor); } @@ -321,7 +319,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// /// 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 728d7cd22..bb021f610 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 6485da076..9da7826c4 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 0aefeda85..da7d3f509 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 3634ebe99..e852e61be 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion 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 fc064a6de..c2f2e5d29 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 d69fb4697..f894d748b 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 0b4a4a9b8..aa12e511e 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 5db91eb75..619d04d0c 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 533d94465..ac9f1f636 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion [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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion [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 20a03fb41..31b11575b 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 c5a599e9e..70cc064a8 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 de187ee59..9b01c8088 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 a804d1d5f..424b43b12 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs @@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 8a406cb33..ac0ab7311 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbAndCieXyzConverterBase.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbAndCieXyzConverterBase.cs @@ -28,25 +28,22 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion 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 f124fdd80..5f0755969 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToCieXyzConverter.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/LinearRgbToCieXyzConverter.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion { 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 ea5ef2bc1..d8cfa7c56 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 5ce09802c..08a684baa 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 727c89dd7..ac4d85738 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion /// 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 b107aacaf..5723d2691 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion 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 98f9bdb7c..01ea512a6 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 a44aebbb1..284ef4e53 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 c3d808c6c..4b5ea842d 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 5dffea678..abf2c6e81 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 7ca8c3cf0..ee7711890 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 4902d98fd..76d55d04d 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// /// 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 cb4d7d091..2670a2700 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 @@ namespace SixLabors.ImageSharp.ColorSpaces 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 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [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 b49e1234f..000000000 --- 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 e21d9e96b..3018b2d0e 100644 --- a/src/ImageSharp/Common/Extensions/StreamExtensions.cs +++ b/src/ImageSharp/Common/Extensions/StreamExtensions.cs @@ -70,51 +70,5 @@ namespace SixLabors.ImageSharp 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 27a5a40f6..40f80a86f 100644 --- a/src/ImageSharp/Common/Helpers/HexConverter.cs +++ b/src/ImageSharp/Common/Helpers/HexConverter.cs @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Common.Helpers { // 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 a6c6d021c..520c19201 100644 --- a/src/ImageSharp/Common/Helpers/InliningOptions.cs +++ b/src/ImageSharp/Common/Helpers/InliningOptions.cs @@ -18,13 +18,11 @@ namespace SixLabors.ImageSharp 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 c149cc7b6..8be59ca9a 100644 --- a/src/ImageSharp/Common/Helpers/Numerics.cs +++ b/src/ImageSharp/Common/Helpers/Numerics.cs @@ -5,10 +5,8 @@ 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 { @@ -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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp if (adjustedCount > 0) { - ClampImpl(span.Slice(0, adjustedCount), min, max); + ClampImpl(span[..adjustedCount], min, max); } return adjustedCount; @@ -512,7 +498,6 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp } } else -#endif { ref Vector4 vectorsRef = ref MemoryMarshal.GetReference(vectors); ref Vector4 vectorsEnd = ref Unsafe.Add(ref vectorsRef, vectors.Length); @@ -727,8 +707,6 @@ namespace SixLabors.ImageSharp } } -#if SUPPORTS_RUNTIME_INTRINSICS - /// /// Performs a linear interpolation between two values based on the given weighting. /// @@ -752,7 +730,6 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp // 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 @@ namespace SixLabors.ImageSharp /// 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 925925ff9..000000000 --- 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 000000000..9c8348c0d --- /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 0d27ea437..9cd7db10d 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 @@ namespace SixLabors.ImageSharp // 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 @@ namespace SixLabors.ImageSharp // 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 @@ namespace SixLabors.ImageSharp // 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 7e878677f..000000000 --- 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 336ff3abc..3a143cda2 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -21,12 +21,7 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 c035ac72f..92c5bf5fb 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs @@ -33,12 +33,10 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp ref ByteVector4 sBase = ref Unsafe.As(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 @@ namespace SixLabors.ImageSharp d.Y = s.Y; d.Z = s.Z; d.W = s.W; - d *= Scale; + d *= scale; Unsafe.Add(ref dBase, i) = d; } } diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs index ceeba0faa..177f4d72b 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.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; @@ -67,12 +66,12 @@ namespace SixLabors.ImageSharp 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..]; } } } @@ -101,12 +100,12 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp } 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp } 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 @@ namespace SixLabors.ImageSharp } } } -#endif diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs b/src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs index fb62cb77e..1643234b1 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 @@ namespace SixLabors.ImageSharp { [MethodImpl(InliningOptions.ShortMethod)] internal static void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, @@ -25,13 +22,11 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp [MethodImpl(InliningOptions.ShortMethod)] internal static void PackFromRgbPlanes( - Configuration configuration, ReadOnlySpan redChannel, ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, @@ -51,13 +45,11 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp } 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 @@ namespace SixLabors.ImageSharp } 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 db86afd64..1459601ea 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs @@ -25,9 +25,7 @@ namespace SixLabors.ImageSharp { 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 @@ namespace SixLabors.ImageSharp { 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 @@ namespace SixLabors.ImageSharp // 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 @@ namespace SixLabors.ImageSharp { 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 @@ namespace SixLabors.ImageSharp { 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 @@ namespace SixLabors.ImageSharp 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 0384cc4ed..1a8d50a5d 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -6,11 +6,8 @@ using System.Diagnostics; 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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp return Unsafe.As, Vector>(ref vRound); } else -#endif { var magic0 = new Vector(int.MinValue); // 0x80000000 var sgn0 = Vector.AsVectorSingle(magic0); @@ -87,13 +81,8 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp { 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 ba7bdb0e0..09bb40312 100644 --- a/src/ImageSharp/Common/Helpers/UnitConverter.cs +++ b/src/ImageSharp/Common/Helpers/UnitConverter.cs @@ -114,11 +114,10 @@ namespace SixLabors.ImageSharp.Common.Helpers 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 7c3b4ae18..d8234e1b8 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib // 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib return adler; } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported && buffer.Length >= MinBufferSize) { return CalculateAvx2(adler, buffer); @@ -77,13 +72,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib } 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib s2 %= BASE; } -#endif [MethodImpl(InliningOptions.HotPath | InliningOptions.ShortMethod)] private static unsafe uint CalculateScalar(uint adler, ReadOnlySpan buffer) @@ -301,7 +291,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 0d900cc17..757682a3f 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib /// public const uint SeedValue = 0U; -#if SUPPORTS_RUNTIME_INTRINSICS private const int MinBufferSize = 64; private const int ChunksizeMask = 15; @@ -35,7 +32,6 @@ namespace SixLabors.ImageSharp.Compression.Zlib 0x0163cd6124, 0x0000000000, // k5, k0 0x01db710641, 0x01f7011641 // polynomial }; -#endif /// /// Calculates the CRC checksum with the bytes taken from the span. @@ -60,21 +56,14 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 a77c22bf8..2d19aabb5 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs @@ -276,8 +276,8 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib /// 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 9ba9d34b1..5b8673da8 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs @@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 @@ namespace SixLabors.ImageSharp.Compression.Zlib 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 b24150faf..1ab6349f0 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib { 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 ea1c4eea2..76c2b31b3 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp 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 274486cec..2cd286cd6 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 @@ namespace SixLabors.ImageSharp.Diagnostics } // 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 298982f8d..0b4b98749 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -491,7 +491,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp // 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp // 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp // 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// /// 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 257159bd2..b216fd7a5 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -160,10 +160,10 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 60aa6732c..ac3bc9d3c 100644 --- a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs +++ b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs @@ -308,7 +308,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 @@ namespace SixLabors.ImageSharp.Formats.Bmp 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 8f16c6ecc..e21f21f7b 100644 --- a/src/ImageSharp/Formats/DecoderOptions.cs +++ b/src/ImageSharp/Formats/DecoderOptions.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Formats /// /// 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 @@ namespace SixLabors.ImageSharp.Formats /// /// 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 bb45c8364..f354e42f3 100644 --- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs @@ -108,10 +108,10 @@ namespace SixLabors.ImageSharp.Formats.Gif 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 @@ namespace SixLabors.ImageSharp.Formats.Gif 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 @@ namespace SixLabors.ImageSharp.Formats.Gif } 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 @@ namespace SixLabors.ImageSharp.Formats.Gif /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Gif /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Gif } } - var descriptor = new GifLogicalScreenDescriptor( + GifLogicalScreenDescriptor descriptor = new( width: (ushort)width, height: (ushort)height, packed: packedValue, @@ -332,14 +332,14 @@ namespace SixLabors.ImageSharp.Formats.Gif // 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 @@ namespace SixLabors.ImageSharp.Formats.Gif 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 @@ namespace SixLabors.ImageSharp.Formats.Gif /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Gif 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 @@ namespace SixLabors.ImageSharp.Formats.Gif 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 @@ namespace SixLabors.ImageSharp.Formats.Gif 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 07e0f6f0c..9f7755b01 100644 --- a/src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs +++ b/src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Formats.Gif { 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 d9ee93883..8965ae345 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 d3a621e7b..9f8d8e4d0 100644 --- a/src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs +++ b/src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs @@ -55,11 +55,11 @@ namespace SixLabors.ImageSharp.Formats.Gif // 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 9f3f0d47f..78e797dcd 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Formats 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 8eba118fd..82eb8324a 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components public Vector256 V67; } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs index 040f7092f..8462cf64b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs @@ -5,11 +5,10 @@ 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 using System.Text; +using SixLabors.ImageSharp.Common.Helpers; namespace SixLabors.ImageSharp.Formats.Jpeg.Components { @@ -188,7 +187,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components return -1; } else -#endif { nint index = Size - 1; ref short elemRef = ref Unsafe.As(ref this); @@ -245,53 +242,46 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 2a03f911b..4c19510b7 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index d2f3e9664..16d95f99f 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -5,11 +5,10 @@ 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 using System.Text; +using SixLabors.ImageSharp.Common.Helpers; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Formats.Jpeg.Components @@ -160,10 +159,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components this.V7 = Avx.Multiply(this.V7, other.V7); } else -#endif { this.V0L *= other.V0L; this.V0R *= other.V0R; @@ -243,10 +239,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components ZigZag.ApplyTransposingZigZagOrderingSsse3(ref dest); } else -#endif { for (int i = 0; i < Size; i++) { @@ -339,6 +331,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components && 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 8edaa2efe..63e112dd7 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs index 26e879185..0fc1fcd55 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs index 5fd97e368..08247e7da 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs index 219584b05..62e0fc1b6 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs index f4549911e..dea9fa0a7 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs index 4af31abac..c9b0054c3 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs index c2e01df99..c159ed7d2 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs @@ -20,6 +20,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Returns the s for the YCbCr colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetYCbCrConverter(int precision) { if (JpegColorConverterAvx.IsSupported) @@ -144,6 +150,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Returns the s for the YccK colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetYccKConverter(int precision) { if (JpegColorConverterAvx.IsSupported) @@ -162,6 +169,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// Returns the s for the CMYK colorspace. /// + /// The precision in bits. private static JpegColorConverterBase GetCmykConverter(int precision) { if (JpegColorConverterAvx.IsSupported) @@ -180,6 +188,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// /// 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 ae97c7e54..21727bc99 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ArithmeticScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ArithmeticScanDecoder.cs @@ -225,10 +225,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { 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 f3ceb3584..185e5b06b 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// 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 9f1d4d91f..ed678bd2b 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs @@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder 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 c96f4acc2..938815dae 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder // 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 18afff738..feb1ae8ee 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder 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 f8f7cdfe8..fe61df5e3 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs @@ -541,7 +541,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder // 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 97f051c76..1a262f480 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs @@ -122,16 +122,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder 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 19349e454..4bc4181ff 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs b/src/ImageSharp/Formats/Jpeg/Components/FloatingPointDCT.cs index 37ec6e190..cf0d69ef4 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components /// 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 c899cf3ad..5872d4767 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components [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 ee1ec501b..2fa1d835e 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } } -#endif diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index c91749f95..50c08eb77 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -213,7 +213,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg switch (fileMarker.Marker) { case JpegConstants.Markers.SOI: - break; case JpegConstants.Markers.RST0: case JpegConstants.Markers.RST7: break; @@ -335,7 +334,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg // 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg { 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg { if (this.hasIptc) { - var profile = new IptcProfile(this.iptcData); - this.Metadata.IptcProfile = profile; + this.Metadata.IptcProfile = new IptcProfile(this.iptcData); } } @@ -681,8 +677,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg { if (this.hasXmp) { - var profile = new XmpProfile(this.xmpData); - this.Metadata.XmpProfile = profile; + this.Metadata.XmpProfile = new XmpProfile(this.xmpData); } } @@ -723,7 +718,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg } 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg } // 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg break; } - blockDataSpan = blockDataSpan.Slice(dataStartIdx + resourceDataSize); + blockDataSpan = blockDataSpan[(dataStartIdx + resourceDataSize)..]; } } } @@ -971,7 +969,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg { // 8 bit values case 0: - { // Validate: 8 bit table needs exactly 64 bytes if (remaining < 64) { @@ -1103,11 +1100,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg } break; - } // 16 bit values case 1: - { // Validate: 16 bit table needs exactly 128 bytes if (remaining < 128) { @@ -1124,14 +1119,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg } break; - } // Unknown precision - error default: - { JpegThrowHelper.ThrowBadQuantizationTablePrecision(tablePrecision); break; - } } // Estimating quality @@ -1139,17 +1131,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg { // 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg tableType, tableIndex, huffmanLengthsSpan, - huffmanValuesSpan.Slice(0, codeLengthSum), + huffmanValuesSpan[..codeLengthSum], tableWorkspace); } } @@ -1399,6 +1387,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg 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 fbbe210ff..61b4a36ad 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Jpeg /// /// 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 25c7ee450..431eea4c4 100644 --- a/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs +++ b/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs @@ -145,17 +145,17 @@ namespace SixLabors.ImageSharp.Formats.Pbm 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 b8d776a37..4446d4b18 100644 --- a/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs @@ -18,13 +18,11 @@ namespace SixLabors.ImageSharp.Formats.Pbm 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 b858d1e63..d989b6e66 100644 --- a/src/ImageSharp/Formats/Pbm/PlainEncoder.cs +++ b/src/ImageSharp/Formats/Pbm/PlainEncoder.cs @@ -94,7 +94,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm 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 @@ namespace SixLabors.ImageSharp.Formats.Pbm 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 @@ namespace SixLabors.ImageSharp.Formats.Pbm 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 @@ namespace SixLabors.ImageSharp.Formats.Pbm 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 8ad2c5a4a..31b845e19 100644 --- a/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs +++ b/src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Chunks /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Chunks /// 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 b381442bd..4471b355e 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters // 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters offset += 4; } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline, int bytesPerPixel) @@ -139,7 +132,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -210,7 +202,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters 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 fd2d9eab4..c0e14d4ab 100644 --- a/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs @@ -23,8 +23,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters { // 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 03d883454..0676f618b 100644 --- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs @@ -5,11 +5,8 @@ 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.Png.Filters { @@ -38,20 +35,16 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters // 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters } } -#endif - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline, int bytesPerPixel) { @@ -168,7 +159,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -213,7 +203,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters return upperLeft; } -#if SUPPORTS_RUNTIME_INTRINSICS private static Vector256 PaethPredictor(Vector256 left, Vector256 above, Vector256 upleft) { Vector256 zero = Vector256.Zero; @@ -324,6 +312,5 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters left: above, right: upperLeft)); } -#endif } } diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs index a7044837e..063cc11c3 100644 --- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs @@ -5,11 +5,8 @@ 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.Png.Filters { @@ -29,19 +26,16 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters offset += 4; } } -#endif private static void DecodeScalar(Span scanline, int bytesPerPixel) { @@ -110,7 +103,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters sum += Numerics.Abs(unchecked((sbyte)res)); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -151,7 +143,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters 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 c5003d111..e80c5d22b 100644 --- a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs +++ b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs @@ -5,11 +5,8 @@ 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.Png.Filters { @@ -30,7 +27,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters { DebugGuard.MustBeSameSized(scanline, previousScanline, nameof(scanline)); -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { DecodeAvx2(scanline, previousScanline); @@ -40,13 +36,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters 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 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters offset++; } } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void DecodeScalar(Span scanline, Span previousScanline) @@ -150,7 +143,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters int x = 0; -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Vector256 zero = Vector256.Zero; @@ -191,7 +183,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters 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 6ab9f4c4b..3d9fc68fa 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png { 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png break; } - this.ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); + ReadPhysicalChunk(metadata, chunk.Data.GetSpan()); break; case PngChunkType.Gamma: if (this.colorMetadataOnly) @@ -281,7 +282,7 @@ namespace SixLabors.ImageSharp.Formats.Png break; } - this.ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); + ReadGammaChunk(pngMetadata, chunk.Data.GetSpan()); break; case PngChunkType.Data: @@ -343,7 +344,7 @@ namespace SixLabors.ImageSharp.Formats.Png { 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png { 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 @@ namespace SixLabors.ImageSharp.Formats.Png { 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png } 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png return false; } - this.MergeOrSetExifProfile(metadata, new ExifProfile(exifBlob), replaceExistingKeys: false); + MergeOrSetExifProfile(metadata, new ExifProfile(exifBlob), replaceExistingKeys: false); return true; } @@ -1205,13 +1195,13 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png { 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png PngMetadata pngMetadata = metadata.GetPngMetadata(); int zeroIndexKeyword = data.IndexOf((byte)0); - if (zeroIndexKeyword < PngConstants.MinTextKeywordLength || zeroIndexKeyword > 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 @@ namespace SixLabors.ImageSharp.Formats.Png } int langStartIdx = zeroIndexKeyword + 3; - int languageLength = data.Slice(langStartIdx).IndexOf((byte)0); + int languageLength = data[langStartIdx..].IndexOf((byte)0); if (languageLength < 0) { return; @@ -1366,11 +1338,11 @@ namespace SixLabors.ImageSharp.Formats.Png string language = PngConstants.LanguageEncoding.GetString(data.Slice(langStartIdx, languageLength)); int translatedKeywordStartIdx = langStartIdx + languageLength + 1; - int translatedKeywordLength = data.Slice(translatedKeywordStartIdx).IndexOf((byte)0); + int translatedKeywordLength = data[translatedKeywordStartIdx..].IndexOf((byte)0); string translatedKeyword = PngConstants.TranslatedEncoding.GetString(data.Slice(translatedKeywordStartIdx, translatedKeywordLength)); - 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 @@ namespace SixLabors.ImageSharp.Formats.Png int dataStartIdx = translatedKeywordStartIdx + translatedKeywordLength + 1; if (compressionFlag == 1) { - 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 @@ namespace SixLabors.ImageSharp.Formats.Png { 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png // 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 9ae8f299a..7ba28393d 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -8,6 +8,7 @@ using System.IO; 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 @@ namespace SixLabors.ImageSharp.Formats.Png } } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Png switch (this.bytesPerPixel) { case 4: - { + // 8 bit Rgba PixelOperations.Instance.ToRgba32Bytes( this.configuration, @@ -323,10 +318,9 @@ namespace SixLabors.ImageSharp.Formats.Png rawScanlineSpan, rowSpan.Length); break; - } case 3: - { + // 8 bit Rgb PixelOperations.Instance.ToRgb24Bytes( this.configuration, @@ -334,10 +328,9 @@ namespace SixLabors.ImageSharp.Formats.Png rawScanlineSpan, rowSpan.Length); break; - } case 8: - { + // 16 bit Rgba using (IMemoryOwner rgbaBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { @@ -357,10 +350,9 @@ namespace SixLabors.ImageSharp.Formats.Png } break; - } default: - { + // 16 bit Rgb using (IMemoryOwner rgbBuffer = this.memoryAllocator.Allocate(rowSpan.Length)) { @@ -379,7 +371,6 @@ namespace SixLabors.ImageSharp.Formats.Png } break; - } } } @@ -412,8 +403,6 @@ namespace SixLabors.ImageSharp.Formats.Png case PngColorType.GrayscaleWithAlpha: this.CollectGrayscaleBytes(rowSpan); break; - case PngColorType.Rgb: - case PngColorType.RgbWithAlpha: default: this.CollectTPixelBytes(rowSpan); break; @@ -423,6 +412,8 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png } 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png byte[] buffer; int bufferLength; - using (var memoryStream = new MemoryStream()) + using (MemoryStream memoryStream = new()) { - using (var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, this.options.CompressionLevel)) + using (ZlibDeflateStream deflateStream = new(this.memoryAllocator, memoryStream, this.options.CompressionLevel)) { if (this.options.InterlaceMethod == PngInterlaceMode.Adam7) { @@ -1173,7 +1155,7 @@ namespace SixLabors.ImageSharp.Formats.Png 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 @@ namespace SixLabors.ImageSharp.Formats.Png 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 da747a189..3e4609aad 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 @@ namespace SixLabors.ImageSharp.Formats.Png } // 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 3d495cba6..7db26b60b 100644 --- a/src/ImageSharp/Formats/Png/PngTextData.cs +++ b/src/ImageSharp/Formats/Png/PngTextData.cs @@ -72,9 +72,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// 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 7cf954f1d..c62775f87 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 0f46d5953..d901759d1 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -826,7 +826,7 @@ namespace SixLabors.ImageSharp.Formats.Tga 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 @@ namespace SixLabors.ImageSharp.Formats.Tga 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 fa0ea6f90..5cfdf3022 100644 --- a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs @@ -5,6 +5,7 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Formats.Tga imageDescriptor |= 0x1; } - var fileHeader = new TgaFileHeader( + TgaFileHeader fileHeader = new( idLength: 0, colorMapType: 0, imageType: imageType, @@ -158,8 +159,6 @@ namespace SixLabors.ImageSharp.Formats.Tga case TgaBitsPerPixel.Pixel32: this.Write32Bit(stream, pixels); break; - default: - break; } } @@ -181,7 +180,7 @@ namespace SixLabors.ImageSharp.Formats.Tga { TPixel currentPixel = pixelRow[x]; currentPixel.ToRgba32(ref color); - byte equalPixelCount = this.FindEqualPixels(pixelRow, x); + byte equalPixelCount = FindEqualPixels(pixelRow, x); if (equalPixelCount > 0) { @@ -193,7 +192,7 @@ namespace SixLabors.ImageSharp.Formats.Tga else { // Write Raw Packet (i.e., Non-Run-Length Encoded): - byte unEqualPixelCount = this.FindUnEqualPixels(pixelRow, x); + byte unEqualPixelCount = FindUnEqualPixels(pixelRow, x); stream.WriteByte(unEqualPixelCount); this.WritePixel(stream, currentPixel, color); x++; @@ -227,7 +226,7 @@ namespace SixLabors.ImageSharp.Formats.Tga 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 @@ namespace SixLabors.ImageSharp.Formats.Tga stream.WriteByte(color.R); stream.WriteByte(color.A); break; - default: - break; } } @@ -258,7 +255,7 @@ namespace SixLabors.ImageSharp.Formats.Tga /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tga /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tga /// /// 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 a29eac21e..61b92d731 100644 --- a/src/ImageSharp/Formats/Tga/TgaMetadata.cs +++ b/src/ImageSharp/Formats/Tga/TgaMetadata.cs @@ -20,9 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Tga /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tga 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 01613222e..472ceb21e 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors { 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 06e2d663c..5c9a70729 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors 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 11bc49f27..7c3ecc643 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T4BitCompressor.cs @@ -93,14 +93,14 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors 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 7e0b6042c..99b4a9fcc 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs @@ -61,12 +61,12 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors { 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors // 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors } 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors 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 511c6914f..c43f24774 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs @@ -195,191 +195,191 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors } } - return MakeupRunLength[MakeupRunLength.Length - 1]; + return MakeupRunLength[^1]; } /// @@ -413,14 +413,14 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors 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 bb2828b91..1b66cbf80 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 ef44263a5..d2247e2d2 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors { 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors { 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 230f9f5c9..80abe0e85 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 1a105e96a..2c10edbea 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors 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 db93406a0..587d302c6 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors { 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 ab8f51844..406d6ef74 100644 --- a/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs +++ b/src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs @@ -235,7 +235,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression 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 e9be797b4..d68d70e9b 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs @@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation 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 b74c43ceb..10c61a6d0 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation 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 94ba69785..074661095 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation 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 ab5a21ac2..be10495e7 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation 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 47c2ae5ad..45f530d62 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation 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 2caede066..36832a198 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs @@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation 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 2412d166b..d277af900 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff 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 16071001d..9ccd4416f 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff // 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff } 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff } 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 8d9c6c2b4..926dbf1c0 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs @@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers grayRowIdx++; } - compressor.CompressStrip(pixelAsGraySpan.Slice(0, stripPixels), height); + compressor.CompressStrip(pixelAsGraySpan[..stripPixels], height); }); } else @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers { 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 19b5e5f88..5bb39771e 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs @@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers 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 8e123c22f..19d071c9e 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers } } - compressor.CompressStrip(rows4bit.Slice(0, idx4bitRows), height); + compressor.CompressStrip(rows4bit[..idx4bitRows], height); } else { @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers indexedPixelsRowIdx++; } - compressor.CompressStrip(indexedPixels.Slice(0, stripPixels), height); + compressor.CompressStrip(indexedPixels[..stripPixels], height); } } @@ -119,7 +119,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers 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 667f75be4..d35d16948 100644 --- a/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs +++ b/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers /// 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 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers /// 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 3a118fc0e..a2628a1db 100644 --- a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs +++ b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs @@ -6,13 +6,11 @@ using System.Buffers; 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp } prev = dst; - dst = dst.Slice(stride); + dst = dst[stride..]; } this.PrevRow = lastRow - 1; @@ -234,8 +232,8 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp } } else -#endif { byte pred = (byte)(prev.IsEmpty ? 0 : prev[0]); @@ -366,7 +362,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } else { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { nint i; @@ -386,7 +381,6 @@ namespace SixLabors.ImageSharp.Formats.Webp } } else -#endif { for (int i = 0; i < width; i++) { diff --git a/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs b/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs index 50af4b19d..ae8ac31dd 100644 --- a/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs +++ b/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitReader { this.Data = memoryAllocator.Allocate(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 e1639b899..24761213e 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitReader range = split + 1; } - int shift = 7 ^ Numerics.Log2(range); + int shift = 7 ^ BitOperations.Log2(range); range <<= shift; this.bits -= shift; @@ -132,7 +133,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitReader 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitReader { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitReader } [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 ecf87d8b5..ed41c29fe 100644 --- a/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs +++ b/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs @@ -5,7 +5,6 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter 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 7b9a79a2e..a218d50f4 100644 --- a/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs +++ b/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs @@ -215,7 +215,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter { if (this.PutBit(s >= 2, p[0])) { - p = p.Slice(1); + p = p[1..]; } this.PutBit(s & 1, p[1]); @@ -433,27 +433,27 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter 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 78494004d..cb4d6d654 100644 --- a/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs +++ b/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs @@ -150,21 +150,21 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter { 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 8c5aa43f5..88d6261cf 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs @@ -252,7 +252,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless while (i < pixelCount) { int maxLen = LosslessUtils.MaxFindCopyLength(pixelCount - i); - int rleLen = LosslessUtils.FindMatchLength(bgra.Slice(i), bgra.Slice(i - 1), 0, maxLen); - int prevRowLen = i < xSize ? 0 : LosslessUtils.FindMatchLength(bgra.Slice(i), bgra.Slice(i - xSize), 0, maxLen); + int rleLen = LosslessUtils.FindMatchLength(bgra[i..], bgra[(i - 1)..], 0, maxLen); + int prevRowLen = i < xSize ? 0 : LosslessUtils.FindMatchLength(bgra[i..], bgra[(i - xSize)..], 0, maxLen); if (rleLen >= 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 06e3c88fc..d80cdc275 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 7bd206391..515ae7a7d 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs @@ -402,7 +402,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { 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 23b355ca4..cb826f75d 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else if (Sse2.IsSupported) @@ -154,11 +152,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - AddGreenToBlueAndRedScalar(pixelData.Slice((int)i)); + AddGreenToBlueAndRedScalar(pixelData[(int)i..]); } } else -#endif { AddGreenToBlueAndRedScalar(pixelData); } @@ -180,10 +177,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else if (Sse2.IsSupported) @@ -238,11 +234,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (i != numPixels) { - SubtractGreenFromBlueAndRedScalar(pixelData.Slice((int)i)); + SubtractGreenFromBlueAndRedScalar(pixelData[(int)i..]); } } else -#endif { SubtractGreenFromBlueAndRedScalar(pixelData); } @@ -375,11 +370,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// The 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless if (idx != pixelData.Length) { - TransformColorInverseScalar(m, pixelData.Slice((int)idx)); + TransformColorInverseScalar(m, pixelData[(int)idx..]); } } else -#endif { TransformColorInverseScalar(m, pixelData); } @@ -753,7 +744,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// Shanon entropy. public static float CombinedShannonEntropy(Span x, Span y) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { double retVal = 0.0d; @@ -906,7 +896,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless return (float)retVal; } else -#endif { double retVal = 0.0d; uint sumX = 0, sumXY = 0; @@ -1053,7 +1042,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } 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 db1273f4e..b2753ab22 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 e2dd8c644..1383eba78 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs @@ -230,8 +230,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless transparentColorMode, usedSubtractGreen, nearLossless, - argb.Slice((y * width) + x), + argb[((y * width) + x)..], scratch); x = xEnd; @@ -820,14 +820,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 f2b855a37..6e7cbd5e8 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs @@ -6,6 +6,7 @@ using System.Buffers; 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless isFirstConfig = false; } - this.BitWriterSwap(ref bitWriterBest, ref this.bitWriter); + BitWriterSwap(ref bitWriterBest, ref this.bitWriter); } /// @@ -484,7 +485,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless refsTmp1, refsTmp2); - var histogramImage = new List() + List histogramImage = new() { new(cacheBits) }; @@ -818,7 +819,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } BundleColorMap(tmpRow, width, xBits, dst); - src = src.Slice(srcStride); - dst = dst.Slice(dstStride); + src = src[srcStride..]; + dst = dst[dstStride..]; } } else @@ -1449,8 +1444,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless LosslessUtils.BundleColorMap(tmpRow, width, xBits, dst); - src = src.Slice(srcStride); - dst = dst.Slice(dstStride); + src = src[srcStride..]; + dst = dst[dstStride..]; } } @@ -1474,8 +1469,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless LosslessUtils.BundleColorMap(tmpRow, width, xBits, dst); - src = src.Slice(srcStride); - dst = dst.Slice(dstStride); + src = src[srcStride..]; + dst = dst[dstStride..]; } } @@ -1484,7 +1479,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } [MethodImpl(InliningOptions.ShortMethod)] - private void BitWriterSwap(ref Vp8LBitWriter src, ref Vp8LBitWriter dst) + private static void BitWriterSwap(ref Vp8LBitWriter src, ref Vp8LBitWriter dst) { Vp8LBitWriter tmp = src; src = dst; diff --git a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs index eea1dd363..a49671917 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs @@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } - uint bestBgra = bgra.Slice(bgraStart)[bestLength]; + uint bestBgra = bgra[bgraStart..][bestLength]; for (; pos >= minPos && (--iter > 0); pos = chain[pos]) { @@ -193,12 +193,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 0c9bed366..dca239e85 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs @@ -5,10 +5,8 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } 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 ff2b808dd..b90dbf4db 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless decoder.Metadata.ColorCacheSize = 0; } - this.UpdateDecoder(decoder, transformXSize, transformYSize); + UpdateDecoder(decoder, transformXSize, transformYSize); if (isLevel0) { // level 0 complete. @@ -199,15 +199,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } totalSize += huffTableZero.BitsUsed; - huffmanTable = huffmanTable.Slice(size); + huffmanTable = huffmanTable[size..]; if (j <= HuffIndex.Alpha) { @@ -488,7 +488,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless hTreeGroup.UsePackedTable = !hTreeGroup.IsTrivialCode && maxBits < HuffmanUtils.HuffmanPackedBits; if (hTreeGroup.UsePackedTable) { - this.BuildPackedTable(hTreeGroup); + BuildPackedTable(hTreeGroup); } } @@ -546,9 +546,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless this.ReadHuffmanCodeLengths(table, codeLengthCodeLengths, alphabetSize, codeLengths); } - int size = HuffmanUtils.BuildHuffmanTable(table, HuffmanUtils.HuffmanTableBits, codeLengths, alphabetSize); - - return size; + return HuffmanUtils.BuildHuffmanTable(table, HuffmanUtils.HuffmanTableBits, codeLengths, alphabetSize); } private void ReadHuffmanCodeLengths(Span table, int[] codeLengthCodeLengths, int numSymbols, int[] codeLengths) @@ -622,8 +620,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless 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 e19a813a4..210125790 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs @@ -5,10 +5,8 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref outputRef) = q0.AsSByte(); } else -#endif { int thresh2 = (2 * thresh) + 1; int end = 16 + offset; @@ -1367,7 +1344,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1416,7 +1389,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1440,7 +1411,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1574,7 +1539,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } else -#endif { for (int k = 3; k > 0; k--) { @@ -1625,7 +1588,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref outputRef) = wide; } else -#endif { for (int k = 0; k < 4; k++) { @@ -1835,7 +1788,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } dc[k] = avg; - input = input.Slice(4); // go to next 4x4 block. + input = input[4..]; // go to next 4x4 block. } } } @@ -1860,7 +1813,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy leftOffset += WebpConstants.Bps; left = yuv[leftOffset]; - dst = dst.Slice(WebpConstants.Bps); + dst = dst[WebpConstants.Bps..]; } } @@ -1959,11 +1912,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // not_hev <= t1 && not_hev <= t2 return Sse2.CompareEqual(tMaxH, 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 a191cbcf8..a8e365270 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return Sse2.MoveMask(cmpeq) != 0xffff ? 1 : 0; } else -#endif { int last = -1; int n; @@ -762,11 +754,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy c[0] += (short)(((C1 * top[0]) + (C2 * left[0])) >> (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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 25894905a..3092e01e3 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs @@ -34,7 +34,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy private int currentMbIdx; private int nzIdx; - - private int predIdx; - private int yTopIdx; private int uvTopIdx; @@ -69,7 +68,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy /// /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public void Init() => this.Reset(); - public void InitFilter() + public static void InitFilter() { // TODO: add support for autofilter } @@ -288,9 +287,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public int MbAnalyzeBestIntra16Mode() { - int maxMode = MaxIntra16Mode; + const int maxMode = MaxIntra16Mode; int mode; int bestAlpha = DefaultAlpha; int bestMode = 0; @@ -394,7 +393,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { this.currentMbIdx++; this.nzIdx++; - this.predIdx += 4; + this.PredIdx += 4; this.yTopIdx += 16; this.uvTopIdx += 16; } @@ -679,7 +678,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 8eaaeda7a..12b2ea7dc 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs @@ -123,10 +123,22 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy (uint)width, (uint)height, hasAlpha, - alphaData.Slice(0, alphaDataSize), + alphaData[..alphaDataSize], this.alphaCompression && alphaCompressionSucceeded); } @@ -399,17 +411,21 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy it.Init(); this.SetLoopParams(stats.Q); - var info = new Vp8ModeScore(); + Vp8ModeScore info = new(); do { info.Clear(); @@ -540,7 +559,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 b98eea415..32d96cba9 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs @@ -5,10 +5,8 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // second half of the vectors will just contain random value we'll never // use nor store. ref short inputRef = ref MemoryMarshal.GetReference(input); - var in0 = Vector128.Create(Unsafe.As(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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // second half of the vectors will just contain random value we'll never // use nor store. ref short inputRef = ref MemoryMarshal.GetReference(input); - var in0 = Vector128.Create(Unsafe.As(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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As(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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy tmp[1] = b + c; tmp[2] = b - c; tmp[3] = a - d; - tmp = tmp.Slice(4); - input = input.Slice(1); + tmp = tmp[4..]; + input = input[1..]; } tmp = scratch; @@ -304,12 +298,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Store(dst, reference, 1, i, b + c); Store(dst, reference, 2, i, b - c); Store(dst, reference, 3, i, a - d); - tmp = tmp.Slice(1); + tmp = tmp[1..]; } } } -#if SUPPORTS_RUNTIME_INTRINSICS private static void InverseTransformVerticalPass(Vector128 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } -#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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // luma 16x16 prediction (paragraph 12.3). public static void EncPredLuma16(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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy vals[3] = LossyUtils.Avg3(top[topOffset + 2], top[topOffset + 3], top[topOffset + 4]); for (int i = 0; i < 4; i++) { - vals.CopyTo(dst.Slice(i * WebpConstants.Bps)); + vals.CopyTo(dst[(i * WebpConstants.Bps)..]); } } @@ -889,11 +875,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 a52d9e90a..1ba359d85 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } 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 e3a5696e3..9541ee1f7 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy public void SetCoeffs(Span coeffs) { -#if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { ref short coeffsRef = ref MemoryMarshal.GetReference(coeffs); @@ -65,10 +63,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } - coeffs.Slice(0, 16).CopyTo(this.Coeffs); + coeffs[..16].CopyTo(this.Coeffs); } // Simulate block coding, but only record statistics. @@ -93,23 +90,23 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if (n < 16) { - this.RecordStats(0, s, 0); + RecordStats(0, s, 0); } return 1; @@ -163,7 +160,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return LossyUtils.Vp8BitCost(0, (byte)p0); } -#if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { Span ctxs = this.scratch.AsSpan(0, 16); @@ -211,7 +207,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy return cost; } -#endif + { int v; for (; n < this.Last; ++n) @@ -241,7 +237,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 0e789060a..e913e9898 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy }; // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if (info.Features?.Alpha == true) { - using (var alphaDecoder = new AlphaDecoder( + using (AlphaDecoder alphaDecoder = new( width, height, alphaData, @@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } // Prepare for next scanline. - this.InitScanline(dec); + InitScanline(dec); // Reconstruct, filter and emit the row. this.ProcessRow(dec, io); @@ -222,9 +222,27 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if (filterRow) { - this.FilterRow(dec); + FilterRow(dec); } int yStart = mby * 16; @@ -649,9 +681,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } } - 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } else { - v = this.GetLargeValue(br, p.Probabilities); + v = GetLargeValue(br, p.Probabilities); p = prob[n + 1].Probabilities[2]; } @@ -971,7 +1003,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy private Vp8SegmentHeader ParseSegmentHeader(Vp8Proba proba) { - var vp8SegmentHeader = new Vp8SegmentHeader + Vp8SegmentHeader vp8SegmentHeader = new() { UseSegment = this.bitReader.ReadBool() }; @@ -1055,15 +1084,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy decoder.DeQuantMatrices[i] = decoder.DeQuantMatrices[0]; continue; } - else - { - q = baseQ0; - } + + q = baseQ0; } Vp8QuantMatrix m = decoder.DeQuantMatrices[i]; @@ -1228,10 +1253,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy } [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 6e350e7dc..ea2b82c2c 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs @@ -5,10 +5,8 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // ([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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy uv0 = (diag12 + tluv) >> 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if ((len & 1) == 0) { uv0 = ((3 * tluv) + luv + 0x00020002u) >> 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy const int xStep = 3; Array.Clear(uvBuffer); 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy ref byte topVRef = ref MemoryMarshal.GetReference(topV); ref byte curURef = ref MemoryMarshal.GetReference(curU); ref byte curVRef = ref MemoryMarshal.GetReference(curV); - if (bottomY != null) + if (bottomY != default) { for (pos = 1, uvPos = 0; pos + 32 + 1 <= len; pos += 32, uvPos += 16) { @@ -163,17 +158,17 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy if (len > 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy ConvertYuvToBgrSse41(tmpTop, tmpTopDst, ru, rv, 0, xStep); } - tmpTopDst.Slice(0, (len - pos) * xStep).CopyTo(topDst.Slice(pos * xStep)); + tmpTopDst[..((len - pos) * xStep)].CopyTo(topDst[(pos * xStep)..]); if (bottomY != default) { - tmpBottomDst.Slice(0, (len - pos) * xStep).CopyTo(bottomDst.Slice(pos * xStep)); + tmpBottomDst[..((len - pos) * xStep)].CopyTo(bottomDst[(pos * xStep)..]); } } } @@ -216,15 +211,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy Unsafe.As>(ref output0Ref) = t1; Unsafe.As>(ref output1Ref) = t2; } -#endif /// /// Converts the RGB values of the image to YUV. @@ -317,11 +311,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy // 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy 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 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy [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 57c01cac7..2be64492e 100644 --- a/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs +++ b/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs @@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Formats.Webp } WebpImageInfo webpInfo = null; - var features = new WebpFeatures(); + WebpFeatures features = new(); switch (chunkType) { case WebpChunkType.Vp8: @@ -169,7 +169,7 @@ namespace SixLabors.ImageSharp.Formats.Webp { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp { 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp } 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 @@ namespace SixLabors.ImageSharp.Formats.Webp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp } /// - /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp /// 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 bd862c41c..c5d8c30ed 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 @@ namespace SixLabors.ImageSharp.Formats.Webp /// 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp } } else -#endif { for (int x = 0; x < row.Length; x++) { @@ -127,10 +123,9 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 fa270b528..cdb6e5662 100644 --- a/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs +++ b/src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs @@ -14,22 +14,26 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 5b74de680..3c9eea38c 100644 --- a/src/ImageSharp/Formats/Webp/WebpImageInfo.cs +++ b/src/ImageSharp/Formats/Webp/WebpImageInfo.cs @@ -49,14 +49,14 @@ namespace SixLabors.ImageSharp.Formats.Webp 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 a117b7d11..e6aeadea2 100644 --- a/src/ImageSharp/IO/BufferedReadStream.cs +++ b/src/ImageSharp/IO/BufferedReadStream.cs @@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.IO 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 @@ namespace SixLabors.ImageSharp.IO return this.ReadToBufferViaCopyFast(buffer, offset, count); } -#if SUPPORTS_SPAN_STREAM /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int Read(Span buffer) @@ -196,7 +195,6 @@ namespace SixLabors.ImageSharp.IO return this.ReadToBufferViaCopyFast(buffer); } -#endif /// public override void Flush() @@ -354,7 +352,7 @@ namespace SixLabors.ImageSharp.IO 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 2bd8563ab..837af618e 100644 --- a/src/ImageSharp/IO/ChunkedMemoryStream.cs +++ b/src/ImageSharp/IO/ChunkedMemoryStream.cs @@ -203,7 +203,7 @@ namespace SixLabors.ImageSharp.IO this.isDisposed = true; if (disposing) { - this.ReleaseMemoryChunks(this.memoryChunk); + ReleaseMemoryChunks(this.memoryChunk); } this.memoryChunk = null; @@ -236,11 +236,9 @@ namespace SixLabors.ImageSharp.IO 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 @@ namespace SixLabors.ImageSharp.IO } 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 @@ namespace SixLabors.ImageSharp.IO 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 @@ namespace SixLabors.ImageSharp.IO } 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 @@ namespace SixLabors.ImageSharp.IO }; } - 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 5c73590aa..4d1b17231 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 @@ namespace SixLabors.ImageSharp } // 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp } 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 @@ namespace SixLabors.ImageSharp [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 a59f5a34c..a8db3483d 100644 --- a/src/ImageSharp/Image.LoadPixelData.cs +++ b/src/ImageSharp/Image.LoadPixelData.cs @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp 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 6646e43c2..9e68d901a 100644 --- a/src/ImageSharp/Image.WrapMemory.cs +++ b/src/ImageSharp/Image.WrapMemory.cs @@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 182047aff..9427c8d61 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp { 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 f6432757e..b1f2b14bd 100644 --- a/src/ImageSharp/ImageFrame.LoadPixelData.cs +++ b/src/ImageSharp/ImageFrame.LoadPixelData.cs @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp 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 6896e069c..000000000 --- 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 319cd523c..000000000 --- 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 87bdbff69..2bd509902 100644 --- a/src/ImageSharp/IndexedImageFrame{TPixel}.cs +++ b/src/ImageSharp/IndexedImageFrame{TPixel}.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp // 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 dd30efa06..54d8e17f0 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 @@ namespace SixLabors.ImageSharp.Memory.Internals 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 @@ namespace SixLabors.ImageSharp.Memory.Internals /// 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 e960aef0d..756f5a995 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 @@ namespace SixLabors.ImageSharp.Memory.Internals 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 @@ namespace SixLabors.ImageSharp.Memory.Internals 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 74a98ed1a..7933f3e13 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 @@ namespace SixLabors.ImageSharp.Memory.Internals // 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 @@ namespace SixLabors.ImageSharp.Memory.Internals { 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 e79eb4967..af04718e8 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 @@ namespace SixLabors.ImageSharp.Memory 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 @@ namespace SixLabors.ImageSharp.Memory 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 @@ namespace SixLabors.ImageSharp.Memory 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 f35ec9b61..c73b96ae6 100644 --- a/src/ImageSharp/Memory/Buffer2D{T}.cs +++ b/src/ImageSharp/Memory/Buffer2D{T}.cs @@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.Memory 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 fd9a06db0..f6d79642a 100644 --- a/src/ImageSharp/Memory/ByteMemoryManager{T}.cs +++ b/src/ImageSharp/Memory/ByteMemoryManager{T}.cs @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Memory // 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 fc8e150d9..51774c881 100644 --- a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs +++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Memory cur.GetSpan(fwd).CopyTo(target); cur.Forward(fwd); - target = target.Slice(fwd); + target = target[fwd..]; position += fwd; } } @@ -102,9 +102,9 @@ namespace SixLabors.ImageSharp.Memory 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 18d80dd51..f044e6cb9 100644 --- a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs +++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs @@ -7,7 +7,6 @@ using System.Collections; 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 @@ namespace SixLabors.ImageSharp.Memory 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 @@ namespace SixLabors.ImageSharp.Memory } } - 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 @@ namespace SixLabors.ImageSharp.Memory } } - 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 @@ namespace SixLabors.ImageSharp.Memory { 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 @@ namespace SixLabors.ImageSharp.Memory { 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 0c415806f..8c3d49d1e 100644 --- a/src/ImageSharp/Memory/MemoryOwnerExtensions.cs +++ b/src/ImageSharp/Memory/MemoryOwnerExtensions.cs @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Memory [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 03f1566d2..f5f884f28 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs @@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif { 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 dc6fad909..722f59316 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs @@ -7,7 +7,9 @@ using System.Buffers.Binary; 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif /// public List ReadValues() { - var values = new List(); + List values = new(); // II == 0x4949 this.IsBigEndian = this.ReadUInt16() != 0x4949; @@ -64,11 +66,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif case ExifDataType.Undefined: if (!isArray) { - return this.ConvertToByte(buffer); + return ConvertToByte(buffer); } return buffer.ToArray(); @@ -370,7 +373,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif } 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif } 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif => (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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 6e98128d5..1212e16cc 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs @@ -49,9 +49,9 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif private List GetPartValues(ExifParts part) { - var result = new List(); + List result = new(); if (!EnumUtils.HasFlag(this.allowedParts, part)) { @@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif return true; } - private uint GetLength(IList values) + private static uint GetLength(IList values) { if (values.Count == 0) { @@ -360,20 +360,18 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif } // 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif 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 2209586ab..2af413cb9 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs @@ -79,6 +79,28 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif /// 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 a4603a02a..6fa985eb2 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 a22c7dcde..5ad61d4a0 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } /// - 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 773140ab2..d84a18f90 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 30b3dafa3..a305eea31 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 c9f4bab45..d63bb7449 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 f7c7d0a81..176c46335 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 bd85cfbf4..35c867827 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs @@ -25,9 +25,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 180fdba03..d3113b014 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 411cdacec..8ff48bf13 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc { 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc // 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc // 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 7807ea4df..8a0c73882 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 d76da6324..bcfc4f8c9 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 000000000..6c488c874 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 2f1aa1952..39b726f90 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs @@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } /// - public IccProfile DeepClone() => new IccProfile(this); + public IccProfile DeepClone() => new(this); /// /// Calculates the MD5 hash value of an ICC profile @@ -108,33 +108,32 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc { 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 96a5e77a0..5e6e69fff 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc }; } - 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 2adfbbc7e..4bf8b5eb9 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } } - 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc // (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 d6882957f..ef2e6eae0 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } /// - 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 e450362a5..00183b6e8 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } /// - 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 3ea707eec..21b372ffa 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 67f25b5ce..5ce56bd11 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } /// - 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 b7bde3f79..c448a71cd 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 392121259..84d399459 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc && 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 5d0bdabe7..8b40dd783 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } 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 1a178b89a..e5f817e95 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 35542c1b4..aa63c3b35 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 0, 0, 1); - } } } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs index 21d46b016..0c338dabd 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs @@ -53,13 +53,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc { 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } } - private Vector3? CreateMatrix3x1(float[] matrix) + private static Vector3? CreateMatrix3x1(float[] matrix) { if (matrix is null) { @@ -271,7 +265,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 89b010180..2c4487bca 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs @@ -53,13 +53,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc && 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc { 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } } - private Vector3? CreateMatrix3x1(float[] matrix) + private static Vector3? CreateMatrix3x1(float[] matrix) { if (matrix is null) { @@ -270,7 +254,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 c2c959d29..8541d287d 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 148450de6..2924a5dc6 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 1d9da5398..6fb2aca20 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs @@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return new IccMultiLocalizedUnicodeTagDataEntry(new[] { localString }, textEntry.TagSignature); - CultureInfo GetCulture(uint value) + static CultureInfo GetCulture(uint value) { if (value == 0) { @@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc && 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc } 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 4af43a1a8..9463f665a 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 e48c9d3b3..d806ca2a5 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 319ea8fde..8a3080240 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 20ca0248a..63f97d45c 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 dfe186d7d..b5709db4d 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc 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 a0e767a7c..8010f78bc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 6633d2a68..b4e6e573b 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 f8f2b653a..4b8cb91f7 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// 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 ec3eed265..bc94e9555 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs @@ -5,6 +5,7 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc /// /// 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 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc 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 f0d40a718..1a74ea418 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc 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 06595b991..095beb24a 100644 --- a/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs @@ -67,15 +67,15 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Xmp } } - 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 0a00fcf35..4c9afecfd 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.Generated.cs @@ -20,7 +20,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 NormalSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -35,7 +35,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 NormalSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -50,7 +50,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 NormalSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -65,7 +65,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 NormalSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -80,7 +80,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 NormalSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -95,7 +95,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 NormalDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -108,7 +108,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 NormalDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -123,7 +123,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 NormalDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -138,7 +138,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 NormalDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -153,7 +153,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 NormalDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -168,7 +168,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 NormalXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -183,7 +183,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 NormalClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -425,7 +425,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 MultiplySrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -440,7 +440,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 MultiplySrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -455,7 +455,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 MultiplySrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -470,7 +470,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 MultiplySrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -485,7 +485,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 MultiplySrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -500,7 +500,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 MultiplyDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -513,7 +513,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 MultiplyDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -528,7 +528,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 MultiplyDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -543,7 +543,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 MultiplyDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -558,7 +558,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 MultiplyDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -573,7 +573,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 MultiplyXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -588,7 +588,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 MultiplyClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -830,7 +830,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 AddSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -845,7 +845,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 AddSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -860,7 +860,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 AddSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -875,7 +875,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 AddSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -890,7 +890,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 AddSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -905,7 +905,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 AddDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -918,7 +918,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 AddDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -933,7 +933,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 AddDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -948,7 +948,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 AddDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -963,7 +963,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 AddDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -978,7 +978,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 AddXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -993,7 +993,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 AddClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1235,7 +1235,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 SubtractSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1250,7 +1250,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 SubtractSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1265,7 +1265,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 SubtractSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1280,7 +1280,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 SubtractSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1295,7 +1295,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 SubtractSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1310,7 +1310,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 SubtractDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -1323,7 +1323,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 SubtractDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1338,7 +1338,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 SubtractDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1353,7 +1353,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 SubtractDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1368,7 +1368,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 SubtractDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1383,7 +1383,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 SubtractXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1398,7 +1398,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 SubtractClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1640,7 +1640,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 ScreenSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1655,7 +1655,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 ScreenSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1670,7 +1670,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 ScreenSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1685,7 +1685,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 ScreenSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1700,7 +1700,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 ScreenSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1715,7 +1715,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 ScreenDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -1728,7 +1728,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 ScreenDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1743,7 +1743,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 ScreenDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1758,7 +1758,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 ScreenDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1773,7 +1773,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 ScreenDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1788,7 +1788,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 ScreenXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -1803,7 +1803,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 ScreenClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2045,7 +2045,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 DarkenSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2060,7 +2060,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 DarkenSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2075,7 +2075,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 DarkenSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2090,7 +2090,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 DarkenSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2105,7 +2105,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 DarkenSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2120,7 +2120,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 DarkenDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -2133,7 +2133,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 DarkenDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2148,7 +2148,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 DarkenDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2163,7 +2163,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 DarkenDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2178,7 +2178,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 DarkenDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2193,7 +2193,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 DarkenXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2208,7 +2208,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 DarkenClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2450,7 +2450,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 LightenSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2465,7 +2465,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 LightenSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2480,7 +2480,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 LightenSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2495,7 +2495,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 LightenSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2510,7 +2510,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 LightenSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2525,7 +2525,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 LightenDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -2538,7 +2538,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 LightenDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2553,7 +2553,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 LightenDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2568,7 +2568,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 LightenDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2583,7 +2583,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 LightenDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2598,7 +2598,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 LightenXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2613,7 +2613,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 LightenClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2855,7 +2855,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 OverlaySrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2870,7 +2870,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 OverlaySrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2885,7 +2885,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 OverlaySrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2900,7 +2900,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 OverlaySrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2915,7 +2915,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 OverlaySrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2930,7 +2930,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 OverlayDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -2943,7 +2943,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 OverlayDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2958,7 +2958,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 OverlayDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2973,7 +2973,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 OverlayDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -2988,7 +2988,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 OverlayDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3003,7 +3003,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 OverlayXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3018,7 +3018,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 OverlayClear(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3260,7 +3260,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 HardLightSrc(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3275,7 +3275,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 HardLightSrcAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3290,7 +3290,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 HardLightSrcOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3305,7 +3305,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 HardLightSrcIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3320,7 +3320,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 HardLightSrcOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3335,7 +3335,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 HardLightDest(Vector4 backdrop, Vector4 source, float opacity) { return backdrop; @@ -3348,7 +3348,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 HardLightDestAtop(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3363,7 +3363,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 HardLightDestOver(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3378,7 +3378,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 HardLightDestIn(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3393,7 +3393,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 HardLightDestOut(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3408,7 +3408,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 HardLightXor(Vector4 backdrop, Vector4 source, float opacity) { source.W *= opacity; @@ -3423,7 +3423,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 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 c651ab4a4..0cd4e637c 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 fe9acd4aa..43bcdf426 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -47,27 +47,22 @@ namespace SixLabors.ImageSharp.PixelFormats 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 @@ namespace SixLabors.ImageSharp.PixelFormats 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 a415f41cc..84354a5c2 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs @@ -18,8 +18,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// 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 80b967dcb..50ea3533b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs @@ -17,24 +17,22 @@ namespace SixLabors.ImageSharp.PixelFormats 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 e55332228..ed3a53758 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats 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 @@ namespace SixLabors.ImageSharp.PixelFormats { 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 @@ namespace SixLabors.ImageSharp.PixelFormats { 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 @@ namespace SixLabors.ImageSharp.PixelFormats /// 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 96d4579c7..240e85ff1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// 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 @@ namespace SixLabors.ImageSharp.PixelFormats /// [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 599857961..d15a46d69 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs @@ -240,6 +240,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The . /// + /// Hexadecimal string is not in the correct format. [MethodImpl(InliningOptions.ShortMethod)] public static Rgba32 ParseHex(string hex) { @@ -432,7 +433,7 @@ namespace SixLabors.ImageSharp.PixelFormats 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 @@ namespace SixLabors.ImageSharp.PixelFormats { 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 93037fcbc..7973ee3dc 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 @@ namespace SixLabors.ImageSharp.PixelFormats 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 db8c98733..0662ffb71 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -20,11 +20,14 @@ namespace SixLabors.ImageSharp.PixelFormats 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 @@ namespace SixLabors.ImageSharp.PixelFormats 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 @@ namespace SixLabors.ImageSharp.PixelFormats /// 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 38250b24a..92007732d 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils // 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 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils // 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 de95ba348..63ca6f756 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. /// @@ -117,10 +92,35 @@ namespace SixLabors.ImageSharp data.CopyTo(this.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. @@ -146,7 +146,7 @@ namespace SixLabors.ImageSharp /// 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 . @@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp 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++) { @@ -199,7 +199,7 @@ namespace SixLabors.ImageSharp [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 a181084aa..062036a57 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp 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 89db9befb..356595cb4 100644 --- a/src/ImageSharp/Primitives/Point.cs +++ b/src/ImageSharp/Primitives/Point.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp /// /// 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 @@ namespace SixLabors.ImageSharp /// /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 9817f04f3..d701f3d54 100644 --- a/src/ImageSharp/Primitives/PointF.cs +++ b/src/ImageSharp/Primitives/PointF.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp /// /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp 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 4c70e0dd9..b21aae1fe 100644 --- a/src/ImageSharp/Primitives/Rectangle.cs +++ b/src/ImageSharp/Primitives/Rectangle.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp /// /// 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 aa6f4fc23..9719d2b7e 100644 --- a/src/ImageSharp/Primitives/RectangleF.cs +++ b/src/ImageSharp/Primitives/RectangleF.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp /// /// 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp 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 @@ namespace SixLabors.ImageSharp [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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 83bd39213..0e55b6845 100644 --- a/src/ImageSharp/Primitives/Size.cs +++ b/src/ImageSharp/Primitives/Size.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp /// /// 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 4e2fba4e9..fed62e512 100644 --- a/src/ImageSharp/Primitives/SizeF.cs +++ b/src/ImageSharp/Primitives/SizeF.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp /// /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 @@ namespace SixLabors.ImageSharp /// 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 eb36183ad..e0221f815 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs @@ -295,8 +295,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution [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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution [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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 5ccaa77c4..8b4eaab80 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs @@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution // 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution // 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 db9557124..697351abc 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs @@ -166,8 +166,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 fa0a01229..ed8b63ab2 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs @@ -114,8 +114,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution // 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 06d4a2755..a4ae9cb4c 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs @@ -60,8 +60,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution } [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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution } } - 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution 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 90c2575fc..ff1bba22d 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 002f35c3d..41d3c8ad2 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 064088432..25007846c 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 435cafb52..2c9ce2419 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErroDither.KnownTypes.cs @@ -11,178 +11,178 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// /// 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 a6838d246..f036273c2 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.KnownTypes.cs @@ -11,26 +11,26 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// /// 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 0e85b20ea..4c6e8e043 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering 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 248c21641..5b336d78f 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// . /// /// 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 cf56d0338..4d33b848b 100644 --- a/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor{TPixel}.cs @@ -30,24 +30,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Effects 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 5c1282666..7cc115137 100644 --- a/src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs @@ -51,8 +51,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters [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 d6d69f161..518b19c4c 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs @@ -628,7 +628,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization 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 a2f346be0..b7e5819e0 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.Numerics; 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization { 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization innerOperation.Invoke); // Process the left border of the image. - var leftBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation leftBorderOperation = new( this.Configuration, this, source, @@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization leftBorderOperation.Invoke); // Process the right border of the image. - var rightBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation rightBorderOperation = new( this.Configuration, this, source, @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization rightBorderOperation.Invoke); // Process the top border of the image. - var topBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation topBorderOperation = new( this.Configuration, this, source, @@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization topBorderOperation.Invoke); // Process the bottom border of the image. - var bottomBorderOperation = new SlidingWindowOperation( + SlidingWindowOperation bottomBorderOperation = new( this.Configuration, this, source, @@ -171,7 +171,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization return; } - this.CopyPixelRowFast(source.PixelBuffer, rowPixels, x, y, tileWidth, configuration); + CopyPixelRowFast(source.PixelBuffer, rowPixels, x, y, tileWidth, configuration); } /// @@ -237,7 +237,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization { 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization // 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization // 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 433207562..c4b925efe 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization } /// -#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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization } /// -#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 71fbc6e5b..0e9bfa7e4 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// 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 4c32c5fd9..021379907 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization 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 981e1cf60..d06661d07 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs @@ -23,7 +23,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization { 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 4e47b0ac5..b3aa58acf 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization 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 ab0f1548f..30043abfb 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // 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 5196070e4..1fcdbc5b1 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 576e34a26..5f04669b7 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization } } - 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization - 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization 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 92f3e8b98..32c93c281 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs @@ -86,9 +86,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [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 01de78198..680ada1d3 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms 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 7dc8b7365..3f4e18b8c 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { // 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// 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 a379dfa8f..9dbf4708f 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms 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 8e26675d8..8f6ba2896 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// 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 4a87c1ea9..53dfb466f 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 23d8efa62..30bc5b5de 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 d6cfbc4cc..73a75bf66 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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms public Span Values { [MethodImpl(InliningOptions.ShortMethod)] - get => new Span(this.bufferPtr, this.Length); + get => new(this.bufferPtr, this.Length); } /// @@ -71,7 +69,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [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 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return *(Vector4*)&result128; } else -#endif { // Destination color components Vector4 result = Vector4.Zero; @@ -167,7 +163,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// [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 888143af4..cb8b68b57 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms [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 3c31c7628..c7b862c1a 100644 --- a/src/ImageSharp/Processing/ResizeOptions.cs +++ b/src/ImageSharp/Processing/ResizeOptions.cs @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Processing /// 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 5b2c8c05e..ee196cbea 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; 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 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations 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 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { 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 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations 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 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations 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 6dc5702fa..1ff81d677 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; 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 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations row3 = SimdUtils.FastRound(row3); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void Sse41_V1() { @@ -491,6 +488,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations 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 c0256caf6..59fe2ed43 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.CmykVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg 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 25ca884c1..5f7078794 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs @@ -22,7 +22,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.GrayscaleScalar(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -30,6 +29,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg 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 4cfe9534d..99b1f8810 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.RgbVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg 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 a01c5d6e2..d528ea5ff 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.YCbCrVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg 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 c4f9633ca..cfc47bdc6 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs @@ -30,7 +30,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg new JpegColorConverterBase.YccKVector(8).ConvertToRgbInplace(values); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void SimdVectorAvx2() { @@ -38,6 +37,5 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg 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 9f7a988e1..bb2985ab7 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -6,10 +6,8 @@ using System.Buffers; 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 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk 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 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.NormalizedFloatToByteSaturate(sBytes, dFloats); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void UseHwIntrinsics() { @@ -161,7 +149,6 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk vf = Avx.Multiply(scale, vf); return Avx.ConvertToVector256Int32(vf); } -#endif // *** RESULTS 2020 March: *** // Intel Core i7-8650U CPU 1.90GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs index 88b4c200e..ec51e104e 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs @@ -26,21 +26,10 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() - { - new PixelOperations().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 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.ExtendedIntrinsics.ByteToNormalizedFloat(sBytes, dFloats); } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark] public void HwIntrinsics() { @@ -60,7 +48,6 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk SimdUtils.HwIntrinsics.ByteToNormalizedFloat(sBytes, dFloats); } -#endif // [Benchmark] public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat_2Loops() @@ -96,8 +83,8 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk { 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 16b016a7c..4de745005 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 @@ namespace SixLabors.ImageSharp.Benchmarks { 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 d0300b057..252ff9058 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 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion } } -#if SUPPORTS_RUNTIME_INTRINSICS [Benchmark(Baseline = true)] public void Rgba32_Avx2_Float() { @@ -261,7 +258,6 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion 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 063ba63cd..6ecb606f5 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 @@ namespace SixLabors.ImageSharp.Tests.Advanced 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 10d18d63c..0cd258bd9 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CieXyzAndCieXyyConversionTest.cs @@ -36,8 +36,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 9e08d572f..095b5e125 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHslConversionTests.cs @@ -34,8 +34,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 44de7383a..770840e9b 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndHsvConversionTests.cs @@ -34,8 +34,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 9c156b18d..a67af332d 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/CmykAndYCbCrConversionTests.cs @@ -34,8 +34,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 3f2386637..04abcf978 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndCmykConversionTest.cs @@ -40,8 +40,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 a5fd9ca77..f1075f866 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHslConversionTest.cs @@ -43,8 +43,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 e7e95e792..2d801b540 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndHsvConversionTest.cs @@ -42,8 +42,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 297b4ad13..0b4193c1a 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Conversion/RgbAndYCbCrConversionTest.cs @@ -71,8 +71,8 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Conversion 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 e8643de27..6f5df4313 100644 --- a/tests/ImageSharp.Tests/Common/NumericsTests.cs +++ b/tests/ImageSharp.Tests/Common/NumericsTests.cs @@ -11,67 +11,10 @@ namespace SixLabors.ImageSharp.Tests.Common { 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 028cc56cd..1ba3c64de 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -5,9 +5,7 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Tests.Common 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 @@ namespace SixLabors.ImageSharp.Tests.Common 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 @@ namespace SixLabors.ImageSharp.Tests.Common 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 @@ namespace SixLabors.ImageSharp.Tests.Common count, HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE41); } -#endif [Theory] [MemberData(nameof(ArbitraryArraySizes))] @@ -239,18 +174,6 @@ namespace SixLabors.ImageSharp.Tests.Common 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 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected2, actual2); } -#if SUPPORTS_RUNTIME_INTRINSICS - [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void HwIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) @@ -299,8 +220,6 @@ namespace SixLabors.ImageSharp.Tests.Common HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); } -#endif - [Theory] [MemberData(nameof(ArbitraryArraySizes))] public void BulkConvertNormalizedFloatToByteClampOverflows(int count) @@ -325,16 +244,15 @@ namespace SixLabors.ImageSharp.Tests.Common 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 @@ namespace SixLabors.ImageSharp.Tests.Common 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 @@ namespace SixLabors.ImageSharp.Tests.Common var actual = new TPixel[count + 3]; // padding for Rgb24 AVX2 packMethod(r, g, b, actual); - Assert.True(expected.AsSpan().SequenceEqual(actual.AsSpan().Slice(0, count))); + Assert.True(expected.AsSpan().SequenceEqual(actual.AsSpan()[..count])); } private static void TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( @@ -434,7 +351,7 @@ namespace SixLabors.ImageSharp.Tests.Common seed = seed > 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 28cf92d10..3d75d3448 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg 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 70b921da2..deeff0992 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs @@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void GetConverterThrowsExceptionOnInvalidColorSpace() { var invalidColorSpace = (JpegColorSpace)(-1); - Assert.Throws(() => JpegColorConverterBase.GetConverter(invalidColorSpace, 8)); + Assert.Throws(() => JpegColorConverterBase.GetConverter(invalidColorSpace, 8)); } [Fact] @@ -49,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { // 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 8a78ef648..a3cf66eeb 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -6,7 +6,6 @@ using System.Threading; 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { 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 0c91c9098..9e13edeba 100644 --- a/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/Adler32Tests.cs @@ -51,7 +51,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png return data; } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void RunCalculateAdlerTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCalculateAdlerTest, HwIntrinsics.AllowAll); @@ -69,6 +68,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png CalculateAdlerAndCompareToReference(testData[i]); } } -#endif } } diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs index a0f93ba29..df364ee50 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderFilterTests.cs @@ -147,7 +147,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png [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 f0611e9c4..7211d5367 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs @@ -340,7 +340,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png 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 bb26d182b..9ce45d3f3 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs @@ -245,7 +245,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff 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 9e1004cec..c9854c022 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs @@ -30,7 +30,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.PhotometricInterpretation 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.PhotometricInterpretation [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 6874019a0..2d594319e 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs @@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff 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 cc3277981..253381985 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Utils { 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 c06936c09..013674cfe 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs @@ -68,7 +68,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 c9c3ba5de..eb7b4dc64 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { // 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { // 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp { // 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 9248f37c6..419d6e266 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs @@ -301,7 +301,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 bbf35e51b..d6c2f415e 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs @@ -5,9 +5,7 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp 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 86f22d67a..0e4630fdb 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs @@ -42,7 +42,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 d8b4acaa1..2923d1aaa 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs @@ -138,7 +138,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 3d8a8dabd..053f8304d 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs @@ -215,12 +215,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp 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 8f56d831f..4aa3c1a5b 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8LHistogramTests.cs @@ -99,12 +99,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 976dc0cb3..5819320e8 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -26,12 +26,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 b197d0105..1346964ec 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs @@ -5,10 +5,8 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [Fact] public void CheckNonOpaque_WithNoneOpaquePixels_WithoutAvx2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithNoneOpaquePixelsTest, HwIntrinsics.DisableAVX2); -#endif private static void RunCheckNoneOpaqueWithNoneOpaquePixelsTest() { @@ -200,7 +196,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp 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 ac5918952..3f000467d 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -401,7 +401,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp } }); -#if SUPPORTS_RUNTIME_INTRINSICS private static void RunDecodeLossyWithHorizontalFilter() { var provider = TestImageProvider.File(TestImageLossyHorizontalFilterPath); @@ -445,6 +444,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp [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 27dccf84a..f16f50b98 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs @@ -326,13 +326,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp 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 6b4b60491..718dd920f 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs @@ -26,25 +26,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp // 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 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp // 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 39a5dccce..000000000 --- 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 a65fd2325..5b9d430af 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 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators } } -#if NETCOREAPP3_1_OR_GREATER public static readonly bool Is32BitProcess = !Environment.Is64BitProcess; private static readonly List PressureArrays = new(); @@ -121,21 +118,21 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators 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 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators } } } -#endif } } } diff --git a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs index e002fcc8e..2cd1c696d 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs @@ -380,7 +380,6 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators } } -#if NETCOREAPP3_1_OR_GREATER [Fact] public void Issue2001_NegativeMemoryReportedByGc() { @@ -393,6 +392,5 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators _ = MemoryAllocator.Create(); } } -#endif } } diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs index a21a4f049..184a6c42e 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccReaderTests.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Icc { 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 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Icc { 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 7aa587a32..039d12663 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccWriterTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/IccWriterTests.cs @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Icc { 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 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Icc { 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 c22b5dbcd..6f11e7aec 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 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations 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 c214a4caa..2e418c5a7 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 @@ namespace SixLabors.ImageSharp.Tests.Primitives [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 @@ namespace SixLabors.ImageSharp.Tests.Primitives [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 @@ namespace SixLabors.ImageSharp.Tests.Primitives hash.Add(m.M54); Assert.Equal(hash.ToHashCode(), m.GetHashCode()); -#endif } [Fact] @@ -163,9 +161,8 @@ namespace SixLabors.ImageSharp.Tests.Primitives Assert.Equal(expected, m.ToString()); } - private ColorMatrix CreateAllOnes() - { - return new ColorMatrix + private static ColorMatrix CreateAllOnes() + => new() { M11 = 1F, M12 = 1F, @@ -188,11 +185,9 @@ namespace SixLabors.ImageSharp.Tests.Primitives M53 = 1F, M54 = 1F }; - } - private ColorMatrix CreateAllTwos() - { - return new ColorMatrix + private static ColorMatrix CreateAllTwos() + => new() { M11 = 2F, M12 = 2F, @@ -215,11 +210,9 @@ namespace SixLabors.ImageSharp.Tests.Primitives M53 = 2F, M54 = 2F }; - } - private ColorMatrix CreateAllThrees() - { - return new ColorMatrix + private static ColorMatrix CreateAllThrees() + => new() { M11 = 3F, M12 = 3F, @@ -242,11 +235,9 @@ namespace SixLabors.ImageSharp.Tests.Primitives M53 = 3F, M54 = 3F }; - } - private ColorMatrix CreateAllFours() - { - return new ColorMatrix + private static ColorMatrix CreateAllFours() + => new() { M11 = 4F, M12 = 4F, @@ -269,6 +260,5 @@ namespace SixLabors.ImageSharp.Tests.Primitives M53 = 4F, M54 = 4F }; - } } } diff --git a/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs index b8668b211..9e0fd2d93 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 @@ using Xunit; 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 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution 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 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution 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 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution 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 90f407484..02bdb8267 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 306121fb0..3d084df07 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ResizeTests.cs @@ -89,7 +89,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms Assert.Equal(mode, resizeOptions.Mode); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void HwIntrinsics_Resize() { @@ -106,6 +105,5 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms 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 d79880d8c..1b91a11b5 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 @@ namespace SixLabors.ImageSharp.Tests 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 1710dba9a..feabf0e19 100644 --- a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs +++ b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs @@ -78,7 +78,6 @@ namespace SixLabors.ImageSharp.Tests 0x64, 0x63, 0x62, 0x61, // CreatorSignature }, profileId, -#pragma warning disable SA1118 // Parameter should not span multiple lines new byte[] { // Padding @@ -93,12 +92,10 @@ namespace SixLabors.ImageSharp.Tests (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 @@ namespace SixLabors.ImageSharp.Tests 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 9cbf4e120..f6d5aadac 100644 --- a/tests/ImageSharp.Tests/TestDataIcc/IccTestDataTagDataEntry.cs +++ b/tests/ImageSharp.Tests/TestDataIcc/IccTestDataTagDataEntry.cs @@ -37,7 +37,8 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 @@ namespace SixLabors.ImageSharp.Tests 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 4dd1e010f..511b2cef5 100644 --- a/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs +++ b/tests/ImageSharp.Tests/TestUtilities/PausedStream.cs @@ -122,7 +122,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities 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 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities } 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 e78659aa6..e0a6ec860 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 @@ namespace SixLabors.ImageSharp.Tests // "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 a4956ffb7..7d3a536c8 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -781,7 +781,6 @@ namespace SixLabors.ImageSharp.Tests internal class AllocatorBufferCapacityConfigurator { -#pragma warning disable CS0618 // 'ArrayPoolMemoryAllocator' is obsolete private readonly TestMemoryAllocator allocator; private readonly int pixelSizeInBytes; @@ -790,7 +789,6 @@ namespace SixLabors.ImageSharp.Tests 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 e660bb153..fc8ca6c45 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/FeatureTestRunnerTests.cs @@ -5,9 +5,7 @@ using System; 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 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests HwIntrinsics.AllowAll); } -#if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CanLimitHwIntrinsicBaseFeatures() { @@ -82,7 +79,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests AssertDisabled, HwIntrinsics.DisableHWIntrinsic); } -#endif [Fact] public void CanLimitHwIntrinsicFeaturesWithIntrinsicsParam() @@ -91,9 +87,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests { 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 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests 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 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests { Assert.NotNull(serializable); Assert.NotNull(FeatureTestRunner.DeserializeForXunit(serializable)); - -#if SUPPORTS_RUNTIME_INTRINSICS Assert.False(Sse.IsSupported); -#endif } FeatureTestRunner.RunWithHwIntrinsicsFeature( @@ -193,9 +184,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests 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 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests 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 46e8b34bc..f37e89c41 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -369,14 +369,14 @@ namespace SixLabors.ImageSharp.Tests } 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 @@ namespace SixLabors.ImageSharp.Tests } 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