From e217d13cc5f03e9346f2aa675f36ea11f726a405 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 31 Mar 2019 22:55:14 +0200 Subject: [PATCH 01/13] make .FromVector4() destructive --- ImageSharp.sln.DotSettings | 1 + src/ImageSharp/Common/Helpers/Guard.cs | 20 +++++++++++++++++++ .../Argb32.PixelOperations.Generated.cs | 4 ++-- .../Bgr24.PixelOperations.Generated.cs | 4 ++-- .../Bgra32.PixelOperations.Generated.cs | 4 ++-- .../Rgb24.PixelOperations.Generated.cs | 4 ++-- .../Generated/_Common.ttinclude | 4 ++-- .../Rgba32.PixelOperations.cs | 4 ++-- .../RgbaVector.PixelOperations.cs | 2 +- .../PixelFormats/PixelOperations{TPixel}.cs | 12 +++++++++-- 10 files changed, 44 insertions(+), 15 deletions(-) diff --git a/ImageSharp.sln.DotSettings b/ImageSharp.sln.DotSettings index 432f4524a..8e7b5dd48 100644 --- a/ImageSharp.sln.DotSettings +++ b/ImageSharp.sln.DotSettings @@ -382,6 +382,7 @@ True True True + True True True True diff --git a/src/ImageSharp/Common/Helpers/Guard.cs b/src/ImageSharp/Common/Helpers/Guard.cs index d8cf69a52..e86da78e3 100644 --- a/src/ImageSharp/Common/Helpers/Guard.cs +++ b/src/ImageSharp/Common/Helpers/Guard.cs @@ -257,6 +257,26 @@ namespace SixLabors.ImageSharp } } + /// + /// Verifies that the 'destination' span is not shorter than 'source'. + /// + /// The source element type + /// The destination element type + /// The source span + /// The destination span + /// The name of the argument for 'destination' + [MethodImpl(InliningOptions.ShortMethod)] + public static void DestinationShouldNotBeTooShort( + Span source, + Span destination, + string destinationParamName) + { + if (destination.Length < source.Length) + { + ThrowArgumentException($"Destination span is too short!", destinationParamName); + } + } + /// /// Verifies, that the `source` span has the length of 'minLength', or longer. /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index 2ec965dfb..add48cfd8 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 711a9d1c1..372c71b32 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index b669dd534..aa4680dcc 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index dbf3102c4..f87ed88e5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } @@ -54,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span destPixels) + internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index f0675cb5b..bfeccfca5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -111,7 +111,7 @@ using System.Runtime.InteropServices; { #> /// - internal override void FromVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span<<#=pixelType#>> destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } @@ -123,7 +123,7 @@ using System.Runtime.InteropServices; } /// - internal override void FromScaledVector4(Configuration configuration, ReadOnlySpan sourceVectors, Span<<#=pixelType#>> destPixels) + internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span<<#=pixelType#>> destPixels) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index 004b25cd3..2801b8225 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4( Configuration configuration, - ReadOnlySpan sourceVectors, + Span sourceVectors, Span destPixels) { Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromScaledVector4( Configuration configuration, - ReadOnlySpan sourceVectors, + Span sourceVectors, Span destinationColors) { this.FromVector4(configuration, sourceVectors, destinationColors); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index bffaf57dd..0cde00736 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromScaledVector4( Configuration configuration, - ReadOnlySpan sourceVectors, + Span sourceVectors, Span destinationColors) { Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 115dd7a43..61e338b9c 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -9,6 +9,14 @@ using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.PixelFormats { + internal enum PixelConversionModifiers + { + None = 0, + Scale = 1 << 0, + Premultiply = 1 << 1, + SRgbCompand = 1 << 2, + } + /// /// A stateless class implementing Strategy Pattern for batched pixel-data conversion operations /// for pixel buffers of type . @@ -30,7 +38,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The to the destination colors. internal virtual void FromVector4( Configuration configuration, - ReadOnlySpan sourceVectors, + Span sourceVectors, Span destPixels) { Guard.NotNull(configuration, nameof(configuration)); @@ -64,7 +72,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The to the destination colors. internal virtual void FromScaledVector4( Configuration configuration, - ReadOnlySpan sourceVectors, + Span sourceVectors, Span destinationColors) { Guard.NotNull(configuration, nameof(configuration)); From 877f31487c835ea765006ddb30fcfe99429431c1 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 31 Mar 2019 23:28:34 +0200 Subject: [PATCH 02/13] replace FromScaledVector4() / ToScaledVector4() with flag usages --- .../Argb32.PixelOperations.Generated.cs | 17 +--- .../Bgr24.PixelOperations.Generated.cs | 17 +--- .../Bgra32.PixelOperations.Generated.cs | 17 +--- .../Rgb24.PixelOperations.Generated.cs | 17 +--- .../Generated/_Common.ttinclude | 17 +--- .../Rgba32.PixelOperations.cs | 24 +---- .../RgbaVector.PixelOperations.cs | 35 +++++--- .../PixelFormats/PixelOperations{TPixel}.cs | 88 ++++++++++++------- .../Utils/Vector4Converters.RgbaCompatible.cs | 4 +- 9 files changed, 97 insertions(+), 139 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index add48cfd8..e832bc97f 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -42,29 +42,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } - - /// - internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 372c71b32..f1885c71b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -42,30 +42,17 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } - /// - internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - - /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index aa4680dcc..2409f6784 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -42,29 +42,16 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } - - /// - internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index f87ed88e5..ddf9813ab 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -42,30 +42,17 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) + internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } - /// - internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - - /// internal override void ToArgb32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) { diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index bfeccfca5..0ff5b8605 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -111,29 +111,16 @@ using System.Runtime.InteropServices; { #> /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span<<#=pixelType#>> destPixels) + internal override void FromVector4(Configuration configuration, Span sourceVectors, Span<<#=pixelType#>> destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); } /// - internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) + internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); } - - /// - internal override void FromScaledVector4(Configuration configuration, Span sourceVectors, Span<<#=pixelType#>> destPixels) - { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, true); - } - - /// - internal override void ToScaledVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors) - { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, true); - } - <#+ } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index 2801b8225..7e8bb7f29 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -22,7 +22,8 @@ namespace SixLabors.ImageSharp.PixelFormats internal override void ToVector4( Configuration configuration, ReadOnlySpan sourcePixels, - Span destVectors) + Span destVectors, + PixelConversionModifiers modifiers) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); @@ -37,7 +38,8 @@ namespace SixLabors.ImageSharp.PixelFormats internal override void FromVector4( Configuration configuration, Span sourceVectors, - Span destPixels) + Span destPixels, + PixelConversionModifiers modifiers) { Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); @@ -47,24 +49,6 @@ namespace SixLabors.ImageSharp.PixelFormats MemoryMarshal.Cast(sourceVectors), MemoryMarshal.Cast(destPixels)); } - - /// - internal override void ToScaledVector4( - Configuration configuration, - ReadOnlySpan sourceColors, - Span destinationVectors) - { - this.ToVector4(configuration, sourceColors, destinationVectors); - } - - /// - internal override void FromScaledVector4( - Configuration configuration, - Span sourceVectors, - Span destinationColors) - { - this.FromVector4(configuration, sourceVectors, destinationColors); - } } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index 0cde00736..777d0da6d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -18,32 +18,43 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void FromScaledVector4( + internal override void FromVector4( Configuration configuration, Span sourceVectors, - Span destinationColors) + Span destinationColors, + PixelConversionModifiers modifiers) { Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); - MemoryMarshal.Cast(sourceVectors).CopyTo(destinationColors); + // TODO: Repeating previous override behavior here. Not sure if this is correct! + if (modifiers.IsDefined(PixelConversionModifiers.Scale)) + { + MemoryMarshal.Cast(sourceVectors).CopyTo(destinationColors); + } + else + { + base.FromVector4(configuration, sourceVectors, destinationColors, modifiers); + } } - /// - internal override void ToScaledVector4( - Configuration configuration, - ReadOnlySpan sourceColors, - Span destinationVectors) - => this.ToVector4(configuration, sourceColors, destinationVectors); - /// internal override void ToVector4( Configuration configuration, ReadOnlySpan sourcePixels, - Span destVectors) + Span destVectors, + PixelConversionModifiers modifiers) { Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - MemoryMarshal.Cast(sourcePixels).CopyTo(destVectors); + // TODO: Repeating previous override behavior here. Not sure if this is correct! + if (modifiers.IsDefined(PixelConversionModifiers.Scale)) + { + base.ToVector4(configuration, sourcePixels, destVectors, modifiers); + } + else + { + MemoryMarshal.Cast(sourcePixels).CopyTo(destVectors); + } } } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 61e338b9c..44c7f2e30 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -17,6 +17,12 @@ namespace SixLabors.ImageSharp.PixelFormats SRgbCompand = 1 << 2, } + internal static class PixelConversionModifiersExtensions + { + public static bool IsDefined(this PixelConversionModifiers modifiers, PixelConversionModifiers expected) => + (modifiers & expected) == expected; + } + /// /// A stateless class implementing Strategy Pattern for batched pixel-data conversion operations /// for pixel buffers of type . @@ -32,71 +38,93 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. + /// TODO: Rename to DestructiveFromVector4() + add explain behavior /// /// A to configure internal operations /// The to the source vectors. /// The to the destination colors. + /// The to apply during the conversion internal virtual void FromVector4( Configuration configuration, Span sourceVectors, - Span destPixels) + Span destPixels, + PixelConversionModifiers modifiers) { Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); - Utils.Vector4Converters.Default.DangerousFromVector4(sourceVectors, destPixels); + if (modifiers.IsDefined(PixelConversionModifiers.Scale)) + { + Utils.Vector4Converters.Default.DangerousFromScaledVector4(sourceVectors, destPixels); + } + else + { + Utils.Vector4Converters.Default.DangerousFromVector4(sourceVectors, destPixels); + } } + /// + /// TODO: For compatibility, should be inlined! + /// + internal void FromScaledVector4( + Configuration configuration, + Span sourceVectors, + Span destPixels) => + this.FromVector4(configuration, sourceVectors, destPixels, PixelConversionModifiers.Scale); + + /// + /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. + /// TODO: Rename to DestructiveFromVector4() + add explain behavior + /// + /// A to configure internal operations + /// The to the source vectors. + /// The to the destination colors. + internal void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) => + this.FromVector4(configuration, sourceVectors, destPixels, PixelConversionModifiers.None); + /// /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. /// /// A to configure internal operations /// The to the source colors. /// The to the destination vectors. + /// The to apply during the conversion internal virtual void ToVector4( Configuration configuration, ReadOnlySpan sourcePixels, - Span destVectors) + Span destVectors, + PixelConversionModifiers modifiers) { Guard.NotNull(configuration, nameof(configuration)); Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - Utils.Vector4Converters.Default.DangerousToVector4(sourcePixels, destVectors); + if (modifiers.IsDefined(PixelConversionModifiers.Scale)) + { + Utils.Vector4Converters.Default.DangerousToScaledVector4(sourcePixels, destVectors); + } + else + { + Utils.Vector4Converters.Default.DangerousToVector4(sourcePixels, destVectors); + } } /// - /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. + /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. /// /// A to configure internal operations - /// The to the source vectors. - /// The to the destination colors. - internal virtual void FromScaledVector4( + /// The to the source colors. + /// The to the destination vectors. + internal virtual void ToVector4( Configuration configuration, - Span sourceVectors, - Span destinationColors) - { - Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); - - Utils.Vector4Converters.Default.DangerousFromScaledVector4(sourceVectors, destinationColors); - } + ReadOnlySpan sourcePixels, + Span destVectors) => + this.ToVector4(configuration, sourcePixels, destVectors, PixelConversionModifiers.None); /// - /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. + /// TODO: For compatibility, should be inlined! /// - /// A to configure internal operations - /// The to the source colors. - /// The to the destination vectors. - internal virtual void ToScaledVector4( - Configuration configuration, - ReadOnlySpan sourceColors, - Span destinationVectors) - { - Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourceColors, destinationVectors, nameof(destinationVectors)); - - Utils.Vector4Converters.Default.DangerousToScaledVector4(sourceColors, destinationVectors); - } + internal void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) => + this.ToVector4(configuration, sourcePixels, destVectors, PixelConversionModifiers.Scale); /// /// Converts 'sourceColors.Length' pixels from 'sourceColors' into 'destinationColors'. diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs index 06c33d79c..006ebe828 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils private static readonly int Vector4ConversionThreshold = CalculateVector4ConversionThreshold(); /// - /// Provides an efficient default implementation for + /// Provides an efficient default implementation for /// and /// which is applicable for -compatible pixel types where /// returns the same scaled result as . @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils } /// - /// Provides an efficient default implementation for + /// Provides an efficient default implementation for /// and /// which is applicable for -compatible pixel types where /// returns the same scaled result as . From b0ff7cf6b6929f35de310b7d61c24ae839fd95d7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 31 Mar 2019 23:40:56 +0200 Subject: [PATCH 03/13] copy companding refactor from #847 --- .../ColorSpaces/Companding/SRgbCompanding.cs | 24 +++++++++++-------- .../PixelFormats/PixelConversionModifiers.cs | 16 +++++++++++++ .../PixelConversionModifiersExtensions.cs | 20 ++++++++++++++++ .../PixelFormats/PixelOperations{TPixel}.cs | 14 ----------- .../Colorspaces/Companding/CompandingTests.cs | 20 ++++++++++++++-- 5 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 src/ImageSharp/PixelFormats/PixelConversionModifiers.cs create mode 100644 src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs diff --git a/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs b/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs index 5ae462913..bbd454fbe 100644 --- a/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs +++ b/src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs @@ -30,9 +30,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding for (int i = 0; i < vectors.Length; i++) { ref Vector4 v = ref Unsafe.Add(ref baseRef, i); - v.X = Expand(v.X); - v.Y = Expand(v.Y); - v.Z = Expand(v.Z); + Expand(ref v); } } @@ -48,9 +46,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding for (int i = 0; i < vectors.Length; i++) { ref Vector4 v = ref Unsafe.Add(ref baseRef, i); - v.X = Compress(v.X); - v.Y = Compress(v.Y); - v.Z = Compress(v.Z); + Compress(ref v); } } @@ -58,17 +54,25 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding /// Expands a companded vector to its linear equivalent with respect to the energy. /// /// The vector. - /// The representing the linear channel values. [MethodImpl(InliningOptions.ShortMethod)] - public static Vector4 Expand(Vector4 vector) => new Vector4(Expand(vector.X), Expand(vector.Y), Expand(vector.Z), vector.W); + public static void Expand(ref Vector4 vector) + { + vector.X = Expand(vector.X); + vector.Y = Expand(vector.Y); + vector.Z = Expand(vector.Z); + } /// /// Compresses an uncompanded vector (linear) to its nonlinear equivalent. /// /// The vector. - /// The representing the nonlinear channel values. [MethodImpl(InliningOptions.ShortMethod)] - public static Vector4 Compress(Vector4 vector) => new Vector4(Compress(vector.X), Compress(vector.Y), Compress(vector.Z), vector.W); + public static void Compress(ref Vector4 vector) + { + vector.X = Compress(vector.X); + vector.Y = Compress(vector.Y); + vector.Z = Compress(vector.Z); + } /// /// Expands a companded channel to its linear equivalent with respect to the energy. diff --git a/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs new file mode 100644 index 000000000..536a23061 --- /dev/null +++ b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs @@ -0,0 +1,16 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; + +namespace SixLabors.ImageSharp.PixelFormats +{ + [Flags] + internal enum PixelConversionModifiers + { + None = 0, + Scale = 1 << 0, + Premultiply = 1 << 1, + SRgbCompand = 1 << 2, + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs b/src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs new file mode 100644 index 000000000..bf77f8511 --- /dev/null +++ b/src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs @@ -0,0 +1,20 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.PixelFormats +{ + internal static class PixelConversionModifiersExtensions + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsDefined(this PixelConversionModifiers modifiers, PixelConversionModifiers expected) => + (modifiers & expected) == expected; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static PixelConversionModifiers Remove( + this PixelConversionModifiers modifiers, + PixelConversionModifiers removeThis) => + modifiers & ~removeThis; + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 44c7f2e30..ea5bc876f 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -9,20 +9,6 @@ using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.PixelFormats { - internal enum PixelConversionModifiers - { - None = 0, - Scale = 1 << 0, - Premultiply = 1 << 1, - SRgbCompand = 1 << 2, - } - - internal static class PixelConversionModifiersExtensions - { - public static bool IsDefined(this PixelConversionModifiers modifiers, PixelConversionModifiers expected) => - (modifiers & expected) == expected; - } - /// /// A stateless class implementing Strategy Pattern for batched pixel-data conversion operations /// for pixel buffers of type . diff --git a/tests/ImageSharp.Tests/Colorspaces/Companding/CompandingTests.cs b/tests/ImageSharp.Tests/Colorspaces/Companding/CompandingTests.cs index 91cacfe3f..b2ee03048 100644 --- a/tests/ImageSharp.Tests/Colorspaces/Companding/CompandingTests.cs +++ b/tests/ImageSharp.Tests/Colorspaces/Companding/CompandingTests.cs @@ -53,7 +53,15 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Companding { var rnd = new Random(42); Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1); - Vector4[] expected = source.Select(v => SRgbCompanding.Expand(v)).ToArray(); + var expected = new Vector4[source.Length]; + + for (int i = 0; i < source.Length; i++) + { + Vector4 s = source[i]; + ref Vector4 e = ref expected[i]; + SRgbCompanding.Expand(ref s); + e = s; + } SRgbCompanding.Expand(source); @@ -68,7 +76,15 @@ namespace SixLabors.ImageSharp.Tests.Colorspaces.Companding { var rnd = new Random(42); Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1); - Vector4[] expected = source.Select(v => SRgbCompanding.Compress(v)).ToArray(); + var expected = new Vector4[source.Length]; + + for (int i = 0; i < source.Length; i++) + { + Vector4 s = source[i]; + ref Vector4 e = ref expected[i]; + SRgbCompanding.Compress(ref s); + e = s; + } SRgbCompanding.Compress(source); From d126b8591ebdeaf6f997f7b0a87aed465ab0de86 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 31 Mar 2019 23:49:43 +0200 Subject: [PATCH 04/13] add (failing) tests from #847 --- ...xelOperationsTests.Rgb24OperationsTests.cs | 23 ++ .../PixelOperations/PixelOperationsTests.cs | 270 +++++++++++++++++- 2 files changed, 280 insertions(+), 13 deletions(-) create mode 100644 tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs new file mode 100644 index 000000000..fa51c2278 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs @@ -0,0 +1,23 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations +{ + public partial class PixelOperationsTests + { + public class Rgb24OperationsTests : PixelOperationsTests + { + public Rgb24OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index d9845e474..9433e19c9 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -6,7 +6,7 @@ using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - +using SixLabors.ImageSharp.ColorSpaces.Companding; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -70,25 +70,33 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations internal static PixelOperations Operations => PixelOperations.Instance; - internal static TPixel[] CreateExpectedPixelData(Vector4[] source) + internal static TPixel[] CreateExpectedPixelData(Vector4[] source, RefAction vectorModifier = null) { var expected = new TPixel[source.Length]; for (int i = 0; i < expected.Length; i++) { - expected[i].FromVector4(source[i]); + Vector4 v = source[i]; + vectorModifier?.Invoke(ref v); + + expected[i].FromVector4(v); } + return expected; } - internal static TPixel[] CreateScaledExpectedPixelData(Vector4[] source) + internal static TPixel[] CreateScaledExpectedPixelData(Vector4[] source, RefAction vectorModifier = null) { var expected = new TPixel[source.Length]; for (int i = 0; i < expected.Length; i++) { - expected[i].FromScaledVector4(source[i]); + Vector4 v = source[i]; + vectorModifier?.Invoke(ref v); + + expected[i].FromScaledVector4(v); } + return expected; } @@ -120,6 +128,112 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations ); } + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromCompandedScaledVector4(int count) + { + void sourceAction(ref Vector4 v) + { + SRgbCompanding.Expand(ref v); + } + + void expectedAction(ref Vector4 v) + { + SRgbCompanding.Compress(ref v); + } + + Vector4[] source = CreateVector4TestData(count, (ref Vector4 v) => sourceAction(ref v)); + TPixel[] expected = CreateScaledExpectedPixelData(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.FromVector4(this.Configuration, s, d.GetSpan(), PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Scale) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromPremultipliedVector4(int count) + { + void sourceAction(ref Vector4 v) + { + Vector4Utils.Premultiply(ref v); + } + + void expectedAction(ref Vector4 v) + { + Vector4Utils.UnPremultiply(ref v); + } + + Vector4[] source = CreateVector4TestData(count, (ref Vector4 v) => sourceAction(ref v)); + TPixel[] expected = CreateExpectedPixelData(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.FromVector4(this.Configuration, s, d.GetSpan(), PixelConversionModifiers.Premultiply) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromPremultipliedScaledVector4(int count) + { + void sourceAction(ref Vector4 v) + { + Vector4Utils.Premultiply(ref v); + } + + void expectedAction(ref Vector4 v) + { + Vector4Utils.UnPremultiply(ref v); + } + + Vector4[] source = CreateVector4TestData(count, (ref Vector4 v) => sourceAction(ref v)); + TPixel[] expected = CreateScaledExpectedPixelData(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.FromVector4( + this.Configuration, + s, + d.GetSpan(), + PixelConversionModifiers.Premultiply | PixelConversionModifiers.Scale) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void FromCompandedPremultipliedScaledVector4(int count) + { + void sourceAction(ref Vector4 v) + { + SRgbCompanding.Expand(ref v); + Vector4Utils.Premultiply(ref v); + } + + void expectedAction(ref Vector4 v) + { + Vector4Utils.UnPremultiply(ref v); + SRgbCompanding.Compress(ref v); + } + + Vector4[] source = CreateVector4TestData(count, (ref Vector4 v) => sourceAction(ref v)); + TPixel[] expected = CreateScaledExpectedPixelData(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.FromVector4( + this.Configuration, + s, + d.GetSpan(), + PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Premultiply) + ); + } + [Theory] [MemberData(nameof(ArraySizesData))] public void ToVector4(int count) @@ -148,6 +262,115 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations ); } + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToCompandedScaledVector4(int count) + { + void sourceAction(ref Vector4 v) + { + SRgbCompanding.Compress(ref v); + } + + void expectedAction(ref Vector4 v) + { + SRgbCompanding.Expand(ref v); + } + + TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => sourceAction(ref v)); + Vector4[] expected = CreateExpectedScaledVector4Data(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.ToVector4( + this.Configuration, + s, + d.GetSpan(), + PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Scale) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToPremultipliedVector4(int count) + { + void sourceAction(ref Vector4 v) + { + Vector4Utils.UnPremultiply(ref v); + } + + void expectedAction(ref Vector4 v) + { + Vector4Utils.Premultiply(ref v); + } + + TPixel[] source = CreatePixelTestData(count, (ref Vector4 v) => sourceAction(ref v)); + Vector4[] expected = CreateExpectedVector4Data(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.ToVector4(this.Configuration, s, d.GetSpan(), PixelConversionModifiers.Premultiply) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToPremultipliedScaledVector4(int count) + { + void sourceAction(ref Vector4 v) + { + Vector4Utils.UnPremultiply(ref v); + } + + void expectedAction(ref Vector4 v) + { + Vector4Utils.Premultiply(ref v); + } + + TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => sourceAction(ref v)); + Vector4[] expected = CreateExpectedScaledVector4Data(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.ToVector4( + this.Configuration, + s, + d.GetSpan(), + PixelConversionModifiers.Premultiply | PixelConversionModifiers.Scale)); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToCompandedPremultipliedScaledVector4(int count) + { + void sourceAction(ref Vector4 v) + { + Vector4Utils.UnPremultiply(ref v); + SRgbCompanding.Compress(ref v); + } + + void expectedAction(ref Vector4 v) + { + SRgbCompanding.Expand(ref v); + Vector4Utils.Premultiply(ref v); + } + + TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => sourceAction(ref v)); + Vector4[] expected = CreateExpectedScaledVector4Data(source, (ref Vector4 v) => expectedAction(ref v)); + + TestOperation( + source, + expected, + (s, d) => Operations.ToVector4( + this.Configuration, + s, + d.GetSpan(), + PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Premultiply | PixelConversionModifiers.Scale) + ); + } + [Theory] [MemberData(nameof(ArraySizesData))] public void FromArgb32Bytes(int count) @@ -477,25 +700,37 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations ); } - internal static Vector4[] CreateExpectedVector4Data(TPixel[] source) + public delegate void RefAction(ref T1 arg1); + + internal static Vector4[] CreateExpectedVector4Data(TPixel[] source, RefAction vectorModifier = null) { var expected = new Vector4[source.Length]; for (int i = 0; i < expected.Length; i++) { - expected[i] = source[i].ToVector4(); + var v = source[i].ToVector4(); + + vectorModifier?.Invoke(ref v); + + expected[i] = v; } + return expected; } - internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source) + internal static Vector4[] CreateExpectedScaledVector4Data(TPixel[] source, RefAction vectorModifier = null) { var expected = new Vector4[source.Length]; for (int i = 0; i < expected.Length; i++) { - expected[i] = source[i].ToScaledVector4(); + Vector4 v = source[i].ToScaledVector4(); + + vectorModifier?.Invoke(ref v); + + expected[i] = v; } + return expected; } @@ -513,19 +748,22 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations } } - internal static Vector4[] CreateVector4TestData(int length) + internal static Vector4[] CreateVector4TestData(int length, RefAction vectorModifier = null) { var result = new Vector4[length]; var rnd = new Random(42); // Deterministic random values for (int i = 0; i < result.Length; i++) { - result[i] = GetVector(rnd); + Vector4 v = GetVector(rnd); + vectorModifier?.Invoke(ref v); + + result[i] = v; } return result; } - internal static TPixel[] CreatePixelTestData(int length) + internal static TPixel[] CreatePixelTestData(int length, RefAction vectorModifier = null) { var result = new TPixel[length]; @@ -534,13 +772,16 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations for (int i = 0; i < result.Length; i++) { Vector4 v = GetVector(rnd); + + vectorModifier?.Invoke(ref v); + result[i].FromVector4(v); } return result; } - internal static TPixel[] CreateScaledPixelTestData(int length) + internal static TPixel[] CreateScaledPixelTestData(int length, RefAction vectorModifier = null) { var result = new TPixel[length]; @@ -549,6 +790,9 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations for (int i = 0; i < result.Length; i++) { Vector4 v = GetVector(rnd); + + vectorModifier?.Invoke(ref v); + result[i].FromScaledVector4(v); } From 1a922f6e14b358ec5d8345117538903581ed6124 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 00:56:11 +0200 Subject: [PATCH 05/13] all pixel types implemented except RgbaVector --- .../Argb32.PixelOperations.Generated.cs | 4 +- .../Bgr24.PixelOperations.Generated.cs | 4 +- .../Bgra32.PixelOperations.Generated.cs | 4 +- .../Rgb24.PixelOperations.Generated.cs | 4 +- .../Generated/_Common.ttinclude | 4 +- .../Rgba32.PixelOperations.cs | 6 +- .../RgbaVector.PixelOperations.cs | 6 ++ .../PixelFormats/PixelOperations{TPixel}.cs | 20 +---- .../Utils/Vector4Converters.Default.cs | 74 +++++++++++++++++-- .../Utils/Vector4Converters.RgbaCompatible.cs | 46 ++++-------- .../PixelFormats/Utils/Vector4Converters.cs | 48 ++++++++++++ .../PixelOperations/PixelOperationsTests.cs | 8 +- 12 files changed, 158 insertions(+), 70 deletions(-) create mode 100644 src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index e832bc97f..c49f3f834 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -44,13 +44,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); } /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index f1885c71b..a9eca8994 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -44,13 +44,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 2409f6784..73eddc235 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -44,13 +44,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); } /// internal override void ToRgba32(Configuration configuration, ReadOnlySpan sourcePixels, Span destPixels) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index ddf9813ab..1648f5341 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -44,13 +44,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index 0ff5b8605..6286eaf72 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -113,13 +113,13 @@ using System.Runtime.InteropServices; /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span<<#=pixelType#>> destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, false); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, false); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); } <#+ } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index 7e8bb7f29..aa9b82be7 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -4,6 +4,8 @@ using System; using System.Numerics; using System.Runtime.InteropServices; + +using SixLabors.ImageSharp.PixelFormats.Utils; using SixLabors.Memory; namespace SixLabors.ImageSharp.PixelFormats @@ -28,10 +30,10 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); destVectors = destVectors.Slice(0, sourcePixels.Length); - SimdUtils.BulkConvertByteToNormalizedFloat( MemoryMarshal.Cast(sourcePixels), MemoryMarshal.Cast(destVectors)); + Vector4Converters.ApplyForwardConversionModifiers(destVectors, modifiers); } /// @@ -44,7 +46,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); destPixels = destPixels.Slice(0, sourceVectors.Length); - + Vector4Converters.ApplyBackwardConversionModifiers(sourceVectors, modifiers); SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows( MemoryMarshal.Cast(sourceVectors), MemoryMarshal.Cast(destPixels)); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index 777d0da6d..3c4d951ee 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -5,6 +5,8 @@ using System; using System.Numerics; using System.Runtime.InteropServices; +using SixLabors.ImageSharp.PixelFormats.Utils; + namespace SixLabors.ImageSharp.PixelFormats { /// @@ -26,6 +28,8 @@ namespace SixLabors.ImageSharp.PixelFormats { Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); + Vector4Converters.ApplyBackwardConversionModifiers(sourceVectors, modifiers); + // TODO: Repeating previous override behavior here. Not sure if this is correct! if (modifiers.IsDefined(PixelConversionModifiers.Scale)) { @@ -55,6 +59,8 @@ namespace SixLabors.ImageSharp.PixelFormats { MemoryMarshal.Cast(sourcePixels).CopyTo(destVectors); } + + Vector4Converters.ApplyForwardConversionModifiers(destVectors, modifiers); } } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index ea5bc876f..53181e7a9 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -37,16 +37,8 @@ namespace SixLabors.ImageSharp.PixelFormats PixelConversionModifiers modifiers) { Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); - if (modifiers.IsDefined(PixelConversionModifiers.Scale)) - { - Utils.Vector4Converters.Default.DangerousFromScaledVector4(sourceVectors, destPixels); - } - else - { - Utils.Vector4Converters.Default.DangerousFromVector4(sourceVectors, destPixels); - } + Utils.Vector4Converters.Default.FromVector4(sourceVectors, destPixels, modifiers); } /// @@ -82,16 +74,8 @@ namespace SixLabors.ImageSharp.PixelFormats PixelConversionModifiers modifiers) { Guard.NotNull(configuration, nameof(configuration)); - Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - if (modifiers.IsDefined(PixelConversionModifiers.Scale)) - { - Utils.Vector4Converters.Default.DangerousToScaledVector4(sourcePixels, destVectors); - } - else - { - Utils.Vector4Converters.Default.DangerousToVector4(sourcePixels, destVectors); - } + Utils.Vector4Converters.Default.ToVector4(sourcePixels, destVectors, modifiers); } /// diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs index e784e3b5a..4c4e60276 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.Default.cs @@ -6,6 +6,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using SixLabors.ImageSharp.ColorSpaces.Companding; + namespace SixLabors.ImageSharp.PixelFormats.Utils { /// @@ -15,13 +17,75 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils { /// /// Provides default implementations for batched to/from conversion. - /// WARNING: The methods are operating without bounds checking and input validation! + /// WARNING: The methods prefixed with "Unsafe" are operating without bounds checking and input validation! /// Input validation is the responsibility of the caller! /// public static class Default { [MethodImpl(InliningOptions.ShortMethod)] - internal static void DangerousFromVector4( + public static void FromVector4( + Span sourceVectors, + Span destPixels, + PixelConversionModifiers modifiers) + where TPixel : struct, IPixel + { + Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels)); + + UnsafeFromVector4(sourceVectors, destPixels, modifiers); + } + + [MethodImpl(InliningOptions.ShortMethod)] + public static void ToVector4( + ReadOnlySpan sourcePixels, + Span destVectors, + PixelConversionModifiers modifiers) + where TPixel : struct, IPixel + { + Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); + + UnsafeToVector4(sourcePixels, destVectors, modifiers); + } + + [MethodImpl(InliningOptions.ShortMethod)] + public static void UnsafeFromVector4( + Span sourceVectors, + Span destPixels, + PixelConversionModifiers modifiers) + where TPixel : struct, IPixel + { + ApplyBackwardConversionModifiers(sourceVectors, modifiers); + + if (modifiers.IsDefined(PixelConversionModifiers.Scale)) + { + UnsafeFromScaledVector4Core(sourceVectors, destPixels); + } + else + { + UnsafeFromVector4Core(sourceVectors, destPixels); + } + } + + [MethodImpl(InliningOptions.ShortMethod)] + public static void UnsafeToVector4( + ReadOnlySpan sourcePixels, + Span destVectors, + PixelConversionModifiers modifiers) + where TPixel : struct, IPixel + { + if (modifiers.IsDefined(PixelConversionModifiers.Scale)) + { + UnsafeToScaledVector4Core(sourcePixels, destVectors); + } + else + { + UnsafeToVector4Core(sourcePixels, destVectors); + } + + ApplyForwardConversionModifiers(destVectors, modifiers); + } + + [MethodImpl(InliningOptions.ShortMethod)] + private static void UnsafeFromVector4Core( ReadOnlySpan sourceVectors, Span destPixels) where TPixel : struct, IPixel @@ -38,7 +102,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils } [MethodImpl(InliningOptions.ShortMethod)] - internal static void DangerousToVector4( + private static void UnsafeToVector4Core( ReadOnlySpan sourcePixels, Span destVectors) where TPixel : struct, IPixel @@ -55,7 +119,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils } [MethodImpl(InliningOptions.ShortMethod)] - internal static void DangerousFromScaledVector4( + private static void UnsafeFromScaledVector4Core( ReadOnlySpan sourceVectors, Span destinationColors) where TPixel : struct, IPixel @@ -72,7 +136,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils } [MethodImpl(InliningOptions.ShortMethod)] - internal static void DangerousToScaledVector4( + private static void UnsafeToScaledVector4Core( ReadOnlySpan sourceColors, Span destinationVectors) where TPixel : struct, IPixel diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs index 006ebe828..efe4dc69a 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -7,6 +7,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using SixLabors.ImageSharp.ColorSpaces.Companding; + namespace SixLabors.ImageSharp.PixelFormats.Utils { /// @@ -41,7 +43,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils PixelOperations pixelOperations, ReadOnlySpan sourcePixels, Span destVectors, - bool scaled) + PixelConversionModifiers modifiers) where TPixel : struct, IPixel { Guard.NotNull(configuration, nameof(configuration)); @@ -52,7 +54,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils // Not worth for small buffers: if (count < Vector4ConversionThreshold) { - ToVector4Fallback(sourcePixels, destVectors, scaled); + Default.UnsafeToVector4(sourcePixels, destVectors, modifiers); return; } @@ -70,6 +72,9 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils MemoryMarshal.Cast(destVectors.Slice(0, countWithoutLastItem))); destVectors[countWithoutLastItem] = sourcePixels[countWithoutLastItem].ToVector4(); + + // TODO: Investigate optimized 1-pass approach! + ApplyForwardConversionModifiers(destVectors, modifiers); } /// @@ -83,9 +88,9 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils internal static void FromVector4( Configuration configuration, PixelOperations pixelOperations, - ReadOnlySpan sourceVectors, + Span sourceVectors, Span destPixels, - bool scaled) + PixelConversionModifiers modifiers) where TPixel : struct, IPixel { Guard.NotNull(configuration, nameof(configuration)); @@ -96,11 +101,14 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils // Not worth for small buffers: if (count < Vector4ConversionThreshold) { - FromVector4Fallback(sourceVectors, destPixels, scaled); + Default.UnsafeFromVector4(sourceVectors, destPixels, modifiers); return; } + // TODO: Investigate optimized 1-pass approach! + ApplyBackwardConversionModifiers(sourceVectors, modifiers); + // For the opposite direction it's not easy to implement the trick used in RunRgba32CompatibleToVector4Conversion, // so let's allocate a temporary buffer as usually: using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(count)) @@ -115,34 +123,6 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils } } - [MethodImpl(InliningOptions.ColdPath)] - private static void ToVector4Fallback(ReadOnlySpan sourcePixels, Span destVectors, bool scaled) - where TPixel : struct, IPixel - { - if (scaled) - { - Default.DangerousToScaledVector4(sourcePixels, destVectors); - } - else - { - Default.DangerousToVector4(sourcePixels, destVectors); - } - } - - [MethodImpl(InliningOptions.ColdPath)] - private static void FromVector4Fallback(ReadOnlySpan sourceVectors, Span destPixels, bool scaled) - where TPixel : struct, IPixel - { - if (scaled) - { - Default.DangerousFromScaledVector4(sourceVectors, destPixels); - } - else - { - Default.DangerousFromVector4(sourceVectors, destPixels); - } - } - private static int CalculateVector4ConversionThreshold() { if (!Vector.IsHardwareAccelerated) diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs new file mode 100644 index 000000000..447869a7d --- /dev/null +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs @@ -0,0 +1,48 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; + +using SixLabors.ImageSharp.ColorSpaces.Companding; + +namespace SixLabors.ImageSharp.PixelFormats.Utils +{ + internal static partial class Vector4Converters + { + /// + /// Apply modifiers used requested by ToVector4() conversion. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void ApplyForwardConversionModifiers(Span vectors, PixelConversionModifiers modifiers) + { + if (modifiers.IsDefined(PixelConversionModifiers.SRgbCompand)) + { + SRgbCompanding.Expand(vectors); + } + + if (modifiers.IsDefined(PixelConversionModifiers.Premultiply)) + { + Vector4Utils.Premultiply(vectors); + } + } + + /// + /// Apply modifiers used requested by FromVector4() conversion. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void ApplyBackwardConversionModifiers(Span vectors, PixelConversionModifiers modifiers) + { + if (modifiers.IsDefined(PixelConversionModifiers.Premultiply)) + { + Vector4Utils.UnPremultiply(vectors); + } + + if (modifiers.IsDefined(PixelConversionModifiers.SRgbCompand)) + { + SRgbCompanding.Compress(vectors); + } + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index 9433e19c9..f51c79034 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -148,7 +148,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.FromVector4(this.Configuration, s, d.GetSpan(), PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Scale) + (s, d) => Operations.FromVector4( + this.Configuration, + s, + d.GetSpan(), + PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Scale) ); } @@ -230,7 +234,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations this.Configuration, s, d.GetSpan(), - PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Premultiply) + PixelConversionModifiers.SRgbCompand | PixelConversionModifiers.Premultiply | PixelConversionModifiers.Scale) ); } From d1dd90c5cc6adc1a96915f68452aa344c4726bac Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 01:00:34 +0200 Subject: [PATCH 06/13] fix RgbaVector --- .../RgbaVector.PixelOperations.cs | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index 3c4d951ee..2d52f98cb 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -29,16 +29,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.DestinationShouldNotBeTooShort(sourceVectors, destinationColors, nameof(destinationColors)); Vector4Converters.ApplyBackwardConversionModifiers(sourceVectors, modifiers); - - // TODO: Repeating previous override behavior here. Not sure if this is correct! - if (modifiers.IsDefined(PixelConversionModifiers.Scale)) - { - MemoryMarshal.Cast(sourceVectors).CopyTo(destinationColors); - } - else - { - base.FromVector4(configuration, sourceVectors, destinationColors, modifiers); - } + MemoryMarshal.Cast(sourceVectors).CopyTo(destinationColors); } /// @@ -50,16 +41,7 @@ namespace SixLabors.ImageSharp.PixelFormats { Guard.DestinationShouldNotBeTooShort(sourcePixels, destVectors, nameof(destVectors)); - // TODO: Repeating previous override behavior here. Not sure if this is correct! - if (modifiers.IsDefined(PixelConversionModifiers.Scale)) - { - base.ToVector4(configuration, sourcePixels, destVectors, modifiers); - } - else - { - MemoryMarshal.Cast(sourcePixels).CopyTo(destVectors); - } - + MemoryMarshal.Cast(sourcePixels).CopyTo(destVectors); Vector4Converters.ApplyForwardConversionModifiers(destVectors, modifiers); } } From 70c4e117f1743488dba5b76718a51487a2df12b3 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 01:05:59 +0200 Subject: [PATCH 07/13] Inlining temporary compatibility methods (FromScaledVector4, ToScaledVector4) --- .../PixelFormats/PixelBlender{TPixel}.cs | 36 +++++++------------ .../PixelFormats/PixelOperations{TPixel}.cs | 15 -------- .../Utils/Vector4Converters.RgbaCompatible.cs | 8 +---- .../Dithering/PaletteDitherProcessorBase.cs | 2 +- .../FrameQuantizerBase{TPixel}.cs | 2 +- .../PixelOperations/PixelOperationsTests.cs | 14 +++++--- .../TestUtilities/TestImageExtensions.cs | 4 +-- 7 files changed, 27 insertions(+), 54 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index 5c8e506ae..e81498463 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -112,21 +112,15 @@ namespace SixLabors.ImageSharp.PixelFormats Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4( - configuration, - background.Slice(0, background.Length), - backgroundSpan); - PixelOperations.Instance.ToScaledVector4( - configuration, - source.Slice(0, background.Length), - sourceSpan); + ReadOnlySpan sourcePixels = background.Slice(0, background.Length); + PixelOperations.Instance.ToVector4(configuration, sourcePixels, backgroundSpan, PixelConversionModifiers.Scale); + ReadOnlySpan sourcePixels1 = source.Slice(0, background.Length); + PixelOperations.Instance.ToVector4(configuration, sourcePixels1, sourceSpan, PixelConversionModifiers.Scale); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4( - configuration, - destinationSpan.Slice(0, background.Length), - destination); + Span sourceVectors = destinationSpan.Slice(0, background.Length); + PixelOperations.Instance.FromVector4(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); } } @@ -161,21 +155,15 @@ namespace SixLabors.ImageSharp.PixelFormats Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length); - PixelOperations.Instance.ToScaledVector4( - configuration, - background.Slice(0, background.Length), - backgroundSpan); - PixelOperations.Instance.ToScaledVector4( - configuration, - source.Slice(0, background.Length), - sourceSpan); + ReadOnlySpan sourcePixels = background.Slice(0, background.Length); + PixelOperations.Instance.ToVector4(configuration, sourcePixels, backgroundSpan, PixelConversionModifiers.Scale); + ReadOnlySpan sourcePixels1 = source.Slice(0, background.Length); + PixelOperations.Instance.ToVector4(configuration, sourcePixels1, sourceSpan, PixelConversionModifiers.Scale); this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); - PixelOperations.Instance.FromScaledVector4( - configuration, - destinationSpan.Slice(0, background.Length), - destination); + Span sourceVectors = destinationSpan.Slice(0, background.Length); + PixelOperations.Instance.FromVector4(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); } } } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 53181e7a9..6dae22c5a 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -41,15 +41,6 @@ namespace SixLabors.ImageSharp.PixelFormats Utils.Vector4Converters.Default.FromVector4(sourceVectors, destPixels, modifiers); } - /// - /// TODO: For compatibility, should be inlined! - /// - internal void FromScaledVector4( - Configuration configuration, - Span sourceVectors, - Span destPixels) => - this.FromVector4(configuration, sourceVectors, destPixels, PixelConversionModifiers.Scale); - /// /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. /// TODO: Rename to DestructiveFromVector4() + add explain behavior @@ -90,12 +81,6 @@ namespace SixLabors.ImageSharp.PixelFormats Span destVectors) => this.ToVector4(configuration, sourcePixels, destVectors, PixelConversionModifiers.None); - /// - /// TODO: For compatibility, should be inlined! - /// - internal void ToScaledVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors) => - this.ToVector4(configuration, sourcePixels, destVectors, PixelConversionModifiers.Scale); - /// /// Converts 'sourceColors.Length' pixels from 'sourceColors' into 'destinationColors'. /// diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs index efe4dc69a..5188a89a3 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -32,10 +32,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils /// /// Provides an efficient default implementation for - /// and - /// which is applicable for -compatible pixel types where - /// returns the same scaled result as . - /// The method is works by internally converting to a therefore it's not applicable for that type! + /// The method works by internally converting to a therefore it's not applicable for that type! /// [MethodImpl(InliningOptions.ShortMethod)] internal static void ToVector4( @@ -79,9 +76,6 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils /// /// Provides an efficient default implementation for - /// and - /// which is applicable for -compatible pixel types where - /// returns the same scaled result as . /// The method is works by internally converting to a therefore it's not applicable for that type! /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs index 43f6c8a45..6313b74c9 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs @@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering if (this.paletteVector is null) { this.paletteVector = new Vector4[this.Palette.Length]; - PixelOperations.Instance.ToScaledVector4(configuration, this.Palette, this.paletteVector); + PixelOperations.Instance.ToVector4(configuration, (ReadOnlySpan)this.Palette, (Span)this.paletteVector, PixelConversionModifiers.Scale); } } } diff --git a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs index 3b9b046a0..a70cfb660 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/FrameQuantizerBase{TPixel}.cs @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // Collect the palette. Required before the second pass runs. TPixel[] palette = this.GetPalette(); this.paletteVector = new Vector4[palette.Length]; - PixelOperations.Instance.ToScaledVector4(image.Configuration, palette, this.paletteVector); + PixelOperations.Instance.ToVector4(image.Configuration, (ReadOnlySpan)palette, (Span)this.paletteVector, PixelConversionModifiers.Scale); var quantizedFrame = new QuantizedFrame(image.MemoryAllocator, width, height, palette); if (this.Dither) diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index f51c79034..b9d3fcff5 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -124,8 +124,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.FromScaledVector4(this.Configuration, s, d.GetSpan()) - ); + (s, d) => + { + Span destPixels = d.GetSpan(); + Operations.FromVector4(this.Configuration, (Span)s, destPixels, PixelConversionModifiers.Scale); + }); } [Theory] @@ -262,8 +265,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.ToScaledVector4(this.Configuration, s, d.GetSpan()) - ); + (s, d) => + { + Span destVectors = d.GetSpan(); + Operations.ToVector4(this.Configuration, (ReadOnlySpan)s, destVectors, PixelConversionModifiers.Scale); + }); } [Theory] diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 29d39596b..ad31319bb 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Tests { Span pixelSpan = frame.GetPixelSpan(); - PixelOperations.Instance.ToScaledVector4(configuration, pixelSpan, tempSpan); + PixelOperations.Instance.ToVector4(configuration, pixelSpan, tempSpan, PixelConversionModifiers.Scale); for (int i = 0; i < tempSpan.Length; i++) { @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests v.W = 1F; } - PixelOperations.Instance.FromScaledVector4(configuration, tempSpan, pixelSpan); + PixelOperations.Instance.FromVector4(configuration, tempSpan, pixelSpan, PixelConversionModifiers.Scale); } } }); From 37563cca01699160d962d84e1e46520d8491e55d Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 01:42:17 +0200 Subject: [PATCH 08/13] Optimization: omit premultiplication for Bgr24 and Rgb24 --- .../PixelFormats/PixelConversionModifiers.cs | 24 +++++++++++++ .../Bgr24.PixelOperations.Generated.cs | 4 +-- .../Rgb24.PixelOperations.Generated.cs | 4 +-- .../Generated/_Common.ttinclude | 16 ++++++--- ...xelOperationsTests.Bgr24OperationsTests.cs | 1 + ...xelOperationsTests.Rgb24OperationsTests.cs | 1 + .../PixelOperations/PixelOperationsTests.cs | 34 +++++++++++++++---- 7 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs index 536a23061..d66dbb57a 100644 --- a/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs +++ b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs @@ -3,14 +3,38 @@ using System; +using SixLabors.ImageSharp.ColorSpaces.Companding; + namespace SixLabors.ImageSharp.PixelFormats { + /// + /// Flags responsible to select additional operations which could be effitiently applied in + /// + /// or + /// + /// knowing the pixel type. + /// [Flags] internal enum PixelConversionModifiers { + /// + /// No special operation is selected + /// None = 0, + + /// + /// Select instead the standard (non scaled) variants. + /// Scale = 1 << 0, + + /// + /// Enable alpha premultiplication / unpremultiplication + /// Premultiply = 1 << 1, + + /// + /// Enable SRGB companding (defined in ). + /// SRgbCompand = 1 << 2, } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index a9eca8994..92925898b 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -44,13 +44,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply)); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index 1648f5341..6de8c92bc 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -44,13 +44,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply)); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude index 6286eaf72..584615532 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/_Common.ttinclude @@ -22,6 +22,7 @@ using System.Runtime.InteropServices; // Types with Rgba32-combatible to/from Vector4 conversion static readonly string[] Rgba32CompatibleTypes = { "Argb32", "Bgra32", "Rgb24", "Bgr24" }; + void GenerateDefaultSelfConversionMethods(string pixelType) { #> @@ -107,19 +108,24 @@ using System.Runtime.InteropServices; <#+ } - void GenerateRgba32CompatibleVector4ConversionMethods(string pixelType) + void GenerateRgba32CompatibleVector4ConversionMethods(string pixelType, bool hasAlpha) { + string removeTheseModifiers = "PixelConversionModifiers.Scale"; + if (!hasAlpha) + { + removeTheseModifiers += " | PixelConversionModifiers.Premultiply"; + } #> /// internal override void FromVector4(Configuration configuration, Span sourceVectors, Span<<#=pixelType#>> destPixels, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); + Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(<#=removeTheseModifiers#>)); } /// internal override void ToVector4(Configuration configuration, ReadOnlySpan<<#=pixelType#>> sourcePixels, Span destVectors, PixelConversionModifiers modifiers) { - Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); + Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(<#=removeTheseModifiers#>)); } <#+ } @@ -130,7 +136,7 @@ using System.Runtime.InteropServices; if (Rgba32CompatibleTypes.Contains(pixelType)) { - GenerateRgba32CompatibleVector4ConversionMethods(pixelType); + GenerateRgba32CompatibleVector4ConversionMethods(pixelType, pixelType.EndsWith("32")); } var matching32BitTypes = Optimized32BitTypes.Contains(pixelType) ? @@ -151,4 +157,4 @@ using System.Runtime.InteropServices; GenerateDefaultConvertToMethod(pixelType, destPixelType); } } -#> \ No newline at end of file +#> diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs index 323d3914c..afcec7938 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Bgr24OperationsTests.cs @@ -15,6 +15,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations public Bgr24OperationsTests(ITestOutputHelper output) : base(output) { + this.HasAlpha = false; } [Fact] diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs index fa51c2278..1c7d312d3 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.Rgb24OperationsTests.cs @@ -14,6 +14,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations public Rgb24OperationsTests(ITestOutputHelper output) : base(output) { + this.HasAlpha = false; } [Fact] diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index b9d3fcff5..659da47a7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -33,6 +33,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations null; #endif + protected bool HasAlpha { get; set; } = true; + protected PixelOperationsTests(ITestOutputHelper output) : base(output) { @@ -165,12 +167,18 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations { void sourceAction(ref Vector4 v) { - Vector4Utils.Premultiply(ref v); + if (this.HasAlpha) + { + Vector4Utils.Premultiply(ref v); + } } void expectedAction(ref Vector4 v) { - Vector4Utils.UnPremultiply(ref v); + if (this.HasAlpha) + { + Vector4Utils.UnPremultiply(ref v); + } } Vector4[] source = CreateVector4TestData(count, (ref Vector4 v) => sourceAction(ref v)); @@ -189,12 +197,18 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations { void sourceAction(ref Vector4 v) { - Vector4Utils.Premultiply(ref v); + if (this.HasAlpha) + { + Vector4Utils.Premultiply(ref v); + } } void expectedAction(ref Vector4 v) { - Vector4Utils.UnPremultiply(ref v); + if (this.HasAlpha) + { + Vector4Utils.UnPremultiply(ref v); + } } Vector4[] source = CreateVector4TestData(count, (ref Vector4 v) => sourceAction(ref v)); @@ -218,12 +232,20 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations void sourceAction(ref Vector4 v) { SRgbCompanding.Expand(ref v); - Vector4Utils.Premultiply(ref v); + + if (this.HasAlpha) + { + Vector4Utils.Premultiply(ref v); + } } void expectedAction(ref Vector4 v) { - Vector4Utils.UnPremultiply(ref v); + if (this.HasAlpha) + { + Vector4Utils.UnPremultiply(ref v); + } + SRgbCompanding.Compress(ref v); } From d2fddce2153124e450012ff30d4f1f61a6891743 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 01:45:39 +0200 Subject: [PATCH 09/13] extend Resize benchmarks --- .../ImageSharp.Benchmarks/Samplers/Resize.cs | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs index 148b25328..239e2fc6f 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs @@ -14,11 +14,12 @@ using SixLabors.ImageSharp.Processing; namespace SixLabors.ImageSharp.Benchmarks { [Config(typeof(Config.ShortClr))] - public abstract class ResizeBenchmarkBase + public abstract class ResizeBenchmarkBase + where TPixel : struct, IPixel { protected readonly Configuration Configuration = new Configuration(new JpegConfigurationModule()); - private Image sourceImage; + private Image sourceImage; private Bitmap sourceBitmap; @@ -31,7 +32,7 @@ namespace SixLabors.ImageSharp.Benchmarks [GlobalSetup] public void Setup() { - this.sourceImage = new Image(this.Configuration, this.SourceSize, this.SourceSize); + this.sourceImage = new Image(this.Configuration, this.SourceSize, this.SourceSize); this.sourceBitmap = new Bitmap(this.SourceSize, this.SourceSize); } @@ -65,26 +66,29 @@ namespace SixLabors.ImageSharp.Benchmarks [Benchmark(Description = "ImageSharp, MaxDegreeOfParallelism = 1")] public int ImageSharp_P1() => this.RunImageSharpResize(1); - [Benchmark(Description = "ImageSharp, MaxDegreeOfParallelism = 4")] - public int ImageSharp_P4() => this.RunImageSharpResize(4); + // Parallel cases have been disabled for fast benchmark execution. + // Uncomment, if you are interested in parallel speedup - [Benchmark(Description = "ImageSharp, MaxDegreeOfParallelism = 8")] - public int ImageSharp_P8() => this.RunImageSharpResize(8); + //[Benchmark(Description = "ImageSharp, MaxDegreeOfParallelism = 4")] + //public int ImageSharp_P4() => this.RunImageSharpResize(4); + + //[Benchmark(Description = "ImageSharp, MaxDegreeOfParallelism = 8")] + //public int ImageSharp_P8() => this.RunImageSharpResize(8); protected int RunImageSharpResize(int maxDegreeOfParallelism) { this.Configuration.MaxDegreeOfParallelism = maxDegreeOfParallelism; - using (Image clone = this.sourceImage.Clone(this.ExecuteResizeOperation)) + using (Image clone = this.sourceImage.Clone(this.ExecuteResizeOperation)) { return clone.Width; } } - protected abstract void ExecuteResizeOperation(IImageProcessingContext ctx); + protected abstract void ExecuteResizeOperation(IImageProcessingContext ctx); } - - public class Resize_Bicubic : ResizeBenchmarkBase + + public class Resize_Bicubic_Rgba32 : ResizeBenchmarkBase { protected override void ExecuteResizeOperation(IImageProcessingContext ctx) { @@ -115,7 +119,15 @@ namespace SixLabors.ImageSharp.Benchmarks } - public class Resize_BicubicCompand : ResizeBenchmarkBase + public class Resize_Bicubic_Bgra32 : ResizeBenchmarkBase + { + protected override void ExecuteResizeOperation(IImageProcessingContext ctx) + { + ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); + } + } + + public class Resize_BicubicCompand_Rgba32 : ResizeBenchmarkBase { protected override void ExecuteResizeOperation(IImageProcessingContext ctx) { @@ -144,4 +156,13 @@ namespace SixLabors.ImageSharp.Benchmarks // 'ImageSharp, MaxDegreeOfParallelism = 4' | Core | 3032 | 400 | 36.21 ms | 53.802 ms | 3.0399 ms | 0.36 | 0.03 | 25300 B | // 'ImageSharp, MaxDegreeOfParallelism = 8' | Core | 3032 | 400 | 26.52 ms | 2.173 ms | 0.1228 ms | 0.27 | 0.00 | 25589 B | } -} + + public class Resize_Bicubic_Rgb24 : ResizeBenchmarkBase + { + protected override void ExecuteResizeOperation(IImageProcessingContext ctx) + { + ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); + } + } + +} \ No newline at end of file From acb1dbc319ba4190e3e253f6126b082eb82a21a5 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 01:56:14 +0200 Subject: [PATCH 10/13] update ResizeProcessor --- .../Transforms/Resize/ResizeProcessor.cs | 102 ++++++++---------- tests/Images/External | 2 +- 2 files changed, 48 insertions(+), 56 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs index 189e21de7..6904122cc 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs @@ -9,7 +9,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; -using SixLabors.ImageSharp.ColorSpaces.Companding; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; @@ -216,27 +215,33 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms workingRect, configuration, rows => + { + for (int y = rows.Min; y < rows.Max; y++) { - for (int y = rows.Min; y < rows.Max; y++) + // Y coordinates of source points + Span sourceRow = + source.GetPixelRowSpan((int)(((y - startY) * heightFactor) + sourceY)); + Span targetRow = destination.GetPixelRowSpan(y); + + for (int x = minX; x < maxX; x++) { - // Y coordinates of source points - Span sourceRow = - source.GetPixelRowSpan((int)(((y - startY) * heightFactor) + sourceY)); - Span targetRow = destination.GetPixelRowSpan(y); - - for (int x = minX; x < maxX; x++) - { - // X coordinates of source points - targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)]; - } + // X coordinates of source points + targetRow[x] = sourceRow[(int)(((x - startX) * widthFactor) + sourceX)]; } - }); + } + }); return; } int sourceHeight = source.Height; + PixelConversionModifiers conversionModifiers = PixelConversionModifiers.Premultiply; + if (this.Compand) + { + conversionModifiers |= PixelConversionModifiers.Scale | PixelConversionModifiers.SRgbCompand; + } + // Interpolate the image using the calculated weights. // A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm // First process the columns. Since we are not using multiple threads startY and endY @@ -251,30 +256,23 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms processColsRect, configuration, (rows, tempRowBuffer) => + { + for (int y = rows.Min; y < rows.Max; y++) { - for (int y = rows.Min; y < rows.Max; y++) - { - Span sourceRow = source.GetPixelRowSpan(y).Slice(sourceX); - Span tempRowSpan = tempRowBuffer.Span.Slice(sourceX); - - PixelOperations.Instance.ToVector4(configuration, sourceRow, tempRowSpan); - Vector4Utils.Premultiply(tempRowSpan); + Span sourceRow = source.GetPixelRowSpan(y).Slice(sourceX); + Span tempRowSpan = tempRowBuffer.Span.Slice(sourceX); - ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y]; + PixelOperations.Instance.ToVector4(configuration, sourceRow, tempRowSpan, conversionModifiers); - if (this.Compand) - { - SRgbCompanding.Expand(tempRowSpan); - } + ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y]; - for (int x = minX; x < maxX; x++) - { - ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - startX); - Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) = - kernel.Convolve(tempRowSpan); - } + for (int x = minX; x < maxX; x++) + { + ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - startX); + Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) = kernel.Convolve(tempRowSpan); } - }); + } + }); var processRowsRect = Rectangle.FromLTRB(0, minY, width, maxY); @@ -283,35 +281,29 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms processRowsRect, configuration, (rows, tempRowBuffer) => - { - Span tempRowSpan = tempRowBuffer.Span; - - for (int y = rows.Min; y < rows.Max; y++) - { - // Ensure offsets are normalized for cropping and padding. - ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY); + { + Span tempRowSpan = tempRowBuffer.Span; - ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempRowSpan); + for (int y = rows.Min; y < rows.Max; y++) + { + // Ensure offsets are normalized for cropping and padding. + ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY); - for (int x = 0; x < width; x++) - { - Span firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY); + ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempRowSpan); - // Destination color components - Unsafe.Add(ref tempRowBase, x) = kernel.Convolve(firstPassColumn); - } + for (int x = 0; x < width; x++) + { + Span firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY); - Vector4Utils.UnPremultiply(tempRowSpan); + // Destination color components + Unsafe.Add(ref tempRowBase, x) = kernel.Convolve(firstPassColumn); + } - if (this.Compand) - { - SRgbCompanding.Compress(tempRowSpan); - } + Span targetRowSpan = destination.GetPixelRowSpan(y); - Span targetRowSpan = destination.GetPixelRowSpan(y); - PixelOperations.Instance.FromVector4(configuration, tempRowSpan, targetRowSpan); - } - }); + PixelOperations.Instance.FromVector4(configuration, tempRowSpan, targetRowSpan, conversionModifiers); + } + }); } } diff --git a/tests/Images/External b/tests/Images/External index c4098e463..4387e56e8 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit c4098e463ab0e7128ae196b7f963369271df8fd3 +Subproject commit 4387e56e8590ee00607efe29a9babfda041621cb From 575a484e61b054ec883c5106637d02106a5c39ca Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 02:06:44 +0200 Subject: [PATCH 11/13] update benchmark results --- .../ImageSharp.Benchmarks/Samplers/Resize.cs | 124 +++++++++++------- 1 file changed, 79 insertions(+), 45 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs index 239e2fc6f..51f3a5653 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs @@ -95,27 +95,25 @@ namespace SixLabors.ImageSharp.Benchmarks ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); } - // RESULTS (2018 October): + // RESULTS (2019 April): // - // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17134.648 (1803/April2018Update/Redstone4) // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores - // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC - // .NET Core SDK=2.1.403 - // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // Job-IGUFBA : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 - // Job-DZFERG : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // - // Method | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | - // ----------------------------------------- |-------- |----------- |--------- |----------:|----------:|----------:|-------:|---------:|----------:| - // SystemDrawing | Clr | 3032 | 400 | 101.13 ms | 18.659 ms | 1.0542 ms | 1.00 | 0.00 | 0 B | - // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | 3032 | 400 | 122.05 ms | 19.622 ms | 1.1087 ms | 1.21 | 0.01 | 21856 B | - // 'ImageSharp, MaxDegreeOfParallelism = 4' | Clr | 3032 | 400 | 41.34 ms | 54.841 ms | 3.0986 ms | 0.41 | 0.03 | 28000 B | - // 'ImageSharp, MaxDegreeOfParallelism = 8' | Clr | 3032 | 400 | 31.68 ms | 12.782 ms | 0.7222 ms | 0.31 | 0.01 | 28256 B | - // | | | | | | | | | | - // SystemDrawing | Core | 3032 | 400 | 100.37 ms | 18.479 ms | 1.0441 ms | 1.00 | 0.00 | 0 B | - // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | 3032 | 400 | 73.03 ms | 10.540 ms | 0.5955 ms | 0.73 | 0.01 | 21368 B | - // 'ImageSharp, MaxDegreeOfParallelism = 4' | Core | 3032 | 400 | 22.59 ms | 4.863 ms | 0.2748 ms | 0.23 | 0.00 | 25220 B | - // 'ImageSharp, MaxDegreeOfParallelism = 8' | Core | 3032 | 400 | 21.10 ms | 23.362 ms | 1.3200 ms | 0.21 | 0.01 | 25539 B | + // Frequency=2742192 Hz, Resolution=364.6718 ns, Timer=TSC + // .NET Core SDK=2.1.602 + // [Host] : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // Clr : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3362.0 + // Core : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // + // IterationCount=3 LaunchCount=1 WarmupCount=3 + // + // Method | Job | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Ratio | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op | + // ----------------------------------------- |----- |-------- |----------- |--------- |----------:|----------:|----------:|------:|------------:|------------:|------------:|--------------------:| + // SystemDrawing | Clr | Clr | 3032 | 400 | 118.71 ms | 4.884 ms | 0.2677 ms | 1.00 | - | - | - | 2048 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | Clr | 3032 | 400 | 94.55 ms | 16.160 ms | 0.8858 ms | 0.80 | - | - | - | 16384 B | + // | | | | | | | | | | | | | + // SystemDrawing | Core | Core | 3032 | 400 | 118.38 ms | 2.814 ms | 0.1542 ms | 1.00 | - | - | - | 96 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | Core | 3032 | 400 | 90.28 ms | 4.679 ms | 0.2565 ms | 0.76 | - | - | - | 15712 B | } @@ -125,44 +123,80 @@ namespace SixLabors.ImageSharp.Benchmarks { ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); } + + // RESULTS (2019 April): + // + // BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17134.648 (1803/April2018Update/Redstone4) + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742192 Hz, Resolution=364.6718 ns, Timer=TSC + // .NET Core SDK=2.1.602 + // [Host] : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // Clr : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3362.0 + // Core : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // + // IterationCount=3 LaunchCount=1 WarmupCount=3 + // + // Method | Job | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Ratio | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op | + // ----------------------------------------- |----- |-------- |----------- |--------- |----------:|----------:|----------:|------:|------------:|------------:|------------:|--------------------:| + // SystemDrawing | Clr | Clr | 3032 | 400 | 119.01 ms | 18.513 ms | 1.0147 ms | 1.00 | - | - | - | 1638 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | Clr | 3032 | 400 | 104.71 ms | 16.078 ms | 0.8813 ms | 0.88 | - | - | - | 45056 B | + // | | | | | | | | | | | | | + // SystemDrawing | Core | Core | 3032 | 400 | 121.58 ms | 50.084 ms | 2.7453 ms | 1.00 | - | - | - | 96 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | Core | 3032 | 400 | 96.96 ms | 7.899 ms | 0.4329 ms | 0.80 | - | - | - | 44512 B | } - public class Resize_BicubicCompand_Rgba32 : ResizeBenchmarkBase + public class Resize_Bicubic_Rgb24 : ResizeBenchmarkBase { - protected override void ExecuteResizeOperation(IImageProcessingContext ctx) + protected override void ExecuteResizeOperation(IImageProcessingContext ctx) { - ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic, true); + ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); } - // RESULTS (2018 October): + // RESULTS (2019 April): // - // BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 + // BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17134.648 (1803/April2018Update/Redstone4) // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores - // Frequency=2742191 Hz, Resolution=364.6719 ns, Timer=TSC - // .NET Core SDK=2.1.403 - // [Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // Job-IGUFBA : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3190.0 - // Job-DZFERG : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT - // - // Method | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Scaled | ScaledSD | Allocated | - // ----------------------------------------- |-------- |----------- |--------- |----------:|----------:|----------:|-------:|---------:|----------:| - // SystemDrawing | Clr | 3032 | 400 | 100.63 ms | 13.864 ms | 0.7833 ms | 1.00 | 0.00 | 0 B | - // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | 3032 | 400 | 156.83 ms | 28.631 ms | 1.6177 ms | 1.56 | 0.02 | 21856 B | - // 'ImageSharp, MaxDegreeOfParallelism = 4' | Clr | 3032 | 400 | 53.43 ms | 38.493 ms | 2.1749 ms | 0.53 | 0.02 | 28512 B | - // 'ImageSharp, MaxDegreeOfParallelism = 8' | Clr | 3032 | 400 | 38.47 ms | 11.969 ms | 0.6763 ms | 0.38 | 0.01 | 28000 B | - // | | | | | | | | | | - // SystemDrawing | Core | 3032 | 400 | 99.87 ms | 23.459 ms | 1.3255 ms | 1.00 | 0.00 | 0 B | - // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | 3032 | 400 | 108.19 ms | 38.562 ms | 2.1788 ms | 1.08 | 0.02 | 21368 B | - // 'ImageSharp, MaxDegreeOfParallelism = 4' | Core | 3032 | 400 | 36.21 ms | 53.802 ms | 3.0399 ms | 0.36 | 0.03 | 25300 B | - // 'ImageSharp, MaxDegreeOfParallelism = 8' | Core | 3032 | 400 | 26.52 ms | 2.173 ms | 0.1228 ms | 0.27 | 0.00 | 25589 B | + // Frequency=2742192 Hz, Resolution=364.6718 ns, Timer=TSC + // .NET Core SDK=2.1.602 + // [Host] : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // Clr : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3362.0 + // Core : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // + // Method | Job | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Ratio | RatioSD | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op | + // ----------------------------------------- |----- |-------- |----------- |--------- |----------:|----------:|----------:|------:|--------:|------------:|------------:|------------:|--------------------:| + // SystemDrawing | Clr | Clr | 3032 | 400 | 121.37 ms | 48.580 ms | 2.6628 ms | 1.00 | 0.00 | - | - | - | 2048 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | Clr | 3032 | 400 | 99.36 ms | 11.356 ms | 0.6224 ms | 0.82 | 0.02 | - | - | - | 45056 B | + // | | | | | | | | | | | | | | + // SystemDrawing | Core | Core | 3032 | 400 | 118.06 ms | 15.667 ms | 0.8587 ms | 1.00 | 0.00 | - | - | - | 96 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | Core | 3032 | 400 | 92.47 ms | 5.683 ms | 0.3115 ms | 0.78 | 0.01 | - | - | - | 44512 B | } - public class Resize_Bicubic_Rgb24 : ResizeBenchmarkBase + + public class Resize_BicubicCompand_Rgba32 : ResizeBenchmarkBase { - protected override void ExecuteResizeOperation(IImageProcessingContext ctx) + protected override void ExecuteResizeOperation(IImageProcessingContext ctx) { - ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic); + ctx.Resize(this.DestSize, this.DestSize, KnownResamplers.Bicubic, true); } - } + // RESULTS (2019 April): + // + // BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17134.648 (1803/April2018Update/Redstone4) + // Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores + // Frequency=2742192 Hz, Resolution=364.6718 ns, Timer=TSC + // .NET Core SDK=2.1.602 + // [Host] : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // Clr : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3362.0 + // Core : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT + // + // IterationCount=3 LaunchCount=1 WarmupCount=3 + // + // Method | Job | Runtime | SourceSize | DestSize | Mean | Error | StdDev | Ratio | RatioSD | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op | + // ----------------------------------------- |----- |-------- |----------- |--------- |---------:|----------:|----------:|------:|--------:|------------:|------------:|------------:|--------------------:| + // SystemDrawing | Clr | Clr | 3032 | 400 | 120.7 ms | 68.985 ms | 3.7813 ms | 1.00 | 0.00 | - | - | - | 1638 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Clr | Clr | 3032 | 400 | 132.2 ms | 15.976 ms | 0.8757 ms | 1.10 | 0.04 | - | - | - | 16384 B | + // | | | | | | | | | | | | | | + // SystemDrawing | Core | Core | 3032 | 400 | 118.3 ms | 6.899 ms | 0.3781 ms | 1.00 | 0.00 | - | - | - | 96 B | + // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | Core | 3032 | 400 | 122.4 ms | 15.069 ms | 0.8260 ms | 1.03 | 0.01 | - | - | - | 15712 B | + } } \ No newline at end of file From 4a0b10080d00c01833d344b0dab709a4f82de39e Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 02:14:16 +0200 Subject: [PATCH 12/13] rename FromVector4(...) to FromVector4Destructive(...) --- .../Decoder/JpegImagePostProcessor.cs | 2 +- .../PixelFormats/PixelBlender{TPixel}.cs | 4 ++-- .../PixelFormats/PixelConversionModifiers.cs | 4 ++-- .../Argb32.PixelOperations.Generated.cs | 2 +- .../Bgr24.PixelOperations.Generated.cs | 2 +- .../Bgra32.PixelOperations.Generated.cs | 2 +- .../Rgb24.PixelOperations.Generated.cs | 2 +- .../Rgba32.PixelOperations.cs | 2 +- .../RgbaVector.PixelOperations.cs | 2 +- .../PixelFormats/PixelOperations{TPixel}.cs | 18 +++++++++++++----- .../Utils/Vector4Converters.RgbaCompatible.cs | 2 +- .../Convolution/Convolution2DProcessor.cs | 2 +- .../Convolution/Convolution2PassProcessor.cs | 2 +- .../Convolution/ConvolutionProcessor.cs | 2 +- .../Processors/Filters/FilterProcessor.cs | 2 +- .../Transforms/AffineTransformProcessor.cs | 2 +- .../Transforms/ProjectiveTransformProcessor.cs | 2 +- .../Transforms/Resize/ResizeProcessor.cs | 2 +- .../Color/Bulk/FromVector4.cs | 4 ++-- .../PixelBlenders/PorterDuffBulkVsPixel.cs | 2 +- .../PixelOperations/PixelOperationsTests.cs | 12 ++++++------ .../TestUtilities/TestImageExtensions.cs | 2 +- 22 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs index 438749abf..2c8190884 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs @@ -173,7 +173,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder Span destRow = destination.GetPixelRowSpan(yy); // TODO: Investigate if slicing is actually necessary - PixelOperations.Instance.FromVector4(this.configuration, this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow); + PixelOperations.Instance.FromVector4Destructive(this.configuration, this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow); } } } diff --git a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs index e81498463..d2a6fbf50 100644 --- a/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs @@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.PixelFormats this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); Span sourceVectors = destinationSpan.Slice(0, background.Length); - PixelOperations.Instance.FromVector4(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); + PixelOperations.Instance.FromVector4Destructive(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); } } @@ -163,7 +163,7 @@ namespace SixLabors.ImageSharp.PixelFormats this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount); Span sourceVectors = destinationSpan.Slice(0, background.Length); - PixelOperations.Instance.FromVector4(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); + PixelOperations.Instance.FromVector4Destructive(configuration, sourceVectors, destination, PixelConversionModifiers.Scale); } } } diff --git a/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs index d66dbb57a..5df5dc62b 100644 --- a/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs +++ b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Flags responsible to select additional operations which could be effitiently applied in /// /// or - /// + /// /// knowing the pixel type. /// [Flags] @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.PixelFormats None = 0, /// - /// Select instead the standard (non scaled) variants. + /// Select and instead the standard (non scaled) variants. /// Scale = 1 << 0, diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs index c49f3f834..4cff1f8c1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Argb32.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) + internal override void FromVector4Destructive(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs index 92925898b..225e4b5e0 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgr24.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) + internal override void FromVector4Destructive(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply)); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs index 73eddc235..ce049115e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Bgra32.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) + internal override void FromVector4Destructive(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale)); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs index 6de8c92bc..02a8869ec 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Generated/Rgb24.PixelOperations.Generated.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) + internal override void FromVector4Destructive(Configuration configuration, Span sourceVectors, Span destPixels, PixelConversionModifiers modifiers) { Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destPixels, modifiers.Remove(PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply)); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs index aa9b82be7..3da5d1855 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.PixelOperations.cs @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void FromVector4( + internal override void FromVector4Destructive( Configuration configuration, Span sourceVectors, Span destPixels, diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs index 2d52f98cb..3112126e7 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.PixelOperations.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override void FromVector4( + internal override void FromVector4Destructive( Configuration configuration, Span sourceVectors, Span destinationColors, diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 6dae22c5a..d009822e8 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -24,13 +24,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. - /// TODO: Rename to DestructiveFromVector4() + add explain behavior + /// The method is DESTRUCTIVE altering the contents of . /// + /// + /// The destructive behavior is a design choice for performance reasons. + /// In a typical use case the contents of are abandoned after the conversion. + /// /// A to configure internal operations /// The to the source vectors. /// The to the destination colors. /// The to apply during the conversion - internal virtual void FromVector4( + internal virtual void FromVector4Destructive( Configuration configuration, Span sourceVectors, Span destPixels, @@ -43,13 +47,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// Bulk version of converting 'sourceVectors.Length' pixels into 'destinationColors'. - /// TODO: Rename to DestructiveFromVector4() + add explain behavior + /// The method is DESTRUCTIVE altering the contents of . /// + /// + /// The destructive behavior is a design choice for performance reasons. + /// In a typical use case the contents of are abandoned after the conversion. + /// /// A to configure internal operations /// The to the source vectors. /// The to the destination colors. - internal void FromVector4(Configuration configuration, Span sourceVectors, Span destPixels) => - this.FromVector4(configuration, sourceVectors, destPixels, PixelConversionModifiers.None); + internal void FromVector4Destructive(Configuration configuration, Span sourceVectors, Span destPixels) => + this.FromVector4Destructive(configuration, sourceVectors, destPixels, PixelConversionModifiers.None); /// /// Bulk version of converting 'sourceColors.Length' pixels into 'destinationVectors'. diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs index 5188a89a3..fe8d7dec3 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs @@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils } /// - /// Provides an efficient default implementation for + /// Provides an efficient default implementation for /// The method is works by internally converting to a therefore it's not applicable for that type! /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs index bd1419e4b..341a26ae8 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2DProcessor.cs @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution DenseMatrixUtils.Convolve2D(in matrixY, in matrixX, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(configuration, vectorSpan.Slice(0, length), targetRowSpan); + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan.Slice(0, length), targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs index 05007c370..9de467328 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor.cs @@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution DenseMatrixUtils.Convolve(in matrix, sourcePixels, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(configuration, vectorSpan.Slice(0, length), targetRowSpan); + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan.Slice(0, length), targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs index 8ef64bdac..7e003cb03 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution DenseMatrixUtils.Convolve(in matrix, source.PixelBuffer, vectorSpan, y, x, maxY, maxX, startX); } - PixelOperations.Instance.FromVector4(configuration, vectorSpan.Slice(0, length), targetRowSpan); + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan.Slice(0, length), targetRowSpan); } }); diff --git a/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs index d6a32d889..dbd843341 100644 --- a/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs @@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters Vector4Utils.Transform(vectorSpan, ref matrix); - PixelOperations.Instance.FromVector4(configuration, vectorSpan, rowSpan); + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, rowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs index 5a3b5943b..0f71c732d 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs @@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); } - PixelOperations.Instance.FromVector4(configuration, vectorSpan, targetRowSpan); + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs index 0b5627e19..8a5d7563f 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs @@ -128,7 +128,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); } - PixelOperations.Instance.FromVector4(configuration, vectorSpan, targetRowSpan); + PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs index 6904122cc..2c186a276 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs @@ -301,7 +301,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms Span targetRowSpan = destination.GetPixelRowSpan(y); - PixelOperations.Instance.FromVector4(configuration, tempRowSpan, targetRowSpan, conversionModifiers); + PixelOperations.Instance.FromVector4Destructive(configuration, tempRowSpan, targetRowSpan, conversionModifiers); } }); } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs index 2b9573ed7..8b2d08e66 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -61,13 +61,13 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk [Benchmark] public void PixelOperations_Base() { - new PixelOperations().FromVector4(this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); + new PixelOperations().FromVector4Destructive(this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); } [Benchmark] public void PixelOperations_Specialized() { - PixelOperations.Instance.FromVector4(this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); + PixelOperations.Instance.FromVector4Destructive(this.Configuration, this.source.GetSpan(), this.destination.GetSpan()); } } diff --git a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs index cdd56fa07..ce4e16c44 100644 --- a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs +++ b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs @@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Benchmarks destinationSpan[i] = PorterDuffFunctions.NormalSrcOver(backgroundSpan[i], sourceSpan[i], amount[i]); } - PixelOperations.Instance.FromVector4(this.Configuration, destinationSpan, destination); + PixelOperations.Instance.FromVector4Destructive(this.Configuration, destinationSpan, destination); } } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs index 659da47a7..d9ae9131f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs @@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.FromVector4(this.Configuration, s, d.GetSpan()) + (s, d) => Operations.FromVector4Destructive(this.Configuration, s, d.GetSpan()) ); } @@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations (s, d) => { Span destPixels = d.GetSpan(); - Operations.FromVector4(this.Configuration, (Span)s, destPixels, PixelConversionModifiers.Scale); + Operations.FromVector4Destructive(this.Configuration, (Span)s, destPixels, PixelConversionModifiers.Scale); }); } @@ -153,7 +153,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.FromVector4( + (s, d) => Operations.FromVector4Destructive( this.Configuration, s, d.GetSpan(), @@ -187,7 +187,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.FromVector4(this.Configuration, s, d.GetSpan(), PixelConversionModifiers.Premultiply) + (s, d) => Operations.FromVector4Destructive(this.Configuration, s, d.GetSpan(), PixelConversionModifiers.Premultiply) ); } @@ -217,7 +217,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.FromVector4( + (s, d) => Operations.FromVector4Destructive( this.Configuration, s, d.GetSpan(), @@ -255,7 +255,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations TestOperation( source, expected, - (s, d) => Operations.FromVector4( + (s, d) => Operations.FromVector4Destructive( this.Configuration, s, d.GetSpan(), diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index ad31319bb..6ca3ed6f9 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests v.W = 1F; } - PixelOperations.Instance.FromVector4(configuration, tempSpan, pixelSpan, PixelConversionModifiers.Scale); + PixelOperations.Instance.FromVector4Destructive(configuration, tempSpan, pixelSpan, PixelConversionModifiers.Scale); } } }); From 408e19645ff80dfbfbb8200377771b419c7e1ba6 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Mon, 1 Apr 2019 02:20:38 +0200 Subject: [PATCH 13/13] pull back the submodule reference with a few revisions --- tests/Images/External | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Images/External b/tests/Images/External index 4387e56e8..9d7198554 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 4387e56e8590ee00607efe29a9babfda041621cb +Subproject commit 9d71985545bb827270ca34af3f78e4c220560ef1