diff --git a/src/ImageSharp/Colors/Color.BulkOperations.cs b/src/ImageSharp/Colors/Color.BulkOperations.cs index e67e29356..2de8222d6 100644 --- a/src/ImageSharp/Colors/Color.BulkOperations.cs +++ b/src/ImageSharp/Colors/Color.BulkOperations.cs @@ -10,9 +10,14 @@ namespace ImageSharp using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - /// - /// Conains the definition of - /// + /// + /// Unpacked pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. + /// The color components are stored in red, green, blue, and alpha order. + /// + /// + /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, + /// as it avoids the need to create new values for modification operations. + /// public partial struct Color { /// @@ -37,15 +42,12 @@ namespace ImageSharp /// https://github.com/dotnet/corefx/issues/15957 /// /// - internal static unsafe void ToVector4SimdAligned( - BufferSpan sourceColors, - BufferSpan destVectors, - int count) + internal static unsafe void ToVector4SimdAligned(BufferSpan sourceColors, BufferSpan destVectors, int count) { if (!Vector.IsHardwareAccelerated) { throw new InvalidOperationException( - "Color.BulkOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); + "Color32.BulkOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); } int vecSize = Vector.Count; @@ -125,10 +127,7 @@ namespace ImageSharp } /// - internal override void PackFromXyzBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal override void PackFromXyzBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { ref RGB24 sourceRef = ref Unsafe.As(ref sourceBytes.DangerousGetPinnableReference()); ref Color destRef = ref destColors.DangerousGetPinnableReference(); @@ -159,10 +158,7 @@ namespace ImageSharp } /// - internal override unsafe void PackFromXyzwBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal override unsafe void PackFromXyzwBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { BufferSpan.Copy(sourceBytes, destColors.AsBytes(), count * sizeof(Color)); } @@ -174,10 +170,7 @@ namespace ImageSharp } /// - internal override void PackFromZyxBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal override void PackFromZyxBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { ref RGB24 sourceRef = ref Unsafe.As(ref sourceBytes.DangerousGetPinnableReference()); ref Color destRef = ref destColors.DangerousGetPinnableReference(); @@ -193,10 +186,7 @@ namespace ImageSharp } /// - internal override void ToZyxBytes( - BufferSpan sourceColors, - BufferSpan destBytes, - int count) + internal override void ToZyxBytes(BufferSpan sourceColors, BufferSpan destBytes, int count) { ref Color sourceRef = ref sourceColors.DangerousGetPinnableReference(); ref RGB24 destRef = ref Unsafe.As(ref destBytes.DangerousGetPinnableReference()); @@ -211,10 +201,7 @@ namespace ImageSharp } /// - internal override void PackFromZyxwBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal override void PackFromZyxwBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { ref RGBA32 sourceRef = ref Unsafe.As(ref sourceBytes.DangerousGetPinnableReference()); ref Color destRef = ref destColors.DangerousGetPinnableReference(); @@ -229,10 +216,7 @@ namespace ImageSharp } /// - internal override void ToZyxwBytes( - BufferSpan sourceColors, - BufferSpan destBytes, - int count) + internal override void ToZyxwBytes(BufferSpan sourceColors, BufferSpan destBytes, int count) { ref Color sourceRef = ref sourceColors.DangerousGetPinnableReference(); ref RGBA32 destRef = ref Unsafe.As(ref destBytes.DangerousGetPinnableReference()); diff --git a/src/ImageSharp/Colors/ColorDefinitions.cs b/src/ImageSharp/Colors/Color.Definitions.cs similarity index 99% rename from src/ImageSharp/Colors/ColorDefinitions.cs rename to src/ImageSharp/Colors/Color.Definitions.cs index 65165289d..4bc0d486a 100644 --- a/src/ImageSharp/Colors/ColorDefinitions.cs +++ b/src/ImageSharp/Colors/Color.Definitions.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // diff --git a/src/ImageSharp/Colors/ColorTransforms.cs b/src/ImageSharp/Colors/Color.Transforms.cs similarity index 92% rename from src/ImageSharp/Colors/ColorTransforms.cs rename to src/ImageSharp/Colors/Color.Transforms.cs index f61afbf5b..31b4aa5be 100644 --- a/src/ImageSharp/Colors/ColorTransforms.cs +++ b/src/ImageSharp/Colors/Color.Transforms.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // @@ -8,7 +8,7 @@ namespace ImageSharp using System.Numerics; /// - /// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 255. + /// Unpacked pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. /// The color components are stored in red, green, blue, and alpha order. /// /// @@ -28,7 +28,7 @@ namespace ImageSharp public static Color operator +(Color left, Color right) { Vector4 add = left.ToVector4() + right.ToVector4(); - return new Color(Pack(ref add)); + return Pack(ref add); } /// @@ -42,7 +42,7 @@ namespace ImageSharp public static Color operator -(Color left, Color right) { Vector4 sub = left.ToVector4() - right.ToVector4(); - return new Color(Pack(ref sub)); + return Pack(ref sub); } /// @@ -56,7 +56,7 @@ namespace ImageSharp public static Color Normal(Color backdrop, Color source) { Vector4 normal = Vector4BlendTransforms.Normal(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref normal)); + return Pack(ref normal); } /// @@ -76,7 +76,7 @@ namespace ImageSharp public static Color Multiply(Color backdrop, Color source) { Vector4 multiply = Vector4BlendTransforms.Multiply(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref multiply)); + return Pack(ref multiply); } /// @@ -95,7 +95,7 @@ namespace ImageSharp public static Color Screen(Color backdrop, Color source) { Vector4 subtract = Vector4BlendTransforms.Screen(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref subtract)); + return Pack(ref subtract); } /// @@ -110,7 +110,7 @@ namespace ImageSharp public static Color HardLight(Color backdrop, Color source) { Vector4 hardlight = Vector4BlendTransforms.HardLight(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref hardlight)); + return Pack(ref hardlight); } /// @@ -129,7 +129,7 @@ namespace ImageSharp public static Color Overlay(Color backdrop, Color source) { Vector4 overlay = Vector4BlendTransforms.Overlay(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref overlay)); + return Pack(ref overlay); } /// @@ -144,7 +144,7 @@ namespace ImageSharp public static Color Darken(Color backdrop, Color source) { Vector4 darken = Vector4BlendTransforms.Darken(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref darken)); + return Pack(ref darken); } /// @@ -159,7 +159,7 @@ namespace ImageSharp public static Color Lighten(Color backdrop, Color source) { Vector4 lighten = Vector4BlendTransforms.Lighten(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref lighten)); + return Pack(ref lighten); } /// @@ -174,7 +174,7 @@ namespace ImageSharp public static Color SoftLight(Color backdrop, Color source) { Vector4 softlight = Vector4BlendTransforms.SoftLight(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref softlight)); + return Pack(ref softlight); } /// @@ -188,7 +188,7 @@ namespace ImageSharp public static Color ColorDodge(Color backdrop, Color source) { Vector4 dodge = Vector4BlendTransforms.Dodge(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref dodge)); + return Pack(ref dodge); } /// @@ -202,7 +202,7 @@ namespace ImageSharp public static Color ColorBurn(Color backdrop, Color source) { Vector4 burn = Vector4BlendTransforms.Burn(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref burn)); + return Pack(ref burn); } /// @@ -217,7 +217,7 @@ namespace ImageSharp public static Color Difference(Color backdrop, Color source) { Vector4 difference = Vector4BlendTransforms.Difference(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref difference)); + return Pack(ref difference); } /// @@ -232,7 +232,7 @@ namespace ImageSharp public static Color Exclusion(Color backdrop, Color source) { Vector4 exclusion = Vector4BlendTransforms.Exclusion(backdrop.ToVector4(), source.ToVector4()); - return new Color(Pack(ref exclusion)); + return Pack(ref exclusion); } /// diff --git a/src/ImageSharp/Colors/Color.cs b/src/ImageSharp/Colors/Color.cs index 1e1e73bab..fb2ce38ac 100644 --- a/src/ImageSharp/Colors/Color.cs +++ b/src/ImageSharp/Colors/Color.cs @@ -5,21 +5,45 @@ namespace ImageSharp { - using System; - using System.Globalization; using System.Numerics; using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; /// - /// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. + /// Unpacked pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. /// The color components are stored in red, green, blue, and alpha order. /// /// /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, /// as it avoids the need to create new values for modification operations. /// - public partial struct Color : IPixel, IPackedVector + [StructLayout(LayoutKind.Explicit)] + public partial struct Color : IPixel { + /// + /// Gets or sets the red component. + /// + [FieldOffset(0)] + public byte R; + + /// + /// Gets or sets the green component. + /// + [FieldOffset(1)] + public byte G; + + /// + /// Gets or sets the blue component. + /// + [FieldOffset(2)] + public byte B; + + /// + /// Gets or sets the alpha component. + /// + [FieldOffset(3)] + public byte A; + /// /// The shift count for the red component /// @@ -50,11 +74,6 @@ namespace ImageSharp /// private static readonly Vector4 Half = new Vector4(0.5F); - /// - /// The packed value. - /// - private uint packedValue; - /// /// Initializes a new instance of the struct. /// @@ -62,10 +81,13 @@ namespace ImageSharp /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] public Color(byte r, byte g, byte b, byte a = 255) + : this() { - this.packedValue = Pack(r, g, b, a); + this.R = r; + this.G = g; + this.B = b; + this.A = a; } /// @@ -75,10 +97,10 @@ namespace ImageSharp /// The green component. /// The blue component. /// The alpha component. - [MethodImpl(MethodImplOptions.AggressiveInlining)] public Color(float r, float g, float b, float a = 1) + : this() { - this.packedValue = Pack(r, g, b, a); + this = Pack(r, g, b, a); } /// @@ -87,10 +109,10 @@ namespace ImageSharp /// /// The vector containing the components for the packed vector. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public Color(Vector3 vector) + : this() { - this.packedValue = Pack(ref vector); + this = Pack(ref vector); } /// @@ -99,108 +121,10 @@ namespace ImageSharp /// /// The vector containing the components for the packed vector. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public Color(Vector4 vector) + : this() { - this.packedValue = Pack(ref vector); - } - - /// - /// Initializes a new instance of the struct. - /// - /// - /// The packed value. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Color(uint packed) - { - this.packedValue = packed; - } - - /// - /// Gets or sets the red component. - /// - public byte R - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return (byte)(this.packedValue >> RedShift); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.packedValue = this.packedValue & 0xFFFFFF00 | (uint)value << RedShift; - } - } - - /// - /// Gets or sets the green component. - /// - public byte G - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return (byte)(this.packedValue >> GreenShift); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.packedValue = this.packedValue & 0xFFFF00FF | (uint)value << GreenShift; - } - } - - /// - /// Gets or sets the blue component. - /// - public byte B - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return (byte)(this.packedValue >> BlueShift); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.packedValue = this.packedValue & 0xFF00FFFF | (uint)value << BlueShift; - } - } - - /// - /// Gets or sets the alpha component. - /// - public byte A - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return (byte)(this.packedValue >> AlphaShift); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.packedValue = this.packedValue & 0x00FFFFFF | (uint)value << AlphaShift; - } - } - - /// - public uint PackedValue - { - get - { - return this.packedValue; - } - - set - { - this.packedValue = value; - } + this = Pack(ref vector); } /// @@ -218,7 +142,10 @@ namespace ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Color left, Color right) { - return left.packedValue == right.packedValue; + return left.R == right.R + && left.G == right.G + && left.B == right.B + && left.A == right.A; } /// @@ -232,7 +159,10 @@ namespace ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Color left, Color right) { - return left.packedValue != right.packedValue; + return left.R != right.R + && left.G != right.G + && left.B != right.B + && left.A != right.A; } /// @@ -251,13 +181,16 @@ namespace ImageSharp } /// - public BulkPixelOperations CreateBulkOperations() => new Color.BulkOperations(); + public BulkPixelOperations CreateBulkOperations() => new BulkOperations(); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromBytes(byte x, byte y, byte z, byte w) { - this.packedValue = Pack(x, y, z, w); + this.R = x; + this.G = y; + this.B = z; + this.A = w; } /// @@ -312,7 +245,7 @@ namespace ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) { - this.packedValue = Pack(ref vector); + this = Pack(ref vector); } /// @@ -332,7 +265,10 @@ namespace ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Color other) { - return this.packedValue == other.packedValue; + return this.R == other.R + && this.G == other.G + && this.B == other.B + && this.A == other.A; } /// @@ -347,33 +283,52 @@ namespace ImageSharp /// public override int GetHashCode() { - return this.packedValue.GetHashCode(); + unchecked + { + int hashCode = this.R.GetHashCode(); + hashCode = (hashCode * 397) ^ this.G.GetHashCode(); + hashCode = (hashCode * 397) ^ this.B.GetHashCode(); + hashCode = (hashCode * 397) ^ this.A.GetHashCode(); + return hashCode; + } + } + + /// + /// Packs the four floats into a . + /// + /// The x-component + /// The y-component + /// The z-component + /// The w-component + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint Pack(byte x, byte y, byte z, byte w) + { + return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift); } /// /// Packs a into a uint. /// /// The vector containing the values to pack. - /// The containing the packed values. + /// The [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(ref Vector4 vector) + private static Color Pack(ref Vector4 vector) { vector *= MaxBytes; vector += Half; vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - return (uint)(((byte)vector.X << RedShift) - | ((byte)vector.Y << GreenShift) - | ((byte)vector.Z << BlueShift) - | (byte)vector.W << AlphaShift); + + return new Color((byte)vector.X, (byte)vector.Y, (byte)vector.Z, (byte)vector.W); } /// /// Packs a into a uint. /// /// The vector containing the values to pack. - /// The containing the packed values. + /// The [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(ref Vector3 vector) + private static Color Pack(ref Vector3 vector) { Vector4 value = new Vector4(vector, 1); return Pack(ref value); @@ -386,26 +341,12 @@ namespace ImageSharp /// The y-component /// The z-component /// The w-component - /// The + /// The [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y, float z, float w) + private static Color Pack(float x, float y, float z, float w) { Vector4 value = new Vector4(x, y, z, w); return Pack(ref value); } - - /// - /// Packs the four floats into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(byte x, byte y, byte z, byte w) - { - return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift); - } } } \ No newline at end of file diff --git a/src/ImageSharp/Colors/ColorVector.BulkOperations.cs b/src/ImageSharp/Colors/ColorVector.BulkOperations.cs new file mode 100644 index 000000000..ab32313c0 --- /dev/null +++ b/src/ImageSharp/Colors/ColorVector.BulkOperations.cs @@ -0,0 +1,27 @@ +namespace ImageSharp +{ + using System.Numerics; + + /// + /// Unpacked pixel type containing four 16-bit unsigned normalized values typically ranging from 0 to 1. + /// The color components are stored in red, green, blue, and alpha order. + /// + /// + /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, + /// as it avoids the need to create new values for modification operations. + /// + public partial struct ColorVector + { + /// + /// implementation optimized for . + /// + internal class BulkOperations : BulkPixelOperations + { + /// + internal override unsafe void ToVector4(BufferSpan sourceColors, BufferSpan destVectors, int count) + { + BufferSpan.Copy(sourceColors.AsBytes(), destVectors.AsBytes(), count * sizeof(Vector4)); + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Colors/ColorVector.Definitions.cs b/src/ImageSharp/Colors/ColorVector.Definitions.cs new file mode 100644 index 000000000..955c0b9db --- /dev/null +++ b/src/ImageSharp/Colors/ColorVector.Definitions.cs @@ -0,0 +1,728 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + /// + /// Unpacked pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. + /// The color components are stored in red, green, blue, and alpha order. + /// + /// + /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, + /// as it avoids the need to create new values for modification operations. + /// + public partial struct ColorVector + { + /// + /// Represents a matching the W3C definition that has an hex value of #F0F8FF. + /// + public static readonly ColorVector AliceBlue = NamedColors.AliceBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #FAEBD7. + /// + public static readonly ColorVector AntiqueWhite = NamedColors.AntiqueWhite; + + /// + /// Represents a matching the W3C definition that has an hex value of #00FFFF. + /// + public static readonly ColorVector Aqua = NamedColors.Aqua; + + /// + /// Represents a matching the W3C definition that has an hex value of #7FFFD4. + /// + public static readonly ColorVector Aquamarine = NamedColors.Aquamarine; + + /// + /// Represents a matching the W3C definition that has an hex value of #F0FFFF. + /// + public static readonly ColorVector Azure = NamedColors.Azure; + + /// + /// Represents a matching the W3C definition that has an hex value of #F5F5DC. + /// + public static readonly ColorVector Beige = NamedColors.Beige; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFE4C4. + /// + public static readonly ColorVector Bisque = NamedColors.Bisque; + + /// + /// Represents a matching the W3C definition that has an hex value of #000000. + /// + public static readonly ColorVector Black = NamedColors.Black; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFEBCD. + /// + public static readonly ColorVector BlanchedAlmond = NamedColors.BlanchedAlmond; + + /// + /// Represents a matching the W3C definition that has an hex value of #0000FF. + /// + public static readonly ColorVector Blue = NamedColors.Blue; + + /// + /// Represents a matching the W3C definition that has an hex value of #8A2BE2. + /// + public static readonly ColorVector BlueViolet = NamedColors.BlueViolet; + + /// + /// Represents a matching the W3C definition that has an hex value of #A52A2A. + /// + public static readonly ColorVector Brown = NamedColors.Brown; + + /// + /// Represents a matching the W3C definition that has an hex value of #DEB887. + /// + public static readonly ColorVector BurlyWood = NamedColors.BurlyWood; + + /// + /// Represents a matching the W3C definition that has an hex value of #5F9EA0. + /// + public static readonly ColorVector CadetBlue = NamedColors.CadetBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #7FFF00. + /// + public static readonly ColorVector Chartreuse = NamedColors.Chartreuse; + + /// + /// Represents a matching the W3C definition that has an hex value of #D2691E. + /// + public static readonly ColorVector Chocolate = NamedColors.Chocolate; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF7F50. + /// + public static readonly ColorVector Coral = NamedColors.Coral; + + /// + /// Represents a matching the W3C definition that has an hex value of #6495ED. + /// + public static readonly ColorVector CornflowerBlue = NamedColors.CornflowerBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFF8DC. + /// + public static readonly ColorVector Cornsilk = NamedColors.Cornsilk; + + /// + /// Represents a matching the W3C definition that has an hex value of #DC143C. + /// + public static readonly ColorVector Crimson = NamedColors.Crimson; + + /// + /// Represents a matching the W3C definition that has an hex value of #00FFFF. + /// + public static readonly ColorVector Cyan = NamedColors.Cyan; + + /// + /// Represents a matching the W3C definition that has an hex value of #00008B. + /// + public static readonly ColorVector DarkBlue = NamedColors.DarkBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #008B8B. + /// + public static readonly ColorVector DarkCyan = NamedColors.DarkCyan; + + /// + /// Represents a matching the W3C definition that has an hex value of #B8860B. + /// + public static readonly ColorVector DarkGoldenrod = NamedColors.DarkGoldenrod; + + /// + /// Represents a matching the W3C definition that has an hex value of #A9A9A9. + /// + public static readonly ColorVector DarkGray = NamedColors.DarkGray; + + /// + /// Represents a matching the W3C definition that has an hex value of #006400. + /// + public static readonly ColorVector DarkGreen = NamedColors.DarkGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #BDB76B. + /// + public static readonly ColorVector DarkKhaki = NamedColors.DarkKhaki; + + /// + /// Represents a matching the W3C definition that has an hex value of #8B008B. + /// + public static readonly ColorVector DarkMagenta = NamedColors.DarkMagenta; + + /// + /// Represents a matching the W3C definition that has an hex value of #556B2F. + /// + public static readonly ColorVector DarkOliveGreen = NamedColors.DarkOliveGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF8C00. + /// + public static readonly ColorVector DarkOrange = NamedColors.DarkOrange; + + /// + /// Represents a matching the W3C definition that has an hex value of #9932CC. + /// + public static readonly ColorVector DarkOrchid = NamedColors.DarkOrchid; + + /// + /// Represents a matching the W3C definition that has an hex value of #8B0000. + /// + public static readonly ColorVector DarkRed = NamedColors.DarkRed; + + /// + /// Represents a matching the W3C definition that has an hex value of #E9967A. + /// + public static readonly ColorVector DarkSalmon = NamedColors.DarkSalmon; + + /// + /// Represents a matching the W3C definition that has an hex value of #8FBC8B. + /// + public static readonly ColorVector DarkSeaGreen = NamedColors.DarkSeaGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #483D8B. + /// + public static readonly ColorVector DarkSlateBlue = NamedColors.DarkSlateBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #2F4F4F. + /// + public static readonly ColorVector DarkSlateGray = NamedColors.DarkSlateGray; + + /// + /// Represents a matching the W3C definition that has an hex value of #00CED1. + /// + public static readonly ColorVector DarkTurquoise = NamedColors.DarkTurquoise; + + /// + /// Represents a matching the W3C definition that has an hex value of #9400D3. + /// + public static readonly ColorVector DarkViolet = NamedColors.DarkViolet; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF1493. + /// + public static readonly ColorVector DeepPink = NamedColors.DeepPink; + + /// + /// Represents a matching the W3C definition that has an hex value of #00BFFF. + /// + public static readonly ColorVector DeepSkyBlue = NamedColors.DeepSkyBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #696969. + /// + public static readonly ColorVector DimGray = NamedColors.DimGray; + + /// + /// Represents a matching the W3C definition that has an hex value of #1E90FF. + /// + public static readonly ColorVector DodgerBlue = NamedColors.DodgerBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #B22222. + /// + public static readonly ColorVector Firebrick = NamedColors.Firebrick; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFAF0. + /// + public static readonly ColorVector FloralWhite = NamedColors.FloralWhite; + + /// + /// Represents a matching the W3C definition that has an hex value of #228B22. + /// + public static readonly ColorVector ForestGreen = NamedColors.ForestGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF00FF. + /// + public static readonly ColorVector Fuchsia = NamedColors.Fuchsia; + + /// + /// Represents a matching the W3C definition that has an hex value of #DCDCDC. + /// + public static readonly ColorVector Gainsboro = NamedColors.Gainsboro; + + /// + /// Represents a matching the W3C definition that has an hex value of #F8F8FF. + /// + public static readonly ColorVector GhostWhite = NamedColors.GhostWhite; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFD700. + /// + public static readonly ColorVector Gold = NamedColors.Gold; + + /// + /// Represents a matching the W3C definition that has an hex value of #DAA520. + /// + public static readonly ColorVector Goldenrod = NamedColors.Goldenrod; + + /// + /// Represents a matching the W3C definition that has an hex value of #808080. + /// + public static readonly ColorVector Gray = NamedColors.Gray; + + /// + /// Represents a matching the W3C definition that has an hex value of #008000. + /// + public static readonly ColorVector Green = NamedColors.Green; + + /// + /// Represents a matching the W3C definition that has an hex value of #ADFF2F. + /// + public static readonly ColorVector GreenYellow = NamedColors.GreenYellow; + + /// + /// Represents a matching the W3C definition that has an hex value of #F0FFF0. + /// + public static readonly ColorVector Honeydew = NamedColors.Honeydew; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF69B4. + /// + public static readonly ColorVector HotPink = NamedColors.HotPink; + + /// + /// Represents a matching the W3C definition that has an hex value of #CD5C5C. + /// + public static readonly ColorVector IndianRed = NamedColors.IndianRed; + + /// + /// Represents a matching the W3C definition that has an hex value of #4B0082. + /// + public static readonly ColorVector Indigo = NamedColors.Indigo; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFFF0. + /// + public static readonly ColorVector Ivory = NamedColors.Ivory; + + /// + /// Represents a matching the W3C definition that has an hex value of #F0E68C. + /// + public static readonly ColorVector Khaki = NamedColors.Khaki; + + /// + /// Represents a matching the W3C definition that has an hex value of #E6E6FA. + /// + public static readonly ColorVector Lavender = NamedColors.Lavender; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFF0F5. + /// + public static readonly ColorVector LavenderBlush = NamedColors.LavenderBlush; + + /// + /// Represents a matching the W3C definition that has an hex value of #7CFC00. + /// + public static readonly ColorVector LawnGreen = NamedColors.LawnGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFACD. + /// + public static readonly ColorVector LemonChiffon = NamedColors.LemonChiffon; + + /// + /// Represents a matching the W3C definition that has an hex value of #ADD8E6. + /// + public static readonly ColorVector LightBlue = NamedColors.LightBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #F08080. + /// + public static readonly ColorVector LightCoral = NamedColors.LightCoral; + + /// + /// Represents a matching the W3C definition that has an hex value of #E0FFFF. + /// + public static readonly ColorVector LightCyan = NamedColors.LightCyan; + + /// + /// Represents a matching the W3C definition that has an hex value of #FAFAD2. + /// + public static readonly ColorVector LightGoldenrodYellow = NamedColors.LightGoldenrodYellow; + + /// + /// Represents a matching the W3C definition that has an hex value of #D3D3D3. + /// + public static readonly ColorVector LightGray = NamedColors.LightGray; + + /// + /// Represents a matching the W3C definition that has an hex value of #90EE90. + /// + public static readonly ColorVector LightGreen = NamedColors.LightGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFB6C1. + /// + public static readonly ColorVector LightPink = NamedColors.LightPink; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFA07A. + /// + public static readonly ColorVector LightSalmon = NamedColors.LightSalmon; + + /// + /// Represents a matching the W3C definition that has an hex value of #20B2AA. + /// + public static readonly ColorVector LightSeaGreen = NamedColors.LightSeaGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #87CEFA. + /// + public static readonly ColorVector LightSkyBlue = NamedColors.LightSkyBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #778899. + /// + public static readonly ColorVector LightSlateGray = NamedColors.LightSlateGray; + + /// + /// Represents a matching the W3C definition that has an hex value of #B0C4DE. + /// + public static readonly ColorVector LightSteelBlue = NamedColors.LightSteelBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFFE0. + /// + public static readonly ColorVector LightYellow = NamedColors.LightYellow; + + /// + /// Represents a matching the W3C definition that has an hex value of #00FF00. + /// + public static readonly ColorVector Lime = NamedColors.Lime; + + /// + /// Represents a matching the W3C definition that has an hex value of #32CD32. + /// + public static readonly ColorVector LimeGreen = NamedColors.LimeGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #FAF0E6. + /// + public static readonly ColorVector Linen = NamedColors.Linen; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF00FF. + /// + public static readonly ColorVector Magenta = NamedColors.Magenta; + + /// + /// Represents a matching the W3C definition that has an hex value of #800000. + /// + public static readonly ColorVector Maroon = NamedColors.Maroon; + + /// + /// Represents a matching the W3C definition that has an hex value of #66CDAA. + /// + public static readonly ColorVector MediumAquamarine = NamedColors.MediumAquamarine; + + /// + /// Represents a matching the W3C definition that has an hex value of #0000CD. + /// + public static readonly ColorVector MediumBlue = NamedColors.MediumBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #BA55D3. + /// + public static readonly ColorVector MediumOrchid = NamedColors.MediumOrchid; + + /// + /// Represents a matching the W3C definition that has an hex value of #9370DB. + /// + public static readonly ColorVector MediumPurple = NamedColors.MediumPurple; + + /// + /// Represents a matching the W3C definition that has an hex value of #3CB371. + /// + public static readonly ColorVector MediumSeaGreen = NamedColors.MediumSeaGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #7B68EE. + /// + public static readonly ColorVector MediumSlateBlue = NamedColors.MediumSlateBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #00FA9A. + /// + public static readonly ColorVector MediumSpringGreen = NamedColors.MediumSpringGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #48D1CC. + /// + public static readonly ColorVector MediumTurquoise = NamedColors.MediumTurquoise; + + /// + /// Represents a matching the W3C definition that has an hex value of #C71585. + /// + public static readonly ColorVector MediumVioletRed = NamedColors.MediumVioletRed; + + /// + /// Represents a matching the W3C definition that has an hex value of #191970. + /// + public static readonly ColorVector MidnightBlue = NamedColors.MidnightBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #F5FFFA. + /// + public static readonly ColorVector MintCream = NamedColors.MintCream; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFE4E1. + /// + public static readonly ColorVector MistyRose = NamedColors.MistyRose; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFE4B5. + /// + public static readonly ColorVector Moccasin = NamedColors.Moccasin; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFDEAD. + /// + public static readonly ColorVector NavajoWhite = NamedColors.NavajoWhite; + + /// + /// Represents a matching the W3C definition that has an hex value of #000080. + /// + public static readonly ColorVector Navy = NamedColors.Navy; + + /// + /// Represents a matching the W3C definition that has an hex value of #FDF5E6. + /// + public static readonly ColorVector OldLace = NamedColors.OldLace; + + /// + /// Represents a matching the W3C definition that has an hex value of #808000. + /// + public static readonly ColorVector Olive = NamedColors.Olive; + + /// + /// Represents a matching the W3C definition that has an hex value of #6B8E23. + /// + public static readonly ColorVector OliveDrab = NamedColors.OliveDrab; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFA500. + /// + public static readonly ColorVector Orange = NamedColors.Orange; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF4500. + /// + public static readonly ColorVector OrangeRed = NamedColors.OrangeRed; + + /// + /// Represents a matching the W3C definition that has an hex value of #DA70D6. + /// + public static readonly ColorVector Orchid = NamedColors.Orchid; + + /// + /// Represents a matching the W3C definition that has an hex value of #EEE8AA. + /// + public static readonly ColorVector PaleGoldenrod = NamedColors.PaleGoldenrod; + + /// + /// Represents a matching the W3C definition that has an hex value of #98FB98. + /// + public static readonly ColorVector PaleGreen = NamedColors.PaleGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #AFEEEE. + /// + public static readonly ColorVector PaleTurquoise = NamedColors.PaleTurquoise; + + /// + /// Represents a matching the W3C definition that has an hex value of #DB7093. + /// + public static readonly ColorVector PaleVioletRed = NamedColors.PaleVioletRed; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFEFD5. + /// + public static readonly ColorVector PapayaWhip = NamedColors.PapayaWhip; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFDAB9. + /// + public static readonly ColorVector PeachPuff = NamedColors.PeachPuff; + + /// + /// Represents a matching the W3C definition that has an hex value of #CD853F. + /// + public static readonly ColorVector Peru = NamedColors.Peru; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFC0CB. + /// + public static readonly ColorVector Pink = NamedColors.Pink; + + /// + /// Represents a matching the W3C definition that has an hex value of #DDA0DD. + /// + public static readonly ColorVector Plum = NamedColors.Plum; + + /// + /// Represents a matching the W3C definition that has an hex value of #B0E0E6. + /// + public static readonly ColorVector PowderBlue = NamedColors.PowderBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #800080. + /// + public static readonly ColorVector Purple = NamedColors.Purple; + + /// + /// Represents a matching the W3C definition that has an hex value of #663399. + /// + public static readonly ColorVector RebeccaPurple = NamedColors.RebeccaPurple; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF0000. + /// + public static readonly ColorVector Red = NamedColors.Red; + + /// + /// Represents a matching the W3C definition that has an hex value of #BC8F8F. + /// + public static readonly ColorVector RosyBrown = NamedColors.RosyBrown; + + /// + /// Represents a matching the W3C definition that has an hex value of #4169E1. + /// + public static readonly ColorVector RoyalBlue = NamedColors.RoyalBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #8B4513. + /// + public static readonly ColorVector SaddleBrown = NamedColors.SaddleBrown; + + /// + /// Represents a matching the W3C definition that has an hex value of #FA8072. + /// + public static readonly ColorVector Salmon = NamedColors.Salmon; + + /// + /// Represents a matching the W3C definition that has an hex value of #F4A460. + /// + public static readonly ColorVector SandyBrown = NamedColors.SandyBrown; + + /// + /// Represents a matching the W3C definition that has an hex value of #2E8B57. + /// + public static readonly ColorVector SeaGreen = NamedColors.SeaGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFF5EE. + /// + public static readonly ColorVector SeaShell = NamedColors.SeaShell; + + /// + /// Represents a matching the W3C definition that has an hex value of #A0522D. + /// + public static readonly ColorVector Sienna = NamedColors.Sienna; + + /// + /// Represents a matching the W3C definition that has an hex value of #C0C0C0. + /// + public static readonly ColorVector Silver = NamedColors.Silver; + + /// + /// Represents a matching the W3C definition that has an hex value of #87CEEB. + /// + public static readonly ColorVector SkyBlue = NamedColors.SkyBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #6A5ACD. + /// + public static readonly ColorVector SlateBlue = NamedColors.SlateBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #708090. + /// + public static readonly ColorVector SlateGray = NamedColors.SlateGray; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFAFA. + /// + public static readonly ColorVector Snow = NamedColors.Snow; + + /// + /// Represents a matching the W3C definition that has an hex value of #00FF7F. + /// + public static readonly ColorVector SpringGreen = NamedColors.SpringGreen; + + /// + /// Represents a matching the W3C definition that has an hex value of #4682B4. + /// + public static readonly ColorVector SteelBlue = NamedColors.SteelBlue; + + /// + /// Represents a matching the W3C definition that has an hex value of #D2B48C. + /// + public static readonly ColorVector Tan = NamedColors.Tan; + + /// + /// Represents a matching the W3C definition that has an hex value of #008080. + /// + public static readonly ColorVector Teal = NamedColors.Teal; + + /// + /// Represents a matching the W3C definition that has an hex value of #D8BFD8. + /// + public static readonly ColorVector Thistle = NamedColors.Thistle; + + /// + /// Represents a matching the W3C definition that has an hex value of #FF6347. + /// + public static readonly ColorVector Tomato = NamedColors.Tomato; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFFFF. + /// + public static readonly ColorVector Transparent = NamedColors.Transparent; + + /// + /// Represents a matching the W3C definition that has an hex value of #40E0D0. + /// + public static readonly ColorVector Turquoise = NamedColors.Turquoise; + + /// + /// Represents a matching the W3C definition that has an hex value of #EE82EE. + /// + public static readonly ColorVector Violet = NamedColors.Violet; + + /// + /// Represents a matching the W3C definition that has an hex value of #F5DEB3. + /// + public static readonly ColorVector Wheat = NamedColors.Wheat; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFFFF. + /// + public static readonly ColorVector White = NamedColors.White; + + /// + /// Represents a matching the W3C definition that has an hex value of #F5F5F5. + /// + public static readonly ColorVector WhiteSmoke = NamedColors.WhiteSmoke; + + /// + /// Represents a matching the W3C definition that has an hex value of #FFFF00. + /// + public static readonly ColorVector Yellow = NamedColors.Yellow; + + /// + /// Represents a matching the W3C definition that has an hex value of #9ACD32. + /// + public static readonly ColorVector YellowGreen = NamedColors.YellowGreen; + } +} \ No newline at end of file diff --git a/src/ImageSharp/Colors/ColorVector.Transforms.cs b/src/ImageSharp/Colors/ColorVector.Transforms.cs new file mode 100644 index 000000000..e9666a351 --- /dev/null +++ b/src/ImageSharp/Colors/ColorVector.Transforms.cs @@ -0,0 +1,253 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System.Numerics; + + /// + /// Unpacked pixel type containing four 16-bit unsigned normalized values typically ranging from 0 to 1. + /// The color components are stored in red, green, blue, and alpha order. + /// + /// + /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, + /// as it avoids the need to create new values for modification operations. + /// + public partial struct ColorVector + { + /// + /// Adds the second color to the first. + /// + /// The first source color. + /// The second source color. + /// + /// The . + /// + public static ColorVector operator +(ColorVector left, ColorVector right) + { + return new ColorVector(left.backingVector + right.backingVector); + } + + /// + /// Subtracts the second color from the first. + /// + /// The first source color. + /// The second source color. + /// + /// The . + /// + public static ColorVector operator -(ColorVector left, ColorVector right) + { + return new ColorVector(left.backingVector - right.backingVector); + } + + /// + /// The blending formula simply selects the source color. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Normal(ColorVector backdrop, ColorVector source) + { + Vector4 normal = Vector4BlendTransforms.Normal(backdrop.backingVector, source.backingVector); + return new ColorVector(normal); + } + + /// + /// Blends two colors by multiplication. + /// + /// The source color is multiplied by the destination color and replaces the destination. + /// The resultant color is always at least as dark as either the source or destination color. + /// Multiplying any color with black results in black. Multiplying any color with white preserves the + /// original color. + /// + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Multiply(ColorVector backdrop, ColorVector source) + { + Vector4 multiply = Vector4BlendTransforms.Multiply(backdrop.backingVector, source.backingVector); + return new ColorVector(multiply); + } + + /// + /// Multiplies the complements of the backdrop and source color values, then complements the result. + /// + /// The result color is always at least as light as either of the two constituent colors. Screening any + /// color with white produces white; screening with black leaves the original color unchanged. + /// The effect is similar to projecting multiple photographic slides simultaneously onto a single screen. + /// + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Screen(ColorVector backdrop, ColorVector source) + { + Vector4 subtract = Vector4BlendTransforms.Screen(backdrop.backingVector, source.backingVector); + return new ColorVector(subtract); + } + + /// + /// Multiplies or screens the colors, depending on the source color value. The effect is similar to + /// shining a harsh spotlight on the backdrop. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector HardLight(ColorVector backdrop, ColorVector source) + { + Vector4 hardlight = Vector4BlendTransforms.HardLight(backdrop.backingVector, source.backingVector); + return new ColorVector(hardlight); + } + + /// + /// Multiplies or screens the colors, depending on the backdrop color value. + /// + /// Source colors overlay the backdrop while preserving its highlights and shadows. + /// The backdrop color is not replaced but is mixed with the source color to reflect the lightness or darkness + /// of the backdrop. + /// + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Overlay(ColorVector backdrop, ColorVector source) + { + Vector4 overlay = Vector4BlendTransforms.Overlay(backdrop.backingVector, source.backingVector); + return new ColorVector(overlay); + } + + /// + /// Selects the darker of the backdrop and source colors. + /// The backdrop is replaced with the source where the source is darker; otherwise, it is left unchanged. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Darken(ColorVector backdrop, ColorVector source) + { + Vector4 darken = Vector4BlendTransforms.Darken(backdrop.backingVector, source.backingVector); + return new ColorVector(darken); + } + + /// + /// Selects the lighter of the backdrop and source colors. + /// The backdrop is replaced with the source where the source is lighter; otherwise, it is left unchanged. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Lighten(ColorVector backdrop, ColorVector source) + { + Vector4 lighten = Vector4BlendTransforms.Lighten(backdrop.backingVector, source.backingVector); + return new ColorVector(lighten); + } + + /// + /// Darkens or lightens the colors, depending on the source color value. The effect is similar to shining + /// a diffused spotlight on the backdrop. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector SoftLight(ColorVector backdrop, ColorVector source) + { + Vector4 softlight = Vector4BlendTransforms.SoftLight(backdrop.backingVector, source.backingVector); + return new ColorVector(softlight); + } + + /// + /// Brightens the backdrop color to reflect the source color. Painting with black produces no changes. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector ColorDodge(ColorVector backdrop, ColorVector source) + { + Vector4 dodge = Vector4BlendTransforms.Dodge(backdrop.backingVector, source.backingVector); + return new ColorVector(dodge); + } + + /// + /// Darkens the backdrop color to reflect the source color. Painting with white produces no change. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector ColorBurn(ColorVector backdrop, ColorVector source) + { + Vector4 burn = Vector4BlendTransforms.Burn(backdrop.backingVector, source.backingVector); + return new ColorVector(burn); + } + + /// + /// Subtracts the darker of the two constituent colors from the lighter color. + /// Painting with white inverts the backdrop color; painting with black produces no change. + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Difference(ColorVector backdrop, ColorVector source) + { + Vector4 difference = Vector4BlendTransforms.Difference(backdrop.backingVector, source.backingVector); + return new ColorVector(difference); + } + + /// + /// Produces an effect similar to that of the mode but lower in contrast. Painting with white + /// inverts the backdrop color; painting with black produces no change + /// + /// The backdrop color. + /// The source color. + /// + /// The . + /// + public static ColorVector Exclusion(ColorVector backdrop, ColorVector source) + { + Vector4 exclusion = Vector4BlendTransforms.Exclusion(backdrop.backingVector, source.backingVector); + return new ColorVector(exclusion); + } + + /// + /// Linearly interpolates from one color to another based on the given weighting. + /// + /// The first color value. + /// The second color value. + /// + /// A value between 0 and 1 indicating the weight of the second source vector. + /// At amount = 0, "from" is returned, at amount = 1, "to" is returned. + /// + /// + /// The + /// + public static ColorVector Lerp(ColorVector from, ColorVector to, float amount) + { + return new ColorVector(Vector4.Lerp(from.backingVector, to.backingVector, amount)); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Colors/ColorVector.cs b/src/ImageSharp/Colors/ColorVector.cs new file mode 100644 index 000000000..354553982 --- /dev/null +++ b/src/ImageSharp/Colors/ColorVector.cs @@ -0,0 +1,316 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System.Numerics; + using System.Runtime.CompilerServices; + + /// + /// Unpacked pixel type containing four 16-bit unsigned normalized values typically ranging from 0 to 1. + /// The color components are stored in red, green, blue, and alpha order. + /// + /// + /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, + /// as it avoids the need to create new values for modification operations. + /// + public partial struct ColorVector : IPixel + { + /// + /// The maximum byte value. + /// + private static readonly Vector4 MaxBytes = new Vector4(255); + + /// + /// The half vector value. + /// + private static readonly Vector4 Half = new Vector4(0.5F); + + /// + /// The backing vector for SIMD support. + /// + private Vector4 backingVector; + + /// + /// Initializes a new instance of the struct. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The alpha component. + public ColorVector(byte r, byte g, byte b, byte a = 255) + : this() + { + this.backingVector = new Vector4(r, g, b, a) / MaxBytes; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The alpha component. + public ColorVector(float r, float g, float b, float a = 1) + : this() + { + this.backingVector = new Vector4(r, g, b, a); + } + + /// + /// Initializes a new instance of the struct. + /// + /// + /// The vector containing the components for the packed vector. + /// + public ColorVector(Vector3 vector) + : this() + { + this.backingVector = new Vector4(vector, 1); + } + + /// + /// Initializes a new instance of the struct. + /// + /// + /// The vector containing the components for the packed vector. + /// + public ColorVector(Vector4 vector) + : this() + { + this.backingVector = vector; + } + + /// + /// Gets or sets the red component. + /// + public float R + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return this.backingVector.X; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.backingVector.X = value; + } + } + + /// + /// Gets or sets the green component. + /// + public float G + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return this.backingVector.Y; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.backingVector.Y = value; + } + } + + /// + /// Gets or sets the blue component. + /// + public float B + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return this.backingVector.Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.backingVector.Z = value; + } + } + + /// + /// Gets or sets the alpha component. + /// + public float A + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return this.backingVector.W; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.backingVector.W = value; + } + } + + /// + /// Compares two objects for equality. + /// + /// + /// The on the left side of the operand. + /// + /// + /// The on the right side of the operand. + /// + /// + /// True if the parameter is equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(ColorVector left, ColorVector right) + { + return left.backingVector == right.backingVector; + } + + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is not equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(ColorVector left, ColorVector right) + { + return left.backingVector != right.backingVector; + } + + /// + /// Creates a new instance of the struct. + /// + /// + /// The hexadecimal representation of the combined color components arranged + /// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax. + /// + /// + /// The . + /// + public static ColorVector FromHex(string hex) + { + return ColorBuilder.FromHex(hex); + } + + /// + public BulkPixelOperations CreateBulkOperations() => new ColorVector.BulkOperations(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBytes(byte x, byte y, byte z, byte w) + { + this.backingVector = new Vector4(x, y, z, w) / MaxBytes; + } + + /// + /// Converts the value of this instance to a hexadecimal string. + /// + /// A hexadecimal string representation of the value. + public string ToHex() + { + // Hex is RRGGBBAA + Vector4 vector = this.backingVector * MaxBytes; + vector += Half; + uint hexOrder = (uint)((byte)vector.W | (byte)vector.Z << 8 | (byte)vector.Y << 16 | (byte)vector.X << 24); + return hexOrder.ToString("X8"); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToXyzBytes(byte[] bytes, int startIndex) + { + Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes; + vector += Half; + bytes[startIndex] = (byte)vector.X; + bytes[startIndex + 1] = (byte)vector.Y; + bytes[startIndex + 2] = (byte)vector.Z; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToXyzwBytes(byte[] bytes, int startIndex) + { + Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes; + vector += Half; + bytes[startIndex] = (byte)vector.X; + bytes[startIndex + 1] = (byte)vector.Y; + bytes[startIndex + 2] = (byte)vector.Z; + bytes[startIndex + 3] = (byte)vector.W; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToZyxBytes(byte[] bytes, int startIndex) + { + Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes; + vector += Half; + bytes[startIndex] = (byte)vector.Z; + bytes[startIndex + 1] = (byte)vector.Y; + bytes[startIndex + 2] = (byte)vector.X; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToZyxwBytes(byte[] bytes, int startIndex) + { + Vector4 vector = Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One) * MaxBytes; + vector += Half; + bytes[startIndex] = (byte)vector.Z; + bytes[startIndex + 1] = (byte)vector.Y; + bytes[startIndex + 2] = (byte)vector.X; + bytes[startIndex + 3] = (byte)vector.W; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromVector4(Vector4 vector) + { + this.backingVector = vector; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return this.backingVector; + } + + /// + public override bool Equals(object obj) + { + return (obj is ColorVector) && this.Equals((ColorVector)obj); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(ColorVector other) + { + return this.backingVector == other.backingVector; + } + + /// + /// Gets a string representation of the packed vector. + /// + /// A string representation of the packed vector. + public override string ToString() + { + return this.ToVector4().ToString(); + } + + /// + public override int GetHashCode() + { + return this.backingVector.GetHashCode(); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Colors/ColorspaceTransforms.cs b/src/ImageSharp/Colors/ColorspaceTransforms.cs index 74f5cb717..cbf40724e 100644 --- a/src/ImageSharp/Colors/ColorspaceTransforms.cs +++ b/src/ImageSharp/Colors/ColorspaceTransforms.cs @@ -10,7 +10,7 @@ namespace ImageSharp using Colors.Spaces; /// - /// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 255. + /// Unpacked pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. /// The color components are stored in red, green, blue, and alpha order. /// /// diff --git a/src/ImageSharp/Colors/NamedColors{TColor}.cs b/src/ImageSharp/Colors/NamedColors{TColor}.cs index bcad4dd40..f8080195d 100644 --- a/src/ImageSharp/Colors/NamedColors{TColor}.cs +++ b/src/ImageSharp/Colors/NamedColors{TColor}.cs @@ -8,719 +8,719 @@ namespace ImageSharp using System; /// - /// A set of named colors mapped to the provided Color space. + /// A set of named colors mapped to the provided color space. /// /// The type of the color. public static class NamedColors where TColor : struct, IPixel { /// - /// Represents a matching the W3C definition that has an hex value of #F0F8FF. + /// Represents a matching the W3C definition that has an hex value of #F0F8FF. /// public static readonly TColor AliceBlue = ColorBuilder.FromRGBA(240, 248, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FAEBD7. + /// Represents a matching the W3C definition that has an hex value of #FAEBD7. /// public static readonly TColor AntiqueWhite = ColorBuilder.FromRGBA(250, 235, 215, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00FFFF. + /// Represents a matching the W3C definition that has an hex value of #00FFFF. /// public static readonly TColor Aqua = ColorBuilder.FromRGBA(0, 255, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #7FFFD4. + /// Represents a matching the W3C definition that has an hex value of #7FFFD4. /// public static readonly TColor Aquamarine = ColorBuilder.FromRGBA(127, 255, 212, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F0FFFF. + /// Represents a matching the W3C definition that has an hex value of #F0FFFF. /// public static readonly TColor Azure = ColorBuilder.FromRGBA(240, 255, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F5F5DC. + /// Represents a matching the W3C definition that has an hex value of #F5F5DC. /// public static readonly TColor Beige = ColorBuilder.FromRGBA(245, 245, 220, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFE4C4. + /// Represents a matching the W3C definition that has an hex value of #FFE4C4. /// public static readonly TColor Bisque = ColorBuilder.FromRGBA(255, 228, 196, 255); /// - /// Represents a matching the W3C definition that has an hex value of #000000. + /// Represents a matching the W3C definition that has an hex value of #000000. /// public static readonly TColor Black = ColorBuilder.FromRGBA(0, 0, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFEBCD. + /// Represents a matching the W3C definition that has an hex value of #FFEBCD. /// public static readonly TColor BlanchedAlmond = ColorBuilder.FromRGBA(255, 235, 205, 255); /// - /// Represents a matching the W3C definition that has an hex value of #0000FF. + /// Represents a matching the W3C definition that has an hex value of #0000FF. /// public static readonly TColor Blue = ColorBuilder.FromRGBA(0, 0, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #8A2BE2. + /// Represents a matching the W3C definition that has an hex value of #8A2BE2. /// public static readonly TColor BlueViolet = ColorBuilder.FromRGBA(138, 43, 226, 255); /// - /// Represents a matching the W3C definition that has an hex value of #A52A2A. + /// Represents a matching the W3C definition that has an hex value of #A52A2A. /// public static readonly TColor Brown = ColorBuilder.FromRGBA(165, 42, 42, 255); /// - /// Represents a matching the W3C definition that has an hex value of #DEB887. + /// Represents a matching the W3C definition that has an hex value of #DEB887. /// public static readonly TColor BurlyWood = ColorBuilder.FromRGBA(222, 184, 135, 255); /// - /// Represents a matching the W3C definition that has an hex value of #5F9EA0. + /// Represents a matching the W3C definition that has an hex value of #5F9EA0. /// public static readonly TColor CadetBlue = ColorBuilder.FromRGBA(95, 158, 160, 255); /// - /// Represents a matching the W3C definition that has an hex value of #7FFF00. + /// Represents a matching the W3C definition that has an hex value of #7FFF00. /// public static readonly TColor Chartreuse = ColorBuilder.FromRGBA(127, 255, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #D2691E. + /// Represents a matching the W3C definition that has an hex value of #D2691E. /// public static readonly TColor Chocolate = ColorBuilder.FromRGBA(210, 105, 30, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF7F50. + /// Represents a matching the W3C definition that has an hex value of #FF7F50. /// public static readonly TColor Coral = ColorBuilder.FromRGBA(255, 127, 80, 255); /// - /// Represents a matching the W3C definition that has an hex value of #6495ED. + /// Represents a matching the W3C definition that has an hex value of #6495ED. /// public static readonly TColor CornflowerBlue = ColorBuilder.FromRGBA(100, 149, 237, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFF8DC. + /// Represents a matching the W3C definition that has an hex value of #FFF8DC. /// public static readonly TColor Cornsilk = ColorBuilder.FromRGBA(255, 248, 220, 255); /// - /// Represents a matching the W3C definition that has an hex value of #DC143C. + /// Represents a matching the W3C definition that has an hex value of #DC143C. /// public static readonly TColor Crimson = ColorBuilder.FromRGBA(220, 20, 60, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00FFFF. + /// Represents a matching the W3C definition that has an hex value of #00FFFF. /// public static readonly TColor Cyan = ColorBuilder.FromRGBA(0, 255, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00008B. + /// Represents a matching the W3C definition that has an hex value of #00008B. /// public static readonly TColor DarkBlue = ColorBuilder.FromRGBA(0, 0, 139, 255); /// - /// Represents a matching the W3C definition that has an hex value of #008B8B. + /// Represents a matching the W3C definition that has an hex value of #008B8B. /// public static readonly TColor DarkCyan = ColorBuilder.FromRGBA(0, 139, 139, 255); /// - /// Represents a matching the W3C definition that has an hex value of #B8860B. + /// Represents a matching the W3C definition that has an hex value of #B8860B. /// public static readonly TColor DarkGoldenrod = ColorBuilder.FromRGBA(184, 134, 11, 255); /// - /// Represents a matching the W3C definition that has an hex value of #A9A9A9. + /// Represents a matching the W3C definition that has an hex value of #A9A9A9. /// public static readonly TColor DarkGray = ColorBuilder.FromRGBA(169, 169, 169, 255); /// - /// Represents a matching the W3C definition that has an hex value of #006400. + /// Represents a matching the W3C definition that has an hex value of #006400. /// public static readonly TColor DarkGreen = ColorBuilder.FromRGBA(0, 100, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #BDB76B. + /// Represents a matching the W3C definition that has an hex value of #BDB76B. /// public static readonly TColor DarkKhaki = ColorBuilder.FromRGBA(189, 183, 107, 255); /// - /// Represents a matching the W3C definition that has an hex value of #8B008B. + /// Represents a matching the W3C definition that has an hex value of #8B008B. /// public static readonly TColor DarkMagenta = ColorBuilder.FromRGBA(139, 0, 139, 255); /// - /// Represents a matching the W3C definition that has an hex value of #556B2F. + /// Represents a matching the W3C definition that has an hex value of #556B2F. /// public static readonly TColor DarkOliveGreen = ColorBuilder.FromRGBA(85, 107, 47, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF8C00. + /// Represents a matching the W3C definition that has an hex value of #FF8C00. /// public static readonly TColor DarkOrange = ColorBuilder.FromRGBA(255, 140, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #9932CC. + /// Represents a matching the W3C definition that has an hex value of #9932CC. /// public static readonly TColor DarkOrchid = ColorBuilder.FromRGBA(153, 50, 204, 255); /// - /// Represents a matching the W3C definition that has an hex value of #8B0000. + /// Represents a matching the W3C definition that has an hex value of #8B0000. /// public static readonly TColor DarkRed = ColorBuilder.FromRGBA(139, 0, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #E9967A. + /// Represents a matching the W3C definition that has an hex value of #E9967A. /// public static readonly TColor DarkSalmon = ColorBuilder.FromRGBA(233, 150, 122, 255); /// - /// Represents a matching the W3C definition that has an hex value of #8FBC8B. + /// Represents a matching the W3C definition that has an hex value of #8FBC8B. /// public static readonly TColor DarkSeaGreen = ColorBuilder.FromRGBA(143, 188, 139, 255); /// - /// Represents a matching the W3C definition that has an hex value of #483D8B. + /// Represents a matching the W3C definition that has an hex value of #483D8B. /// public static readonly TColor DarkSlateBlue = ColorBuilder.FromRGBA(72, 61, 139, 255); /// - /// Represents a matching the W3C definition that has an hex value of #2F4F4F. + /// Represents a matching the W3C definition that has an hex value of #2F4F4F. /// public static readonly TColor DarkSlateGray = ColorBuilder.FromRGBA(47, 79, 79, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00CED1. + /// Represents a matching the W3C definition that has an hex value of #00CED1. /// public static readonly TColor DarkTurquoise = ColorBuilder.FromRGBA(0, 206, 209, 255); /// - /// Represents a matching the W3C definition that has an hex value of #9400D3. + /// Represents a matching the W3C definition that has an hex value of #9400D3. /// public static readonly TColor DarkViolet = ColorBuilder.FromRGBA(148, 0, 211, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF1493. + /// Represents a matching the W3C definition that has an hex value of #FF1493. /// public static readonly TColor DeepPink = ColorBuilder.FromRGBA(255, 20, 147, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00BFFF. + /// Represents a matching the W3C definition that has an hex value of #00BFFF. /// public static readonly TColor DeepSkyBlue = ColorBuilder.FromRGBA(0, 191, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #696969. + /// Represents a matching the W3C definition that has an hex value of #696969. /// public static readonly TColor DimGray = ColorBuilder.FromRGBA(105, 105, 105, 255); /// - /// Represents a matching the W3C definition that has an hex value of #1E90FF. + /// Represents a matching the W3C definition that has an hex value of #1E90FF. /// public static readonly TColor DodgerBlue = ColorBuilder.FromRGBA(30, 144, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #B22222. + /// Represents a matching the W3C definition that has an hex value of #B22222. /// public static readonly TColor Firebrick = ColorBuilder.FromRGBA(178, 34, 34, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFAF0. + /// Represents a matching the W3C definition that has an hex value of #FFFAF0. /// public static readonly TColor FloralWhite = ColorBuilder.FromRGBA(255, 250, 240, 255); /// - /// Represents a matching the W3C definition that has an hex value of #228B22. + /// Represents a matching the W3C definition that has an hex value of #228B22. /// public static readonly TColor ForestGreen = ColorBuilder.FromRGBA(34, 139, 34, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF00FF. + /// Represents a matching the W3C definition that has an hex value of #FF00FF. /// public static readonly TColor Fuchsia = ColorBuilder.FromRGBA(255, 0, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #DCDCDC. + /// Represents a matching the W3C definition that has an hex value of #DCDCDC. /// public static readonly TColor Gainsboro = ColorBuilder.FromRGBA(220, 220, 220, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F8F8FF. + /// Represents a matching the W3C definition that has an hex value of #F8F8FF. /// public static readonly TColor GhostWhite = ColorBuilder.FromRGBA(248, 248, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFD700. + /// Represents a matching the W3C definition that has an hex value of #FFD700. /// public static readonly TColor Gold = ColorBuilder.FromRGBA(255, 215, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #DAA520. + /// Represents a matching the W3C definition that has an hex value of #DAA520. /// public static readonly TColor Goldenrod = ColorBuilder.FromRGBA(218, 165, 32, 255); /// - /// Represents a matching the W3C definition that has an hex value of #808080. + /// Represents a matching the W3C definition that has an hex value of #808080. /// public static readonly TColor Gray = ColorBuilder.FromRGBA(128, 128, 128, 255); /// - /// Represents a matching the W3C definition that has an hex value of #008000. + /// Represents a matching the W3C definition that has an hex value of #008000. /// public static readonly TColor Green = ColorBuilder.FromRGBA(0, 128, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #ADFF2F. + /// Represents a matching the W3C definition that has an hex value of #ADFF2F. /// public static readonly TColor GreenYellow = ColorBuilder.FromRGBA(173, 255, 47, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F0FFF0. + /// Represents a matching the W3C definition that has an hex value of #F0FFF0. /// public static readonly TColor Honeydew = ColorBuilder.FromRGBA(240, 255, 240, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF69B4. + /// Represents a matching the W3C definition that has an hex value of #FF69B4. /// public static readonly TColor HotPink = ColorBuilder.FromRGBA(255, 105, 180, 255); /// - /// Represents a matching the W3C definition that has an hex value of #CD5C5C. + /// Represents a matching the W3C definition that has an hex value of #CD5C5C. /// public static readonly TColor IndianRed = ColorBuilder.FromRGBA(205, 92, 92, 255); /// - /// Represents a matching the W3C definition that has an hex value of #4B0082. + /// Represents a matching the W3C definition that has an hex value of #4B0082. /// public static readonly TColor Indigo = ColorBuilder.FromRGBA(75, 0, 130, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFFF0. + /// Represents a matching the W3C definition that has an hex value of #FFFFF0. /// public static readonly TColor Ivory = ColorBuilder.FromRGBA(255, 255, 240, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F0E68C. + /// Represents a matching the W3C definition that has an hex value of #F0E68C. /// public static readonly TColor Khaki = ColorBuilder.FromRGBA(240, 230, 140, 255); /// - /// Represents a matching the W3C definition that has an hex value of #E6E6FA. + /// Represents a matching the W3C definition that has an hex value of #E6E6FA. /// public static readonly TColor Lavender = ColorBuilder.FromRGBA(230, 230, 250, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFF0F5. + /// Represents a matching the W3C definition that has an hex value of #FFF0F5. /// public static readonly TColor LavenderBlush = ColorBuilder.FromRGBA(255, 240, 245, 255); /// - /// Represents a matching the W3C definition that has an hex value of #7CFC00. + /// Represents a matching the W3C definition that has an hex value of #7CFC00. /// public static readonly TColor LawnGreen = ColorBuilder.FromRGBA(124, 252, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFACD. + /// Represents a matching the W3C definition that has an hex value of #FFFACD. /// public static readonly TColor LemonChiffon = ColorBuilder.FromRGBA(255, 250, 205, 255); /// - /// Represents a matching the W3C definition that has an hex value of #ADD8E6. + /// Represents a matching the W3C definition that has an hex value of #ADD8E6. /// public static readonly TColor LightBlue = ColorBuilder.FromRGBA(173, 216, 230, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F08080. + /// Represents a matching the W3C definition that has an hex value of #F08080. /// public static readonly TColor LightCoral = ColorBuilder.FromRGBA(240, 128, 128, 255); /// - /// Represents a matching the W3C definition that has an hex value of #E0FFFF. + /// Represents a matching the W3C definition that has an hex value of #E0FFFF. /// public static readonly TColor LightCyan = ColorBuilder.FromRGBA(224, 255, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FAFAD2. + /// Represents a matching the W3C definition that has an hex value of #FAFAD2. /// public static readonly TColor LightGoldenrodYellow = ColorBuilder.FromRGBA(250, 250, 210, 255); /// - /// Represents a matching the W3C definition that has an hex value of #D3D3D3. + /// Represents a matching the W3C definition that has an hex value of #D3D3D3. /// public static readonly TColor LightGray = ColorBuilder.FromRGBA(211, 211, 211, 255); /// - /// Represents a matching the W3C definition that has an hex value of #90EE90. + /// Represents a matching the W3C definition that has an hex value of #90EE90. /// public static readonly TColor LightGreen = ColorBuilder.FromRGBA(144, 238, 144, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFB6C1. + /// Represents a matching the W3C definition that has an hex value of #FFB6C1. /// public static readonly TColor LightPink = ColorBuilder.FromRGBA(255, 182, 193, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFA07A. + /// Represents a matching the W3C definition that has an hex value of #FFA07A. /// public static readonly TColor LightSalmon = ColorBuilder.FromRGBA(255, 160, 122, 255); /// - /// Represents a matching the W3C definition that has an hex value of #20B2AA. + /// Represents a matching the W3C definition that has an hex value of #20B2AA. /// public static readonly TColor LightSeaGreen = ColorBuilder.FromRGBA(32, 178, 170, 255); /// - /// Represents a matching the W3C definition that has an hex value of #87CEFA. + /// Represents a matching the W3C definition that has an hex value of #87CEFA. /// public static readonly TColor LightSkyBlue = ColorBuilder.FromRGBA(135, 206, 250, 255); /// - /// Represents a matching the W3C definition that has an hex value of #778899. + /// Represents a matching the W3C definition that has an hex value of #778899. /// public static readonly TColor LightSlateGray = ColorBuilder.FromRGBA(119, 136, 153, 255); /// - /// Represents a matching the W3C definition that has an hex value of #B0C4DE. + /// Represents a matching the W3C definition that has an hex value of #B0C4DE. /// public static readonly TColor LightSteelBlue = ColorBuilder.FromRGBA(176, 196, 222, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFFE0. + /// Represents a matching the W3C definition that has an hex value of #FFFFE0. /// public static readonly TColor LightYellow = ColorBuilder.FromRGBA(255, 255, 224, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00FF00. + /// Represents a matching the W3C definition that has an hex value of #00FF00. /// public static readonly TColor Lime = ColorBuilder.FromRGBA(0, 255, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #32CD32. + /// Represents a matching the W3C definition that has an hex value of #32CD32. /// public static readonly TColor LimeGreen = ColorBuilder.FromRGBA(50, 205, 50, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FAF0E6. + /// Represents a matching the W3C definition that has an hex value of #FAF0E6. /// public static readonly TColor Linen = ColorBuilder.FromRGBA(250, 240, 230, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF00FF. + /// Represents a matching the W3C definition that has an hex value of #FF00FF. /// public static readonly TColor Magenta = ColorBuilder.FromRGBA(255, 0, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #800000. + /// Represents a matching the W3C definition that has an hex value of #800000. /// public static readonly TColor Maroon = ColorBuilder.FromRGBA(128, 0, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #66CDAA. + /// Represents a matching the W3C definition that has an hex value of #66CDAA. /// public static readonly TColor MediumAquamarine = ColorBuilder.FromRGBA(102, 205, 170, 255); /// - /// Represents a matching the W3C definition that has an hex value of #0000CD. + /// Represents a matching the W3C definition that has an hex value of #0000CD. /// public static readonly TColor MediumBlue = ColorBuilder.FromRGBA(0, 0, 205, 255); /// - /// Represents a matching the W3C definition that has an hex value of #BA55D3. + /// Represents a matching the W3C definition that has an hex value of #BA55D3. /// public static readonly TColor MediumOrchid = ColorBuilder.FromRGBA(186, 85, 211, 255); /// - /// Represents a matching the W3C definition that has an hex value of #9370DB. + /// Represents a matching the W3C definition that has an hex value of #9370DB. /// public static readonly TColor MediumPurple = ColorBuilder.FromRGBA(147, 112, 219, 255); /// - /// Represents a matching the W3C definition that has an hex value of #3CB371. + /// Represents a matching the W3C definition that has an hex value of #3CB371. /// public static readonly TColor MediumSeaGreen = ColorBuilder.FromRGBA(60, 179, 113, 255); /// - /// Represents a matching the W3C definition that has an hex value of #7B68EE. + /// Represents a matching the W3C definition that has an hex value of #7B68EE. /// public static readonly TColor MediumSlateBlue = ColorBuilder.FromRGBA(123, 104, 238, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00FA9A. + /// Represents a matching the W3C definition that has an hex value of #00FA9A. /// public static readonly TColor MediumSpringGreen = ColorBuilder.FromRGBA(0, 250, 154, 255); /// - /// Represents a matching the W3C definition that has an hex value of #48D1CC. + /// Represents a matching the W3C definition that has an hex value of #48D1CC. /// public static readonly TColor MediumTurquoise = ColorBuilder.FromRGBA(72, 209, 204, 255); /// - /// Represents a matching the W3C definition that has an hex value of #C71585. + /// Represents a matching the W3C definition that has an hex value of #C71585. /// public static readonly TColor MediumVioletRed = ColorBuilder.FromRGBA(199, 21, 133, 255); /// - /// Represents a matching the W3C definition that has an hex value of #191970. + /// Represents a matching the W3C definition that has an hex value of #191970. /// public static readonly TColor MidnightBlue = ColorBuilder.FromRGBA(25, 25, 112, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F5FFFA. + /// Represents a matching the W3C definition that has an hex value of #F5FFFA. /// public static readonly TColor MintCream = ColorBuilder.FromRGBA(245, 255, 250, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFE4E1. + /// Represents a matching the W3C definition that has an hex value of #FFE4E1. /// public static readonly TColor MistyRose = ColorBuilder.FromRGBA(255, 228, 225, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFE4B5. + /// Represents a matching the W3C definition that has an hex value of #FFE4B5. /// public static readonly TColor Moccasin = ColorBuilder.FromRGBA(255, 228, 181, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFDEAD. + /// Represents a matching the W3C definition that has an hex value of #FFDEAD. /// public static readonly TColor NavajoWhite = ColorBuilder.FromRGBA(255, 222, 173, 255); /// - /// Represents a matching the W3C definition that has an hex value of #000080. + /// Represents a matching the W3C definition that has an hex value of #000080. /// public static readonly TColor Navy = ColorBuilder.FromRGBA(0, 0, 128, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FDF5E6. + /// Represents a matching the W3C definition that has an hex value of #FDF5E6. /// public static readonly TColor OldLace = ColorBuilder.FromRGBA(253, 245, 230, 255); /// - /// Represents a matching the W3C definition that has an hex value of #808000. + /// Represents a matching the W3C definition that has an hex value of #808000. /// public static readonly TColor Olive = ColorBuilder.FromRGBA(128, 128, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #6B8E23. + /// Represents a matching the W3C definition that has an hex value of #6B8E23. /// public static readonly TColor OliveDrab = ColorBuilder.FromRGBA(107, 142, 35, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFA500. + /// Represents a matching the W3C definition that has an hex value of #FFA500. /// public static readonly TColor Orange = ColorBuilder.FromRGBA(255, 165, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF4500. + /// Represents a matching the W3C definition that has an hex value of #FF4500. /// public static readonly TColor OrangeRed = ColorBuilder.FromRGBA(255, 69, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #DA70D6. + /// Represents a matching the W3C definition that has an hex value of #DA70D6. /// public static readonly TColor Orchid = ColorBuilder.FromRGBA(218, 112, 214, 255); /// - /// Represents a matching the W3C definition that has an hex value of #EEE8AA. + /// Represents a matching the W3C definition that has an hex value of #EEE8AA. /// public static readonly TColor PaleGoldenrod = ColorBuilder.FromRGBA(238, 232, 170, 255); /// - /// Represents a matching the W3C definition that has an hex value of #98FB98. + /// Represents a matching the W3C definition that has an hex value of #98FB98. /// public static readonly TColor PaleGreen = ColorBuilder.FromRGBA(152, 251, 152, 255); /// - /// Represents a matching the W3C definition that has an hex value of #AFEEEE. + /// Represents a matching the W3C definition that has an hex value of #AFEEEE. /// public static readonly TColor PaleTurquoise = ColorBuilder.FromRGBA(175, 238, 238, 255); /// - /// Represents a matching the W3C definition that has an hex value of #DB7093. + /// Represents a matching the W3C definition that has an hex value of #DB7093. /// public static readonly TColor PaleVioletRed = ColorBuilder.FromRGBA(219, 112, 147, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFEFD5. + /// Represents a matching the W3C definition that has an hex value of #FFEFD5. /// public static readonly TColor PapayaWhip = ColorBuilder.FromRGBA(255, 239, 213, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFDAB9. + /// Represents a matching the W3C definition that has an hex value of #FFDAB9. /// public static readonly TColor PeachPuff = ColorBuilder.FromRGBA(255, 218, 185, 255); /// - /// Represents a matching the W3C definition that has an hex value of #CD853F. + /// Represents a matching the W3C definition that has an hex value of #CD853F. /// public static readonly TColor Peru = ColorBuilder.FromRGBA(205, 133, 63, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFC0CB. + /// Represents a matching the W3C definition that has an hex value of #FFC0CB. /// public static readonly TColor Pink = ColorBuilder.FromRGBA(255, 192, 203, 255); /// - /// Represents a matching the W3C definition that has an hex value of #DDA0DD. + /// Represents a matching the W3C definition that has an hex value of #DDA0DD. /// public static readonly TColor Plum = ColorBuilder.FromRGBA(221, 160, 221, 255); /// - /// Represents a matching the W3C definition that has an hex value of #B0E0E6. + /// Represents a matching the W3C definition that has an hex value of #B0E0E6. /// public static readonly TColor PowderBlue = ColorBuilder.FromRGBA(176, 224, 230, 255); /// - /// Represents a matching the W3C definition that has an hex value of #800080. + /// Represents a matching the W3C definition that has an hex value of #800080. /// public static readonly TColor Purple = ColorBuilder.FromRGBA(128, 0, 128, 255); /// - /// Represents a matching the W3C definition that has an hex value of #663399. + /// Represents a matching the W3C definition that has an hex value of #663399. /// public static readonly TColor RebeccaPurple = ColorBuilder.FromRGBA(102, 51, 153, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF0000. + /// Represents a matching the W3C definition that has an hex value of #FF0000. /// public static readonly TColor Red = ColorBuilder.FromRGBA(255, 0, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #BC8F8F. + /// Represents a matching the W3C definition that has an hex value of #BC8F8F. /// public static readonly TColor RosyBrown = ColorBuilder.FromRGBA(188, 143, 143, 255); /// - /// Represents a matching the W3C definition that has an hex value of #4169E1. + /// Represents a matching the W3C definition that has an hex value of #4169E1. /// public static readonly TColor RoyalBlue = ColorBuilder.FromRGBA(65, 105, 225, 255); /// - /// Represents a matching the W3C definition that has an hex value of #8B4513. + /// Represents a matching the W3C definition that has an hex value of #8B4513. /// public static readonly TColor SaddleBrown = ColorBuilder.FromRGBA(139, 69, 19, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FA8072. + /// Represents a matching the W3C definition that has an hex value of #FA8072. /// public static readonly TColor Salmon = ColorBuilder.FromRGBA(250, 128, 114, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F4A460. + /// Represents a matching the W3C definition that has an hex value of #F4A460. /// public static readonly TColor SandyBrown = ColorBuilder.FromRGBA(244, 164, 96, 255); /// - /// Represents a matching the W3C definition that has an hex value of #2E8B57. + /// Represents a matching the W3C definition that has an hex value of #2E8B57. /// public static readonly TColor SeaGreen = ColorBuilder.FromRGBA(46, 139, 87, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFF5EE. + /// Represents a matching the W3C definition that has an hex value of #FFF5EE. /// public static readonly TColor SeaShell = ColorBuilder.FromRGBA(255, 245, 238, 255); /// - /// Represents a matching the W3C definition that has an hex value of #A0522D. + /// Represents a matching the W3C definition that has an hex value of #A0522D. /// public static readonly TColor Sienna = ColorBuilder.FromRGBA(160, 82, 45, 255); /// - /// Represents a matching the W3C definition that has an hex value of #C0C0C0. + /// Represents a matching the W3C definition that has an hex value of #C0C0C0. /// public static readonly TColor Silver = ColorBuilder.FromRGBA(192, 192, 192, 255); /// - /// Represents a matching the W3C definition that has an hex value of #87CEEB. + /// Represents a matching the W3C definition that has an hex value of #87CEEB. /// public static readonly TColor SkyBlue = ColorBuilder.FromRGBA(135, 206, 235, 255); /// - /// Represents a matching the W3C definition that has an hex value of #6A5ACD. + /// Represents a matching the W3C definition that has an hex value of #6A5ACD. /// public static readonly TColor SlateBlue = ColorBuilder.FromRGBA(106, 90, 205, 255); /// - /// Represents a matching the W3C definition that has an hex value of #708090. + /// Represents a matching the W3C definition that has an hex value of #708090. /// public static readonly TColor SlateGray = ColorBuilder.FromRGBA(112, 128, 144, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFAFA. + /// Represents a matching the W3C definition that has an hex value of #FFFAFA. /// public static readonly TColor Snow = ColorBuilder.FromRGBA(255, 250, 250, 255); /// - /// Represents a matching the W3C definition that has an hex value of #00FF7F. + /// Represents a matching the W3C definition that has an hex value of #00FF7F. /// public static readonly TColor SpringGreen = ColorBuilder.FromRGBA(0, 255, 127, 255); /// - /// Represents a matching the W3C definition that has an hex value of #4682B4. + /// Represents a matching the W3C definition that has an hex value of #4682B4. /// public static readonly TColor SteelBlue = ColorBuilder.FromRGBA(70, 130, 180, 255); /// - /// Represents a matching the W3C definition that has an hex value of #D2B48C. + /// Represents a matching the W3C definition that has an hex value of #D2B48C. /// public static readonly TColor Tan = ColorBuilder.FromRGBA(210, 180, 140, 255); /// - /// Represents a matching the W3C definition that has an hex value of #008080. + /// Represents a matching the W3C definition that has an hex value of #008080. /// public static readonly TColor Teal = ColorBuilder.FromRGBA(0, 128, 128, 255); /// - /// Represents a matching the W3C definition that has an hex value of #D8BFD8. + /// Represents a matching the W3C definition that has an hex value of #D8BFD8. /// public static readonly TColor Thistle = ColorBuilder.FromRGBA(216, 191, 216, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FF6347. + /// Represents a matching the W3C definition that has an hex value of #FF6347. /// public static readonly TColor Tomato = ColorBuilder.FromRGBA(255, 99, 71, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFFFF. + /// Represents a matching the W3C definition that has an hex value of #FFFFFF. /// public static readonly TColor Transparent = ColorBuilder.FromRGBA(255, 255, 255, 0); /// - /// Represents a matching the W3C definition that has an hex value of #40E0D0. + /// Represents a matching the W3C definition that has an hex value of #40E0D0. /// public static readonly TColor Turquoise = ColorBuilder.FromRGBA(64, 224, 208, 255); /// - /// Represents a matching the W3C definition that has an hex value of #EE82EE. + /// Represents a matching the W3C definition that has an hex value of #EE82EE. /// public static readonly TColor Violet = ColorBuilder.FromRGBA(238, 130, 238, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F5DEB3. + /// Represents a matching the W3C definition that has an hex value of #F5DEB3. /// public static readonly TColor Wheat = ColorBuilder.FromRGBA(245, 222, 179, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFFFF. + /// Represents a matching the W3C definition that has an hex value of #FFFFFF. /// public static readonly TColor White = ColorBuilder.FromRGBA(255, 255, 255, 255); /// - /// Represents a matching the W3C definition that has an hex value of #F5F5F5. + /// Represents a matching the W3C definition that has an hex value of #F5F5F5. /// public static readonly TColor WhiteSmoke = ColorBuilder.FromRGBA(245, 245, 245, 255); /// - /// Represents a matching the W3C definition that has an hex value of #FFFF00. + /// Represents a matching the W3C definition that has an hex value of #FFFF00. /// public static readonly TColor Yellow = ColorBuilder.FromRGBA(255, 255, 0, 255); /// - /// Represents a matching the W3C definition that has an hex value of #9ACD32. + /// Represents a matching the W3C definition that has an hex value of #9ACD32. /// public static readonly TColor YellowGreen = ColorBuilder.FromRGBA(154, 205, 50, 255); } diff --git a/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs b/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs index ccb1c2261..db0251703 100644 --- a/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs +++ b/src/ImageSharp/Colors/PackedPixel/BulkPixelOperations{TColor}.cs @@ -27,10 +27,7 @@ namespace ImageSharp /// The to the source vectors. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void PackFromVector4( - BufferSpan sourceVectors, - BufferSpan destColors, - int count) + internal virtual void PackFromVector4(BufferSpan sourceVectors, BufferSpan destColors, int count) { ref Vector4 sourceRef = ref sourceVectors.DangerousGetPinnableReference(); ref TColor destRef = ref destColors.DangerousGetPinnableReference(); @@ -49,10 +46,7 @@ namespace ImageSharp /// The to the source colors. /// The to the destination vectors. /// The number of pixels to convert. - internal virtual void ToVector4( - BufferSpan sourceColors, - BufferSpan destVectors, - int count) + internal virtual void ToVector4(BufferSpan sourceColors, BufferSpan destVectors, int count) { ref TColor sourceRef = ref sourceColors.DangerousGetPinnableReference(); ref Vector4 destRef = ref destVectors.DangerousGetPinnableReference(); @@ -71,10 +65,7 @@ namespace ImageSharp /// The to the source bytes. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void PackFromXyzBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal virtual void PackFromXyzBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TColor destRef = ref destColors.DangerousGetPinnableReference(); @@ -115,10 +106,7 @@ namespace ImageSharp /// The to the source bytes. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void PackFromXyzwBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal virtual void PackFromXyzwBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TColor destRef = ref destColors.DangerousGetPinnableReference(); @@ -141,10 +129,7 @@ namespace ImageSharp /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - internal virtual void ToXyzwBytes( - BufferSpan sourceColors, - BufferSpan destBytes, - int count) + internal virtual void ToXyzwBytes(BufferSpan sourceColors, BufferSpan destBytes, int count) { ref TColor sourceRef = ref sourceColors.DangerousGetPinnableReference(); byte[] dest = destBytes.Array; @@ -162,10 +147,7 @@ namespace ImageSharp /// The to the source bytes. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void PackFromZyxBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal virtual void PackFromZyxBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TColor destRef = ref destColors.DangerousGetPinnableReference(); @@ -206,10 +188,7 @@ namespace ImageSharp /// The to the source bytes. /// The to the destination colors. /// The number of pixels to convert. - internal virtual void PackFromZyxwBytes( - BufferSpan sourceBytes, - BufferSpan destColors, - int count) + internal virtual void PackFromZyxwBytes(BufferSpan sourceBytes, BufferSpan destColors, int count) { ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); ref TColor destRef = ref destColors.DangerousGetPinnableReference(); @@ -232,10 +211,7 @@ namespace ImageSharp /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - internal virtual void ToZyxwBytes( - BufferSpan sourceColors, - BufferSpan destBytes, - int count) + internal virtual void ToZyxwBytes(BufferSpan sourceColors, BufferSpan destBytes, int count) { ref TColor sourceRef = ref sourceColors.DangerousGetPinnableReference(); byte[] dest = destBytes.Array; diff --git a/src/ImageSharp/Colors/PackedPixel/Rgba32.cs b/src/ImageSharp/Colors/PackedPixel/Rgba32.cs new file mode 100644 index 000000000..727d91c93 --- /dev/null +++ b/src/ImageSharp/Colors/PackedPixel/Rgba32.cs @@ -0,0 +1,398 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System.Numerics; + using System.Runtime.CompilerServices; + + /// + /// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. + /// The color components are stored in red, green, blue, and alpha order. + /// + /// + /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, + /// as it avoids the need to create new values for modification operations. + /// + public struct Rgba32 : IPixel, IPackedVector + { + /// + /// The shift count for the red component + /// + private const int RedShift = 0; + + /// + /// The shift count for the green component + /// + private const int GreenShift = 8; + + /// + /// The shift count for the blue component + /// + private const int BlueShift = 16; + + /// + /// The shift count for the alpha component + /// + private const int AlphaShift = 24; + + /// + /// The maximum byte value. + /// + private static readonly Vector4 MaxBytes = new Vector4(255); + + /// + /// The half vector value. + /// + private static readonly Vector4 Half = new Vector4(0.5F); + + /// + /// The packed value. + /// + private uint packedValue; + + /// + /// Initializes a new instance of the struct. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The alpha component. + public Rgba32(byte r, byte g, byte b, byte a = 255) + { + this.packedValue = Pack(r, g, b, a); + } + + /// + /// Initializes a new instance of the struct. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The alpha component. + public Rgba32(float r, float g, float b, float a = 1) + { + this.packedValue = Pack(r, g, b, a); + } + + /// + /// Initializes a new instance of the struct. + /// + /// + /// The vector containing the components for the packed vector. + /// + public Rgba32(Vector3 vector) + { + this.packedValue = Pack(ref vector); + } + + /// + /// Initializes a new instance of the struct. + /// + /// + /// The vector containing the components for the packed vector. + /// + public Rgba32(Vector4 vector) + { + this.packedValue = Pack(ref vector); + } + + /// + /// Initializes a new instance of the struct. + /// + /// + /// The packed value. + /// + public Rgba32(uint packed) + { + this.packedValue = packed; + } + + /// + /// Gets or sets the red component. + /// + public byte R + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return (byte)(this.packedValue >> RedShift); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.packedValue = this.packedValue & 0xFFFFFF00 | (uint)value << RedShift; + } + } + + /// + /// Gets or sets the green component. + /// + public byte G + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return (byte)(this.packedValue >> GreenShift); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.packedValue = this.packedValue & 0xFFFF00FF | (uint)value << GreenShift; + } + } + + /// + /// Gets or sets the blue component. + /// + public byte B + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return (byte)(this.packedValue >> BlueShift); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.packedValue = this.packedValue & 0xFF00FFFF | (uint)value << BlueShift; + } + } + + /// + /// Gets or sets the alpha component. + /// + public byte A + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return (byte)(this.packedValue >> AlphaShift); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + this.packedValue = this.packedValue & 0x00FFFFFF | (uint)value << AlphaShift; + } + } + + /// + public uint PackedValue + { + get => this.packedValue; + + set => this.packedValue = value; + } + + /// + /// Compares two objects for equality. + /// + /// + /// The on the left side of the operand. + /// + /// + /// The on the right side of the operand. + /// + /// + /// True if the parameter is equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Rgba32 left, Rgba32 right) + { + return left.packedValue == right.packedValue; + } + + /// + /// Compares two objects for equality. + /// + /// The on the left side of the operand. + /// The on the right side of the operand. + /// + /// True if the parameter is not equal to the parameter; otherwise, false. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Rgba32 left, Rgba32 right) + { + return left.packedValue != right.packedValue; + } + + /// + /// Creates a new instance of the struct. + /// + /// + /// The hexadecimal representation of the combined color components arranged + /// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax. + /// + /// + /// The . + /// + public static Rgba32 FromHex(string hex) + { + return ColorBuilder.FromHex(hex); + } + + /// + public BulkPixelOperations CreateBulkOperations() => new BulkPixelOperations(); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBytes(byte x, byte y, byte z, byte w) + { + this.packedValue = Pack(x, y, z, w); + } + + /// + /// Converts the value of this instance to a hexadecimal string. + /// + /// A hexadecimal string representation of the value. + public string ToHex() + { + uint hexOrder = Pack(this.A, this.B, this.G, this.R); + return hexOrder.ToString("X8"); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToXyzBytes(byte[] bytes, int startIndex) + { + bytes[startIndex] = this.R; + bytes[startIndex + 1] = this.G; + bytes[startIndex + 2] = this.B; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToXyzwBytes(byte[] bytes, int startIndex) + { + bytes[startIndex] = this.R; + bytes[startIndex + 1] = this.G; + bytes[startIndex + 2] = this.B; + bytes[startIndex + 3] = this.A; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToZyxBytes(byte[] bytes, int startIndex) + { + bytes[startIndex] = this.B; + bytes[startIndex + 1] = this.G; + bytes[startIndex + 2] = this.R; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToZyxwBytes(byte[] bytes, int startIndex) + { + bytes[startIndex] = this.B; + bytes[startIndex + 1] = this.G; + bytes[startIndex + 2] = this.R; + bytes[startIndex + 3] = this.A; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromVector4(Vector4 vector) + { + this.packedValue = Pack(ref vector); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 ToVector4() + { + return new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; + } + + /// + public override bool Equals(object obj) + { + return (obj is Rgba32) && this.Equals((Rgba32)obj); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(Rgba32 other) + { + return this.packedValue == other.packedValue; + } + + /// + /// Gets a string representation of the packed vector. + /// + /// A string representation of the packed vector. + public override string ToString() + { + return this.ToVector4().ToString(); + } + + /// + public override int GetHashCode() + { + return this.packedValue.GetHashCode(); + } + + /// + /// Packs a into a uint. + /// + /// The vector containing the values to pack. + /// The containing the packed values. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint Pack(ref Vector4 vector) + { + vector *= MaxBytes; + vector += Half; + vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); + return (uint)(((byte)vector.X << RedShift) + | ((byte)vector.Y << GreenShift) + | ((byte)vector.Z << BlueShift) + | (byte)vector.W << AlphaShift); + } + + /// + /// Packs a into a uint. + /// + /// The vector containing the values to pack. + /// The containing the packed values. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint Pack(ref Vector3 vector) + { + Vector4 value = new Vector4(vector, 1); + return Pack(ref value); + } + + /// + /// Packs the four floats into a . + /// + /// The x-component + /// The y-component + /// The z-component + /// The w-component + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint Pack(float x, float y, float z, float w) + { + Vector4 value = new Vector4(x, y, z, w); + return Pack(ref value); + } + + /// + /// Packs the four floats into a . + /// + /// The x-component + /// The y-component + /// The z-component + /// The w-component + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint Pack(byte x, byte y, byte z, byte w) + { + return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs index f02cf5663..befff61d5 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs @@ -6,7 +6,7 @@ using BenchmarkDotNet.Attributes; using ImageSharp; - + /// /// Compares two implementation candidates for general BulkPixelOperations.ToVector4(): /// - One iterating with pointers diff --git a/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs b/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs index e2f96f191..c7a2021de 100644 --- a/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs +++ b/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs @@ -12,7 +12,7 @@ namespace ImageSharp.Benchmarks.General public unsafe class ClearBuffer { private Buffer buffer; - + [Params(32, 128, 512)] public int Count { get; set; } @@ -37,7 +37,7 @@ namespace ImageSharp.Benchmarks.General [Benchmark] public void Unsafe_InitBlock() { - Unsafe.InitBlock((void*)this.buffer.Pin(), default(byte), (uint)this.Count*sizeof(uint)); + Unsafe.InitBlock((void*)this.buffer.Pin(), default(byte), (uint)this.Count * sizeof(uint)); } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs index 04570ce8f..569070af2 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Resize.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Resize.cs @@ -11,6 +11,7 @@ namespace ImageSharp.Benchmarks using BenchmarkDotNet.Attributes; using CoreSize = ImageSharp.Size; using CoreImage = ImageSharp.Image; + using CoreVectorImage = ImageSharp.Image; public class Resize : BenchmarkBase { @@ -44,6 +45,16 @@ namespace ImageSharp.Benchmarks } } + [Benchmark(Description = "ImageSharp Vector Resize")] + public CoreSize ResizeCoreVector() + { + using (CoreVectorImage image = new CoreVectorImage(2000, 2000)) + { + image.Resize(400, 400); + return new CoreSize(image.Width, image.Height); + } + } + [Benchmark(Description = "ImageSharp Compand Resize")] public CoreSize ResizeCoreCompand() { @@ -53,5 +64,15 @@ namespace ImageSharp.Benchmarks return new CoreSize(image.Width, image.Height); } } + + [Benchmark(Description = "ImageSharp Vector Compand Resize")] + public CoreSize ResizeCoreVectorCompand() + { + using (CoreVectorImage image = new CoreVectorImage(2000, 2000)) + { + image.Resize(400, 400, true); + return new CoreSize(image.Width, image.Height); + } + } } } diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index dad603523..1bd51d8f3 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -7,7 +7,7 @@ namespace ImageSharp.Sandbox46 { using System; using System.Runtime.DesignerServices; - + using ImageSharp.Tests; using ImageSharp.Tests.Colors; @@ -53,10 +53,10 @@ namespace ImageSharp.Sandbox46 private static void RunToVector4ProfilingTest() { - BulkPixelOperationsTests.Color tests = new BulkPixelOperationsTests.Color(new ConsoleOutput()); + BulkPixelOperationsTests.Color32 tests = new BulkPixelOperationsTests.Color32(new ConsoleOutput()); tests.Benchmark_ToVector4(); } - + private static void RunDecodeJpegProfilingTests() { Console.WriteLine("RunDecodeJpegProfilingTests..."); diff --git a/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs b/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs index 7db5a45f3..0b1e6dc7b 100644 --- a/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/Colors/BulkPixelOperationsTests.cs @@ -10,9 +10,9 @@ namespace ImageSharp.Tests.Colors public class BulkPixelOperationsTests { - public class Color : BulkPixelOperationsTests + public class Color32 : BulkPixelOperationsTests { - public Color(ITestOutputHelper output) + public Color32(ITestOutputHelper output) : base(output) { } @@ -25,7 +25,7 @@ namespace ImageSharp.Tests.Colors { Assert.IsType(BulkPixelOperations.Instance); } - + [Fact] public void ToVector4SimdAligned() { @@ -36,7 +36,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => ImageSharp.Color.BulkOperations.ToVector4SimdAligned(s, d, 64) - ); + ); } // [Fact] // Profiling benchmark - enable manually! @@ -72,7 +72,7 @@ namespace ImageSharp.Tests.Colors [Theory] [WithBlankImages(1, 1, PixelTypes.All)] public void GetGlobalInstance(TestImageProvider dummy) - where TColor:struct, IPixel + where TColor : struct, IPixel { Assert.NotNull(BulkPixelOperations.Instance); } @@ -112,7 +112,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.PackFromVector4(s, d, count) - ); + ); } internal static Vector4[] CreateExpectedVector4Data(TColor[] source) @@ -137,7 +137,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.ToVector4(s, d, count) - ); + ); } @@ -156,10 +156,10 @@ namespace ImageSharp.Tests.Colors } TestOperation( - source, - expected, + source, + expected, (s, d) => Operations.PackFromXyzBytes(s, d, count) - ); + ); } [Theory] @@ -179,7 +179,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.ToXyzBytes(s, d, count) - ); + ); } [Theory] @@ -200,7 +200,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.PackFromXyzwBytes(s, d, count) - ); + ); } [Theory] @@ -220,7 +220,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.ToXyzwBytes(s, d, count) - ); + ); } [Theory] @@ -241,7 +241,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.PackFromZyxBytes(s, d, count) - ); + ); } [Theory] @@ -261,7 +261,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.ToZyxBytes(s, d, count) - ); + ); } [Theory] @@ -282,7 +282,7 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.PackFromZyxwBytes(s, d, count) - ); + ); } [Theory] @@ -302,10 +302,10 @@ namespace ImageSharp.Tests.Colors source, expected, (s, d) => Operations.ToZyxwBytes(s, d, count) - ); + ); } - + private class TestBuffers : IDisposable where TSource : struct where TDest : struct @@ -316,7 +316,7 @@ namespace ImageSharp.Tests.Colors public BufferSpan Source => this.SourceBuffer; public BufferSpan ActualDest => this.ActualDestBuffer; - + public TestBuffers(TSource[] source, TDest[] expectedDest) { this.SourceBuffer = new Buffer(source); diff --git a/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs b/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs index b5b09c828..42481799f 100644 --- a/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs +++ b/tests/ImageSharp.Tests/Colors/ColorEqualityTests.cs @@ -33,6 +33,7 @@ namespace ImageSharp.Tests.Colors { new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.One), typeof(NormalizedShort4) }, { new Rg32(Vector2.One), new Rg32(Vector2.One), typeof(Rg32) }, { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.One), typeof(Rgba1010102) }, + { new Rgba32(Vector4.One), new Rgba32(Vector4.One), typeof(Rgba32) }, { new Rgba64(Vector4.One), new Rgba64(Vector4.One), typeof(Rgba64) }, { new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.One * 0x7FFF), typeof(Short2) }, { new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.One * 0x7FFF), typeof(Short4) }, @@ -144,6 +145,7 @@ namespace ImageSharp.Tests.Colors { new NormalizedShort4(Vector4.One), new NormalizedShort4(Vector4.Zero), typeof(NormalizedShort4) }, { new Rg32(Vector2.One), new Rg32(Vector2.Zero), typeof(Rg32) }, { new Rgba1010102(Vector4.One), new Rgba1010102(Vector4.Zero), typeof(Rgba1010102) }, + { new Rgba32(Vector4.One), new Rgba32(Vector4.Zero), typeof(Rgba32) }, { new Rgba64(Vector4.One), new Rgba64(Vector4.Zero), typeof(Rgba64) }, { new Short2(Vector2.One * 0x7FFF), new Short2(Vector2.Zero), typeof(Short2) }, { new Short4(Vector4.One * 0x7FFF), new Short4(Vector4.Zero), typeof(Short4) }, @@ -289,10 +291,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(EqualityDataColorSpaces))] public void EqualityObject(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -308,10 +310,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(NotEqualityDataColorSpaces))] public void NotEqualityObject(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -327,10 +329,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(EqualityDataColorSpaces))] public void EqualityOperator(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -346,10 +348,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(NotEqualityDataColorSpaces))] public void NotEqualityOperator(object first, object second, Type type) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -364,10 +366,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(AlmostEqualsData))] public void AlmostEquals(object first, object second, Type type, float precision) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); @@ -382,10 +384,10 @@ namespace ImageSharp.Tests.Colors [MemberData(nameof(AlmostNotEqualsData))] public void AlmostNotEquals(object first, object second, Type type, float precision) { - // Arrange - // Cast to the known object types, this is so that we can hit the - // equality operator on the concrete type, otherwise it goes to the - // default "object" one :) + // Arrange + // Cast to the known object types, this is so that we can hit the + // equality operator on the concrete type, otherwise it goes to the + // default "object" one :) dynamic firstObject = Convert.ChangeType(first, type); dynamic secondObject = Convert.ChangeType(second, type); diff --git a/tests/ImageSharp.Tests/Colors/ColorVectorTests.cs b/tests/ImageSharp.Tests/Colors/ColorVectorTests.cs new file mode 100644 index 000000000..4300b1b38 --- /dev/null +++ b/tests/ImageSharp.Tests/Colors/ColorVectorTests.cs @@ -0,0 +1,132 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests +{ + using System.Numerics; + using System.Runtime.CompilerServices; + + using Xunit; + + /// + /// Tests the struct. + /// + public class ColorVectorTests + { + /// + /// Tests the equality operators for equality. + /// + [Fact] + public void AreEqual() + { + ColorVector color1 = new ColorVector(0, 0, 0F); + ColorVector color2 = new ColorVector(0, 0, 0, 1F); + ColorVector color3 = ColorVector.FromHex("#000"); + ColorVector color4 = ColorVector.FromHex("#000F"); + ColorVector color5 = ColorVector.FromHex("#000000"); + ColorVector color6 = ColorVector.FromHex("#000000FF"); + + Assert.Equal(color1, color2); + Assert.Equal(color1, color3); + Assert.Equal(color1, color4); + Assert.Equal(color1, color5); + Assert.Equal(color1, color6); + } + + /// + /// Tests the equality operators for inequality. + /// + [Fact] + public void AreNotEqual() + { + ColorVector color1 = new ColorVector(1, 0, 0, 1); + ColorVector color2 = new ColorVector(0, 0, 0, 1); + ColorVector color3 = ColorVector.FromHex("#000"); + ColorVector color4 = ColorVector.FromHex("#000000"); + ColorVector color5 = ColorVector.FromHex("#FF000000"); + + Assert.NotEqual(color1, color2); + Assert.NotEqual(color1, color3); + Assert.NotEqual(color1, color4); + Assert.NotEqual(color1, color5); + } + + /// + /// Tests whether the color constructor correctly assign properties. + /// + [Fact] + public void ConstructorAssignsProperties() + { + ColorVector color1 = new ColorVector(1, .1F, .133F, .864F); + Assert.Equal(1F, color1.R); + Assert.Equal(.1F, color1.G); + Assert.Equal(.133F, color1.B); + Assert.Equal(.864F, color1.A); + + ColorVector color2 = new ColorVector(1, .1f, .133f); + Assert.Equal(1F, color2.R); + Assert.Equal(.1F, color2.G); + Assert.Equal(.133F, color2.B); + Assert.Equal(1F, color2.A); + + ColorVector color4 = new ColorVector(new Vector3(1, .1f, .133f)); + Assert.Equal(1F, color4.R); + Assert.Equal(.1F, color4.G); + Assert.Equal(.133F, color4.B); + Assert.Equal(1F, color4.A); + + ColorVector color5 = new ColorVector(new Vector4(1, .1f, .133f, .5f)); + Assert.Equal(1F, color5.R); + Assert.Equal(.1F, color5.G); + Assert.Equal(.133F, color5.B); + Assert.Equal(.5F, color5.A); + } + + /// + /// Tests whether FromHex and ToHex work correctly. + /// + [Fact] + public void FromAndToHex() + { + ColorVector color = ColorVector.FromHex("#AABBCCDD"); + Assert.Equal(170 / 255F, color.R); + Assert.Equal(187 / 255F, color.G); + Assert.Equal(204 / 255F, color.B); + Assert.Equal(221 / 255F, color.A); + + color.A = 170 / 255F; + color.B = 187 / 255F; + color.G = 204 / 255F; + color.R = 221 / 255F; + + Assert.Equal("DDCCBBAA", color.ToHex()); + + color.R = 0; + + Assert.Equal("00CCBBAA", color.ToHex()); + + color.A = 255 / 255F; + + Assert.Equal("00CCBBFF", color.ToHex()); + } + + /// + /// Tests that the individual float elements are layed out in RGBA order. + /// + [Fact] + public void FloatLayout() + { + ColorVector color = new ColorVector(1F, 2, 3, 4); + Vector4 colorBase = Unsafe.As(ref Unsafe.Add(ref color, 0)); + float[] ordered = new float[4]; + colorBase.CopyTo(ordered); + + Assert.Equal(1, ordered[0]); + Assert.Equal(2, ordered[1]); + Assert.Equal(3, ordered[2]); + Assert.Equal(4, ordered[3]); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Colors/ColorVectorTransformTests.cs b/tests/ImageSharp.Tests/Colors/ColorVectorTransformTests.cs new file mode 100644 index 000000000..c2e27d231 --- /dev/null +++ b/tests/ImageSharp.Tests/Colors/ColorVectorTransformTests.cs @@ -0,0 +1,118 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Tests.Colors +{ + using Xunit; + + /// + /// Tests the color transform algorithms. Test results match the output of CSS equivalents. + /// + /// + public class ColorVectorTransformTests + { + private static readonly ApproximateFloatComparer FloatComparer = new ApproximateFloatComparer(0.01F); + + /// + /// Orange backdrop + /// + private static readonly ColorVector Backdrop = new ColorVector(204, 102, 0); + + /// + /// Blue source + /// + private static readonly ColorVector Source = new ColorVector(0, 102, 153); + + [Fact] + public void Normal() + { + ColorVector normal = ColorVector.Normal(Backdrop, Source); + Assert.True(normal == Source); + } + + [Fact] + public void Multiply() + { + Assert.Equal(ColorVector.Multiply(Backdrop, ColorVector.Black).ToVector4(), Color.Black.ToVector4(), FloatComparer); + Assert.Equal(ColorVector.Multiply(Backdrop, ColorVector.White).ToVector4(), Backdrop.ToVector4(), FloatComparer); + + ColorVector multiply = ColorVector.Multiply(Backdrop, Source); + Assert.Equal(multiply.ToVector4(), new ColorVector(0, 41, 0).ToVector4(), FloatComparer); + } + + [Fact] + public void Screen() + { + Assert.Equal(ColorVector.Screen(Backdrop, ColorVector.Black).ToVector4(), Backdrop.ToVector4(), FloatComparer); + Assert.Equal(ColorVector.Screen(Backdrop, ColorVector.White).ToVector4(), ColorVector.White.ToVector4(), FloatComparer); + + ColorVector screen = ColorVector.Screen(Backdrop, Source); + Assert.Equal(screen.ToVector4(), new ColorVector(204, 163, 153).ToVector4(), FloatComparer); + } + + [Fact] + public void HardLight() + { + ColorVector hardLight = ColorVector.HardLight(Backdrop, Source); + Assert.Equal(hardLight.ToVector4(), new ColorVector(0, 82, 51).ToVector4(), FloatComparer); + } + + [Fact] + public void Overlay() + { + ColorVector overlay = ColorVector.Overlay(Backdrop, Source); + Assert.Equal(overlay.ToVector4(), new ColorVector(153, 82, 0).ToVector4(), FloatComparer); + } + + [Fact] + public void Darken() + { + ColorVector darken = ColorVector.Darken(Backdrop, Source); + Assert.Equal(darken.ToVector4(), new ColorVector(0, 102, 0).ToVector4(), FloatComparer); + } + + [Fact] + public void Lighten() + { + ColorVector lighten = ColorVector.Lighten(Backdrop, Source); + Assert.Equal(lighten.ToVector4(), new ColorVector(204, 102, 153).ToVector4(), FloatComparer); + } + + [Fact] + public void SoftLight() + { + ColorVector softLight = ColorVector.SoftLight(Backdrop, Source); + Assert.Equal(softLight.ToVector4(), new ColorVector(163, 90, 0).ToVector4(), FloatComparer); + } + + [Fact] + public void ColorDodge() + { + ColorVector colorDodge = ColorVector.ColorDodge(Backdrop, Source); + Assert.Equal(colorDodge.ToVector4(), new ColorVector(204, 170, 0).ToVector4(), FloatComparer); + } + + [Fact] + public void ColorBurn() + { + ColorVector colorBurn = ColorVector.ColorBurn(Backdrop, Source); + Assert.Equal(colorBurn.ToVector4(), new ColorVector(0, 0, 0).ToVector4(), FloatComparer); + } + + [Fact] + public void Difference() + { + ColorVector difference = ColorVector.Difference(Backdrop, Source); + Assert.Equal(difference.ToVector4(), new ColorVector(204, 0, 153).ToVector4(), FloatComparer); + } + + [Fact] + public void Exclusion() + { + ColorVector exclusion = ColorVector.Exclusion(Backdrop, Source); + Assert.Equal(exclusion.ToVector4(), new ColorVector(204, 122, 153).ToVector4(), FloatComparer); + } + } +} diff --git a/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs b/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs index 3e2b6fcd5..b5e159d9a 100644 --- a/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs +++ b/tests/ImageSharp.Tests/Colors/PackedPixelTests.cs @@ -711,6 +711,51 @@ namespace ImageSharp.Tests.Colors Assert.Equal(rgba, new byte[] { 25, 0, 128, 0 }); } + [Fact] + public void Rgba32() + { + // Test the limits. + Assert.Equal((uint)0x0, new Rgba32(Vector4.Zero).PackedValue); + Assert.Equal(0xFFFFFFFF, new Rgba32(Vector4.One).PackedValue); + + // Test ToVector4. + Assert.True(Equal(Vector4.One, new Rgba32(Vector4.One).ToVector4())); + Assert.True(Equal(Vector4.Zero, new Rgba32(Vector4.Zero).ToVector4())); + Assert.True(Equal(Vector4.UnitX, new Rgba32(Vector4.UnitX).ToVector4())); + Assert.True(Equal(Vector4.UnitY, new Rgba32(Vector4.UnitY).ToVector4())); + Assert.True(Equal(Vector4.UnitZ, new Rgba32(Vector4.UnitZ).ToVector4())); + Assert.True(Equal(Vector4.UnitW, new Rgba32(Vector4.UnitW).ToVector4())); + + // Test clamping. + Assert.True(Equal(Vector4.Zero, new Rgba32(Vector4.One * -1234.0f).ToVector4())); + Assert.True(Equal(Vector4.One, new Rgba32(Vector4.One * +1234.0f).ToVector4())); + + float x = +0.1f; + float y = -0.3f; + float z = +0.5f; + float w = -0.7f; + Rgba32 rgba32 = new Rgba32(x, y, z, w); + Assert.Equal(0x80001Au, rgba32.PackedValue); + + // Test ordering + byte[] rgb = new byte[3]; + byte[] rgba = new byte[4]; + byte[] bgr = new byte[3]; + byte[] bgra = new byte[4]; + + rgba32.ToXyzBytes(rgb, 0); + Assert.Equal(rgb, new byte[] { 0x1a, 0, 0x80 }); + + rgba32.ToXyzwBytes(rgba, 0); + Assert.Equal(rgba, new byte[] { 0x1a, 0, 0x80, 0 }); + + rgba32.ToZyxBytes(bgr, 0); + Assert.Equal(bgr, new byte[] { 0x80, 0, 0x1a }); + + rgba32.ToZyxwBytes(bgra, 0); + Assert.Equal(bgra, new byte[] { 0x80, 0, 0x1a, 0 }); + } + [Fact] public void Rgba64() { diff --git a/tests/ImageSharp.Tests/Colors/UnPackedPixelTests.cs b/tests/ImageSharp.Tests/Colors/UnPackedPixelTests.cs new file mode 100644 index 000000000..4fb189ca8 --- /dev/null +++ b/tests/ImageSharp.Tests/Colors/UnPackedPixelTests.cs @@ -0,0 +1,148 @@ +namespace ImageSharp.Tests.Colors +{ + using System.Numerics; + + using Xunit; + + public class UnPackedPixelTests + { + [Fact] + public void Color_Types_From_Bytes_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Floats_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); + ColorVector colorVector = new ColorVector(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Vector4_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(new Vector4(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F)); + ColorVector colorVector = new ColorVector(new Vector4(24 / 255F, 48 / 255F, 96 / 255F, 192 / 255F)); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Vector3_Produce_Equal_Scaled_Component_OutPut() + { + Color color = new Color(new Vector3(24 / 255F, 48 / 255F, 96 / 255F)); + ColorVector colorVector = new ColorVector(new Vector3(24 / 255F, 48 / 255F, 96 / 255F)); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_From_Hex_Produce_Equal_Scaled_Component_OutPut() + { + Color color = Color.FromHex("183060C0"); + ColorVector colorVector = ColorVector.FromHex("183060C0"); + + Assert.Equal(color.R, (byte)(colorVector.R * 255)); + Assert.Equal(color.G, (byte)(colorVector.G * 255)); + Assert.Equal(color.B, (byte)(colorVector.B * 255)); + Assert.Equal(color.A, (byte)(colorVector.A * 255)); + } + + [Fact] + public void Color_Types_To_Vector4_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + Assert.Equal(color.ToVector4(), colorVector.ToVector4()); + } + + [Fact] + public void Color_Types_To_RgbBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] rgb = new byte[3]; + byte[] rgbVector = new byte[3]; + + color.ToXyzBytes(rgb, 0); + colorVector.ToXyzBytes(rgbVector, 0); + + Assert.Equal(rgb, rgbVector); + } + + [Fact] + public void Color_Types_To_RgbaBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] rgba = new byte[4]; + byte[] rgbaVector = new byte[4]; + + color.ToXyzwBytes(rgba, 0); + colorVector.ToXyzwBytes(rgbaVector, 0); + + Assert.Equal(rgba, rgbaVector); + } + + [Fact] + public void Color_Types_To_BgrBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] bgr = new byte[3]; + byte[] bgrVector = new byte[3]; + + color.ToZyxBytes(bgr, 0); + colorVector.ToZyxBytes(bgrVector, 0); + + Assert.Equal(bgr, bgrVector); + } + + [Fact] + public void Color_Types_To_BgraBytes_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + byte[] bgra = new byte[4]; + byte[] bgraVector = new byte[4]; + + color.ToZyxwBytes(bgra, 0); + colorVector.ToZyxwBytes(bgraVector, 0); + + Assert.Equal(bgra, bgraVector); + } + + [Fact] + public void Color_Types_To_Hex_Produce_Equal_OutPut() + { + Color color = new Color(24, 48, 96, 192); + ColorVector colorVector = new ColorVector(24, 48, 96, 192); + + // 183060C0 + Assert.Equal(color.ToHex(), colorVector.ToHex()); + } + } +} \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Common/BufferSpanTests.cs b/tests/ImageSharp.Tests/Common/BufferSpanTests.cs index 067ef6622..ebf3a866a 100644 --- a/tests/ImageSharp.Tests/Common/BufferSpanTests.cs +++ b/tests/ImageSharp.Tests/Common/BufferSpanTests.cs @@ -9,7 +9,7 @@ namespace ImageSharp.Tests.Common using Xunit; using static TestStructs; - + public unsafe class BufferSpanTests { // ReSharper disable once ClassNeverInstantiated.Local @@ -38,7 +38,7 @@ namespace ImageSharp.Tests.Common Assert.SameRefs(ref orig.DangerousGetPinnableReference(), ref asBytes.DangerousGetPinnableReference()); } } - + public class Construct { [Fact] @@ -331,7 +331,7 @@ namespace ImageSharp.Tests.Common BufferSpan apSource = new BufferSpan(source, 1); BufferSpan apDest = new BufferSpan(dest, sizeof(Foo)); - BufferSpan.Copy(apSource.AsBytes(), apDest, (count - 1)*sizeof(Foo)); + BufferSpan.Copy(apSource.AsBytes(), apDest, (count - 1) * sizeof(Foo)); AssertNotDefault(source, 1); @@ -377,7 +377,7 @@ namespace ImageSharp.Tests.Common BufferSpan apSource = new BufferSpan(source); BufferSpan apDest = new BufferSpan(dest); - BufferSpan.Copy(apSource.AsBytes(), apDest, count*sizeof(int)); + BufferSpan.Copy(apSource.AsBytes(), apDest, count * sizeof(int)); AssertNotDefault(source, 1); @@ -398,7 +398,7 @@ namespace ImageSharp.Tests.Common BufferSpan apSource = new BufferSpan(source); BufferSpan apDest = new BufferSpan(dest); - BufferSpan.Copy(apSource, apDest.AsBytes(), count*sizeof(Foo)); + BufferSpan.Copy(apSource, apDest.AsBytes(), count * sizeof(Foo)); AssertNotDefault(source, sizeof(Foo) + 1); AssertNotDefault(dest, 1); @@ -410,14 +410,14 @@ namespace ImageSharp.Tests.Common } [Fact] - public void ColorToBytes() + public void Color32ToBytes() { Color[] colors = { new Color(0, 1, 2, 3), new Color(4, 5, 6, 7), new Color(8, 9, 10, 11), }; using (Buffer colorBuf = new Buffer(colors)) using (Buffer byteBuf = new Buffer(colors.Length * 4)) { - BufferSpan.Copy(colorBuf.Span.AsBytes(), byteBuf, colorBuf.Length*sizeof(Color)); + BufferSpan.Copy(colorBuf.Span.AsBytes(), byteBuf, colorBuf.Length * sizeof(Color)); byte[] a = byteBuf.Array; diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs index 39ce61495..c9312eed1 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs @@ -61,7 +61,7 @@ namespace ImageSharp.Tests BlackWhiteChecker(pixels); // top left VirticalBars(pixels); // top right TransparentGradients(pixels); // bottom left - Rainbow(pixels); // bottom right + Rainbow(pixels); // bottom right } } /// @@ -70,7 +70,7 @@ namespace ImageSharp.Tests /// private static void VirticalBars(PixelAccessor pixels) { - // topLeft + // topLeft int left = pixels.Width / 2; int right = pixels.Width; int top = 0; @@ -101,7 +101,7 @@ namespace ImageSharp.Tests /// private static void BlackWhiteChecker(PixelAccessor pixels) { - // topLeft + // topLeft int left = 0; int right = pixels.Width / 2; int top = 0; @@ -140,7 +140,7 @@ namespace ImageSharp.Tests /// private static void TransparentGradients(PixelAccessor pixels) { - // topLeft + // topLeft int left = 0; int right = pixels.Width / 2; int top = pixels.Height / 2; @@ -193,7 +193,7 @@ namespace ImageSharp.Tests int pixelCount = left * top; uint stepsPerPixel = (uint)(uint.MaxValue / pixelCount); TColor c = default(TColor); - Color t = new Color(0); + Rgba32 t = new Rgba32(0); for (int x = left; x < right; x++) for (int y = top; y < bottom; y++)