diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index 57e2e984b..e781538c0 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) @@ -114,6 +120,15 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = this.PackedValue; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ToArgb32(ref Argb32 dest) { + dest.R = 0; + dest.G = 0; + dest.B = 0; + dest.A = this.PackedValue; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToBgr24(ref Bgr24 dest) diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 7030006f6..603821410 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,27 +18,28 @@ 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 { /// - /// The shift count for the blue component + /// Gets or sets the alpha component. /// - private const int BlueShift = 0; + public byte A; /// - /// The shift count for the green component + /// Gets or sets the red component. /// - private const int GreenShift = 8; + public byte R; /// - /// The shift count for the red component + /// Gets or sets the green component. /// - private const int RedShift = 16; + public byte G; /// - /// The shift count for the alpha component + /// Gets or sets the blue component. /// - private const int AlphaShift = 24; + public byte B; /// /// The maximum byte value. @@ -56,11 +57,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 +72,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 +89,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 +102,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Argb32(Vector3 vector) + : this() { - this.PackedValue = Pack(ref vector); + this.Pack(ref vector); } /// @@ -104,9 +115,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The vector containing the components for the packed vector. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Argb32(Vector4 vector) + : this() { - this.PackedValue = Pack(ref vector); + this.Pack(ref vector); } /// @@ -115,84 +128,36 @@ 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); + return Unsafe.As(ref this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - this.PackedValue = this.PackedValue & 0xFFFFFF00 | (uint)value << BlueShift; + 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 +175,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 +189,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); } /// @@ -262,7 +227,17 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromRgba32(Rgba32 source) { - this.PackedValue = Pack(source.R, source.G, source.B, source.A); + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = source.A; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.PackedValue = source.PackedValue; } /// @@ -284,6 +259,13 @@ 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) @@ -303,6 +285,13 @@ namespace SixLabors.ImageSharp.PixelFormats dest.A = this.A; } + /// + /// Converts the pixel to format. + /// + /// The RGBA value + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); + /// public override bool Equals(object obj) { @@ -313,7 +302,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,65 +319,59 @@ namespace SixLabors.ImageSharp.PixelFormats public override int GetHashCode() { // ReSharper disable once NonReadonlyMemberInGetHashCode - return this.PackedValue.GetHashCode(); + return this.Argb.GetHashCode(); } /// - /// Packs the four floats into a . + /// Gets the representation without normalizing to [0, 1] /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The + /// A of values in [0, 255] [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(float x, float y, float z, float w) + internal Vector4 ToByteScaledVector4() { - var value = new Vector4(x, y, z, w); - return Pack(ref value); + return new Vector4(this.R, this.G, this.B, this.A); } /// - /// 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 61b447b88..5c1845768 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) { + this.R = source.R; + this.G = source.G; + this.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 54e29e21e..92717ad0a 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 ad5efa257..91875671a 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 0f52d0068..b8afac958 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 d24bab848..028b85fc1 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 d7aae5df9..f9e34a645 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/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index 81a86cdc5..d196f6e23 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -10,8 +10,8 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations { - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -19,12 +19,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - Rgba32 rgba = new Rgba32(0, 0, 0, 255); + var rgba = new Rgba32(0, 0, 0, 255); for (int i = 0; i < count; i++) { @@ -33,8 +33,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba32(rgba); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -46,8 +46,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -69,20 +69,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgba32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToRgba32(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -90,8 +90,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -104,8 +104,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba32(rgba); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -117,8 +117,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -140,20 +140,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgra32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToBgra32(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -161,8 +161,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); @@ -175,8 +175,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba32(rgba); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -188,8 +188,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -211,20 +211,20 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToRgb24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToRgb24(sourceColors, MemoryMarshal.Cast(destBytes), count); } - - /// + + /// /// Converts 'count' elements in 'source` span of data to a span of -s. /// /// The source of data. @@ -232,12 +232,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The number of pixels to convert. internal virtual void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - Rgba32 rgba = new Rgba32(0, 0, 0, 255); + var rgba = new Rgba32(0, 0, 0, 255); for (int i = 0; i < count; i++) { @@ -246,8 +246,8 @@ namespace SixLabors.ImageSharp.PixelFormats dp.PackFromRgba32(rgba); } } - - /// + + /// /// A helper for that expects a byte span. /// The layout of the data in 'sourceBytes' must be compatible with layout. /// @@ -259,8 +259,8 @@ namespace SixLabors.ImageSharp.PixelFormats { this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } - - /// + + /// /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// Bulk version of . /// @@ -282,18 +282,89 @@ namespace SixLabors.ImageSharp.PixelFormats } } - /// + /// /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// /// The to the source colors. /// The to the destination bytes. /// The number of pixels to convert. - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void ToBgr24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { this.ToBgr24(sourceColors, MemoryMarshal.Cast(destBytes), count); } + + /// + /// Converts 'count' elements in 'source` span of data to a span of -s. + /// + /// The source of data. + /// The to the destination pixels. + /// The number of pixels to convert. + internal virtual void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); + + var argb = new Argb32(0, 0, 0, 255); + + for (int i = 0; i < count; i++) + { + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + argb = Unsafe.Add(ref sourceRef, i); + dp.PackFromArgb32(argb); + } + } + + /// + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// + /// The to the source bytes. + /// The to the destination pixels. + /// The number of pixels to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void PackFromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + { + this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + } + + /// + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Bulk version of . + /// + /// The span of source pixels + /// The destination span of data. + /// The number of pixels to convert. + internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span dest, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + + ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destBaseRef = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); + sp.ToArgb32(ref dp); + } + } - } + /// + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. + /// + /// The to the source colors. + /// The to the destination bytes. + /// The number of pixels to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void ToArgb32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + { + this.ToArgb32(sourceColors, MemoryMarshal.Cast(destBytes), count); + } + + } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index d0a05677f..c9955864c 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -46,7 +46,7 @@ [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void To<#=pixelType#>Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) { - this.To<#=pixelType#>(sourceColors, destBytes.NonPortableCast>(), count); + this.To<#=pixelType#>(sourceColors, MemoryMarshal.Cast>(destBytes), count); } <# } @@ -68,13 +68,13 @@ ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - Rgba32 rgba = new Rgba32(0, 0, 0, 255); + var rgba = new Rgba32(0, 0, 0, 255); for (int i = 0; i < count; i++) { ref TPixel dp = ref Unsafe.Add(ref destRef, i); <#=rgbaOperationCode#> - dp.PackFromRgba32(rgba); + dp.PackFromRgba32(rgba); } } @@ -88,7 +88,49 @@ [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void PackFrom<#=pixelType#>Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFrom<#=pixelType#>(sourceBytes.NonPortableCast>(), destPixels, count); + this.PackFrom<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); + } + <# + } + + void GeneratePackFromMethodUsingPackFromArgb32(string pixelType, string argbOperationCode) + { + #> + + /// + /// Converts 'count' elements in 'source` span of data to a span of -s. + /// + /// The source of data. + /// The to the destination pixels. + /// The number of pixels to convert. + internal virtual void PackFrom<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); + ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); + + var argb = new Argb32(0, 0, 0, 255); + + for (int i = 0; i < count; i++) + { + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + <#=argbOperationCode#> + dp.PackFromArgb32(argb); + } + } + + /// + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// + /// The to the source bytes. + /// The to the destination pixels. + /// The number of pixels to convert. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void PackFrom<#=pixelType#>Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + { + this.PackFrom<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); } <# } @@ -120,6 +162,9 @@ namespace SixLabors.ImageSharp.PixelFormats GeneratePackFromMethodUsingPackFromRgba32("Bgr24", "rgba.Bgr = Unsafe.Add(ref sourceRef, i);"); GenerateToDestFormatMethods("Bgr24"); + GeneratePackFromMethodUsingPackFromArgb32("Argb32", "argb = Unsafe.Add(ref sourceRef, i);"); + GenerateToDestFormatMethods("Argb32"); + #> } diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs index a8e68e36d..e68efba25 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs @@ -112,6 +112,38 @@ namespace SixLabors.ImageSharp.PixelFormats } } + /// + internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + dp = sp.ToRgba32(); + } + } + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span dest, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(dest); + + for (int i = 0; i < count; i++) + { + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + dp = sp.ToArgb32(); + } + } + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt index 4a88bbad7..a73433339 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt @@ -79,6 +79,9 @@ namespace SixLabors.ImageSharp.PixelFormats GeneratePackFromMethod("Bgra32", "dp = sp.ToRgba32();"); GenerateConvertToMethod("Bgra32", "dp = sp.ToBgra32();"); + + GeneratePackFromMethod("Argb32", "dp = sp.ToRgba32();"); + GenerateConvertToMethod("Argb32", "dp = sp.ToArgb32();"); #> } diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 0569b796d..07548a90a 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 b26ae9598..5e09a4d9a 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 c92de4ef1..31d5c6d6b 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 954e14cc0..dcdedac0e 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 9bac82856..2d5a72a6e 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 a3aa60fd2..413730561 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 afea6aaad..c7f8e9b16 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 87c92cb73..314c00d6c 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/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 5ce029af3..21863d48a 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 f07eadd56..db798e053 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) + { + this.R = source.R; + this.G = source.G; + this.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 39eed08f3..1d161b6ff 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 182fd7cce..a948a2c6c 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -275,6 +275,16 @@ namespace SixLabors.ImageSharp.PixelFormats this = source; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromArgb32(Argb32 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = source.A; + } + /// /// Converts the value of this instance to a hexadecimal string. /// @@ -299,6 +309,16 @@ 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) @@ -357,6 +377,17 @@ namespace SixLabors.ImageSharp.PixelFormats return new Bgra32(this.R, this.G, this.B, this.A); } + /// + /// Gets the value of this struct as . + /// Useful for changing the component order. + /// + /// A value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Argb32 ToArgb32() + { + return new Argb32(this.R, this.G, this.B, this.A); + } + /// public override bool Equals(object obj) { @@ -380,16 +411,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 4a2f9ef6a..6d7162992 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 92faa4e27..7609b4149 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 75429c0af..cb3b51e7e 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 0ea2b10c2..786eaf74b 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) diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index 0ff0b8557..d63467435 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(Rgba32.White, backgroundPixel); Assert.Equal(overlayPixel, background[0, 0]); - background.DebugSave(provider, new[] { "Negative" }); + background.DebugSave(provider, testOutputDetails: "Negative"); } } @@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(Rgba32.White, backgroundPixel); Assert.Equal(overlayPixel, background[xy, xy]); - background.DebugSave(provider, new[] { "Positive" }); + background.DebugSave(provider, testOutputDetails: "Positive"); } } } diff --git a/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs b/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs index 5c0e3586e..028153142 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs @@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Tests.Colors float z = +0.5f; float w = -0.7f; var argb = new Argb32(x, y, z, w); - Assert.Equal(0x001a0080u, argb.PackedValue); + Assert.Equal(0x80001a00u, argb.PackedValue); // Test ordering var rgb = default(Rgb24); diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs index d1270dcfd..d04d2343f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs @@ -12,72 +12,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs { public static class SystemDrawingBridge { - // TODO: It would be nice to have this method in PixelOperations - private static void ToArgb32(Span source, Span dest) - where TPixel : struct, IPixel - { - int length = source.Length; - Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); - - using (IBuffer rgbaBuffer = Configuration.Default.MemoryManager.Allocate(length)) - { - Span rgbaSpan = rgbaBuffer.Span; - PixelOperations.Instance.ToRgba32(source, rgbaSpan, length); - - for (int i = 0; i < length; i++) - { - ref Rgba32 s = ref rgbaSpan[i]; - ref Argb32 d = ref dest[i]; - - d.PackFromRgba32(s); - } - } - } - - private static void FromArgb32(Span source, Span dest) - where TPixel : struct, IPixel - { - int length = source.Length; - Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); - - using (IBuffer rgbaBuffer = Configuration.Default.MemoryManager.Allocate(length)) - { - Span rgbaSpan = rgbaBuffer.Span; - PixelOperations.Instance.ToRgba32(source, rgbaSpan, length); - - for (int i = 0; i < length; i++) - { - ref Rgba32 s = ref rgbaSpan[i]; - ref TPixel d = ref dest[i]; - - d.PackFromRgba32(s); - } - } - } - - private static void FromRgb24(Span source, Span dest) - where TPixel : struct, IPixel - { - int length = source.Length; - Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); - - using (IBuffer rgbBuffer = Configuration.Default.MemoryManager.Allocate(length)) - { - Span rgbSpan = rgbBuffer.Span; - PixelOperations.Instance.ToRgb24(source, rgbSpan, length); - - for (int i = 0; i < length; i++) - { - ref Rgb24 s = ref rgbSpan[i]; - ref TPixel d = ref dest[i]; - var rgba = default(Rgba32); - s.ToRgba32(ref rgba); - - d.PackFromRgba32(rgba); - } - } - } - internal static unsafe Image FromFromArgb32SystemDrawingBitmap(System.Drawing.Bitmap bmp) where TPixel : struct, IPixel { @@ -99,9 +33,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs var image = new Image(w, h); - using (IBuffer workBuffer = Configuration.Default.MemoryManager.Allocate(w)) + using (IBuffer workBuffer = Configuration.Default.MemoryManager.Allocate(w)) { - fixed (Argb32* destPtr = &workBuffer.DangerousGetPinnableReference()) + fixed (Bgra32* destPtr = &workBuffer.DangerousGetPinnableReference()) { for (int y = 0; y < h; y++) { @@ -110,8 +44,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + data.Stride * y; Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); - - FromArgb32(workBuffer.Span, row); + PixelOperations.Instance.PackFromBgra32(workBuffer.Span, row, row.Length); } } } @@ -139,13 +72,13 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtrBase = (byte*)data.Scan0; long sourceRowByteCount = data.Stride; - long destRowByteCount = w * sizeof(Rgb24); + long destRowByteCount = w * sizeof(Bgr24); var image = new Image(w, h); - using (IBuffer workBuffer = Configuration.Default.MemoryManager.Allocate(w)) + using (IBuffer workBuffer = Configuration.Default.MemoryManager.Allocate(w)) { - fixed (Rgb24* destPtr = &workBuffer.DangerousGetPinnableReference()) + fixed (Bgr24* destPtr = &workBuffer.DangerousGetPinnableReference()) { for (int y = 0; y < h; y++) { @@ -154,8 +87,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* sourcePtr = sourcePtrBase + data.Stride * y; Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); + PixelOperations.Instance.PackFromBgr24(workBuffer.Span, row, row.Length); - FromRgb24(workBuffer.Span, row); + // FromRgb24(workBuffer.Span, row); } } } @@ -175,17 +109,17 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs byte* destPtrBase = (byte*)data.Scan0; long destRowByteCount = data.Stride; - long sourceRowByteCount = w * sizeof(Argb32); + long sourceRowByteCount = w * sizeof(Bgra32); - using (IBuffer workBuffer = image.GetConfiguration().MemoryManager.Allocate(w)) + using (IBuffer workBuffer = image.GetConfiguration().MemoryManager.Allocate(w)) { - fixed (Argb32* sourcePtr = &workBuffer.DangerousGetPinnableReference()) + fixed (Bgra32* sourcePtr = &workBuffer.DangerousGetPinnableReference()) { for (int y = 0; y < h; y++) { Span row = image.Frames.RootFrame.GetPixelRowSpan(y); - ToArgb32(row, workBuffer.Span); + PixelOperations.Instance.ToBgra32(row, workBuffer.Span, row.Length); byte* destPtr = destPtrBase + data.Stride * y; Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs index 6ff935b54..eda6c99a3 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Tests } } - [Theory(Skip = "Doesen't work yet :(")] + [Theory] [WithTestPatternImages(100, 100, PixelTypes.Rgba32)] public void FromFromRgb24SystemDrawingBitmap2(TestImageProvider provider) where TPixel : struct, IPixel