diff --git a/.editorconfig b/.editorconfig
index 0e4883082c..83670fa830 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,373 +1,436 @@
-###############################################################################
-# EditorConfig is awesome: http://EditorConfig.org
-###############################################################################
+# Version: 1.6.2 (Using https://semver.org/)
+# Updated: 2020-11-02
+# 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.
-###############################################################################
-# Top-most EditorConfig file
-###############################################################################
+##########################################
+# Common Settings
+##########################################
+
+# This file is the top-most EditorConfig file
root = true
-###############################################################################
-# Set default behavior to:
-# a UTF-8 encoding,
-# Unix-style line endings,
-# a newline ending the file,
-# 4 space indentation, and
-# trimming of trailing whitespace
-###############################################################################
+# All Files
[*]
charset = utf-8
-end_of_line = lf
-insert_final_newline = true
indent_style = space
indent_size = 4
+end_of_line = lf
+insert_final_newline = true
trim_trailing_whitespace = true
-###############################################################################
-# Set file behavior to:
-# 2 space indentation
-###############################################################################
-[*.{cmd,config,csproj,json,props,ps1,resx,sh,targets}]
-indent_size = 2
+##########################################
+# File Extension Settings
+##########################################
-###############################################################################
-# Set file behavior to:
-# Windows-style line endings, and
-# tabular indentation
-###############################################################################
+# Visual Studio Solution Files
[*.sln]
+indent_style = tab
+
+# Visual Studio XML Project Files
+[*.{csproj,vbproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# T4 Templates Files
+[*.{tt,ttinclude}]
end_of_line = crlf
+
+# XML Configuration Files
+[*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}]
+indent_size = 2
+
+# JSON Files
+[*.{json,json5,webmanifest}]
+indent_size = 2
+
+# YAML Files
+[*.{yml,yaml}]
+indent_size = 2
+
+# Markdown Files
+[*.md]
+trim_trailing_whitespace = false
+
+# Web Files
+[*.{htm,html,js,jsm,ts,tsx,css,sass,scss,less,svg,vue}]
+indent_size = 2
+
+# Batch Files
+[*.{cmd,bat}]
+end_of_line = crlf
+
+# Makefiles
+[Makefile]
indent_style = tab
-###############################################################################
-# Set dotnet naming rules to:
-# suggest async members be pascal case suffixed with Async
-# suggest const declarations be pascal case
-# suggest interfaces be pascal case prefixed with I
-# suggest parameters be camel case
-# suggest private and internal static fields be camel case
-# suggest private and internal fields be camel case
-# suggest public and protected declarations be pascal case
-# suggest static readonly declarations be pascal case
-# suggest type parameters be prefixed with T
-###############################################################################
-[*.cs]
-dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.severity = suggestion
-dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.style = pascal_case_suffixed_with_async
-dotnet_naming_rule.async_members_should_be_pascal_case_suffixed_with_async.symbols = async_members
-
-dotnet_naming_rule.const_declarations_should_be_pascal_case.severity = suggestion
-dotnet_naming_rule.const_declarations_should_be_pascal_case.style = pascal_case
-dotnet_naming_rule.const_declarations_should_be_pascal_case.symbols = const_declarations
-
-dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.severity = suggestion
-dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.style = pascal_case_prefixed_with_i
-dotnet_naming_rule.interfaces_should_be_pascal_case_prefixed_with_i.symbols = interfaces
-
-dotnet_naming_rule.parameters_should_be_camel_case.severity = suggestion
-dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case
-dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameters
-
-dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.severity = suggestion
-dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.style = camel_case
-dotnet_naming_rule.private_and_internal_static_fields_should_be_camel_case.symbols = private_and_internal_static_fields
-
-dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.severity = suggestion
-dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.style = camel_case
-dotnet_naming_rule.private_and_internal_fields_should_be_camel_case.symbols = private_and_internal_fields
-
-dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.severity = suggestion
-dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.style = pascal_case
-dotnet_naming_rule.public_and_protected_declarations_should_be_pascal_case.symbols = public_and_protected_declarations
-dotnet_naming_symbols.public_and_protected_declarations.applicable_kinds = method, field, event, property
-
-dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.severity = suggestion
-dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.style = pascal_case
-dotnet_naming_rule.static_readonly_declarations_should_be_pascal_case.symbols = static_readonly_declarations
-
-dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.severity = suggestion
-dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.style = pascal_case_prefixed_with_t
-dotnet_naming_rule.type_parameters_should_be_pascal_case_prefixed_with_t.symbols = type_parameters
-
-###############################################################################
-# Set dotnet naming styles to define:
-# camel case
-# pascal case
-# pascal case suffixed with Async
-# pascal case prefixed with I
-# pascal case prefixed with T
-###############################################################################
-[*.cs]
-dotnet_naming_style.camel_case.capitalization = camel_case
-
-dotnet_naming_style.pascal_case.capitalization = pascal_case
-
-dotnet_naming_style.pascal_case_suffixed_with_async.capitalization = pascal_case
-dotnet_naming_style.pascal_case_suffixed_with_async.required_suffix = Async
-
-dotnet_naming_style.pascal_case_prefixed_with_i.capitalization = pascal_case
-dotnet_naming_style.pascal_case_prefixed_with_i.required_prefix = I
-
-dotnet_naming_style.pascal_case_prefixed_with_t.capitalization = pascal_case
-dotnet_naming_style.pascal_case_prefixed_with_t.required_prefix = T
-
-###############################################################################
-# Set dotnet naming symbols to:
-# async members
-# const declarations
-# interfaces
-# private and internal fields
-# private and internal static fields
-# public and protected declarations
-# static readonly declarations
-# type parameters
-###############################################################################
-[*.cs]
-dotnet_naming_symbols.async_members.required_modifiers = async
-
-dotnet_naming_symbols.const_declarations.required_modifiers = const
-
-dotnet_naming_symbols.interfaces.applicable_kinds = interface
-
-dotnet_naming_symbols.parameters.applicable_kinds = parameter
-
-dotnet_naming_symbols.private_and_internal_fields.applicable_accessibilities = private, internal
-dotnet_naming_symbols.private_and_internal_fields.applicable_kinds = field
-
-dotnet_naming_symbols.private_and_internal_static_fields.applicable_accessibilities = private, internal
-dotnet_naming_symbols.private_and_internal_static_fields.applicable_kinds = field
-dotnet_naming_symbols.private_and_internal_static_fields.required_modifiers = static
-
-dotnet_naming_symbols.public_and_protected_declarations.applicable_accessibilities = public, protected
-
-dotnet_naming_symbols.static_readonly_declarations.required_modifiers = static, readonly
-
-dotnet_naming_symbols.type_parameters.applicable_kinds = type_parameter
-
-###############################################################################
-# Set dotnet sort options to:
-# do not separate import directives into groups, and
-# sort system directives first
-###############################################################################
-[*.cs]
-dotnet_separate_import_directive_groups = false
-dotnet_sort_system_directives_first = true
+##########################################
+# File Header (Uncomment to support file headers)
+# https://docs.microsoft.com/visualstudio/ide/reference/add-file-header
+##########################################
-###############################################################################
-# Set dotnet style options to:
-# suggest null-coalescing expressions,
-# suggest collection-initializers,
-# suggest explicit tuple names,
-# suggest null-propogation
-# suggest object-initializers,
-# generate parentheses in arithmetic binary operators for clarity,
-# generate parentheses in other binary operators for clarity,
-# don't generate parentheses in other operators if unnecessary,
-# generate parentheses in relational binary operators for clarity,
-# warn when not using predefined-types for locals, parameters, and members,
-# generate predefined-types of type names for member access,
-# generate auto properties,
-# suggest compound assignment,
-# generate conditional expression over assignment,
-# generate conditional expression over return,
-# suggest inferred anonymous types,
-# suggest inferred tuple names,
-# suggest 'is null' checks over '== null',
-# don't generate 'this.' and 'Me.' for events,
-# warn when not using 'this.' and 'Me.' for fields,
-# warn when not using 'this.' and 'Me.' for methods,
-# warn when not using 'this.' and 'Me.' for properties,
-# suggest readonly fields, and
-# generate accessibility modifiers for non interface members
-###############################################################################
-[*.cs]
-dotnet_style_coalesce_expression = true:suggestion
-dotnet_style_collection_initializer = true:suggestion
-dotnet_style_explicit_tuple_names = true:suggestion
-dotnet_style_null_propagation = true:suggestion
-dotnet_style_object_initializer = true:suggestion
-
-dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
-dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
-dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
-dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
+# [*.{cs,csx,cake,vb,vbx,tt,ttinclude}]
+file_header_template = Copyright (c) Six Labors.\nLicensed under the Apache License, Version 2.0.
-dotnet_style_predefined_type_for_locals_parameters_members = true:warning
-dotnet_style_predefined_type_for_member_access = true:silent
+# SA1636: File header copyright text should match
+# Justification: .editorconfig supports file headers. If this is changed to a value other than "none", a stylecop.json file will need to added to the project.
+# dotnet_diagnostic.SA1636.severity = none
-dotnet_style_prefer_auto_properties = true:silent
-dotnet_style_prefer_compound_assignment = true:suggestion
-dotnet_style_prefer_conditional_expression_over_assignment = true:silent
-dotnet_style_prefer_conditional_expression_over_return = true:silent
-dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
-dotnet_style_prefer_inferred_tuple_names = true:suggestion
-dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+##########################################
+# .NET Language Conventions
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions
+##########################################
-dotnet_style_qualification_for_event = false:silent
+# .NET Code Style Settings
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#net-code-style-settings
+[*.{cs,csx,cake,vb,vbx}]
+# "this." and "Me." qualifiers
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#this-and-me
dotnet_style_qualification_for_field = true:warning
-dotnet_style_qualification_for_method = true:warning
dotnet_style_qualification_for_property = true:warning
-
-dotnet_style_readonly_field = true:suggestion
-dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
-
-###############################################################################
-# Set dotnet style options to:
-# suggest removing all unused parameters
-###############################################################################
-[*.cs]
-dotnet_code_quality_unused_parameters = all:suggestion
-
-###############################################################################
-# Set csharp indent options to:
-# indent block contents,
-# not indent braces,
-# indent case contents,
-# not indent case contents when block,
-# indent labels one less than the current, and
-# indent switch labels
-###############################################################################
-[*.cs]
-csharp_indent_block_contents = true
-csharp_indent_braces = false
-csharp_indent_case_contents = true
-csharp_indent_case_contents_when_block = false
-csharp_indent_labels = one_less_than_current
-csharp_indent_switch_labels = true
-
-###############################################################################
-# Set csharp new-line options to:
-# insert a new-line before "catch",
-# insert a new-line before "else",
-# insert a new-line before "finally",
-# insert a new-line before members in anonymous-types,
-# insert a new-line before members in object-initializers, and
-# insert a new-line before all open braces
-###############################################################################
-[*.cs]
-csharp_new_line_before_catch = true
+dotnet_style_qualification_for_method = true:warning
+dotnet_style_qualification_for_event = true:warning
+# Language keywords instead of framework type names for type references
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#language-keywords
+dotnet_style_predefined_type_for_locals_parameters_members = true:warning
+dotnet_style_predefined_type_for_member_access = true:warning
+# Modifier preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#normalize-modifiers
+dotnet_style_require_accessibility_modifiers = always:warning
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning
+visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:warning
+dotnet_style_readonly_field = true:warning
+# Parentheses preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parentheses-preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
+# Expression-level preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
+dotnet_style_object_initializer = true:warning
+dotnet_style_collection_initializer = true:warning
+dotnet_style_explicit_tuple_names = true:warning
+dotnet_style_prefer_inferred_tuple_names = true:warning
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
+dotnet_style_prefer_auto_properties = true:warning
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
+dotnet_style_prefer_conditional_expression_over_assignment = false:suggestion
+dotnet_style_prefer_conditional_expression_over_return = false:suggestion
+dotnet_style_prefer_compound_assignment = true:warning
+# Null-checking preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#null-checking-preferences
+dotnet_style_coalesce_expression = true:warning
+dotnet_style_null_propagation = true:warning
+# Parameter preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parameter-preferences
+dotnet_code_quality_unused_parameters = all:warning
+# More style options (Undocumented)
+# https://github.com/MicrosoftDocs/visualstudio-docs/issues/3641
+dotnet_style_operator_placement_when_wrapping = end_of_line
+# https://github.com/dotnet/roslyn/pull/40070
+dotnet_style_prefer_simplified_interpolation = true:warning
+
+# C# Code Style Settings
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-code-style-settings
+[*.{cs,csx,cake}]
+# Implicit and explicit types
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#implicit-and-explicit-types
+csharp_style_var_for_built_in_types = never
+csharp_style_var_when_type_is_apparent = true:warning
+csharp_style_var_elsewhere = false:warning
+# Expression-bodied members
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-bodied-members
+csharp_style_expression_bodied_methods = true:warning
+csharp_style_expression_bodied_constructors = true:warning
+csharp_style_expression_bodied_operators = true:warning
+csharp_style_expression_bodied_properties = true:warning
+csharp_style_expression_bodied_indexers = true:warning
+csharp_style_expression_bodied_accessors = true:warning
+csharp_style_expression_bodied_lambdas = true:warning
+csharp_style_expression_bodied_local_functions = true:warning
+# Pattern matching
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#pattern-matching
+csharp_style_pattern_matching_over_is_with_cast_check = true:warning
+csharp_style_pattern_matching_over_as_with_null_check = true:warning
+# Inlined variable declarations
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#inlined-variable-declarations
+csharp_style_inlined_variable_declaration = true:warning
+# Expression-level preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
+csharp_prefer_simple_default_expression = true:warning
+# "Null" checking preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-null-checking-preferences
+csharp_style_throw_expression = true:warning
+csharp_style_conditional_delegate_call = true:warning
+# Code block preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#code-block-preferences
+csharp_prefer_braces = true:warning
+# Unused value preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#unused-value-preferences
+csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:suggestion
+# Index and range preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#index-and-range-preferences
+csharp_style_prefer_index_operator = true:warning
+csharp_style_prefer_range_operator = true:warning
+# Miscellaneous preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#miscellaneous-preferences
+csharp_style_deconstructed_variable_declaration = true:warning
+csharp_style_pattern_local_over_anonymous_function = true:warning
+csharp_using_directive_placement = outside_namespace:warning
+csharp_prefer_static_local_function = true:warning
+csharp_prefer_simple_using_statement = true:suggestion
+
+##########################################
+# .NET Formatting Conventions
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference#formatting-conventions
+##########################################
+
+# Organize usings
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#organize-using-directives
+dotnet_sort_system_directives_first = true
+# Newline options
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#new-line-options
+csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
-
-csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
-
-csharp_new_line_before_open_brace = all
-
-###############################################################################
-# Set csharp preserve options to:
-# preserve single-line blocks, and
-# preserve single-line statements
-###############################################################################
-[*.cs]
-csharp_preserve_single_line_blocks = true
-csharp_preserve_single_line_statements = true
-
-###############################################################################
-# Set csharp space options to:
-# remove any space after a cast,
-# add a space after the colon in an inheritance clause,
-# add a space after a comma,
-# remove any space after a dot,
-# add a space after keywords in control flow statements,
-# add a space after a semicolon in a "for" statement,
-# add a space before and after binary operators,
-# remove space around declaration statements,
-# add a space before the colon in an inheritance clause,
-# remove any space before a comma,
-# remove any space before a dot,
-# remove any space before an open square-bracket,
-# remove any space before a semicolon in a "for" statement,
-# remove any space between empty square-brackets,
-# remove any space between a method call's empty parameter list parenthesis,
-# remove any space between a method call's name and its opening parenthesis,
-# remove any space between a method call's parameter list parenthesis,
-# remove any space between a method declaration's empty parameter list parenthesis,
-# remove any space between a method declaration's name and its openening parenthesis,
-# remove any space between a method declaration's parameter list parenthesis,
-# remove any space between parentheses, and
-# remove any space between square brackets
-###############################################################################
-[*.cs]
+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
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = no_change
+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
csharp_space_after_cast = false
-csharp_space_after_colon_in_inheritance_clause = true
-csharp_space_after_comma = true
-csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
-csharp_space_after_semicolon_in_for_statement = true
-
-csharp_space_around_binary_operators = before_and_after
-csharp_space_around_declaration_statements = do_not_ignore
-
+csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_after_comma = true
csharp_space_before_comma = false
+csharp_space_after_dot = false
csharp_space_before_dot = false
-csharp_space_before_open_square_brackets = false
+csharp_space_after_semicolon_in_for_statement = true
csharp_space_before_semicolon_in_for_statement = false
-
+csharp_space_around_declaration_statements = false
+csharp_space_before_open_square_brackets = false
csharp_space_between_empty_square_brackets = false
-csharp_space_between_method_call_empty_parameter_list_parentheses = false
-csharp_space_between_method_call_name_and_opening_parenthesis = false
-csharp_space_between_method_call_parameter_list_parentheses = false
-csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
-csharp_space_between_method_declaration_name_and_open_parenthesis = false
-csharp_space_between_method_declaration_parameter_list_parentheses = false
-csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
+# Wrapping options
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#wrap-options
+csharp_preserve_single_line_statements = false
+csharp_preserve_single_line_blocks = true
-###############################################################################
-# Set csharp style options to:
-# generate braces,
-# suggest simple default expressions,
-# generate a preferred modifier order,
-# suggest conditional delegate calls,
-# suggest deconstructed variable declarations,
-# generate expression-bodied accessors,
-# generate expression-bodied constructors,
-# generate expression-bodied indexers,
-# generate expression-bodied lambdas,
-# generate expression-bodied methods,
-# generate expression-bodied operators,
-# generate expression-bodied properties,
-# suggest inlined variable declarations,
-# suggest local over anonymous functions,
-# suggest pattern-matching over "as" with "null" check,
-# suggest pattern-matching over "is" with "cast" check,
-# suggest throw expressions,
-# generate a discard variable for unused value expression statements,
-# suggest a discard variable for unused assignments,
-# warn when using var for built-in types,
-# warn when using var when the type is not apparent, and
-# warn when not using var when the type is apparent
-# warn when using simplified "using" declaration
-###############################################################################
-[*.cs]
-csharp_prefer_braces = true:silent
-csharp_prefer_simple_default_expression = true:suggestion
-csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
-
-csharp_style_conditional_delegate_call = true:suggestion
-csharp_style_deconstructed_variable_declaration = true:suggestion
-
-csharp_style_expression_bodied_accessors = true:silent
-csharp_style_expression_bodied_constructors = true:silent
-csharp_style_expression_bodied_indexers = true:silent
-csharp_style_expression_bodied_lambdas = true:silent
-csharp_style_expression_bodied_methods = true:silent
-csharp_style_expression_bodied_operators = true:silent
-csharp_style_expression_bodied_properties = true:silent
-
-csharp_style_inlined_variable_declaration = true:suggestion
-
-csharp_style_pattern_local_over_anonymous_function = true:suggestion
-csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
-csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
-
-csharp_style_throw_expression = true:suggestion
-
-csharp_style_unused_value_expression_statement_preference = discard_variable:silent
-csharp_style_unused_value_assignment_preference = discard_variable:suggestion
-
-csharp_style_var_for_built_in_types = never
-csharp_style_var_when_type_is_apparent = true:warning
-csharp_style_var_elsewhere = false:warning
+##########################################
+# .NET Naming Conventions
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-naming-conventions
+##########################################
+
+[*.{cs,csx,cake,vb,vbx}]
+
+##########################################
+# Styles
+##########################################
+
+# camel_case_style - Define the camelCase style
+dotnet_naming_style.camel_case_style.capitalization = camel_case
+# pascal_case_style - Define the PascalCase style
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+# first_upper_style - The first character must start with an upper-case character
+dotnet_naming_style.first_upper_style.capitalization = first_word_upper
+# prefix_interface_with_i_style - Interfaces must be PascalCase and the first character of an interface must be an 'I'
+dotnet_naming_style.prefix_interface_with_i_style.capitalization = pascal_case
+dotnet_naming_style.prefix_interface_with_i_style.required_prefix = I
+# prefix_type_parameters_with_t_style - Generic Type Parameters must be PascalCase and the first character must be a 'T'
+dotnet_naming_style.prefix_type_parameters_with_t_style.capitalization = pascal_case
+dotnet_naming_style.prefix_type_parameters_with_t_style.required_prefix = T
+# disallowed_style - Anything that has this style applied is marked as disallowed
+dotnet_naming_style.disallowed_style.capitalization = pascal_case
+dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____
+dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____
+# internal_error_style - This style should never occur... if it does, it indicates a bug in file or in the parser using the file
+dotnet_naming_style.internal_error_style.capitalization = pascal_case
+dotnet_naming_style.internal_error_style.required_prefix = ____INTERNAL_ERROR____
+dotnet_naming_style.internal_error_style.required_suffix = ____INTERNAL_ERROR____
+
+##########################################
+# .NET Design Guideline Field Naming Rules
+# Naming rules for fields follow the .NET Framework design guidelines
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/index
+##########################################
+
+# All public/protected/protected_internal constant fields must be PascalCase
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
+dotnet_naming_symbols.public_protected_constant_fields_group.applicable_accessibilities = public, protected, protected_internal
+dotnet_naming_symbols.public_protected_constant_fields_group.required_modifiers = const
+dotnet_naming_symbols.public_protected_constant_fields_group.applicable_kinds = field
+dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.symbols = public_protected_constant_fields_group
+dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.style = pascal_case_style
+dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.severity = warning
+
+# All public/protected/protected_internal static readonly fields must be PascalCase
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
+dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_accessibilities = public, protected, protected_internal
+dotnet_naming_symbols.public_protected_static_readonly_fields_group.required_modifiers = static, readonly
+dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_kinds = field
+dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.symbols = public_protected_static_readonly_fields_group
+dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style
+dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.severity = warning
+
+# No other public/protected/protected_internal fields are allowed
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
+dotnet_naming_symbols.other_public_protected_fields_group.applicable_accessibilities = public, protected, protected_internal
+dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field
+dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group
+dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style
+dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error
+
+##########################################
+# StyleCop Field Naming Rules
+# Naming rules for fields follow the StyleCop analyzers
+# This does not override any rules using disallowed_style above
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers
+##########################################
+
+# All constant fields must be PascalCase
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1303.md
+dotnet_naming_symbols.stylecop_constant_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
+dotnet_naming_symbols.stylecop_constant_fields_group.required_modifiers = const
+dotnet_naming_symbols.stylecop_constant_fields_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.symbols = stylecop_constant_fields_group
+dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.style = pascal_case_style
+dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.severity = warning
+
+# All static readonly fields must be PascalCase
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1311.md
+dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
+dotnet_naming_symbols.stylecop_static_readonly_fields_group.required_modifiers = static, readonly
+dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.symbols = stylecop_static_readonly_fields_group
+dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style
+dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.severity = warning
+
+# No non-private instance fields are allowed
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1401.md
+dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected
+dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.symbols = stylecop_fields_must_be_private_group
+dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.style = disallowed_style
+dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.severity = error
+
+# Private fields must be camelCase
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1306.md
+dotnet_naming_symbols.stylecop_private_fields_group.applicable_accessibilities = private
+dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group
+dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = camel_case_style
+dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning
+
+# Local variables must be camelCase
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1312.md
+dotnet_naming_symbols.stylecop_local_fields_group.applicable_accessibilities = local
+dotnet_naming_symbols.stylecop_local_fields_group.applicable_kinds = local
+dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.symbols = stylecop_local_fields_group
+dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.style = camel_case_style
+dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.severity = silent
+
+# This rule should never fire. However, it's included for at least two purposes:
+# First, it helps to understand, reason about, and root-case certain types of issues, such as bugs in .editorconfig parsers.
+# Second, it helps to raise immediate awareness if a new field type is added (as occurred recently in C#).
+dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_accessibilities = *
+dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_kinds = field
+dotnet_naming_rule.sanity_check_uncovered_field_case_rule.symbols = sanity_check_uncovered_field_case_group
+dotnet_naming_rule.sanity_check_uncovered_field_case_rule.style = internal_error_style
+dotnet_naming_rule.sanity_check_uncovered_field_case_rule.severity = error
+
+
+##########################################
+# Other Naming Rules
+##########################################
+
+# All of the following must be PascalCase:
+# - Namespaces
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-namespaces
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
+# - Classes and Enumerations
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
+# - Delegates
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces#names-of-common-types
+# - Constructors, Properties, Events, Methods
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-type-members
+dotnet_naming_symbols.element_group.applicable_kinds = namespace, class, enum, struct, delegate, event, method, property
+dotnet_naming_rule.element_rule.symbols = element_group
+dotnet_naming_rule.element_rule.style = pascal_case_style
+dotnet_naming_rule.element_rule.severity = warning
+
+# Interfaces use PascalCase and are prefixed with uppercase 'I'
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
+dotnet_naming_symbols.interface_group.applicable_kinds = interface
+dotnet_naming_rule.interface_rule.symbols = interface_group
+dotnet_naming_rule.interface_rule.style = prefix_interface_with_i_style
+dotnet_naming_rule.interface_rule.severity = warning
+
+# Generics Type Parameters use PascalCase and are prefixed with uppercase 'T'
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
+dotnet_naming_symbols.type_parameter_group.applicable_kinds = type_parameter
+dotnet_naming_rule.type_parameter_rule.symbols = type_parameter_group
+dotnet_naming_rule.type_parameter_rule.style = prefix_type_parameters_with_t_style
+dotnet_naming_rule.type_parameter_rule.severity = warning
+
+# Function parameters use camelCase
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/naming-parameters
+dotnet_naming_symbols.parameters_group.applicable_kinds = parameter
+dotnet_naming_rule.parameters_rule.symbols = parameters_group
+dotnet_naming_rule.parameters_rule.style = camel_case_style
+dotnet_naming_rule.parameters_rule.severity = warning
+
+##########################################
+# License
+##########################################
+# The following applies as to the .editorconfig file ONLY, and is
+# included below for reference, per the requirements of the license
+# corresponding to this .editorconfig file.
+# See: https://github.com/RehanSaeed/EditorConfig
+#
+# MIT License
+#
+# Copyright (c) 2017-2019 Muhammad Rehan Saeed
+# Copyright (c) 2019 Henry Gabryjelski
+#
+# Permission is hereby granted, free of charge, to any
+# person obtaining a copy of this software and associated
+# documentation files (the "Software"), to deal in the
+# Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute,
+# sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject
+# to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# 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.
+##########################################
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index c8f3997946..2876682bcd 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -18,6 +18,10 @@ jobs:
framework: netcoreapp3.1
runtime: -x64
codecov: true
+ - os: macos-latest
+ framework: netcoreapp3.1
+ runtime: -x64
+ codecov: false
- os: windows-latest
framework: netcoreapp3.1
runtime: -x64
@@ -52,6 +56,14 @@ jobs:
git fetch --prune --unshallow
git submodule -q update --init --recursive
+ - name: Setup NuGet Cache
+ uses: actions/cache@v2
+ id: nuget-cache
+ with:
+ path: ~/.nuget
+ key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props', '**/*.targets') }}
+ restore-keys: ${{ runner.os }}-nuget-
+
- name: Build
shell: pwsh
run: ./ci-build.ps1 "${{matrix.options.framework}}"
@@ -63,6 +75,13 @@ jobs:
CI: True
XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit
+ - name: Store Output Images after failed tests
+ uses: actions/upload-artifact@v2
+ if: failure()
+ with:
+ name: actual_output_${{ runner.os }}_${{ matrix.options.framework }}${{ matrix.options.runtime }}.zip
+ path: tests/Images/ActualOutput/
+
- name: Update Codecov
uses: codecov/codecov-action@v1
if: matrix.options.codecov == true && startsWith(github.repository, 'SixLabors')
diff --git a/.gitignore b/.gitignore
index a89cfcf104..475d6e76b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -221,3 +221,4 @@ artifacts/
# Tests
**/Images/ActualOutput
**/Images/ReferenceOutput
+.DS_Store
diff --git a/Directory.Build.props b/Directory.Build.props
index bb97810a8f..3a133efe7a 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -10,133 +10,12 @@
that is done by the file that imports us.
-->
-
- $(MSBuildThisFileDirectory)artifacts/
- $(SixLaborsProjectCategory)/$(MSBuildProjectName)
- https://github.com/SixLabors/ImageSharp/
- $(MSBuildThisFileDirectory)/.runsettings
+
+ $(MSBuildThisFileDirectory)
-
-
- true
- $(BaseArtifactsPath)obj/$(BaseArtifactsPathSuffix)/
- portable
- full
- disable
- true
- true
-
-
-
-
-
- $(DefineConstants);SUPPORTS_MATHF
- $(DefineConstants);SUPPORTS_HASHCODE
- $(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS
- $(DefineConstants);SUPPORTS_SPAN_STREAM
- $(DefineConstants);SUPPORTS_ENCODING_STRING
- $(DefineConstants);SUPPORTS_RUNTIME_INTRINSICS
- $(DefineConstants);SUPPORTS_CODECOVERAGE
- $(DefineConstants);SUPPORTS_HOTPATH
- $(DefineConstants);SUPPORTS_CREATESPAN
-
-
- $(DefineConstants);SUPPORTS_MATHF
- $(DefineConstants);SUPPORTS_HASHCODE
- $(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS
- $(DefineConstants);SUPPORTS_SPAN_STREAM
- $(DefineConstants);SUPPORTS_ENCODING_STRING
- $(DefineConstants);SUPPORTS_CODECOVERAGE
- $(DefineConstants);SUPPORTS_CREATESPAN
-
-
- $(DefineConstants);SUPPORTS_MATHF
- $(DefineConstants);SUPPORTS_CODECOVERAGE
- $(DefineConstants);SUPPORTS_CREATESPAN
-
-
- $(DefineConstants);SUPPORTS_MATHF
- $(DefineConstants);SUPPORTS_HASHCODE
- $(DefineConstants);SUPPORTS_SPAN_STREAM
- $(DefineConstants);SUPPORTS_ENCODING_STRING
- $(DefineConstants);SUPPORTS_CODECOVERAGE
- $(DefineConstants);SUPPORTS_CREATESPAN
-
-
- $(DefineConstants);SUPPORTS_CODECOVERAGE
-
-
- $(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS
- $(DefineConstants);SUPPORTS_CODECOVERAGE
-
-
-
-
- Six Labors and contributors
- $(BaseArtifactsPath)bin/$(BaseArtifactsPathSuffix)/
- Six Labors
- $(BaseArtifactsPath)pkg/$(BaseArtifactsPathSuffix)/$(Configuration)/
- SixLabors.ImageSharp
- 0.0.1
- $(PackageVersion)
-
-
-
-
-
- v
- normal
-
-
-
-
- Copyright © Six Labors
- strict;IOperation
- true
- 8.0
- en
- true
- sixlabors.imagesharp.128.png
- Apache-2.0
- $(RepositoryUrl)
- true
- git
-
- https://www.myget.org/F/sixlabors/api/v3/index.json;
- https://api.nuget.org/v3/index.json;
-
- https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json;
- https://www.myget.org/F/coverlet-dev/api/v3/index.json;
-
- true
- $(MSBuildThisFileDirectory)shared-infrastructure/SixLabors.snk
- 00240000048000009400000006020000002400005253413100040000010001000147e6fe6766715eec6cfed61f1e7dcdbf69748a3e355c67e9d8dfd953acab1d5e012ba34b23308166fdc61ee1d0390d5f36d814a6091dd4b5ed9eda5a26afced924c683b4bfb4b3d64b0586a57eff9f02b1f84e3cb0ddd518bd1697f2c84dcbb97eb8bb5c7801be12112ed0ec86db934b0e9a5171e6bb1384b6d2f7d54dfa97
- true
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 2a7d25b977..9730219482 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -5,35 +5,12 @@
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
- instead. The import fairly late and most other props/targets will have been
+ instead. They import fairly late and most other props/targets will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
-
-
- $(DefineConstants);$(OS)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/ImageSharp.sln b/ImageSharp.sln
index b1d3176ad2..8dfab6033c 100644
--- a/ImageSharp.sln
+++ b/ImageSharp.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28902.138
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C317F1B1-D75E-4C6D-83EB-80367343E0D7}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_root", "_root", "{C317F1B1-D75E-4C6D-83EB-80367343E0D7}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitattributes = .gitattributes
@@ -15,7 +15,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ci-test.ps1 = ci-test.ps1
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
- GitVersion.yml = GitVersion.yml
LICENSE = LICENSE
README.md = README.md
EndProjectSection
@@ -46,6 +45,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{56801022
ProjectSection(SolutionItems) = preProject
tests\Directory.Build.props = tests\Directory.Build.props
tests\Directory.Build.targets = tests\Directory.Build.targets
+ tests\ImageSharp.Tests.ruleset = tests\ImageSharp.Tests.ruleset
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Images", "Images", "{FA55F5DE-11A6-487D-ABA4-BC93A02717DD}"
@@ -54,16 +54,23 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Input", "Input", "{9DA226A1
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bmp", "Bmp", "{1A82C5F6-90E0-4E97-BE16-A825C046B493}"
ProjectSection(SolutionItems) = preProject
+ tests\Images\Input\Bmp\9S.BMP = tests\Images\Input\Bmp\9S.BMP
+ tests\Images\Input\Bmp\ba-bm.bmp = tests\Images\Input\Bmp\ba-bm.bmp
tests\Images\Input\Bmp\BitmapCoreHeaderQR.bmp = tests\Images\Input\Bmp\BitmapCoreHeaderQR.bmp
tests\Images\Input\Bmp\BITMAPV5HEADER.bmp = tests\Images\Input\Bmp\BITMAPV5HEADER.bmp
tests\Images\Input\Bmp\Car.bmp = tests\Images\Input\Bmp\Car.bmp
+ tests\Images\Input\Bmp\DIAMOND.BMP = tests\Images\Input\Bmp\DIAMOND.BMP
tests\Images\Input\Bmp\F.bmp = tests\Images\Input\Bmp\F.bmp
+ tests\Images\Input\Bmp\GMARBLE.BMP = tests\Images\Input\Bmp\GMARBLE.BMP
+ tests\Images\Input\Bmp\invalidPaletteSize.bmp = tests\Images\Input\Bmp\invalidPaletteSize.bmp
tests\Images\Input\Bmp\issue735.bmp = tests\Images\Input\Bmp\issue735.bmp
tests\Images\Input\Bmp\neg_height.bmp = tests\Images\Input\Bmp\neg_height.bmp
tests\Images\Input\Bmp\pal1.bmp = tests\Images\Input\Bmp\pal1.bmp
tests\Images\Input\Bmp\pal1p1.bmp = tests\Images\Input\Bmp\pal1p1.bmp
tests\Images\Input\Bmp\pal4.bmp = tests\Images\Input\Bmp\pal4.bmp
tests\Images\Input\Bmp\pal4rle.bmp = tests\Images\Input\Bmp\pal4rle.bmp
+ tests\Images\Input\Bmp\pal4rlecut.bmp = tests\Images\Input\Bmp\pal4rlecut.bmp
+ tests\Images\Input\Bmp\pal4rletrns.bmp = tests\Images\Input\Bmp\pal4rletrns.bmp
tests\Images\Input\Bmp\pal8-0.bmp = tests\Images\Input\Bmp\pal8-0.bmp
tests\Images\Input\Bmp\pal8gs.bmp = tests\Images\Input\Bmp\pal8gs.bmp
tests\Images\Input\Bmp\pal8offs.bmp = tests\Images\Input\Bmp\pal8offs.bmp
@@ -71,26 +78,45 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Bmp", "Bmp", "{1A82C5F6-90E
tests\Images\Input\Bmp\pal8os2v1_winv2.bmp = tests\Images\Input\Bmp\pal8os2v1_winv2.bmp
tests\Images\Input\Bmp\pal8os2v2-16.bmp = tests\Images\Input\Bmp\pal8os2v2-16.bmp
tests\Images\Input\Bmp\pal8os2v2.bmp = tests\Images\Input\Bmp\pal8os2v2.bmp
+ tests\Images\Input\Bmp\pal8oversizepal.bmp = tests\Images\Input\Bmp\pal8oversizepal.bmp
+ tests\Images\Input\Bmp\pal8rlecut.bmp = tests\Images\Input\Bmp\pal8rlecut.bmp
+ tests\Images\Input\Bmp\pal8rletrns.bmp = tests\Images\Input\Bmp\pal8rletrns.bmp
tests\Images\Input\Bmp\pal8v4.bmp = tests\Images\Input\Bmp\pal8v4.bmp
tests\Images\Input\Bmp\pal8v5.bmp = tests\Images\Input\Bmp\pal8v5.bmp
+ tests\Images\Input\Bmp\PINES.BMP = tests\Images\Input\Bmp\PINES.BMP
tests\Images\Input\Bmp\rgb16-565.bmp = tests\Images\Input\Bmp\rgb16-565.bmp
tests\Images\Input\Bmp\rgb16-565pal.bmp = tests\Images\Input\Bmp\rgb16-565pal.bmp
tests\Images\Input\Bmp\rgb16.bmp = tests\Images\Input\Bmp\rgb16.bmp
tests\Images\Input\Bmp\rgb16bfdef.bmp = tests\Images\Input\Bmp\rgb16bfdef.bmp
tests\Images\Input\Bmp\rgb24.bmp = tests\Images\Input\Bmp\rgb24.bmp
+ tests\Images\Input\Bmp\rgb24jpeg.bmp = tests\Images\Input\Bmp\rgb24jpeg.bmp
+ tests\Images\Input\Bmp\rgb24largepal.bmp = tests\Images\Input\Bmp\rgb24largepal.bmp
+ tests\Images\Input\Bmp\rgb24png.bmp = tests\Images\Input\Bmp\rgb24png.bmp
+ tests\Images\Input\Bmp\rgb24rle24.bmp = tests\Images\Input\Bmp\rgb24rle24.bmp
tests\Images\Input\Bmp\rgb32.bmp = tests\Images\Input\Bmp\rgb32.bmp
tests\Images\Input\Bmp\rgb32bf.bmp = tests\Images\Input\Bmp\rgb32bf.bmp
tests\Images\Input\Bmp\rgb32bfdef.bmp = tests\Images\Input\Bmp\rgb32bfdef.bmp
+ tests\Images\Input\Bmp\rgb32h52.bmp = tests\Images\Input\Bmp\rgb32h52.bmp
tests\Images\Input\Bmp\rgba32-1010102.bmp = tests\Images\Input\Bmp\rgba32-1010102.bmp
tests\Images\Input\Bmp\rgba32.bmp = tests\Images\Input\Bmp\rgba32.bmp
tests\Images\Input\Bmp\rgba32abf.bmp = tests\Images\Input\Bmp\rgba32abf.bmp
tests\Images\Input\Bmp\rgba32h56.bmp = tests\Images\Input\Bmp\rgba32h56.bmp
+ tests\Images\Input\Bmp\rgba32v4.bmp = tests\Images\Input\Bmp\rgba32v4.bmp
+ tests\Images\Input\Bmp\rle24rlecut.bmp = tests\Images\Input\Bmp\rle24rlecut.bmp
+ tests\Images\Input\Bmp\rle24rletrns.bmp = tests\Images\Input\Bmp\rle24rletrns.bmp
+ tests\Images\Input\Bmp\rle4-delta-320x240.bmp = tests\Images\Input\Bmp\rle4-delta-320x240.bmp
+ tests\Images\Input\Bmp\rle8-blank-160x120.bmp = tests\Images\Input\Bmp\rle8-blank-160x120.bmp
+ tests\Images\Input\Bmp\rle8-delta-320x240.bmp = tests\Images\Input\Bmp\rle8-delta-320x240.bmp
tests\Images\Input\Bmp\RunLengthEncoded-inverted.bmp = tests\Images\Input\Bmp\RunLengthEncoded-inverted.bmp
tests\Images\Input\Bmp\RunLengthEncoded.bmp = tests\Images\Input\Bmp\RunLengthEncoded.bmp
+ tests\Images\Input\Bmp\SKATER.BMP = tests\Images\Input\Bmp\SKATER.BMP
+ tests\Images\Input\Bmp\SPADE.BMP = tests\Images\Input\Bmp\SPADE.BMP
+ tests\Images\Input\Bmp\SUNFLOW.BMP = tests\Images\Input\Bmp\SUNFLOW.BMP
tests\Images\Input\Bmp\test16-inverted.bmp = tests\Images\Input\Bmp\test16-inverted.bmp
tests\Images\Input\Bmp\test16.bmp = tests\Images\Input\Bmp\test16.bmp
tests\Images\Input\Bmp\test8-inverted.bmp = tests\Images\Input\Bmp\test8-inverted.bmp
tests\Images\Input\Bmp\test8.bmp = tests\Images\Input\Bmp\test8.bmp
+ tests\Images\Input\Bmp\WARPD.BMP = tests\Images\Input\Bmp\WARPD.BMP
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gif", "Gif", "{EE3FB0B3-1C31-41E9-93AB-BA800560A868}"
@@ -99,8 +125,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gif", "Gif", "{EE3FB0B3-1C3
tests\Images\Input\Gif\base_4x1.gif = tests\Images\Input\Gif\base_4x1.gif
tests\Images\Input\Gif\cheers.gif = tests\Images\Input\Gif\cheers.gif
tests\Images\Input\Gif\giphy.gif = tests\Images\Input\Gif\giphy.gif
+ tests\Images\Input\Gif\GlobalQuantizationTest.gif = tests\Images\Input\Gif\GlobalQuantizationTest.gif
+ tests\Images\Input\Gif\image-zero-height.gif = tests\Images\Input\Gif\image-zero-height.gif
+ tests\Images\Input\Gif\image-zero-size.gif = tests\Images\Input\Gif\image-zero-size.gif
+ tests\Images\Input\Gif\image-zero-width.gif = tests\Images\Input\Gif\image-zero-width.gif
tests\Images\Input\Gif\kumin.gif = tests\Images\Input\Gif\kumin.gif
+ tests\Images\Input\Gif\large_comment.gif = tests\Images\Input\Gif\large_comment.gif
tests\Images\Input\Gif\leo.gif = tests\Images\Input\Gif\leo.gif
+ tests\Images\Input\Gif\max-height.gif = tests\Images\Input\Gif\max-height.gif
+ tests\Images\Input\Gif\max-width.gif = tests\Images\Input\Gif\max-width.gif
+ tests\Images\Input\Gif\receipt.gif = tests\Images\Input\Gif\receipt.gif
tests\Images\Input\Gif\rings.gif = tests\Images\Input\Gif\rings.gif
tests\Images\Input\Gif\trans.gif = tests\Images\Input\Gif\trans.gif
EndProjectSection
@@ -116,6 +150,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Jpg", "Jpg", "{DB21FED7-E8C
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "baseline", "baseline", "{195BA3D3-3E9F-4BC5-AB40-5F9FEB638146}"
ProjectSection(SolutionItems) = preProject
+ tests\Images\Input\Jpg\baseline\640px-Unequalized_Hawkes_Bay_NZ.jpg = tests\Images\Input\Jpg\baseline\640px-Unequalized_Hawkes_Bay_NZ.jpg
tests\Images\Input\Jpg\baseline\AsianCarvingLowContrast.jpg = tests\Images\Input\Jpg\baseline\AsianCarvingLowContrast.jpg
tests\Images\Input\Jpg\baseline\badeof.jpg = tests\Images\Input\Jpg\baseline\badeof.jpg
tests\Images\Input\Jpg\baseline\badrst.jpg = tests\Images\Input\Jpg\baseline\badrst.jpg
@@ -125,6 +160,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "baseline", "baseline", "{19
tests\Images\Input\Jpg\baseline\Floorplan.jpg = tests\Images\Input\Jpg\baseline\Floorplan.jpg
tests\Images\Input\Jpg\baseline\gamma_dalai_lama_gray.jpg = tests\Images\Input\Jpg\baseline\gamma_dalai_lama_gray.jpg
tests\Images\Input\Jpg\baseline\Hiyamugi.jpg = tests\Images\Input\Jpg\baseline\Hiyamugi.jpg
+ tests\Images\Input\Jpg\baseline\iptc-psAPP13-wIPTCempty.jpg = tests\Images\Input\Jpg\baseline\iptc-psAPP13-wIPTCempty.jpg
+ tests\Images\Input\Jpg\baseline\iptc.jpg = tests\Images\Input\Jpg\baseline\iptc.jpg
tests\Images\Input\Jpg\baseline\jpeg400jfif.jpg = tests\Images\Input\Jpg\baseline\jpeg400jfif.jpg
tests\Images\Input\Jpg\baseline\jpeg420exif.jpg = tests\Images\Input\Jpg\baseline\jpeg420exif.jpg
tests\Images\Input\Jpg\baseline\jpeg420small.jpg = tests\Images\Input\Jpg\baseline\jpeg420small.jpg
@@ -167,6 +204,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "JpegSnoopReports", "JpegSno
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "issues", "issues", "{5C9B689F-B96D-47BE-A208-C23B1B2A8570}"
ProjectSection(SolutionItems) = preProject
+ tests\Images\Input\Jpg\issues\issue-1076-invalid-subsampling.jpg = tests\Images\Input\Jpg\issues\issue-1076-invalid-subsampling.jpg
+ tests\Images\Input\Jpg\issues\issue-1221-identify-multi-frame.jpg = tests\Images\Input\Jpg\issues\issue-1221-identify-multi-frame.jpg
+ tests\Images\Input\Jpg\issues\issue1006-incorrect-resize.jpg = tests\Images\Input\Jpg\issues\issue1006-incorrect-resize.jpg
+ tests\Images\Input\Jpg\issues\issue1049-exif-resize.jpg = tests\Images\Input\Jpg\issues\issue1049-exif-resize.jpg
tests\Images\Input\Jpg\issues\Issue159-MissingFF00-Progressive-Bedroom.jpg = tests\Images\Input\Jpg\issues\Issue159-MissingFF00-Progressive-Bedroom.jpg
tests\Images\Input\Jpg\issues\Issue159-MissingFF00-Progressive-Girl.jpg = tests\Images\Input\Jpg\issues\Issue159-MissingFF00-Progressive-Girl.jpg
tests\Images\Input\Jpg\issues\Issue178-BadCoeffsProgressive-Lemon.jpg = tests\Images\Input\Jpg\issues\Issue178-BadCoeffsProgressive-Lemon.jpg
@@ -214,6 +255,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fuzz", "fuzz", "{516A3532-6
tests\Images\Input\Jpg\issues\fuzz\Issue826-ArgumentException-C.jpg = tests\Images\Input\Jpg\issues\fuzz\Issue826-ArgumentException-C.jpg
tests\Images\Input\Jpg\issues\fuzz\Issue827-AccessViolationException.jpg = tests\Images\Input\Jpg\issues\fuzz\Issue827-AccessViolationException.jpg
tests\Images\Input\Jpg\issues\fuzz\Issue839-ExecutionEngineException.jpg = tests\Images\Input\Jpg\issues\fuzz\Issue839-ExecutionEngineException.jpg
+ tests\Images\Input\Jpg\issues\fuzz\Issue922-AccessViolationException.jpg = tests\Images\Input\Jpg\issues\fuzz\Issue922-AccessViolationException.jpg
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "JpegSnoopReports", "JpegSnoopReports", "{714CDEA1-9AE6-4F76-B8B1-A7DB8C1DB82F}"
@@ -261,16 +303,24 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Png", "Png", "{E1C42A6F-913
ProjectSection(SolutionItems) = preProject
tests\Images\Input\Png\banner7-adam.png = tests\Images\Input\Png\banner7-adam.png
tests\Images\Input\Png\banner8-index.png = tests\Images\Input\Png\banner8-index.png
+ tests\Images\Input\Png\basn3p01.png = tests\Images\Input\Png\basn3p01.png
+ tests\Images\Input\Png\basn3p02.png = tests\Images\Input\Png\basn3p02.png
+ tests\Images\Input\Png\basn3p04.png = tests\Images\Input\Png\basn3p04.png
+ tests\Images\Input\Png\basn3p08.png = tests\Images\Input\Png\basn3p08.png
tests\Images\Input\Png\big-corrupted-chunk.png = tests\Images\Input\Png\big-corrupted-chunk.png
+ tests\Images\Input\Png\bike-small.png = tests\Images\Input\Png\bike-small.png
tests\Images\Input\Png\Bike.png = tests\Images\Input\Png\Bike.png
tests\Images\Input\Png\BikeGrayscale.png = tests\Images\Input\Png\BikeGrayscale.png
tests\Images\Input\Png\blur.png = tests\Images\Input\Png\blur.png
tests\Images\Input\Png\bpp1.png = tests\Images\Input\Png\bpp1.png
+ tests\Images\Input\Png\Bradley01.png = tests\Images\Input\Png\Bradley01.png
+ tests\Images\Input\Png\Bradley02.png = tests\Images\Input\Png\Bradley02.png
tests\Images\Input\Png\CalliphoraPartial.png = tests\Images\Input\Png\CalliphoraPartial.png
tests\Images\Input\Png\CalliphoraPartialGrayscale.png = tests\Images\Input\Png\CalliphoraPartialGrayscale.png
tests\Images\Input\Png\chunklength1.png = tests\Images\Input\Png\chunklength1.png
tests\Images\Input\Png\chunklength2.png = tests\Images\Input\Png\chunklength2.png
tests\Images\Input\Png\cross.png = tests\Images\Input\Png\cross.png
+ tests\Images\Input\Png\david.png = tests\Images\Input\Png\david.png
tests\Images\Input\Png\ducky.png = tests\Images\Input\Png\ducky.png
tests\Images\Input\Png\filter0.png = tests\Images\Input\Png\filter0.png
tests\Images\Input\Png\filter1.png = tests\Images\Input\Png\filter1.png
@@ -293,6 +343,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Png", "Png", "{E1C42A6F-913
tests\Images\Input\Png\iftbbn0g04.png = tests\Images\Input\Png\iftbbn0g04.png
tests\Images\Input\Png\indexed.png = tests\Images\Input\Png\indexed.png
tests\Images\Input\Png\interlaced.png = tests\Images\Input\Png\interlaced.png
+ tests\Images\Input\Png\InvalidTextData.png = tests\Images\Input\Png\InvalidTextData.png
tests\Images\Input\Png\kaboom.png = tests\Images\Input\Png\kaboom.png
tests\Images\Input\Png\low-variance.png = tests\Images\Input\Png\low-variance.png
tests\Images\Input\Png\palette-8bpp.png = tests\Images\Input\Png\palette-8bpp.png
@@ -300,6 +351,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Png", "Png", "{E1C42A6F-913
tests\Images\Input\Png\pd-source.png = tests\Images\Input\Png\pd-source.png
tests\Images\Input\Png\pd.png = tests\Images\Input\Png\pd.png
tests\Images\Input\Png\pl.png = tests\Images\Input\Png\pl.png
+ tests\Images\Input\Png\PngWithMetaData.png = tests\Images\Input\Png\PngWithMetaData.png
tests\Images\Input\Png\pp.png = tests\Images\Input\Png\pp.png
tests\Images\Input\Png\rainbow.png = tests\Images\Input\Png\rainbow.png
tests\Images\Input\Png\ratio-1x4.png = tests\Images\Input\Png\ratio-1x4.png
@@ -317,7 +369,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Png", "Png", "{E1C42A6F-913
tests\Images\Input\Png\versioning-1_2.png = tests\Images\Input\Png\versioning-1_2.png
tests\Images\Input\Png\vim16x16_1.png = tests\Images\Input\Png\vim16x16_1.png
tests\Images\Input\Png\vim16x16_2.png = tests\Images\Input\Png\vim16x16_2.png
+ tests\Images\Input\Png\xc1n0g08.png = tests\Images\Input\Png\xc1n0g08.png
+ tests\Images\Input\Png\xc9n2c08.png = tests\Images\Input\Png\xc9n2c08.png
+ tests\Images\Input\Png\xd0n2c08.png = tests\Images\Input\Png\xd0n2c08.png
+ tests\Images\Input\Png\xd3n2c08.png = tests\Images\Input\Png\xd3n2c08.png
+ tests\Images\Input\Png\xdtn0g01.png = tests\Images\Input\Png\xdtn0g01.png
tests\Images\Input\Png\zlib-overflow.png = tests\Images\Input\Png\zlib-overflow.png
+ tests\Images\Input\Png\zlib-overflow2.png = tests\Images\Input\Png\zlib-overflow2.png
+ tests\Images\Input\Png\zlib-ztxt-bad-header.png = tests\Images\Input\Png\zlib-ztxt-bad-header.png
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Tests", "tests\ImageSharp.Tests\ImageSharp.Tests.csproj", "{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}"
@@ -333,6 +392,87 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedInfrastructure", "sha
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageSharp.Tests.ProfilingSandbox", "tests\ImageSharp.Tests.ProfilingSandbox\ImageSharp.Tests.ProfilingSandbox.csproj", "{FC527290-2F22-432C-B77B-6E815726B02C}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "issues", "issues", "{670DD46C-82E9-499A-B2D2-00A802ED0141}"
+ ProjectSection(SolutionItems) = preProject
+ tests\Images\Input\Png\issues\Issue_1014_1.png = tests\Images\Input\Png\issues\Issue_1014_1.png
+ tests\Images\Input\Png\issues\Issue_1014_2.png = tests\Images\Input\Png\issues\Issue_1014_2.png
+ tests\Images\Input\Png\issues\Issue_1014_3.png = tests\Images\Input\Png\issues\Issue_1014_3.png
+ tests\Images\Input\Png\issues\Issue_1014_4.png = tests\Images\Input\Png\issues\Issue_1014_4.png
+ tests\Images\Input\Png\issues\Issue_1014_5.png = tests\Images\Input\Png\issues\Issue_1014_5.png
+ tests\Images\Input\Png\issues\Issue_1014_6.png = tests\Images\Input\Png\issues\Issue_1014_6.png
+ tests\Images\Input\Png\issues\Issue_1047.png = tests\Images\Input\Png\issues\Issue_1047.png
+ tests\Images\Input\Png\issues\Issue_1127.png = tests\Images\Input\Png\issues\Issue_1127.png
+ tests\Images\Input\Png\issues\Issue_1177_1.png = tests\Images\Input\Png\issues\Issue_1177_1.png
+ tests\Images\Input\Png\issues\Issue_1177_2.png = tests\Images\Input\Png\issues\Issue_1177_2.png
+ tests\Images\Input\Png\issues\Issue_410.png = tests\Images\Input\Png\issues\Issue_410.png
+ tests\Images\Input\Png\issues\Issue_935.png = tests\Images\Input\Png\issues\Issue_935.png
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tga", "Tga", "{5DFC394F-136F-4B76-9BCA-3BA786515EFC}"
+ ProjectSection(SolutionItems) = preProject
+ tests\Images\Input\Tga\16bit_noalphabits.tga = tests\Images\Input\Tga\16bit_noalphabits.tga
+ tests\Images\Input\Tga\16bit_rle_noalphabits.tga = tests\Images\Input\Tga\16bit_rle_noalphabits.tga
+ tests\Images\Input\Tga\32bit_no_alphabits.tga = tests\Images\Input\Tga\32bit_no_alphabits.tga
+ tests\Images\Input\Tga\32bit_rle_no_alphabits.tga = tests\Images\Input\Tga\32bit_rle_no_alphabits.tga
+ tests\Images\Input\Tga\ccm8.tga = tests\Images\Input\Tga\ccm8.tga
+ tests\Images\Input\Tga\grayscale_a_LL.tga = tests\Images\Input\Tga\grayscale_a_LL.tga
+ tests\Images\Input\Tga\grayscale_a_LR.tga = tests\Images\Input\Tga\grayscale_a_LR.tga
+ tests\Images\Input\Tga\grayscale_a_rle_LL.tga = tests\Images\Input\Tga\grayscale_a_rle_LL.tga
+ tests\Images\Input\Tga\grayscale_a_rle_LR.tga = tests\Images\Input\Tga\grayscale_a_rle_LR.tga
+ tests\Images\Input\Tga\grayscale_a_rle_UL.tga = tests\Images\Input\Tga\grayscale_a_rle_UL.tga
+ tests\Images\Input\Tga\grayscale_a_rle_UR.tga = tests\Images\Input\Tga\grayscale_a_rle_UR.tga
+ tests\Images\Input\Tga\grayscale_a_UL.tga = tests\Images\Input\Tga\grayscale_a_UL.tga
+ tests\Images\Input\Tga\grayscale_a_UR.tga = tests\Images\Input\Tga\grayscale_a_UR.tga
+ tests\Images\Input\Tga\grayscale_LL.tga = tests\Images\Input\Tga\grayscale_LL.tga
+ tests\Images\Input\Tga\grayscale_LR.tga = tests\Images\Input\Tga\grayscale_LR.tga
+ tests\Images\Input\Tga\grayscale_rle_LR.tga = tests\Images\Input\Tga\grayscale_rle_LR.tga
+ tests\Images\Input\Tga\grayscale_rle_UL.tga = tests\Images\Input\Tga\grayscale_rle_UL.tga
+ tests\Images\Input\Tga\grayscale_rle_UR.tga = tests\Images\Input\Tga\grayscale_rle_UR.tga
+ tests\Images\Input\Tga\grayscale_UL.tga = tests\Images\Input\Tga\grayscale_UL.tga
+ tests\Images\Input\Tga\grayscale_UR.tga = tests\Images\Input\Tga\grayscale_UR.tga
+ tests\Images\Input\Tga\indexed_a_LL.tga = tests\Images\Input\Tga\indexed_a_LL.tga
+ tests\Images\Input\Tga\indexed_a_LR.tga = tests\Images\Input\Tga\indexed_a_LR.tga
+ tests\Images\Input\Tga\indexed_a_rle_LL.tga = tests\Images\Input\Tga\indexed_a_rle_LL.tga
+ tests\Images\Input\Tga\indexed_a_rle_LR.tga = tests\Images\Input\Tga\indexed_a_rle_LR.tga
+ tests\Images\Input\Tga\indexed_a_rle_UL.tga = tests\Images\Input\Tga\indexed_a_rle_UL.tga
+ tests\Images\Input\Tga\indexed_a_rle_UR.tga = tests\Images\Input\Tga\indexed_a_rle_UR.tga
+ tests\Images\Input\Tga\indexed_a_UL.tga = tests\Images\Input\Tga\indexed_a_UL.tga
+ tests\Images\Input\Tga\indexed_a_UR.tga = tests\Images\Input\Tga\indexed_a_UR.tga
+ tests\Images\Input\Tga\indexed_LR.tga = tests\Images\Input\Tga\indexed_LR.tga
+ tests\Images\Input\Tga\indexed_rle_LL.tga = tests\Images\Input\Tga\indexed_rle_LL.tga
+ tests\Images\Input\Tga\indexed_rle_LR.tga = tests\Images\Input\Tga\indexed_rle_LR.tga
+ tests\Images\Input\Tga\indexed_rle_UL.tga = tests\Images\Input\Tga\indexed_rle_UL.tga
+ tests\Images\Input\Tga\indexed_rle_UR.tga = tests\Images\Input\Tga\indexed_rle_UR.tga
+ tests\Images\Input\Tga\indexed_UL.tga = tests\Images\Input\Tga\indexed_UL.tga
+ tests\Images\Input\Tga\indexed_UR.tga = tests\Images\Input\Tga\indexed_UR.tga
+ tests\Images\Input\Tga\rgb15.tga = tests\Images\Input\Tga\rgb15.tga
+ tests\Images\Input\Tga\rgb15rle.tga = tests\Images\Input\Tga\rgb15rle.tga
+ tests\Images\Input\Tga\rgb24_top_left.tga = tests\Images\Input\Tga\rgb24_top_left.tga
+ tests\Images\Input\Tga\rgb_a_LL.tga = tests\Images\Input\Tga\rgb_a_LL.tga
+ tests\Images\Input\Tga\rgb_a_LR.tga = tests\Images\Input\Tga\rgb_a_LR.tga
+ tests\Images\Input\Tga\rgb_a_rle_LR.tga = tests\Images\Input\Tga\rgb_a_rle_LR.tga
+ tests\Images\Input\Tga\rgb_a_rle_UL.tga = tests\Images\Input\Tga\rgb_a_rle_UL.tga
+ tests\Images\Input\Tga\rgb_a_rle_UR.tga = tests\Images\Input\Tga\rgb_a_rle_UR.tga
+ tests\Images\Input\Tga\rgb_a_UL.tga = tests\Images\Input\Tga\rgb_a_UL.tga
+ tests\Images\Input\Tga\rgb_a_UR.tga = tests\Images\Input\Tga\rgb_a_UR.tga
+ tests\Images\Input\Tga\rgb_LR.tga = tests\Images\Input\Tga\rgb_LR.tga
+ tests\Images\Input\Tga\rgb_rle_LR.tga = tests\Images\Input\Tga\rgb_rle_LR.tga
+ tests\Images\Input\Tga\rgb_rle_UR.tga = tests\Images\Input\Tga\rgb_rle_UR.tga
+ tests\Images\Input\Tga\rgb_UR.tga = tests\Images\Input\Tga\rgb_UR.tga
+ tests\Images\Input\Tga\targa_16bit.tga = tests\Images\Input\Tga\targa_16bit.tga
+ tests\Images\Input\Tga\targa_16bit_pal.tga = tests\Images\Input\Tga\targa_16bit_pal.tga
+ tests\Images\Input\Tga\targa_16bit_rle.tga = tests\Images\Input\Tga\targa_16bit_rle.tga
+ tests\Images\Input\Tga\targa_24bit.tga = tests\Images\Input\Tga\targa_24bit.tga
+ tests\Images\Input\Tga\targa_24bit_pal.tga = tests\Images\Input\Tga\targa_24bit_pal.tga
+ tests\Images\Input\Tga\targa_24bit_pal_origin_topleft.tga = tests\Images\Input\Tga\targa_24bit_pal_origin_topleft.tga
+ tests\Images\Input\Tga\targa_24bit_rle.tga = tests\Images\Input\Tga\targa_24bit_rle.tga
+ tests\Images\Input\Tga\targa_24bit_rle_origin_topleft.tga = tests\Images\Input\Tga\targa_24bit_rle_origin_topleft.tga
+ tests\Images\Input\Tga\targa_32bit.tga = tests\Images\Input\Tga\targa_32bit.tga
+ tests\Images\Input\Tga\targa_32bit_rle.tga = tests\Images\Input\Tga\targa_32bit_rle.tga
+ tests\Images\Input\Tga\targa_8bit.tga = tests\Images\Input\Tga\targa_8bit.tga
+ tests\Images\Input\Tga\targa_8bit_rle.tga = tests\Images\Input\Tga\targa_8bit_rle.tga
+ EndProjectSection
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems*{2aa31a1f-142c-43f4-8687-09abca4b3a26}*SharedItemsImports = 5
@@ -400,6 +540,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
+ {1799C43E-5C54-4A8F-8D64-B1475241DB0D} = {C317F1B1-D75E-4C6D-83EB-80367343E0D7}
{FBE8C1AD-5AEC-4514-9B64-091D8E145865} = {1799C43E-5C54-4A8F-8D64-B1475241DB0D}
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26} = {815C0625-CD3D-440F-9F80-2D83856AB7AE}
{FA55F5DE-11A6-487D-ABA4-BC93A02717DD} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC}
@@ -421,6 +562,8 @@ Global
{C0D7754B-5277-438E-ABEB-2BA34401B5A7} = {1799C43E-5C54-4A8F-8D64-B1475241DB0D}
{68A8CC40-6AED-4E96-B524-31B1158FDEEA} = {815C0625-CD3D-440F-9F80-2D83856AB7AE}
{FC527290-2F22-432C-B77B-6E815726B02C} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC}
+ {670DD46C-82E9-499A-B2D2-00A802ED0141} = {E1C42A6F-913B-4A7B-B1A8-2BB62843B254}
+ {5DFC394F-136F-4B76-9BCA-3BA786515EFC} = {9DA226A1-8656-49A8-A58A-A8B5C081AD66}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5F8B9D1F-CD8B-4CC5-8216-D531E25BD795}
diff --git a/shared-infrastructure b/shared-infrastructure
index b0d4cd9864..3ad6e96a5f 160000
--- a/shared-infrastructure
+++ b/shared-infrastructure
@@ -1 +1 @@
-Subproject commit b0d4cd98647996265a668e852574d901b27f22d6
+Subproject commit 3ad6e96a5f900fecd134f0dbba937cb97c7fb94f
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 650f30fe1c..d211992a94 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -5,40 +5,22 @@
Directory.Build.props is automatically picked up and imported by
Microsoft.Common.props. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
- instead. The import fairly early and only Sdk.props will have been
+ instead. They import fairly early and only Sdk.props will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
-
- $(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props
- src
-
+
+
+
-
- $(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.ruleset
- true
-
-
+
true
-
-
- true
- true
-
-
-
- true
-
- true
- snupkg
-
-
@@ -47,6 +29,4 @@
-
-
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
index 9b8be05b56..c15c2a90cc 100644
--- a/src/Directory.Build.targets
+++ b/src/Directory.Build.targets
@@ -5,91 +5,15 @@
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
- instead. The import fairly late and most other props/targets will have
+ instead. They import fairly late and most other props/targets will have
been imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
-
- $(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.targets
-
+
+
+
-
- $(IntermediateOutputPath)$(MSBuildProjectName).InternalsVisibleTo$(DefaultLanguageSourceExtension)
-
-
-
-
- $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
-
-
-
-
-
-
-
-
-
-
- <_LocalTopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/>
-
-
-
-
-
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ImageSharp/Color/Color.cs b/src/ImageSharp/Color/Color.cs
index 554fcb8354..72f16528a6 100644
--- a/src/ImageSharp/Color/Color.cs
+++ b/src/ImageSharp/Color/Color.cs
@@ -27,19 +27,19 @@ namespace SixLabors.ImageSharp
private Color(byte r, byte g, byte b, byte a)
{
this.data = new Rgba64(
- ImageMaths.UpscaleFrom8BitTo16Bit(r),
- ImageMaths.UpscaleFrom8BitTo16Bit(g),
- ImageMaths.UpscaleFrom8BitTo16Bit(b),
- ImageMaths.UpscaleFrom8BitTo16Bit(a));
+ ColorNumerics.UpscaleFrom8BitTo16Bit(r),
+ ColorNumerics.UpscaleFrom8BitTo16Bit(g),
+ ColorNumerics.UpscaleFrom8BitTo16Bit(b),
+ ColorNumerics.UpscaleFrom8BitTo16Bit(a));
}
[MethodImpl(InliningOptions.ShortMethod)]
private Color(byte r, byte g, byte b)
{
this.data = new Rgba64(
- ImageMaths.UpscaleFrom8BitTo16Bit(r),
- ImageMaths.UpscaleFrom8BitTo16Bit(g),
- ImageMaths.UpscaleFrom8BitTo16Bit(b),
+ ColorNumerics.UpscaleFrom8BitTo16Bit(r),
+ ColorNumerics.UpscaleFrom8BitTo16Bit(g),
+ ColorNumerics.UpscaleFrom8BitTo16Bit(b),
ushort.MaxValue);
}
diff --git a/src/ImageSharp/ColorSpaces/Cmyk.cs b/src/ImageSharp/ColorSpaces/Cmyk.cs
index 0aab295548..675f1f814c 100644
--- a/src/ImageSharp/ColorSpaces/Cmyk.cs
+++ b/src/ImageSharp/ColorSpaces/Cmyk.cs
@@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
[MethodImpl(InliningOptions.ShortMethod)]
public Cmyk(Vector4 vector)
{
- vector = Vector4Utilities.FastClamp(vector, Min, Max);
+ vector = Numerics.Clamp(vector, Min, Max);
this.C = vector.X;
this.M = vector.Y;
this.Y = vector.Z;
diff --git a/src/ImageSharp/ColorSpaces/Companding/LCompanding.cs b/src/ImageSharp/ColorSpaces/Companding/LCompanding.cs
index 719565fd81..5cd89abfd6 100644
--- a/src/ImageSharp/ColorSpaces/Companding/LCompanding.cs
+++ b/src/ImageSharp/ColorSpaces/Companding/LCompanding.cs
@@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding
/// The representing the linear channel value.
[MethodImpl(InliningOptions.ShortMethod)]
public static float Expand(float channel)
- => channel <= 0.08F ? (100F * channel) / CieConstants.Kappa : ImageMaths.Pow3((channel + 0.16F) / 1.16F);
+ => channel <= 0.08F ? (100F * channel) / CieConstants.Kappa : Numerics.Pow3((channel + 0.16F) / 1.16F);
///
/// Compresses an uncompanded channel (linear) to its nonlinear equivalent.
diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs
index 31c3f46330..34354efe54 100644
--- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs
+++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLabToCieXyzConverter.cs
@@ -25,11 +25,11 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
float fx = (a / 500F) + fy;
float fz = fy - (b / 200F);
- float fx3 = ImageMaths.Pow3(fx);
- float fz3 = ImageMaths.Pow3(fz);
+ float fx3 = Numerics.Pow3(fx);
+ float fz3 = Numerics.Pow3(fz);
float xr = fx3 > CieConstants.Epsilon ? fx3 : ((116F * fx) - 16F) / CieConstants.Kappa;
- float yr = l > CieConstants.Kappa * CieConstants.Epsilon ? ImageMaths.Pow3((l + 16F) / 116F) : l / CieConstants.Kappa;
+ 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);
diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs
index 7f15fc77d8..12c65105fc 100644
--- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs
+++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieLuvToCieXyzConverter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Runtime.CompilerServices;
@@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
float v0 = ComputeV0(input.WhitePoint);
float y = l > CieConstants.Kappa * CieConstants.Epsilon
- ? ImageMaths.Pow3((l + 16) / 116)
+ ? Numerics.Pow3((l + 16) / 116)
: l / CieConstants.Kappa;
float a = ((52 * l / (u + (13 * l * u0))) - 1) / 3;
@@ -71,4 +71,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
private static float ComputeV0(in CieXyz input)
=> (9 * input.Y) / (input.X + (15 * input.Y) + (3 * input.Z));
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs
index 4c3cdba224..f120d6f3dd 100644
--- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs
+++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/HunterLabToCieXyzConverter.cs
@@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
float ka = ComputeKa(input.WhitePoint);
float kb = ComputeKb(input.WhitePoint);
- float pow = ImageMaths.Pow2(l / 100F);
+ float pow = Numerics.Pow2(l / 100F);
float sqrtPow = MathF.Sqrt(pow);
float y = pow * yn;
diff --git a/src/ImageSharp/Common/Extensions/ComparableExtensions.cs b/src/ImageSharp/Common/Extensions/ComparableExtensions.cs
deleted file mode 100644
index ef3d1deac3..0000000000
--- a/src/ImageSharp/Common/Extensions/ComparableExtensions.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// Extension methods for classes that implement .
- ///
- internal static class ComparableExtensions
- {
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The value to clamp.
- /// The minimum value. If value is less than min, min will be returned.
- /// The maximum value. If value is greater than max, max will be returned.
- ///
- /// The representing the clamped value.
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static byte Clamp(this byte value, byte min, byte max)
- {
- // Order is important here as someone might set min to higher than max.
- if (value >= max)
- {
- return max;
- }
-
- if (value <= min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The The value to clamp.
- /// The minimum value. If value is less than min, min will be returned.
- /// The maximum value. If value is greater than max, max will be returned.
- ///
- /// The representing the clamped value.
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static uint Clamp(this uint value, uint min, uint max)
- {
- if (value >= max)
- {
- return max;
- }
-
- if (value <= min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The The value to clamp.
- /// The minimum value. If value is less than min, min will be returned.
- /// The maximum value. If value is greater than max, max will be returned.
- ///
- /// The representing the clamped value.
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int Clamp(this int value, int min, int max)
- {
- if (value >= max)
- {
- return max;
- }
-
- if (value <= min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The The value to clamp.
- /// The minimum value. If value is less than min, min will be returned.
- /// The maximum value. If value is greater than max, max will be returned.
- ///
- /// The representing the clamped value.
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static float Clamp(this float value, float min, float max)
- {
- if (value >= max)
- {
- return max;
- }
-
- if (value <= min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The The value to clamp.
- /// The minimum value. If value is less than min, min will be returned.
- /// The maximum value. If value is greater than max, max will be returned.
- ///
- /// The representing the clamped value.
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static double Clamp(this double value, double min, double max)
- {
- if (value >= max)
- {
- return max;
- }
-
- if (value <= min)
- {
- return min;
- }
-
- return value;
- }
- }
-}
diff --git a/src/ImageSharp/Common/Helpers/Buffer2DUtils.cs b/src/ImageSharp/Common/Helpers/Buffer2DUtils.cs
index f4811d6ca8..02a5afff7e 100644
--- a/src/ImageSharp/Common/Helpers/Buffer2DUtils.cs
+++ b/src/ImageSharp/Common/Helpers/Buffer2DUtils.cs
@@ -50,8 +50,8 @@ namespace SixLabors.ImageSharp
for (int i = 0; i < kernelLength; i++)
{
- int offsetY = (row + i - radiusY).Clamp(minRow, maxRow);
- int offsetX = sourceOffsetColumnBase.Clamp(minColumn, maxColumn);
+ int offsetY = Numerics.Clamp(row + i - radiusY, minRow, maxRow);
+ int offsetX = Numerics.Clamp(sourceOffsetColumnBase, minColumn, maxColumn);
Span sourceRowSpan = sourcePixels.GetRowSpan(offsetY);
var currentColor = sourceRowSpan[offsetX].ToVector4();
@@ -93,13 +93,13 @@ namespace SixLabors.ImageSharp
int radiusX = kernelLength >> 1;
int sourceOffsetColumnBase = column + minColumn;
- int offsetY = row.Clamp(minRow, maxRow);
+ int offsetY = Numerics.Clamp(row, minRow, maxRow);
ref ComplexVector4 sourceRef = ref MemoryMarshal.GetReference(sourceValues.GetRowSpan(offsetY));
ref Complex64 baseRef = ref MemoryMarshal.GetReference(kernel);
for (int x = 0; x < kernelLength; x++)
{
- int offsetX = (sourceOffsetColumnBase + x - radiusX).Clamp(minColumn, maxColumn);
+ int offsetX = Numerics.Clamp(sourceOffsetColumnBase + x - radiusX, minColumn, maxColumn);
vector.Sum(Unsafe.Add(ref baseRef, x) * Unsafe.Add(ref sourceRef, offsetX));
}
diff --git a/src/ImageSharp/Common/Helpers/ColorNumerics.cs b/src/ImageSharp/Common/Helpers/ColorNumerics.cs
new file mode 100644
index 0000000000..6f225b1109
--- /dev/null
+++ b/src/ImageSharp/Common/Helpers/ColorNumerics.cs
@@ -0,0 +1,177 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace SixLabors.ImageSharp
+{
+ ///
+ /// Provides optimized static methods for common mathematical functions specific
+ /// to color processing.
+ ///
+ internal static class ColorNumerics
+ {
+ ///
+ /// Vector for converting pixel to gray value as specified by
+ /// ITU-R Recommendation BT.709.
+ ///
+ private static readonly Vector4 Bt709 = new Vector4(.2126f, .7152f, .0722f, 0.0f);
+
+ ///
+ /// Convert a pixel value to grayscale using ITU-R Recommendation BT.709.
+ ///
+ /// The vector to get the luminance from.
+ ///
+ /// The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images).
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GetBT709Luminance(ref Vector4 vector, int luminanceLevels)
+ => (int)MathF.Round(Vector4.Dot(vector, Bt709) * (luminanceLevels - 1));
+
+ ///
+ /// Gets the luminance from the rgb components using the formula
+ /// as specified by ITU-R Recommendation BT.709.
+ ///
+ /// The red component.
+ /// The green component.
+ /// The blue component.
+ /// The .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static byte Get8BitBT709Luminance(byte r, byte g, byte b)
+ => (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
+
+ ///
+ /// Gets the luminance from the rgb components using the formula as
+ /// specified by ITU-R Recommendation BT.709.
+ ///
+ /// The red component.
+ /// The green component.
+ /// The blue component.
+ /// The .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b)
+ => (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
+
+ ///
+ /// Gets the luminance from the rgb components using the formula as specified
+ /// by ITU-R Recommendation BT.709.
+ ///
+ /// The red component.
+ /// The green component.
+ /// The blue component.
+ /// The .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ushort Get16BitBT709Luminance(float r, float g, float b)
+ => (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
+
+ ///
+ /// Scales a value from a 16 bit to an
+ /// 8 bit equivalent.
+ ///
+ /// The 8 bit component value.
+ /// The
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static byte DownScaleFrom16BitTo8Bit(ushort component)
+ {
+ // To scale to 8 bits From a 16-bit value V the required value (from the PNG specification) is:
+ //
+ // (V * 255) / 65535
+ //
+ // This reduces to round(V / 257), or floor((V + 128.5)/257)
+ //
+ // Represent V as the two byte value vhi.vlo. Make a guess that the
+ // result is the top byte of V, vhi, then the correction to this value
+ // is:
+ //
+ // error = floor(((V-vhi.vhi) + 128.5) / 257)
+ // = floor(((vlo-vhi) + 128.5) / 257)
+ //
+ // This can be approximated using integer arithmetic (and a signed
+ // shift):
+ //
+ // error = (vlo-vhi+128) >> 8;
+ //
+ // The approximate differs from the exact answer only when (vlo-vhi) is
+ // 128; it then gives a correction of +1 when the exact correction is
+ // 0. This gives 128 errors. The exact answer (correct for all 16-bit
+ // input values) is:
+ //
+ // error = (vlo-vhi+128)*65535 >> 24;
+ //
+ // An alternative arithmetic calculation which also gives no errors is:
+ //
+ // (V * 255 + 32895) >> 16
+ return (byte)(((component * 255) + 32895) >> 16);
+ }
+
+ ///
+ /// Scales a value from an 8 bit to
+ /// an 16 bit equivalent.
+ ///
+ /// The 8 bit component value.
+ /// The
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ushort UpscaleFrom8BitTo16Bit(byte component)
+ => (ushort)(component * 257);
+
+ ///
+ /// Returns how many bits are required to store the specified number of colors.
+ /// Performs a Log2() on the value.
+ ///
+ /// The number of colors.
+ ///
+ /// The
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GetBitsNeededForColorDepth(int colors)
+ => Math.Max(1, (int)Math.Ceiling(Math.Log(colors, 2)));
+
+ ///
+ /// Returns how many colors will be created by the specified number of bits.
+ ///
+ /// The bit depth.
+ /// The
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GetColorCountForBitDepth(int bitDepth)
+ => 1 << bitDepth;
+
+ ///
+ /// Transforms a vector by the given color matrix.
+ ///
+ /// The source vector.
+ /// The transformation color matrix.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Transform(ref Vector4 vector, ref ColorMatrix matrix)
+ {
+ float x = vector.X;
+ float y = vector.Y;
+ float z = vector.Z;
+ float w = vector.W;
+
+ vector.X = (x * matrix.M11) + (y * matrix.M21) + (z * matrix.M31) + (w * matrix.M41) + matrix.M51;
+ vector.Y = (x * matrix.M12) + (y * matrix.M22) + (z * matrix.M32) + (w * matrix.M42) + matrix.M52;
+ vector.Z = (x * matrix.M13) + (y * matrix.M23) + (z * matrix.M33) + (w * matrix.M43) + matrix.M53;
+ vector.W = (x * matrix.M14) + (y * matrix.M24) + (z * matrix.M34) + (w * matrix.M44) + matrix.M54;
+ }
+
+ ///
+ /// Bulk variant of .
+ ///
+ /// The span of vectors
+ /// The transformation color matrix.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Transform(Span vectors, ref ColorMatrix matrix)
+ {
+ ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
+
+ for (int i = 0; i < vectors.Length; i++)
+ {
+ ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
+ Transform(ref v, ref matrix);
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs b/src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
index 61f90e23e1..f265bdd517 100644
--- a/src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
+++ b/src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
@@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
vector.W = target.W;
- Vector4Utilities.UnPremultiply(ref vector);
+ Numerics.UnPremultiply(ref vector);
target = vector;
}
@@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp
out Vector4 vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
- Vector4Utilities.UnPremultiply(ref vector);
+ Numerics.UnPremultiply(ref vector);
target = vector;
}
@@ -133,14 +133,14 @@ namespace SixLabors.ImageSharp
for (int y = 0; y < matrixHeight; y++)
{
- int offsetY = (row + y - radiusY).Clamp(minRow, maxRow);
+ int offsetY = Numerics.Clamp(row + y - radiusY, minRow, maxRow);
Span sourceRowSpan = sourcePixels.GetRowSpan(offsetY);
for (int x = 0; x < matrixWidth; x++)
{
- int offsetX = (sourceOffsetColumnBase + x - radiusX).Clamp(minColumn, maxColumn);
+ int offsetX = Numerics.Clamp(sourceOffsetColumnBase + x - radiusX, minColumn, maxColumn);
var currentColor = sourceRowSpan[offsetX].ToVector4();
- Vector4Utilities.Premultiply(ref currentColor);
+ Numerics.Premultiply(ref currentColor);
vectorX += matrixX[y, x] * currentColor;
vectorY += matrixY[y, x] * currentColor;
@@ -193,7 +193,7 @@ namespace SixLabors.ImageSharp
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
vector.W = target.W;
- Vector4Utilities.UnPremultiply(ref vector);
+ Numerics.UnPremultiply(ref vector);
target = vector;
}
@@ -238,7 +238,7 @@ namespace SixLabors.ImageSharp
ref vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
- Vector4Utilities.UnPremultiply(ref vector);
+ Numerics.UnPremultiply(ref vector);
target = vector;
}
@@ -263,14 +263,14 @@ namespace SixLabors.ImageSharp
for (int y = 0; y < matrixHeight; y++)
{
- int offsetY = (row + y - radiusY).Clamp(minRow, maxRow);
+ int offsetY = Numerics.Clamp(row + y - radiusY, minRow, maxRow);
Span sourceRowSpan = sourcePixels.GetRowSpan(offsetY);
for (int x = 0; x < matrixWidth; x++)
{
- int offsetX = (sourceOffsetColumnBase + x - radiusX).Clamp(minColumn, maxColumn);
+ int offsetX = Numerics.Clamp(sourceOffsetColumnBase + x - radiusX, minColumn, maxColumn);
var currentColor = sourceRowSpan[offsetX].ToVector4();
- Vector4Utilities.Premultiply(ref currentColor);
+ Numerics.Premultiply(ref currentColor);
vector += matrix[y, x] * currentColor;
}
}
diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs
deleted file mode 100644
index d24230fe18..0000000000
--- a/src/ImageSharp/Common/Helpers/ImageMaths.cs
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Numerics;
-using System.Runtime.CompilerServices;
-
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// Provides common mathematical methods.
- ///
- internal static class ImageMaths
- {
- ///
- /// Vector for converting pixel to gray value as specified by ITU-R Recommendation BT.709.
- ///
- private static readonly Vector4 Bt709 = new Vector4(.2126f, .7152f, .0722f, 0.0f);
-
- ///
- /// Convert a pixel value to grayscale using ITU-R Recommendation BT.709.
- ///
- /// The vector to get the luminance from.
- /// The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images)
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int GetBT709Luminance(ref Vector4 vector, int luminanceLevels)
- => (int)MathF.Round(Vector4.Dot(vector, Bt709) * (luminanceLevels - 1));
-
- ///
- /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
- ///
- /// The red component.
- /// The green component.
- /// The blue component.
- /// The .
- [MethodImpl(InliningOptions.ShortMethod)]
- public static byte Get8BitBT709Luminance(byte r, byte g, byte b) =>
- (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
-
- ///
- /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
- ///
- /// The red component.
- /// The green component.
- /// The blue component.
- /// The .
- [MethodImpl(InliningOptions.ShortMethod)]
- public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b) =>
- (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
-
- ///
- /// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
- ///
- /// The red component.
- /// The green component.
- /// The blue component.
- /// The .
- [MethodImpl(InliningOptions.ShortMethod)]
- public static ushort Get16BitBT709Luminance(float r, float g, float b) =>
- (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
-
- ///
- /// Scales a value from a 16 bit to it's 8 bit equivalent.
- ///
- /// The 8 bit component value.
- /// The
- [MethodImpl(InliningOptions.ShortMethod)]
- public static byte DownScaleFrom16BitTo8Bit(ushort component)
- {
- // To scale to 8 bits From a 16-bit value V the required value (from the PNG specification) is:
- //
- // (V * 255) / 65535
- //
- // This reduces to round(V / 257), or floor((V + 128.5)/257)
- //
- // Represent V as the two byte value vhi.vlo. Make a guess that the
- // result is the top byte of V, vhi, then the correction to this value
- // is:
- //
- // error = floor(((V-vhi.vhi) + 128.5) / 257)
- // = floor(((vlo-vhi) + 128.5) / 257)
- //
- // This can be approximated using integer arithmetic (and a signed
- // shift):
- //
- // error = (vlo-vhi+128) >> 8;
- //
- // The approximate differs from the exact answer only when (vlo-vhi) is
- // 128; it then gives a correction of +1 when the exact correction is
- // 0. This gives 128 errors. The exact answer (correct for all 16-bit
- // input values) is:
- //
- // error = (vlo-vhi+128)*65535 >> 24;
- //
- // An alternative arithmetic calculation which also gives no errors is:
- //
- // (V * 255 + 32895) >> 16
- return (byte)(((component * 255) + 32895) >> 16);
- }
-
- ///
- /// Scales a value from an 8 bit to it's 16 bit equivalent.
- ///
- /// The 8 bit component value.
- /// The
- [MethodImpl(InliningOptions.ShortMethod)]
- public static ushort UpscaleFrom8BitTo16Bit(byte component) => (ushort)(component * 257);
-
- ///
- /// Determine the Greatest CommonDivisor (GCD) of two numbers.
- ///
- public static int GreatestCommonDivisor(int a, int b)
- {
- while (b != 0)
- {
- int temp = b;
- b = a % b;
- a = temp;
- }
-
- return a;
- }
-
- ///
- /// Determine the Least Common Multiple (LCM) of two numbers.
- ///
- public static int LeastCommonMultiple(int a, int b)
- {
- // https://en.wikipedia.org/wiki/Least_common_multiple#Reduction_by_the_greatest_common_divisor
- return (a / GreatestCommonDivisor(a, b)) * b;
- }
-
- ///
- /// Calculates % 2
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int Modulo2(int x) => x & 1;
-
- ///
- /// Calculates % 4
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int Modulo4(int x) => x & 3;
-
- ///
- /// Calculates % 8
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int Modulo8(int x) => x & 7;
-
- ///
- /// Fast (x mod m) calculator, with the restriction that
- /// should be power of 2.
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int ModuloP2(int x, int m) => x & (m - 1);
-
- ///
- /// Returns the absolute value of a 32-bit signed integer. Uses bit shifting to speed up the operation.
- ///
- ///
- /// A number that is greater than , but less than or equal to
- ///
- /// The
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int FastAbs(int x)
- {
- int y = x >> 31;
- return (x ^ y) - y;
- }
-
- ///
- /// Returns a specified number raised to the power of 2
- ///
- /// A single-precision floating-point number
- /// The number raised to the power of 2.
- [MethodImpl(InliningOptions.ShortMethod)]
- public static float Pow2(float x) => x * x;
-
- ///
- /// Returns a specified number raised to the power of 3
- ///
- /// A single-precision floating-point number
- /// The number raised to the power of 3.
- [MethodImpl(InliningOptions.ShortMethod)]
- public static float Pow3(float x) => x * x * x;
-
- ///
- /// Returns how many bits are required to store the specified number of colors.
- /// Performs a Log2() on the value.
- ///
- /// The number of colors.
- ///
- /// The
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int GetBitsNeededForColorDepth(int colors) => Math.Max(1, (int)Math.Ceiling(Math.Log(colors, 2)));
-
- ///
- /// Returns how many colors will be created by the specified number of bits.
- ///
- /// The bit depth.
- /// The
- [MethodImpl(InliningOptions.ShortMethod)]
- public static int GetColorCountForBitDepth(int bitDepth) => 1 << bitDepth;
-
- ///
- /// Implementation of 1D Gaussian G(x) function
- ///
- /// The x provided to G(x).
- /// The spread of the blur.
- /// The Gaussian G(x)
- [MethodImpl(InliningOptions.ShortMethod)]
- public static float Gaussian(float x, float sigma)
- {
- 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 right = MathF.Exp(exponentNumerator / exponentDenominator);
-
- return left * right;
- }
-
- ///
- /// Returns the result of a normalized sine cardinal function for the given value.
- /// SinC(x) = sin(pi*x)/(pi*x).
- ///
- /// A single-precision floating-point number to calculate the result for.
- ///
- /// The sine cardinal of .
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static float SinC(float f)
- {
- if (MathF.Abs(f) > Constants.Epsilon)
- {
- f *= MathF.PI;
- float result = MathF.Sin(f) / f;
- return MathF.Abs(result) < Constants.Epsilon ? 0F : result;
- }
-
- return 1F;
- }
-
- ///
- /// Gets the bounding from the given points.
- ///
- ///
- /// The designating the top left position.
- ///
- ///
- /// The designating the bottom right position.
- ///
- ///
- /// The bounding .
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- public static Rectangle GetBoundingRectangle(Point topLeft, Point bottomRight) => new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
-
- ///
- /// Finds the bounding rectangle based on the first instance of any color component other
- /// than the given one.
- ///
- /// The pixel format.
- /// The to search within.
- /// The color component value to remove.
- /// The channel to test against.
- ///
- /// The .
- ///
- public static Rectangle GetFilteredBoundingRectangle(ImageFrame bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
- where TPixel : unmanaged, IPixel
- {
- int width = bitmap.Width;
- int height = bitmap.Height;
- Point topLeft = default;
- Point bottomRight = default;
-
- Func, int, int, float, bool> delegateFunc;
-
- // Determine which channel to check against
- switch (channel)
- {
- case RgbaComponent.R:
- delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().X - b) > Constants.Epsilon;
- break;
-
- case RgbaComponent.G:
- delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Y - b) > Constants.Epsilon;
- break;
-
- case RgbaComponent.B:
- delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Z - b) > Constants.Epsilon;
- break;
-
- default:
- delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().W - b) > Constants.Epsilon;
- break;
- }
-
- int GetMinY(ImageFrame pixels)
- {
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return y;
- }
- }
- }
-
- return 0;
- }
-
- int GetMaxY(ImageFrame pixels)
- {
- for (int y = height - 1; y > -1; y--)
- {
- for (int x = 0; x < width; x++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return y;
- }
- }
- }
-
- return height;
- }
-
- int GetMinX(ImageFrame pixels)
- {
- for (int x = 0; x < width; x++)
- {
- for (int y = 0; y < height; y++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return x;
- }
- }
- }
-
- return 0;
- }
-
- int GetMaxX(ImageFrame pixels)
- {
- for (int x = width - 1; x > -1; x--)
- {
- for (int y = 0; y < height; y++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return x;
- }
- }
- }
-
- return width;
- }
-
- topLeft.Y = GetMinY(bitmap);
- topLeft.X = GetMinX(bitmap);
- bottomRight.Y = (GetMaxY(bitmap) + 1).Clamp(0, height);
- bottomRight.X = (GetMaxX(bitmap) + 1).Clamp(0, width);
-
- return GetBoundingRectangle(topLeft, bottomRight);
- }
- }
-}
diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs
new file mode 100644
index 0000000000..b2bedb87b4
--- /dev/null
+++ b/src/ImageSharp/Common/Helpers/Numerics.cs
@@ -0,0 +1,551 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+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
+{
+ ///
+ /// Provides optimized static methods for trigonometric, logarithmic,
+ /// and other common mathematical functions.
+ ///
+ internal static class Numerics
+ {
+#if SUPPORTS_RUNTIME_INTRINSICS
+ private const int BlendAlphaControl = 0b_10_00_10_00;
+ private const int ShuffleAlphaControl = 0b_11_11_11_11;
+#endif
+
+ ///
+ /// Determine the Greatest CommonDivisor (GCD) of two numbers.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GreatestCommonDivisor(int a, int b)
+ {
+ while (b != 0)
+ {
+ int temp = b;
+ b = a % b;
+ a = temp;
+ }
+
+ return a;
+ }
+
+ ///
+ /// Determine the Least Common Multiple (LCM) of two numbers.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int LeastCommonMultiple(int a, int b)
+ {
+ // https://en.wikipedia.org/wiki/Least_common_multiple#Reduction_by_the_greatest_common_divisor
+ return (a / GreatestCommonDivisor(a, b)) * b;
+ }
+
+ ///
+ /// Calculates % 2
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Modulo2(int x) => x & 1;
+
+ ///
+ /// Calculates % 4
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Modulo4(int x) => x & 3;
+
+ ///
+ /// Calculates % 8
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Modulo8(int x) => x & 7;
+
+ ///
+ /// Fast (x mod m) calculator, with the restriction that
+ /// should be power of 2.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int ModuloP2(int x, int m) => x & (m - 1);
+
+ ///
+ /// Returns the absolute value of a 32-bit signed integer.
+ /// Uses bit shifting to speed up the operation compared to .
+ ///
+ ///
+ /// A number that is greater than , but less than
+ /// or equal to
+ ///
+ /// The
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Abs(int x)
+ {
+ int y = x >> 31;
+ return (x ^ y) - y;
+ }
+
+ ///
+ /// Returns a specified number raised to the power of 2
+ ///
+ /// A single-precision floating-point number
+ /// The number raised to the power of 2.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Pow2(float x) => x * x;
+
+ ///
+ /// Returns a specified number raised to the power of 3
+ ///
+ /// A single-precision floating-point number
+ /// The number raised to the power of 3.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Pow3(float x) => x * x * x;
+
+ ///
+ /// Implementation of 1D Gaussian G(x) function
+ ///
+ /// The x provided to G(x).
+ /// The spread of the blur.
+ /// The Gaussian G(x)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Gaussian(float x, float sigma)
+ {
+ 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 right = MathF.Exp(exponentNumerator / exponentDenominator);
+
+ return left * right;
+ }
+
+ ///
+ /// Returns the result of a normalized sine cardinal function for the given value.
+ /// SinC(x) = sin(pi*x)/(pi*x).
+ ///
+ /// A single-precision floating-point number to calculate the result for.
+ ///
+ /// The sine cardinal of .
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float SinC(float f)
+ {
+ if (MathF.Abs(f) > Constants.Epsilon)
+ {
+ f *= MathF.PI;
+ float result = MathF.Sin(f) / f;
+ return MathF.Abs(result) < Constants.Epsilon ? 0F : result;
+ }
+
+ return 1F;
+ }
+
+ ///
+ /// Returns the value clamped to the inclusive range of min and max.
+ ///
+ /// The value to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ /// The clamped .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static byte Clamp(byte value, byte min, byte max)
+ {
+ // Order is important here as someone might set min to higher than max.
+ if (value > max)
+ {
+ return max;
+ }
+
+ if (value < min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+
+ ///
+ /// Returns the value clamped to the inclusive range of min and max.
+ ///
+ /// The value to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ /// The clamped .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint Clamp(uint value, uint min, uint max)
+ {
+ if (value > max)
+ {
+ return max;
+ }
+
+ if (value < min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+
+ ///
+ /// Returns the value clamped to the inclusive range of min and max.
+ ///
+ /// The value to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ /// The clamped .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Clamp(int value, int min, int max)
+ {
+ if (value > max)
+ {
+ return max;
+ }
+
+ if (value < min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+
+ ///
+ /// Returns the value clamped to the inclusive range of min and max.
+ ///
+ /// The value to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ /// The clamped .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float Clamp(float value, float min, float max)
+ {
+ if (value > max)
+ {
+ return max;
+ }
+
+ if (value < min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+
+ ///
+ /// Returns the value clamped to the inclusive range of min and max.
+ ///
+ /// The value to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ /// The clamped .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double Clamp(double value, double min, double max)
+ {
+ if (value > max)
+ {
+ return max;
+ }
+
+ if (value < min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+
+ ///
+ /// Returns the value clamped to the inclusive range of min and max.
+ /// 5x Faster than
+ /// on platforms < NET 5.
+ ///
+ /// The value to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ /// The clamped .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector4 Clamp(Vector4 value, Vector4 min, Vector4 max)
+ => Vector4.Min(Vector4.Max(value, min), max);
+
+ ///
+ /// Clamps the span values to the inclusive range of min and max.
+ ///
+ /// The span containing the values to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Clamp(Span span, byte min, byte max)
+ {
+ Span remainder = span.Slice(ClampReduce(span, min, max));
+
+ if (remainder.Length > 0)
+ {
+ for (int i = 0; i < remainder.Length; i++)
+ {
+ ref byte v = ref remainder[i];
+ v = Clamp(v, min, max);
+ }
+ }
+ }
+
+ ///
+ /// Clamps the span values to the inclusive range of min and max.
+ ///
+ /// The span containing the values to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Clamp(Span span, uint min, uint max)
+ {
+ Span remainder = span.Slice(ClampReduce(span, min, max));
+
+ if (remainder.Length > 0)
+ {
+ for (int i = 0; i < remainder.Length; i++)
+ {
+ ref uint v = ref remainder[i];
+ v = Clamp(v, min, max);
+ }
+ }
+ }
+
+ ///
+ /// Clamps the span values to the inclusive range of min and max.
+ ///
+ /// The span containing the values to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Clamp(Span span, int min, int max)
+ {
+ Span remainder = span.Slice(ClampReduce(span, min, max));
+
+ if (remainder.Length > 0)
+ {
+ for (int i = 0; i < remainder.Length; i++)
+ {
+ ref int v = ref remainder[i];
+ v = Clamp(v, min, max);
+ }
+ }
+ }
+
+ ///
+ /// Clamps the span values to the inclusive range of min and max.
+ ///
+ /// The span containing the values to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Clamp(Span span, float min, float max)
+ {
+ Span remainder = span.Slice(ClampReduce(span, min, max));
+
+ if (remainder.Length > 0)
+ {
+ for (int i = 0; i < remainder.Length; i++)
+ {
+ ref float v = ref remainder[i];
+ v = Clamp(v, min, max);
+ }
+ }
+ }
+
+ ///
+ /// Clamps the span values to the inclusive range of min and max.
+ ///
+ /// The span containing the values to clamp.
+ /// The minimum inclusive value.
+ /// The maximum inclusive value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Clamp(Span span, double min, double max)
+ {
+ Span remainder = span.Slice(ClampReduce(span, min, max));
+
+ if (remainder.Length > 0)
+ {
+ for (int i = 0; i < remainder.Length; i++)
+ {
+ ref double v = ref remainder[i];
+ v = Clamp(v, min, max);
+ }
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static int ClampReduce(Span span, T min, T max)
+ where T : unmanaged
+ {
+ if (Vector.IsHardwareAccelerated && span.Length >= Vector.Count)
+ {
+ int remainder = ModuloP2(span.Length, Vector.Count);
+ int adjustedCount = span.Length - remainder;
+
+ if (adjustedCount > 0)
+ {
+ ClampImpl(span.Slice(0, adjustedCount), min, max);
+ }
+
+ return adjustedCount;
+ }
+
+ return 0;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void ClampImpl(Span span, T min, T max)
+ where T : unmanaged
+ {
+ ref T sRef = ref MemoryMarshal.GetReference(span);
+ ref Vector vsBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(span));
+ var vmin = new Vector(min);
+ var vmax = new Vector(max);
+
+ int n = span.Length / Vector.Count;
+ int m = Modulo4(n);
+ int u = n - m;
+
+ for (int i = 0; i < u; i += 4)
+ {
+ ref Vector vs0 = ref Unsafe.Add(ref vsBase, i);
+ ref Vector vs1 = ref Unsafe.Add(ref vs0, 1);
+ ref Vector vs2 = ref Unsafe.Add(ref vs0, 2);
+ ref Vector vs3 = ref Unsafe.Add(ref vs0, 3);
+
+ vs0 = Vector.Min(Vector.Max(vmin, vs0), vmax);
+ vs1 = Vector.Min(Vector.Max(vmin, vs1), vmax);
+ vs2 = Vector.Min(Vector.Max(vmin, vs2), vmax);
+ vs3 = Vector.Min(Vector.Max(vmin, vs3), vmax);
+ }
+
+ if (m > 0)
+ {
+ for (int i = u; i < n; i++)
+ {
+ ref Vector vs0 = ref Unsafe.Add(ref vsBase, i);
+ vs0 = Vector.Min(Vector.Max(vmin, vs0), vmax);
+ }
+ }
+ }
+
+ ///
+ /// Pre-multiplies the "x", "y", "z" components of a vector by its "w" component leaving the "w" component intact.
+ ///
+ /// The to premultiply
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Premultiply(ref Vector4 source)
+ {
+ float w = source.W;
+ source *= w;
+ source.W = w;
+ }
+
+ ///
+ /// Reverses the result of premultiplying a vector via .
+ ///
+ /// The to premultiply
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void UnPremultiply(ref Vector4 source)
+ {
+ float w = source.W;
+ source /= w;
+ source.W = w;
+ }
+
+ ///
+ /// Bulk variant of
+ ///
+ /// The span of vectors
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Premultiply(Span vectors)
+ {
+#if SUPPORTS_RUNTIME_INTRINSICS
+ if (Avx2.IsSupported && vectors.Length >= 2)
+ {
+ ref Vector256 vectorsBase =
+ ref Unsafe.As>(ref MemoryMarshal.GetReference(vectors));
+
+ // Divide by 2 as 4 elements per Vector4 and 8 per Vector256
+ ref Vector256 vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
+
+ while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
+ {
+ Vector256 source = vectorsBase;
+ Vector256 multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
+ vectorsBase = Avx.Blend(Avx.Multiply(source, multiply), source, BlendAlphaControl);
+ vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
+ }
+
+ 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)));
+ }
+ }
+ else
+#endif
+ {
+ ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
+
+ for (int i = 0; i < vectors.Length; i++)
+ {
+ ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
+ Premultiply(ref v);
+ }
+ }
+ }
+
+ ///
+ /// Bulk variant of
+ ///
+ /// The span of vectors
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void UnPremultiply(Span vectors)
+ {
+#if SUPPORTS_RUNTIME_INTRINSICS
+ if (Avx2.IsSupported && vectors.Length >= 2)
+ {
+ ref Vector256 vectorsBase =
+ ref Unsafe.As>(ref MemoryMarshal.GetReference(vectors));
+
+ // Divide by 2 as 4 elements per Vector4 and 8 per Vector256
+ ref Vector256 vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
+
+ while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
+ {
+ Vector256 source = vectorsBase;
+ Vector256 multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
+ vectorsBase = Avx.Blend(Avx.Divide(source, multiply), source, BlendAlphaControl);
+ vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
+ }
+
+ 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)));
+ }
+ }
+ else
+#endif
+ {
+ ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
+
+ for (int i = 0; i < vectors.Length; i++)
+ {
+ ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
+ UnPremultiply(ref v);
+ }
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp/Common/Helpers/Shuffle/IShuffle4Slice3.cs b/src/ImageSharp/Common/Helpers/Shuffle/IShuffle4Slice3.cs
index 86e4174f11..3ecad3c5d9 100644
--- a/src/ImageSharp/Common/Helpers/Shuffle/IShuffle4Slice3.cs
+++ b/src/ImageSharp/Common/Helpers/Shuffle/IShuffle4Slice3.cs
@@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp
ref Byte3 dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest));
int n = source.Length / 4;
- int m = ImageMaths.Modulo4(n);
+ int m = Numerics.Modulo4(n);
int u = n - m;
ref uint sLoopEnd = ref Unsafe.Add(ref sBase, u);
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs
index de6990db5b..75555f88a5 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.BasicIntrinsics256.cs
@@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp
return;
}
- int remainder = ImageMaths.Modulo8(source.Length);
+ int remainder = Numerics.Modulo8(source.Length);
int adjustedCount = source.Length - remainder;
if (adjustedCount > 0)
@@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp
return;
}
- int remainder = ImageMaths.Modulo8(source.Length);
+ int remainder = Numerics.Modulo8(source.Length);
int adjustedCount = source.Length - remainder;
if (adjustedCount > 0)
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs
index bd35d1583e..0abc0e26da 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs
@@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp
return;
}
- int remainder = ImageMaths.ModuloP2(source.Length, Vector.Count);
+ int remainder = Numerics.ModuloP2(source.Length, Vector.Count);
int adjustedCount = source.Length - remainder;
if (adjustedCount > 0)
@@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp
return;
}
- int remainder = ImageMaths.ModuloP2(source.Length, Vector.Count);
+ int remainder = Numerics.ModuloP2(source.Length, Vector.Count);
int adjustedCount = source.Length - remainder;
if (adjustedCount > 0)
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs
index 1e89aaeb83..15133770f6 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs
@@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp
{
DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!");
- int remainder = ImageMaths.Modulo4(source.Length);
+ int remainder = Numerics.Modulo4(source.Length);
int adjustedCount = source.Length - remainder;
if (adjustedCount > 0)
@@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp
{
DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!");
- int remainder = ImageMaths.Modulo4(source.Length);
+ int remainder = Numerics.Modulo4(source.Length);
int adjustedCount = source.Length - remainder;
if (adjustedCount > 0)
@@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp
Vector4 s = Unsafe.Add(ref sBase, i);
s *= maxBytes;
s += half;
- s = Vector4Utilities.FastClamp(s, Vector4.Zero, maxBytes);
+ s = Numerics.Clamp(s, Vector4.Zero, maxBytes);
ref ByteVector4 d = ref Unsafe.Add(ref dBase, i);
d.X = (byte)s.X;
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
index 2ea7f2c9bd..b760301167 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
@@ -38,8 +38,8 @@ namespace SixLabors.ImageSharp
if (Avx.IsSupported || Sse.IsSupported)
{
int remainder = Avx.IsSupported
- ? ImageMaths.ModuloP2(source.Length, Vector256.Count)
- : ImageMaths.ModuloP2(source.Length, Vector128.Count);
+ ? Numerics.ModuloP2(source.Length, Vector256.Count)
+ : Numerics.ModuloP2(source.Length, Vector128.Count);
int adjustedCount = source.Length - remainder;
@@ -72,8 +72,8 @@ namespace SixLabors.ImageSharp
if (Avx2.IsSupported || Ssse3.IsSupported)
{
int remainder = Avx2.IsSupported
- ? ImageMaths.ModuloP2(source.Length, Vector256.Count)
- : ImageMaths.ModuloP2(source.Length, Vector128.Count);
+ ? Numerics.ModuloP2(source.Length, Vector256.Count)
+ : Numerics.ModuloP2(source.Length, Vector128.Count);
int adjustedCount = source.Length - remainder;
@@ -203,7 +203,7 @@ namespace SixLabors.ImageSharp
ref Unsafe.As>(ref MemoryMarshal.GetReference(dest));
int n = dest.Length / Vector256.Count;
- int m = ImageMaths.Modulo4(n);
+ int m = Numerics.Modulo4(n);
int u = n - m;
for (int i = 0; i < u; i += 4)
@@ -235,7 +235,7 @@ namespace SixLabors.ImageSharp
ref Unsafe.As>(ref MemoryMarshal.GetReference(dest));
int n = dest.Length / Vector128.Count;
- int m = ImageMaths.Modulo4(n);
+ int m = Numerics.Modulo4(n);
int u = n - m;
for (int i = 0; i < u; i += 4)
@@ -288,7 +288,7 @@ namespace SixLabors.ImageSharp
ref Unsafe.As>(ref MemoryMarshal.GetReference(dest));
int n = dest.Length / Vector256.Count;
- int m = ImageMaths.Modulo4(n);
+ int m = Numerics.Modulo4(n);
int u = n - m;
for (int i = 0; i < u; i += 4)
@@ -324,7 +324,7 @@ namespace SixLabors.ImageSharp
ref Unsafe.As>(ref MemoryMarshal.GetReference(dest));
int n = dest.Length / Vector128.Count;
- int m = ImageMaths.Modulo4(n);
+ int m = Numerics.Modulo4(n);
int u = n - m;
for (int i = 0; i < u; i += 4)
@@ -550,11 +550,11 @@ namespace SixLabors.ImageSharp
int remainder;
if (Avx2.IsSupported)
{
- remainder = ImageMaths.ModuloP2(source.Length, Vector256.Count);
+ remainder = Numerics.ModuloP2(source.Length, Vector256.Count);
}
else
{
- remainder = ImageMaths.ModuloP2(source.Length, Vector128.Count);
+ remainder = Numerics.ModuloP2(source.Length, Vector128.Count);
}
int adjustedCount = source.Length - remainder;
@@ -683,11 +683,11 @@ namespace SixLabors.ImageSharp
int remainder;
if (Avx2.IsSupported)
{
- remainder = ImageMaths.ModuloP2(source.Length, Vector256.Count);
+ remainder = Numerics.ModuloP2(source.Length, Vector256.Count);
}
else
{
- remainder = ImageMaths.ModuloP2(source.Length, Vector128.Count);
+ remainder = Numerics.ModuloP2(source.Length, Vector128.Count);
}
int adjustedCount = source.Length - remainder;
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs
index 7cbb5bfe35..aaf6d405cf 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs
@@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Vector4 PseudoRound(this Vector4 v)
{
- Vector4 sign = Vector4Utilities.FastClamp(v, new Vector4(-1), new Vector4(1));
+ Vector4 sign = Numerics.Clamp(v, new Vector4(-1), new Vector4(1));
return v + (sign * 0.5f);
}
@@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp
}
[MethodImpl(InliningOptions.ShortMethod)]
- private static byte ConvertToByte(float f) => (byte)ComparableExtensions.Clamp((f * 255f) + 0.5f, 0, 255f);
+ private static byte ConvertToByte(float f) => (byte)Numerics.Clamp((f * 255F) + 0.5F, 0, 255F);
[Conditional("DEBUG")]
private static void VerifyHasVector8(string operation)
@@ -206,7 +206,7 @@ namespace SixLabors.ImageSharp
{
DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!");
DebugGuard.IsTrue(
- ImageMaths.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0,
+ Numerics.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0,
nameof(source),
$"length should be divisible by {shouldBeDivisibleBy}!");
}
@@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp
{
DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!");
DebugGuard.IsTrue(
- ImageMaths.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0,
+ Numerics.ModuloP2(dest.Length, shouldBeDivisibleBy) == 0,
nameof(source),
$"length should be divisible by {shouldBeDivisibleBy}!");
}
diff --git a/src/ImageSharp/Common/Helpers/Vector4Utilities.cs b/src/ImageSharp/Common/Helpers/Vector4Utilities.cs
deleted file mode 100644
index f617e9a3ea..0000000000
--- a/src/ImageSharp/Common/Helpers/Vector4Utilities.cs
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Apache License, Version 2.0.
-
-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
-{
- ///
- /// Utility methods for the struct.
- ///
- internal static class Vector4Utilities
- {
- private const int BlendAlphaControl = 0b_10_00_10_00;
- private const int ShuffleAlphaControl = 0b_11_11_11_11;
-
- ///
- /// Restricts a vector between a minimum and a maximum value.
- /// 5x Faster then .
- ///
- /// The vector to restrict.
- /// The minimum value.
- /// The maximum value.
- /// The .
- [MethodImpl(InliningOptions.ShortMethod)]
- public static Vector4 FastClamp(Vector4 x, Vector4 min, Vector4 max)
- => Vector4.Min(Vector4.Max(x, min), max);
-
- ///
- /// Pre-multiplies the "x", "y", "z" components of a vector by its "w" component leaving the "w" component intact.
- ///
- /// The to premultiply
- [MethodImpl(InliningOptions.ShortMethod)]
- public static void Premultiply(ref Vector4 source)
- {
- float w = source.W;
- source *= w;
- source.W = w;
- }
-
- ///
- /// Reverses the result of premultiplying a vector via .
- ///
- /// The to premultiply
- [MethodImpl(InliningOptions.ShortMethod)]
- public static void UnPremultiply(ref Vector4 source)
- {
- float w = source.W;
- source /= w;
- source.W = w;
- }
-
- ///
- /// Bulk variant of
- ///
- /// The span of vectors
- [MethodImpl(InliningOptions.ShortMethod)]
- public static void Premultiply(Span vectors)
- {
-#if SUPPORTS_RUNTIME_INTRINSICS
- if (Avx2.IsSupported && vectors.Length >= 2)
- {
- ref Vector256 vectorsBase =
- ref Unsafe.As>(ref MemoryMarshal.GetReference(vectors));
-
- // Divide by 2 as 4 elements per Vector4 and 8 per Vector256
- ref Vector256 vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
-
- while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
- {
- Vector256 source = vectorsBase;
- Vector256 multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
- vectorsBase = Avx.Blend(Avx.Multiply(source, multiply), source, BlendAlphaControl);
- vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
- }
-
- if (ImageMaths.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)));
- }
- }
- else
-#endif
- {
- ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
-
- for (int i = 0; i < vectors.Length; i++)
- {
- ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
- Premultiply(ref v);
- }
- }
- }
-
- ///
- /// Bulk variant of
- ///
- /// The span of vectors
- [MethodImpl(InliningOptions.ShortMethod)]
- public static void UnPremultiply(Span vectors)
- {
-#if SUPPORTS_RUNTIME_INTRINSICS
- if (Avx2.IsSupported && vectors.Length >= 2)
- {
- ref Vector256 vectorsBase =
- ref Unsafe.As>(ref MemoryMarshal.GetReference(vectors));
-
- // Divide by 2 as 4 elements per Vector4 and 8 per Vector256
- ref Vector256 vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
-
- while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
- {
- Vector256 source = vectorsBase;
- Vector256 multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
- vectorsBase = Avx.Blend(Avx.Divide(source, multiply), source, BlendAlphaControl);
- vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
- }
-
- if (ImageMaths.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)));
- }
- }
- else
-#endif
- {
- ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
-
- for (int i = 0; i < vectors.Length; i++)
- {
- ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
- UnPremultiply(ref v);
- }
- }
- }
-
- ///
- /// Transforms a vector by the given matrix.
- ///
- /// The source vector.
- /// The transformation matrix.
- [MethodImpl(InliningOptions.ShortMethod)]
- public static void Transform(ref Vector4 vector, ref ColorMatrix matrix)
- {
- float x = vector.X;
- float y = vector.Y;
- float z = vector.Z;
- float w = vector.W;
-
- vector.X = (x * matrix.M11) + (y * matrix.M21) + (z * matrix.M31) + (w * matrix.M41) + matrix.M51;
- vector.Y = (x * matrix.M12) + (y * matrix.M22) + (z * matrix.M32) + (w * matrix.M42) + matrix.M52;
- vector.Z = (x * matrix.M13) + (y * matrix.M23) + (z * matrix.M33) + (w * matrix.M43) + matrix.M53;
- vector.W = (x * matrix.M14) + (y * matrix.M24) + (z * matrix.M34) + (w * matrix.M44) + matrix.M54;
- }
-
- ///
- /// Bulk variant of .
- ///
- /// The span of vectors
- /// The transformation matrix.
- [MethodImpl(InliningOptions.ShortMethod)]
- public static void Transform(Span vectors, ref ColorMatrix matrix)
- {
- ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
-
- for (int i = 0; i < vectors.Length; i++)
- {
- ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
- Transform(ref v, ref matrix);
- }
- }
- }
-}
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
index 6f92236372..0be0385725 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
@@ -1385,7 +1385,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
{
case BmpFileMarkerType.Bitmap:
colorMapSizeBytes = this.fileHeader.Offset - BmpFileHeader.Size - this.infoHeader.HeaderSize;
- int colorCountForBitDepth = ImageMaths.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel);
+ int colorCountForBitDepth = ColorNumerics.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel);
bytesPerColorMapEntry = colorMapSizeBytes / colorCountForBitDepth;
// Edge case for less-than-full-sized palette: bytesPerColorMapEntry should be at least 3.
@@ -1399,7 +1399,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
case BmpFileMarkerType.Pointer:
// OS/2 bitmaps always have 3 colors per color palette entry.
bytesPerColorMapEntry = 3;
- colorMapSizeBytes = ImageMaths.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel) * bytesPerColorMapEntry;
+ colorMapSizeBytes = ColorNumerics.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel) * bytesPerColorMapEntry;
break;
}
}
diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
index 454440f634..7819b1ebdb 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
@@ -6,7 +6,6 @@ using System.Buffers;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
-using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.Memory;
@@ -263,7 +262,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp
private void Write24Bit(Stream stream, Buffer2D pixels)
where TPixel : unmanaged, IPixel
{
- using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 3))
+ int width = pixels.Width;
+ int rowBytesWithoutPadding = width * 3;
+ using (IManagedByteBuffer row = this.AllocateRow(width, 3))
{
for (int y = pixels.Height - 1; y >= 0; y--)
{
@@ -271,8 +272,8 @@ namespace SixLabors.ImageSharp.Formats.Bmp
PixelOperations.Instance.ToBgr24Bytes(
this.configuration,
pixelSpan,
- row.GetSpan(),
- pixelSpan.Length);
+ row.Slice(0, rowBytesWithoutPadding),
+ width);
stream.Write(row.Array, 0, row.Length());
}
}
@@ -287,7 +288,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp
private void Write16Bit(Stream stream, Buffer2D pixels)
where TPixel : unmanaged, IPixel
{
- using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 2))
+ int width = pixels.Width;
+ int rowBytesWithoutPadding = width * 2;
+ using (IManagedByteBuffer row = this.AllocateRow(width, 2))
{
for (int y = pixels.Height - 1; y >= 0; y--)
{
@@ -296,7 +299,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
PixelOperations.Instance.ToBgra5551Bytes(
this.configuration,
pixelSpan,
- row.GetSpan(),
+ row.Slice(0, rowBytesWithoutPadding),
pixelSpan.Length);
stream.Write(row.Array, 0, row.Length());
@@ -342,20 +345,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp
using IndexedImageFrame quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image, image.Bounds());
ReadOnlySpan quantizedColors = quantized.Palette.Span;
- var color = default(Rgba32);
-
- // TODO: Use bulk conversion here for better perf
- int idx = 0;
- foreach (TPixel quantizedColor in quantizedColors)
+ var quantizedColorBytes = quantizedColors.Length * 4;
+ PixelOperations.Instance.ToBgra32(this.configuration, quantizedColors, MemoryMarshal.Cast(colorPalette.Slice(0, quantizedColorBytes)));
+ Span colorPaletteAsUInt = MemoryMarshal.Cast(colorPalette);
+ for (int i = 0; i < colorPaletteAsUInt.Length; i++)
{
- quantizedColor.ToRgba32(ref color);
- colorPalette[idx] = color.B;
- colorPalette[idx + 1] = color.G;
- colorPalette[idx + 2] = color.R;
-
- // Padding byte, always 0.
- colorPalette[idx + 3] = 0;
- idx += 4;
+ colorPaletteAsUInt[i] = colorPaletteAsUInt[i] & 0x00FFFFFF; // Padding byte, always 0.
}
stream.Write(colorPalette);
diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
index 070864e603..9c1e95285c 100644
--- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
@@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
}
// Get the number of bits.
- this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(quantized.Palette.Length);
+ this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length);
// Write the header.
this.WriteHeader(stream);
@@ -212,7 +212,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
}
}
- this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(quantized.Palette.Length);
+ this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length);
this.WriteGraphicalControlExtension(frameMetadata, this.GetTransparentIndex(quantized), stream);
this.WriteImageDescriptor(frame, true, stream);
this.WriteColorTable(quantized, stream);
@@ -468,7 +468,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
where TPixel : unmanaged, IPixel
{
// The maximum number of colors for the bit depth
- int colorTableLength = ImageMaths.GetColorCountForBitDepth(this.bitDepth) * Unsafe.SizeOf();
+ int colorTableLength = ColorNumerics.GetColorCountForBitDepth(this.bitDepth) * Unsafe.SizeOf();
using IManagedByteBuffer colorTable = this.memoryAllocator.AllocateManagedByteBuffer(colorTableLength, AllocationOptions.Clean);
PixelOperations.Instance.ToRgb24Bytes(
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
index 0efefc06b5..dd5d3f1960 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
@@ -19,22 +19,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
var CMax4 = new Vector4(maximum);
var COff4 = new Vector4(MathF.Ceiling(maximum / 2));
- this.V0L = Vector4Utilities.FastClamp(this.V0L + COff4, CMin4, CMax4);
- this.V0R = Vector4Utilities.FastClamp(this.V0R + COff4, CMin4, CMax4);
- this.V1L = Vector4Utilities.FastClamp(this.V1L + COff4, CMin4, CMax4);
- this.V1R = Vector4Utilities.FastClamp(this.V1R + COff4, CMin4, CMax4);
- this.V2L = Vector4Utilities.FastClamp(this.V2L + COff4, CMin4, CMax4);
- this.V2R = Vector4Utilities.FastClamp(this.V2R + COff4, CMin4, CMax4);
- this.V3L = Vector4Utilities.FastClamp(this.V3L + COff4, CMin4, CMax4);
- this.V3R = Vector4Utilities.FastClamp(this.V3R + COff4, CMin4, CMax4);
- this.V4L = Vector4Utilities.FastClamp(this.V4L + COff4, CMin4, CMax4);
- this.V4R = Vector4Utilities.FastClamp(this.V4R + COff4, CMin4, CMax4);
- this.V5L = Vector4Utilities.FastClamp(this.V5L + COff4, CMin4, CMax4);
- this.V5R = Vector4Utilities.FastClamp(this.V5R + COff4, CMin4, CMax4);
- this.V6L = Vector4Utilities.FastClamp(this.V6L + COff4, CMin4, CMax4);
- this.V6R = Vector4Utilities.FastClamp(this.V6R + COff4, CMin4, CMax4);
- this.V7L = Vector4Utilities.FastClamp(this.V7L + COff4, CMin4, CMax4);
- this.V7R = Vector4Utilities.FastClamp(this.V7R + COff4, CMin4, CMax4);
+ this.V0L = Numerics.Clamp(this.V0L + COff4, CMin4, CMax4);
+ this.V0R = Numerics.Clamp(this.V0R + COff4, CMin4, CMax4);
+ this.V1L = Numerics.Clamp(this.V1L + COff4, CMin4, CMax4);
+ this.V1R = Numerics.Clamp(this.V1R + COff4, CMin4, CMax4);
+ this.V2L = Numerics.Clamp(this.V2L + COff4, CMin4, CMax4);
+ this.V2R = Numerics.Clamp(this.V2R + COff4, CMin4, CMax4);
+ this.V3L = Numerics.Clamp(this.V3L + COff4, CMin4, CMax4);
+ this.V3R = Numerics.Clamp(this.V3R + COff4, CMin4, CMax4);
+ this.V4L = Numerics.Clamp(this.V4L + COff4, CMin4, CMax4);
+ this.V4R = Numerics.Clamp(this.V4R + COff4, CMin4, CMax4);
+ this.V5L = Numerics.Clamp(this.V5L + COff4, CMin4, CMax4);
+ this.V5R = Numerics.Clamp(this.V5R + COff4, CMin4, CMax4);
+ this.V6L = Numerics.Clamp(this.V6L + COff4, CMin4, CMax4);
+ this.V6R = Numerics.Clamp(this.V6R + COff4, CMin4, CMax4);
+ this.V7L = Numerics.Clamp(this.V7L + COff4, CMin4, CMax4);
+ this.V7R = Numerics.Clamp(this.V7R + COff4, CMin4, CMax4);
}
///
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
index e5a62dc075..8897efbe00 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
@@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
for (int j = 0; j < 2; j++)
{
char side = j == 0 ? 'L' : 'R';
- Write($"this.V{i}{side} = Vector4Utilities.FastClamp(this.V{i}{side} + COff4, CMin4, CMax4);\r\n");
+ Write($"this.V{i}{side} = Numerics.Clamp(this.V{i}{side} + COff4, CMin4, CMax4);\r\n");
}
}
PopIndent();
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
index 0dbdadbeb4..fd4748fa9d 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
@@ -671,7 +671,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
private static Vector4 DivideRound(Vector4 dividend, Vector4 divisor)
{
// sign(dividend) = max(min(dividend, 1), -1)
- Vector4 sign = Vector4Utilities.FastClamp(dividend, NegativeOne, Vector4.One);
+ Vector4 sign = Numerics.Clamp(dividend, NegativeOne, Vector4.One);
// AlmostRound(dividend/divisor) = dividend/divisor + 0.5*sign(dividend)
return (dividend / divisor) + (sign * Offset);
diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
index c4ff1c0360..36766d05f0 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
@@ -212,8 +212,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ImageMetadata metadata = image.Metadata;
// System.Drawing produces identical output for jpegs with a quality parameter of 0 and 1.
- int qlty = (this.quality ?? metadata.GetJpegMetadata().Quality).Clamp(1, 100);
- this.subsample = this.subsample ?? (qlty >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420);
+ int qlty = Numerics.Clamp(this.quality ?? metadata.GetJpegMetadata().Quality, 1, 100);
+ this.subsample ??= qlty >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420;
// Convert from a quality rating to a scaling factor.
int scale;
diff --git a/src/ImageSharp/Formats/PixelTypeInfo.cs b/src/ImageSharp/Formats/PixelTypeInfo.cs
index d53d496fa5..718b05e33a 100644
--- a/src/ImageSharp/Formats/PixelTypeInfo.cs
+++ b/src/ImageSharp/Formats/PixelTypeInfo.cs
@@ -1,8 +1,7 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Runtime.CompilerServices;
-
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats
@@ -16,9 +15,11 @@ namespace SixLabors.ImageSharp.Formats
/// Initializes a new instance of the class.
///
/// Color depth, in number of bits per pixel.
- internal PixelTypeInfo(int bitsPerPixel)
+ /// Tthe pixel alpha transparency behavior.
+ internal PixelTypeInfo(int bitsPerPixel, PixelAlphaRepresentation? alpha = null)
{
this.BitsPerPixel = bitsPerPixel;
+ this.AlphaRepresentation = alpha;
}
///
@@ -26,8 +27,20 @@ namespace SixLabors.ImageSharp.Formats
///
public int BitsPerPixel { get; }
+ ///
+ /// Gets the pixel alpha transparency behavior.
+ /// means unknown, unspecified.
+ ///
+ public PixelAlphaRepresentation? AlphaRepresentation { get; }
+
internal static PixelTypeInfo Create()
where TPixel : unmanaged, IPixel =>
new PixelTypeInfo(Unsafe.SizeOf() * 8);
+
+ internal static PixelTypeInfo Create(PixelAlphaRepresentation alpha)
+ where TPixel : unmanaged, IPixel
+ {
+ return new PixelTypeInfo(Unsafe.SizeOf() * 8, alpha);
+ }
}
}
diff --git a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
index 8d9f6e4156..d1c214e3d6 100644
--- a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = (byte)(scan - (above >> 1));
- sum += ImageMaths.FastAbs(unchecked((sbyte)res));
+ sum += Numerics.Abs(unchecked((sbyte)res));
}
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */)
@@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = (byte)(scan - Average(left, above));
- sum += ImageMaths.FastAbs(unchecked((sbyte)res));
+ sum += Numerics.Abs(unchecked((sbyte)res));
}
sum -= 3;
@@ -102,4 +102,4 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int Average(byte left, byte above) => (left + above) >> 1;
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
index 7b5c71a010..fab6788061 100644
--- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = (byte)(scan - PaethPredictor(0, above, 0));
- sum += ImageMaths.FastAbs(unchecked((sbyte)res));
+ sum += Numerics.Abs(unchecked((sbyte)res));
}
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */)
@@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = (byte)(scan - PaethPredictor(left, above, upperLeft));
- sum += ImageMaths.FastAbs(unchecked((sbyte)res));
+ sum += Numerics.Abs(unchecked((sbyte)res));
}
sum -= 4;
@@ -111,9 +111,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
private static byte PaethPredictor(byte left, byte above, byte upperLeft)
{
int p = left + above - upperLeft;
- int pa = ImageMaths.FastAbs(p - left);
- int pb = ImageMaths.FastAbs(p - above);
- int pc = ImageMaths.FastAbs(p - upperLeft);
+ int pa = Numerics.Abs(p - left);
+ int pb = Numerics.Abs(p - above);
+ int pc = Numerics.Abs(p - upperLeft);
if (pa <= pb && pa <= pc)
{
@@ -128,4 +128,4 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
return upperLeft;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
index c448e71f43..cb4cfb471f 100644
--- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
@@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = scan;
- sum += ImageMaths.FastAbs(unchecked((sbyte)res));
+ sum += Numerics.Abs(unchecked((sbyte)res));
}
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */)
@@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = (byte)(scan - prev);
- sum += ImageMaths.FastAbs(unchecked((sbyte)res));
+ sum += Numerics.Abs(unchecked((sbyte)res));
}
sum -= 1;
diff --git a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
index 2a77bccb97..cf553cbb68 100644
--- a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
@@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = (byte)(scan - above);
- sum += ImageMaths.FastAbs(unchecked((sbyte)res));
+ sum += Numerics.Abs(unchecked((sbyte)res));
}
sum -= 2;
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index 5cf11099cd..5d2af8ec6a 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -284,7 +284,7 @@ namespace SixLabors.ImageSharp.Formats.Png
rowSpan.Length,
AllocationOptions.Clean))
{
- int scaleFactor = 255 / (ImageMaths.GetColorCountForBitDepth(this.bitDepth) - 1);
+ 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.
@@ -314,7 +314,7 @@ namespace SixLabors.ImageSharp.Formats.Png
for (int x = 0, o = 0; x < rgbaSpan.Length; x++, o += 4)
{
Rgba64 rgba = Unsafe.Add(ref rgbaRef, x);
- ushort luminance = ImageMaths.Get16BitBT709Luminance(rgba.R, rgba.G, rgba.B);
+ ushort luminance = ColorNumerics.Get16BitBT709Luminance(rgba.R, rgba.G, rgba.B);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), luminance);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgba.A);
}
@@ -329,7 +329,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
Unsafe.Add(ref rowSpanRef, x).ToRgba32(ref rgba);
Unsafe.Add(ref rawScanlineSpanRef, o) =
- ImageMaths.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
+ ColorNumerics.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
Unsafe.Add(ref rawScanlineSpanRef, o + 1) = rgba.A;
}
}
diff --git a/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs b/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs
index 9342e09dfe..23ca869936 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs
@@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (options.Quantizer is null)
{
byte bits = (byte)options.BitDepth;
- var maxColors = ImageMaths.GetColorCountForBitDepth(bits);
+ var maxColors = ColorNumerics.GetColorCountForBitDepth(bits);
options.Quantizer = new WuQuantizer(new QuantizerOptions { MaxColors = maxColors });
}
@@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Formats.Png
byte bitDepth;
if (options.ColorType == PngColorType.Palette)
{
- byte quantizedBits = (byte)ImageMaths.GetBitsNeededForColorDepth(quantizedFrame.Palette.Length).Clamp(1, 8);
+ byte quantizedBits = (byte)Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(quantizedFrame.Palette.Length), 1, 8);
byte bits = Math.Max((byte)options.BitDepth, quantizedBits);
// Png only supports in four pixel depths: 1, 2, 4, and 8 bits when using the PLTE chunk
diff --git a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs
index 48ec9bdcdc..58fa5aca82 100644
--- a/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs
+++ b/src/ImageSharp/Formats/Png/PngScanlineProcessor.cs
@@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Formats.Png
TPixel pixel = default;
ref byte scanlineSpanRef = ref MemoryMarshal.GetReference(scanlineSpan);
ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan);
- int scaleFactor = 255 / (ImageMaths.GetColorCountForBitDepth(header.BitDepth) - 1);
+ int scaleFactor = 255 / (ColorNumerics.GetColorCountForBitDepth(header.BitDepth) - 1);
if (!hasTrans)
{
@@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Formats.Png
TPixel pixel = default;
ref byte scanlineSpanRef = ref MemoryMarshal.GetReference(scanlineSpan);
ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan);
- int scaleFactor = 255 / (ImageMaths.GetColorCountForBitDepth(header.BitDepth) - 1);
+ int scaleFactor = 255 / (ColorNumerics.GetColorCountForBitDepth(header.BitDepth) - 1);
if (!hasTrans)
{
diff --git a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
index d3a628531e..1d31ea9f4e 100644
--- a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
+++ b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
@@ -365,7 +365,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
where TPixel : unmanaged, IPixel
{
var vector = sourcePixel.ToVector4();
- return ImageMaths.GetBT709Luminance(ref vector, 256);
+ return ColorNumerics.GetBT709Luminance(ref vector, 256);
}
}
}
diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj
index c3d9618c8c..1d7fb2958b 100644
--- a/src/ImageSharp/ImageSharp.csproj
+++ b/src/ImageSharp/ImageSharp.csproj
@@ -4,41 +4,36 @@
SixLabors.ImageSharp
SixLabors.ImageSharp
- A cross-platform library for the processing of image files; written in C#
- en
-
- $(packageversion)
- 0.0.1
-
- netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.3;net472
-
- true
- true
- SixLabors.ImageSharp
- Image Resize Crop Gif Jpg Jpeg Bitmap Png Core
SixLabors.ImageSharp
+ SixLabors.ImageSharp
+ sixlabors.imagesharp.128.png
+ Apache-2.0
+ https://github.com/SixLabors/ImageSharp/
+ $(RepositoryUrl)
+ Image Resize Crop Gif Jpg Jpeg Bitmap Png Tga NetCore
+ A new, fully featured, fully managed, cross-platform, 2D graphics API for .NET
+ netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.3;net472
-
-
+
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
@@ -62,62 +57,62 @@
True
PixelOperations{TPixel}.Generated.tt
-
+
True
True
Argb32.PixelOperations.Generated.tt
-
+
True
True
Bgr24.PixelOperations.Generated.tt
-
+
True
True
Bgra32.PixelOperations.Generated.tt
-
+
True
True
Bgra5551.PixelOperations.Generated.tt
-
+
True
True
- L8.PixelOperations.Generated.tt
+ L16.PixelOperations.Generated.tt
-
+
True
True
- L16.PixelOperations.Generated.tt
+ L8.PixelOperations.Generated.tt
-
+
True
True
La16.PixelOperations.Generated.tt
-
+
True
True
La32.PixelOperations.Generated.tt
-
+
True
True
Rgb24.PixelOperations.Generated.tt
-
+
True
True
- Rgba32.PixelOperations.Generated.tt
+ Rgb48.PixelOperations.Generated.tt
-
+
True
True
- Rgb48.PixelOperations.Generated.tt
+ Rgba32.PixelOperations.Generated.tt
-
+
True
True
Rgba64.PixelOperations.Generated.tt
@@ -156,51 +151,51 @@
TextTemplatingFileGenerator
PixelOperations{TPixel}.Generated.cs
-
+
TextTemplatingFileGenerator
Argb32.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
Bgr24.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
Bgra32.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
Bgra5551.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
L8.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
L16.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
La16.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
La32.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
Rgb24.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
Rgba32.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
Rgb48.PixelOperations.Generated.cs
-
+
TextTemplatingFileGenerator
Rgba64.PixelOperations.Generated.cs
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/DC-008-Translation-2019-E.pdf b/src/ImageSharp/Metadata/Profiles/Exif/DC-008-Translation-2019-E.pdf
deleted file mode 100644
index 9be0c8402b..0000000000
Binary files a/src/ImageSharp/Metadata/Profiles/Exif/DC-008-Translation-2019-E.pdf and /dev/null differ
diff --git a/src/ImageSharp/Metadata/Profiles/Exif/DC-X008-Translation-2019-E.pdf b/src/ImageSharp/Metadata/Profiles/Exif/DC-X008-Translation-2019-E.pdf
new file mode 100644
index 0000000000..cd7141fc8d
Binary files /dev/null and b/src/ImageSharp/Metadata/Profiles/Exif/DC-X008-Translation-2019-E.pdf differ
diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs
index 925a86ac20..8e9cad5636 100644
--- a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs
+++ b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.cs
@@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// The new index position
public void SetIndex(int index)
{
- this.currentIndex = index.Clamp(0, this.data.Length);
+ this.currentIndex = Numerics.Clamp(index, 0, this.data.Length);
}
///
diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Lut.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Lut.cs
index a5eef3d237..40a1792e2d 100644
--- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Lut.cs
+++ b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Lut.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
@@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
foreach (float item in value.Values)
{
- this.WriteByte((byte)((item * byte.MaxValue) + 0.5f).Clamp(0, byte.MaxValue));
+ this.WriteByte((byte)Numerics.Clamp((item * byte.MaxValue) + 0.5F, 0, byte.MaxValue));
}
return value.Values.Length;
@@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
foreach (float item in value.Values)
{
- this.WriteUInt16((ushort)((item * ushort.MaxValue) + 0.5f).Clamp(0, ushort.MaxValue));
+ this.WriteUInt16((ushort)Numerics.Clamp((item * ushort.MaxValue) + 0.5F, 0, ushort.MaxValue));
}
return value.Values.Length * 2;
@@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
foreach (float item in inArray)
{
- count += this.WriteByte((byte)((item * byte.MaxValue) + 0.5f).Clamp(0, byte.MaxValue));
+ count += this.WriteByte((byte)Numerics.Clamp((item * byte.MaxValue) + 0.5F, 0, byte.MaxValue));
}
}
@@ -97,7 +97,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
foreach (float item in inArray)
{
- count += this.WriteUInt16((ushort)((item * ushort.MaxValue) + 0.5f).Clamp(0, ushort.MaxValue));
+ count += this.WriteUInt16((ushort)Numerics.Clamp((item * ushort.MaxValue) + 0.5F, 0, ushort.MaxValue));
}
}
diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitives.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitives.cs
index 53dd5f008b..305fe47fd5 100644
--- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitives.cs
+++ b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitives.cs
@@ -33,9 +33,9 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// the number of bytes written
public int WriteVersionNumber(in IccVersion value)
{
- int major = value.Major.Clamp(0, byte.MaxValue);
- int minor = value.Minor.Clamp(0, 15);
- int bugfix = value.Patch.Clamp(0, 15);
+ int major = Numerics.Clamp(value.Major, 0, byte.MaxValue);
+ int minor = Numerics.Clamp(value.Minor, 0, 15);
+ int bugfix = Numerics.Clamp(value.Patch, 0, 15);
int version = (major << 24) | (minor << 20) | (bugfix << 16);
return this.WriteInt32(version);
diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs
index 5fb8e57d2f..c58dd96565 100644
--- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs
+++ b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
const double Max = short.MaxValue + (65535d / 65536d);
const double Min = short.MinValue;
- value = value.Clamp(Min, Max);
+ value = Numerics.Clamp(value, Min, Max);
value *= 65536d;
return this.WriteInt32((int)Math.Round(value, MidpointRounding.AwayFromZero));
@@ -128,7 +128,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
const double Max = ushort.MaxValue + (65535d / 65536d);
const double Min = ushort.MinValue;
- value = value.Clamp(Min, Max);
+ value = Numerics.Clamp(value, Min, Max);
value *= 65536d;
return this.WriteUInt32((uint)Math.Round(value, MidpointRounding.AwayFromZero));
@@ -144,7 +144,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
const double Max = 1 + (32767d / 32768d);
const double Min = 0;
- value = value.Clamp(Min, Max);
+ value = Numerics.Clamp(value, Min, Max);
value *= 32768d;
return this.WriteUInt16((ushort)Math.Round(value, MidpointRounding.AwayFromZero));
@@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
const double Max = byte.MaxValue + (255d / 256d);
const double Min = byte.MinValue;
- value = value.Clamp(Min, Max);
+ value = Numerics.Clamp(value, Min, Max);
value *= 256d;
return this.WriteUInt16((ushort)Math.Round(value, MidpointRounding.AwayFromZero));
diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs
index fdbf2a4778..25454fa951 100644
--- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs
+++ b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs
@@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
count += this.WriteUInt32((uint)value.CurveData.Length);
for (int i = 0; i < value.CurveData.Length; i++)
{
- count += this.WriteUInt16((ushort)((value.CurveData[i] * ushort.MaxValue) + 0.5f).Clamp(0, ushort.MaxValue));
+ count += this.WriteUInt16((ushort)Numerics.Clamp((value.CurveData[i] * ushort.MaxValue) + 0.5F, 0, ushort.MaxValue));
}
}
diff --git a/src/ImageSharp/PixelFormats/PixelAlphaRepresentation.cs b/src/ImageSharp/PixelFormats/PixelAlphaRepresentation.cs
new file mode 100644
index 0000000000..4690fb66ab
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/PixelAlphaRepresentation.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.PixelFormats
+{
+ ///
+ /// Provides enumeration of the alpha value transparency behavior of a pixel format.
+ ///
+ public enum PixelAlphaRepresentation
+ {
+ ///
+ /// Indicates that the pixel format does not contain an alpha channel.
+ ///
+ None,
+
+ ///
+ /// Indicates that the transparency behavior is premultiplied.
+ /// Each color is first scaled by the alpha value. The alpha value itself is the same
+ /// in both straight and premultiplied alpha. Typically, no color channel value is
+ /// greater than the alpha channel value.
+ /// If a color channel value in a premultiplied format is greater than the alpha
+ /// channel, the standard source-over blending math results in an additive blend.
+ ///
+ Associated,
+
+ ///
+ /// Indicates that the transparency behavior is not premultiplied.
+ /// The alpha channel indicates the transparency of the color.
+ ///
+ Unassociated
+ }
+}
diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
index 2cb528a036..db61d9383a 100644
--- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
+++ b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
@@ -36,14 +36,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.NormalSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.NormalSrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.NormalSrc(background[i], source[i], amount);
@@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.NormalSrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.NormalSrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -74,14 +74,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.MultiplySrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.MultiplySrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.MultiplySrc(background[i], source[i], amount);
@@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.MultiplySrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.MultiplySrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -112,14 +112,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.AddSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.AddSrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.AddSrc(background[i], source[i], amount);
@@ -131,7 +131,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.AddSrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.AddSrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -150,14 +150,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.SubtractSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.SubtractSrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.SubtractSrc(background[i], source[i], amount);
@@ -169,7 +169,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.SubtractSrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.SubtractSrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -188,14 +188,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.ScreenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.ScreenSrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.ScreenSrc(background[i], source[i], amount);
@@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.ScreenSrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.ScreenSrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -226,14 +226,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.DarkenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.DarkenSrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.DarkenSrc(background[i], source[i], amount);
@@ -245,7 +245,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.DarkenSrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.DarkenSrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -264,14 +264,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.LightenSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.LightenSrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.LightenSrc(background[i], source[i], amount);
@@ -283,7 +283,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.LightenSrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.LightenSrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -302,14 +302,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.OverlaySrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.OverlaySrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.OverlaySrc(background[i], source[i], amount);
@@ -321,7 +321,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.OverlaySrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.OverlaySrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -340,14 +340,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.HardLightSrc(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.HardLightSrc(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.HardLightSrc(background[i], source[i], amount);
@@ -359,7 +359,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.HardLightSrc(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.HardLightSrc(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -378,14 +378,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.NormalSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.NormalSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.NormalSrcAtop(background[i], source[i], amount);
@@ -397,7 +397,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.NormalSrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.NormalSrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -416,14 +416,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.MultiplySrcAtop(background[i], source[i], amount);
@@ -435,7 +435,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.MultiplySrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.MultiplySrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -454,14 +454,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.AddSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.AddSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.AddSrcAtop(background[i], source[i], amount);
@@ -473,7 +473,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.AddSrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.AddSrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -492,14 +492,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.SubtractSrcAtop(background[i], source[i], amount);
@@ -511,7 +511,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.SubtractSrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.SubtractSrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -530,14 +530,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.ScreenSrcAtop(background[i], source[i], amount);
@@ -549,7 +549,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.ScreenSrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.ScreenSrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -568,14 +568,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.DarkenSrcAtop(background[i], source[i], amount);
@@ -587,7 +587,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.DarkenSrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.DarkenSrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -606,14 +606,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.LightenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.LightenSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.LightenSrcAtop(background[i], source[i], amount);
@@ -625,7 +625,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.LightenSrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.LightenSrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -644,14 +644,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.OverlaySrcAtop(background[i], source[i], amount);
@@ -663,7 +663,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.OverlaySrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.OverlaySrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -682,14 +682,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcAtop(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.HardLightSrcAtop(background[i], source[i], amount);
@@ -701,7 +701,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.HardLightSrcAtop(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.HardLightSrcAtop(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -720,14 +720,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.NormalSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.NormalSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.NormalSrcOver(background[i], source[i], amount);
@@ -739,7 +739,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.NormalSrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.NormalSrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -758,14 +758,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.MultiplySrcOver(background[i], source[i], amount);
@@ -777,7 +777,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.MultiplySrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.MultiplySrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -796,14 +796,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.AddSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.AddSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.AddSrcOver(background[i], source[i], amount);
@@ -815,7 +815,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.AddSrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.AddSrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -834,14 +834,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.SubtractSrcOver(background[i], source[i], amount);
@@ -853,7 +853,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.SubtractSrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.SubtractSrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -872,14 +872,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.ScreenSrcOver(background[i], source[i], amount);
@@ -891,7 +891,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.ScreenSrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.ScreenSrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -910,14 +910,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.DarkenSrcOver(background[i], source[i], amount);
@@ -929,7 +929,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.DarkenSrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.DarkenSrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -948,14 +948,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.LightenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.LightenSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.LightenSrcOver(background[i], source[i], amount);
@@ -967,7 +967,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.LightenSrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.LightenSrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -986,14 +986,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.OverlaySrcOver(background[i], source[i], amount);
@@ -1005,7 +1005,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.OverlaySrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.OverlaySrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1024,14 +1024,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.HardLightSrcOver(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.HardLightSrcOver(background[i], source[i], amount);
@@ -1043,7 +1043,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.HardLightSrcOver(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.HardLightSrcOver(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1062,14 +1062,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.NormalSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.NormalSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.NormalSrcIn(background[i], source[i], amount);
@@ -1081,7 +1081,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.NormalSrcIn(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.NormalSrcIn(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1100,14 +1100,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.MultiplySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.MultiplySrcIn(background[i], source[i], amount);
@@ -1119,7 +1119,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.MultiplySrcIn(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.MultiplySrcIn(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1138,14 +1138,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.AddSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.AddSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.AddSrcIn(background[i], source[i], amount);
@@ -1157,7 +1157,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.AddSrcIn(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.AddSrcIn(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1176,14 +1176,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.SubtractSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.SubtractSrcIn(background[i], source[i], amount);
@@ -1195,7 +1195,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.SubtractSrcIn(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.SubtractSrcIn(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1214,14 +1214,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.ScreenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.ScreenSrcIn(background[i], source[i], amount);
@@ -1233,7 +1233,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.ScreenSrcIn(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.ScreenSrcIn(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1252,14 +1252,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.DarkenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.DarkenSrcIn(background[i], source[i], amount);
@@ -1271,7 +1271,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.DarkenSrcIn(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.DarkenSrcIn(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1290,14 +1290,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.LightenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.LightenSrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan source, float amount)
{
- amount = amount.Clamp(0, 1);
+ amount = Numerics.Clamp(amount, 0, 1);
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.LightenSrcIn(background[i], source[i], amount);
@@ -1309,7 +1309,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{
for (int i = 0; i < destination.Length; i++)
{
- destination[i] = PorterDuffFunctions.LightenSrcIn(background[i], source[i], amount[i].Clamp(0, 1));
+ destination[i] = PorterDuffFunctions.LightenSrcIn(background[i], source[i], Numerics.Clamp(amount[i], 0, 1));
}
}
}
@@ -1328,14 +1328,14 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
public override TPixel Blend(TPixel background, TPixel source, float amount)
{
TPixel dest = default;
- dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), amount.Clamp(0, 1)));
+ dest.FromScaledVector4(PorterDuffFunctions.OverlaySrcIn(background.ToScaledVector4(), source.ToScaledVector4(), Numerics.Clamp(amount, 0, 1)));
return dest;
}
///
protected override void BlendFunction(Span destination, ReadOnlySpan background, ReadOnlySpan