From 14d9583c8cd5efe073f7fd53472321a5484cc915 Mon Sep 17 00:00:00 2001 From: woutware <35376607+woutware@users.noreply.github.com> Date: Thu, 19 Apr 2018 05:16:38 +0200 Subject: [PATCH] Added IPixel.PackFromArgb32 and ToArgb32. Added IPixel.PackFromArgb32 and ToArgb32. Also refactored Argb32 to be closer to Rgba32 using pixel component byte fields. --- src/ImageSharp/PixelFormats/Alpha8.cs | 17 +- src/ImageSharp/PixelFormats/Argb32.cs | 208 +++++++++--------- src/ImageSharp/PixelFormats/Bgr24.cs | 17 ++ src/ImageSharp/PixelFormats/Bgr565.cs | 16 ++ src/ImageSharp/PixelFormats/Bgra32.cs | 19 ++ src/ImageSharp/PixelFormats/Bgra4444.cs | 17 ++ src/ImageSharp/PixelFormats/Bgra5551.cs | 17 ++ src/ImageSharp/PixelFormats/Byte4.cs | 17 ++ src/ImageSharp/PixelFormats/HalfSingle.cs | 17 ++ src/ImageSharp/PixelFormats/HalfVector2.cs | 17 ++ src/ImageSharp/PixelFormats/HalfVector4.cs | 17 ++ src/ImageSharp/PixelFormats/IPixel.cs | 12 + .../PixelFormats/NormalizedByte2.cs | 22 ++ .../PixelFormats/NormalizedByte4.cs | 21 ++ .../PixelFormats/NormalizedShort2.cs | 21 ++ .../PixelFormats/NormalizedShort4.cs | 22 ++ .../PixelFormats/PixelOperations{TPixel}.cs | 42 ++++ src/ImageSharp/PixelFormats/Rg32.cs | 17 ++ src/ImageSharp/PixelFormats/Rgb24.cs | 17 ++ src/ImageSharp/PixelFormats/Rgba1010102.cs | 17 ++ src/ImageSharp/PixelFormats/Rgba32.cs | 26 ++- src/ImageSharp/PixelFormats/Rgba64.cs | 17 ++ src/ImageSharp/PixelFormats/RgbaVector.cs | 17 ++ src/ImageSharp/PixelFormats/Short2.cs | 20 ++ src/ImageSharp/PixelFormats/Short4.cs | 20 ++ 25 files changed, 560 insertions(+), 110 deletions(-) diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index 57e2e984be..ddaea541d5 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -97,6 +97,12 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackedValue = source.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) { + this.PackedValue = source.A; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -108,10 +114,13 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgba32(ref Rgba32 dest) { - dest.R = 0; - dest.G = 0; - dest.B = 0; - dest.A = this.PackedValue; + dest.PackedValue = this.PackedValue; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + dest.PackedValue = (uint)this.PackedValue << 24; } /// diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 7030006f61..0cf7e8532b 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -1,9 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. -using System; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace SixLabors.ImageSharp.PixelFormats { @@ -18,8 +18,29 @@ namespace SixLabors.ImageSharp.PixelFormats /// 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. /// + [StructLayout(LayoutKind.Sequential)] public struct Argb32 : IPixel, IPackedVector { + /// + /// Gets or sets the alpha component. + /// + public byte A; + + /// + /// Gets or sets the red component. + /// + public byte R; + + /// + /// Gets or sets the green component. + /// + public byte G; + + /// + /// Gets or sets the blue component. + /// + public byte B; + /// /// The shift count for the blue component /// @@ -56,11 +77,13 @@ namespace SixLabors.ImageSharp.PixelFormats /// The red component. /// The green component. /// The blue component. - /// The alpha component. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Argb32(byte r, byte g, byte b, byte a) + public Argb32(byte r, byte g, byte b) { - this.PackedValue = Pack(r, g, b, a); + this.R = r; + this.G = g; + this.B = b; + this.A = 255; } /// @@ -69,10 +92,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// The red component. /// The green component. /// The blue component. + /// The alpha component. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Argb32(byte r, byte g, byte b) + public Argb32(byte r, byte g, byte b, byte a) { - this.PackedValue = Pack(r, g, b, 255); + this.R = r; + this.G = g; + this.B = b; + this.A = a; } /// @@ -82,9 +109,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// The green component. /// The blue component. /// The alpha component. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Argb32(float r, float g, float b, float a = 1) + : this() { - this.PackedValue = Pack(r, g, b, a); + this.Pack(r, g, b, a); } /// @@ -93,9 +122,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// - public Argb32(Vector3 vector) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Argb32(Vector3 vector) + : this() { - this.PackedValue = Pack(ref vector); + this.Pack(ref vector); } /// @@ -104,9 +135,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// - public Argb32(Vector4 vector) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Argb32(Vector4 vector) + : this() { - this.PackedValue = Pack(ref vector); + this.Pack(ref vector); } /// @@ -115,84 +148,33 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The packed value. /// - public Argb32(uint packed = 0) - { - this.PackedValue = packed; - } - - /// - public uint PackedValue { get; set; } - - /// - /// 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 & 0xFF00FFFF | (uint)value << RedShift; - } - } - - /// - /// Gets or sets the green component. - /// - public byte G + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Argb32(uint packed) + : this() { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return (byte)(this.PackedValue >> GreenShift); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.PackedValue = this.PackedValue & 0xFFFF00FF | (uint)value << GreenShift; - } + this.Argb = packed; } /// - /// Gets or sets the blue component. + /// Gets or sets the packed representation of the Argb32 struct. /// - public byte B - { + public uint Argb { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return (byte)(this.PackedValue >> BlueShift); + get { + return Unsafe.As(ref this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.PackedValue = this.PackedValue & 0xFFFFFF00 | (uint)value << BlueShift; + set { + Unsafe.As(ref this) = value; } } - /// - /// Gets or sets the alpha component. - /// - public byte A + /// + public uint PackedValue { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return (byte)(this.PackedValue >> AlphaShift); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - this.PackedValue = this.PackedValue & 0x00FFFFFF | (uint)value << AlphaShift; - } + get => this.Argb; + set => this.Argb = value; } /// @@ -210,7 +192,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Argb32 left, Argb32 right) { - return left.PackedValue == right.PackedValue; + return left.Argb == right.Argb; } /// @@ -224,14 +206,14 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Argb32 left, Argb32 right) { - return left.PackedValue != right.PackedValue; + return left.Argb != right.Argb; } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromVector4(Vector4 vector) { - this.PackedValue = Pack(ref vector); + this.Pack(ref vector); } /// @@ -265,6 +247,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackedValue = Pack(source.R, source.G, source.B, source.A); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackedValue = source.PackedValue; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -284,6 +273,12 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = this.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + dest = this; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) @@ -313,7 +308,16 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Argb32 other) { - return this.PackedValue == other.PackedValue; + return this.Argb == other.Argb; + } + + /// + /// Gets a string representation of the packed vector. + /// + /// A string representation of the packed vector. + public override string ToString() + { + return $"({this.R},{this.G},{this.B},{this.A})"; } /// @@ -321,7 +325,17 @@ namespace SixLabors.ImageSharp.PixelFormats public override int GetHashCode() { // ReSharper disable once NonReadonlyMemberInGetHashCode - return this.PackedValue.GetHashCode(); + return this.Argb.GetHashCode(); + } + + /// + /// Gets the representation without normalizing to [0, 1] + /// + /// A of values in [0, 255] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Vector4 ToByteScaledVector4() + { + return new Vector4(this.R, this.G, this.B, this.A); } /// @@ -333,53 +347,51 @@ namespace SixLabors.ImageSharp.PixelFormats /// The w-component /// The [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y, float z, float w) + private static uint Pack(byte x, byte y, byte z, byte w) { - var value = new Vector4(x, y, z, w); - return Pack(ref value); + return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift); } /// - /// Packs the four floats into a . + /// Packs the four floats into a color. /// /// 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) + private void Pack(float x, float y, float z, float w) { - return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift); + var value = new Vector4(x, y, z, w); + this.Pack(ref value); } /// /// 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) + private void Pack(ref Vector3 vector) { var value = new Vector4(vector, 1); - return Pack(ref value); + this.Pack(ref value); } /// - /// Packs a into a uint. + /// Packs a into a color. /// /// The vector containing the values to pack. - /// The containing the packed values. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(ref Vector4 vector) + private void 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); + + this.R = (byte)vector.X; + this.G = (byte)vector.Y; + this.B = (byte)vector.Z; + this.A = (byte)vector.W; } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index 61b447b882..6ceaa2097b 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -82,6 +82,14 @@ namespace SixLabors.ImageSharp.PixelFormats this = source.Bgr; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) { + R = source.R; + G = source.G; + B = source.B; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromScaledVector4(Vector4 vector) @@ -131,6 +139,15 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = 255; + } + /// public void ToBgr24(ref Bgr24 dest) { diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 54e29e21e6..92717ad0a1 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -120,6 +120,12 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -141,6 +147,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToVector4() * 255F; + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = (byte)MathF.Round(vector.Z); + dest.A = (byte)MathF.Round(vector.W); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index ad5efa2578..91875671a9 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -159,6 +159,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = source.A; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -178,6 +188,15 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = this.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = this.A; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index 0f52d00687..b8afac958b 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -111,6 +111,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -132,6 +139,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToVector4() * 255F; + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = (byte)vector.Z; + dest.A = (byte)vector.W; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index d24bab848e..028b85fc1d 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -111,6 +111,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -132,6 +139,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = (byte)vector.Z; + dest.A = (byte)vector.W; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index d7aae5df9a..f9e34a6459 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -112,6 +112,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToByteScaledVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToByteScaledVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -133,6 +140,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + var vector = this.ToVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = (byte)vector.Z; + dest.A = (byte)vector.W; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 0569b796d4..07548a90ab 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -125,6 +125,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -146,6 +153,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = (byte)vector.Z; + dest.A = (byte)vector.W; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index b26ae95983..5e09a4d9a7 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -140,6 +140,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -161,6 +168,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = 0; + dest.A = 255; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index c92de4ef13..31d5c6d6bf 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -133,6 +133,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -154,6 +161,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = (byte)vector.Z; + dest.A = (byte)vector.W; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index 954e14cc09..dcdedac0ec 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -59,6 +59,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromRgba32(Rgba32 source); + /// + /// Packs the pixel from an value. + /// + /// The value. + void PackFromArgb32(Argb32 source); + /// /// Converts the pixel to format. /// @@ -71,6 +77,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The destination pixel to write to void ToRgba32(ref Rgba32 dest); + /// + /// Converts the pixel to format. + /// + /// The destination pixel to write to + void ToArgb32(ref Argb32 dest); + /// /// Converts the pixel to format. /// diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 9bac828560..2d5a72a6e5 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -149,6 +149,18 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(vector); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + Vector4 vector = source.ToByteScaledVector4(); + vector -= Round; + vector -= Half; + vector -= Round; + vector /= Half; + this.PackFromVector4(vector); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -170,6 +182,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = 0; + dest.A = 255; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index a3aa60fd21..4137305619 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -142,6 +142,17 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(vector); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) { + Vector4 vector = source.ToByteScaledVector4(); + vector -= Round; + vector -= Half; + vector -= Round; + vector /= Half; + this.PackFromVector4(vector); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -163,6 +174,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = (byte)vector.Z; + dest.A = (byte)vector.W; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index afea6aaad8..c7f8e9b164 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -136,6 +136,17 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(vector); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) { + Vector4 vector = source.ToByteScaledVector4(); + vector -= Round; + vector -= Half; + vector -= Round; + vector /= Half; + this.PackFromVector4(vector); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -157,6 +168,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = 0; + dest.A = 255; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 87c92cb73b..314c00d6c3 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -144,6 +144,18 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(vector); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + Vector4 vector = source.ToByteScaledVector4(); + vector -= Round; + vector -= Half; + vector -= Round; + vector /= Half; + this.PackFromVector4(vector); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -165,6 +177,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = (byte)MathF.Round(vector.Z); + dest.A = (byte)MathF.Round(vector.W); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index b12a2bfa58..4cc20ed89b 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -63,6 +63,48 @@ namespace SixLabors.ImageSharp.PixelFormats } } + /// + /// Bulk version of + /// + /// The to the source vectors. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void PackFromArgb32(ReadOnlySpan sourceVectors, Span destinationColors, int count) + { + GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourceVectors); + ref TPixel destRef = ref MemoryMarshal.GetReference(destinationColors); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromArgb32(sp); + } + } + + /// + /// Bulk version of . + /// + /// The to the source colors. + /// The to the destination vectors. + /// The number of pixels to convert. + internal virtual void ToArgb32(ReadOnlySpan sourceColors, Span destinationVectors, int count) + { + GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); + + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destinationVectors); + + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + sp.ToArgb32(ref dp); + } + } + /// /// Bulk version of /// diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 5ce029af35..21863d48a4 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -124,6 +124,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -145,6 +152,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)vector.W; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)vector.X; + dest.G = (byte)vector.Y; + dest.B = (byte)vector.Z; + dest.A = (byte)vector.W; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index f07eadd56e..4d6dc2d9d5 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -83,6 +83,15 @@ namespace SixLabors.ImageSharp.PixelFormats this = Unsafe.As(ref source); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + R = source.R; + G = source.G; + B = source.B; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromScaledVector4(Vector4 vector) @@ -127,6 +136,14 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + public void ToArgb32(ref Argb32 dest) { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = 255; + } + /// public void ToBgr24(ref Bgr24 dest) { diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 39eed08f38..1d161b6ff8 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -118,6 +118,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -139,6 +146,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToVector4() * 255F; + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = (byte)MathF.Round(vector.Z); + dest.A = (byte)MathF.Round(vector.W); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index 182fd7cce0..feafde1fad 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -275,6 +275,12 @@ namespace SixLabors.ImageSharp.PixelFormats this = source; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) { + Pack(source.R, source.G, source.B, source.A); + } + /// /// Converts the value of this instance to a hexadecimal string. /// @@ -299,6 +305,15 @@ namespace SixLabors.ImageSharp.PixelFormats dest = this; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = this.A; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) @@ -380,16 +395,11 @@ namespace SixLabors.ImageSharp.PixelFormats } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { - unchecked - { - int hashCode = this.R; - hashCode = (hashCode * 397) ^ this.G; - hashCode = (hashCode * 397) ^ this.B; - hashCode = (hashCode * 397) ^ this.A; - return hashCode; - } + // ReSharper disable once NonReadonlyMemberInGetHashCode + return this.Rgba.GetHashCode(); } /// diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 4a2f9ef6aa..6d7162992e 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -117,6 +117,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -138,6 +145,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToVector4() * 255F; + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = (byte)MathF.Round(vector.Z); + dest.A = (byte)MathF.Round(vector.W); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index 92faa4e27b..7609b41499 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -218,6 +218,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.backingVector = source.ToVector4(); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.backingVector = source.ToVector4(); + } + /// /// Converts the value of this instance to a hexadecimal string. /// @@ -252,6 +259,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = (byte)MathF.Round(vector.Z); + dest.A = (byte)MathF.Round(vector.W); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index 75429c0afb..cb3b51e7e5 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -134,6 +134,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackedValue = Pack(vector.X, vector.Y); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + Vector2 vector = new Vector2(source.R, source.G) / 255; + vector *= 65534; + vector -= new Vector2(32767); + this.PackedValue = Pack(vector.X, vector.Y); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -155,6 +165,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = 255; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector2 vector = this.ToByteScaledVector2(); + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = 0; + dest.A = 255; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 0ea2b10c29..786eaf74b7 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -140,6 +140,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + var vector = source.ToVector4(); + vector *= 65534; + vector -= new Vector4(32767); + this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -161,6 +171,16 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = (byte)MathF.Round(vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + Vector4 vector = this.ToByteScaledVector4(); + dest.R = (byte)MathF.Round(vector.X); + dest.G = (byte)MathF.Round(vector.Y); + dest.B = (byte)MathF.Round(vector.Z); + dest.A = (byte)MathF.Round(vector.W); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest)