diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index e781538c0..659b2439f 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -99,7 +99,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) { + public void PackFromArgb32(Argb32 source) + { + this.PackedValue = source.A; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { this.PackedValue = source.A; } @@ -122,7 +130,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { dest.R = 0; dest.G = 0; dest.B = 0; diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 603821410..ef869af01 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// /// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. - /// The color components are stored in alpha, red, green, and blue order. + /// The color components are stored in alpha, red, green, and blue order (least significant to most significant byte). /// /// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form. /// @@ -141,16 +141,10 @@ namespace SixLabors.ImageSharp.PixelFormats public uint Argb { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return Unsafe.As(ref this); - } + get => Unsafe.As(ref this); [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - Unsafe.As(ref this) = value; - } + set => Unsafe.As(ref this) = value; } /// @@ -240,6 +234,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackedValue = source.PackedValue; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 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) @@ -292,10 +296,24 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); + /// + /// Converts the pixel to format. + /// + /// The RGBA value + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Bgra32 ToBgra32() => new Bgra32(this.R, this.G, this.B, this.A); + + /// + /// Converts the pixel to format. + /// + /// The RGBA value + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Argb32 ToArgb32() => this; + /// public override bool Equals(object obj) { - return obj is Argb32 && this.Equals((Argb32)obj); + return obj is Argb32 argb32 && this.Equals(argb32); } /// diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index 5c1845768..955b5c161 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// /// Pixel type containing three 8-bit unsigned normalized values ranging from 0 to 255. - /// The color components are stored in blue, green, red order. + /// The color components are stored in blue, green, red order (least significant to most significant byte). /// /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. /// @@ -84,7 +84,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) { + public void PackFromArgb32(Argb32 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { this.R = source.R; this.G = source.G; this.B = source.B; @@ -141,7 +151,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { dest.R = this.R; dest.G = this.G; dest.B = this.B; diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 92717ad0a..d1fa162e7 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -122,7 +122,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) { + public void PackFromArgb32(Argb32 source) + { + this.PackFromVector4(source.ToVector4()); + } + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { this.PackFromVector4(source.ToVector4()); } @@ -149,7 +157,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + 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); diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index 91875671a..20dfda504 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// /// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. - /// The color components are stored in blue, green, red, and alpha order. + /// The color components are stored in blue, green, red, and alpha order (least significant to most significant byte). /// /// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form. /// @@ -75,16 +75,10 @@ namespace SixLabors.ImageSharp.PixelFormats public uint Bgra { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return Unsafe.As(ref this); - } + get => Unsafe.As(ref this); [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - Unsafe.As(ref this) = value; - } + set => Unsafe.As(ref this) = value; } /// @@ -119,6 +113,16 @@ namespace SixLabors.ImageSharp.PixelFormats } } + /// + /// 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); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromScaledVector4(Vector4 vector) @@ -169,6 +173,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackedValue = source.PackedValue; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -190,7 +201,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { dest.R = this.R; dest.G = this.G; dest.B = this.B; @@ -217,5 +229,19 @@ namespace SixLabors.ImageSharp.PixelFormats /// The RGBA value [MethodImpl(MethodImplOptions.AggressiveInlining)] public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); + + /// + /// Converts the pixel to format. + /// + /// The RGBA value + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Argb32 ToArgb32() => new Argb32(this.R, this.G, this.B, this.A); + + /// + /// Converts the pixel to format. + /// + /// The RGBA value + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Bgra32 ToBgra32() => this; } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index b8afac958..393723c85 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -118,6 +118,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -141,7 +148,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToVector4() * 255F; dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index 028b85fc1..ba3441270 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -118,6 +118,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -141,7 +148,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index f9e34a645..d91dac9ac 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -119,6 +119,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToByteScaledVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToByteScaledVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -142,7 +149,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { var vector = this.ToVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index d196f6e23..025204c89 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -95,13 +95,13 @@ namespace SixLabors.ImageSharp.PixelFormats ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - var rgba = new Rgba32(0, 0, 0, 255); + var bgra = new Bgra32(0, 0, 0, 255); for (int i = 0; i < count; i++) { ref TPixel dp = ref Unsafe.Add(ref destRef, i); - rgba = Unsafe.Add(ref sourceRef, i).ToRgba32(); - dp.PackFromRgba32(rgba); + bgra = Unsafe.Add(ref sourceRef, i); + dp.PackFromBgra32(bgra); } } diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index c9955864c..060973c74 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -135,6 +135,48 @@ <# } + void GeneratePackFromMethodUsingPackFromBgra32(string pixelType, string bgraOperationCode) + { + #> + + /// + /// 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 bgra = new Bgra32(0, 0, 0, 255); + + for (int i = 0; i < count; i++) + { + ref TPixel dp = ref Unsafe.Add(ref destRef, i); + <#=bgraOperationCode#> + dp.PackFromBgra32(bgra); + } + } + + /// + /// 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); + } + <# + } + #> // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. @@ -153,7 +195,7 @@ namespace SixLabors.ImageSharp.PixelFormats GeneratePackFromMethodUsingPackFromRgba32("Rgba32", "rgba = Unsafe.Add(ref sourceRef, i);"); GenerateToDestFormatMethods("Rgba32"); - GeneratePackFromMethodUsingPackFromRgba32("Bgra32", "rgba = Unsafe.Add(ref sourceRef, i).ToRgba32();"); + GeneratePackFromMethodUsingPackFromBgra32("Bgra32", "bgra = Unsafe.Add(ref sourceRef, i);"); GenerateToDestFormatMethods("Bgra32"); GeneratePackFromMethodUsingPackFromRgba32("Rgb24", "rgba.Rgb = Unsafe.Add(ref sourceRef, i);"); diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 07548a90a..f85370ba1 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -132,6 +132,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -155,7 +162,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index 5e09a4d9a..acee34d6c 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -147,6 +147,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -170,7 +177,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index 31d5c6d6b..7c4cfb31c 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -140,6 +140,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -163,7 +170,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index dcdedac0e..7501cf382 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -8,6 +8,8 @@ namespace SixLabors.ImageSharp.PixelFormats { /// /// An interface that represents a generic pixel type. + /// The naming convention of each pixel format is to order the color components from least significant to most significant, reading from left to right. + /// For example in the pixel format the R component is the least significant byte, and the A component is the most significant. /// /// The type implementing this interface public interface IPixel : IPixel, IEquatable @@ -65,6 +67,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromArgb32(Argb32 source); + /// + /// Packs the pixel from an value. + /// + /// The value. + void PackFromBgra32(Bgra32 source); + /// /// Converts the pixel to format. /// diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 2d5a72a6e..36ca11dd8 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -161,6 +161,18 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(vector); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 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) @@ -184,7 +196,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index 413730561..8471285c7 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -144,7 +144,20 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) { + 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 PackFromBgra32(Bgra32 source) + { Vector4 vector = source.ToByteScaledVector4(); vector -= Round; vector -= Half; @@ -176,7 +189,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index c7f8e9b16..6907594a0 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -138,7 +138,20 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromArgb32(Argb32 source) { + 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 PackFromBgra32(Bgra32 source) + { Vector4 vector = source.ToByteScaledVector4(); vector -= Round; vector -= Half; @@ -170,7 +183,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)MathF.Round(vector.X); dest.G = (byte)MathF.Round(vector.Y); diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 314c00d6c..78c65212b 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -156,6 +156,18 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(vector); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 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) @@ -179,7 +191,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)MathF.Round(vector.X); dest.G = (byte)MathF.Round(vector.Y); diff --git a/src/ImageSharp/PixelFormats/README.md b/src/ImageSharp/PixelFormats/README.md index c7aa01295..c332bc92c 100644 --- a/src/ImageSharp/PixelFormats/README.md +++ b/src/ImageSharp/PixelFormats/README.md @@ -4,4 +4,7 @@ https://github.com/MonoGame/MonoGame Rgba32 is our default format. As such it positioned within the ImageSharp root namespace to ensure visibility of the format. -All other pixel formats should be positioned within ImageSharp.PixelFormats to reduce intellisense burden. \ No newline at end of file +All other pixel formats should be positioned within ImageSharp.PixelFormats to reduce intellisense burden. + +The naming convention of each pixel format is to order the color components from least significant to most significant, reading from left to right. +For example in the Rgba32 pixel format the R component is the least significant byte, and the A component is the most significant. diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 21863d48a..696b823ce 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -131,6 +131,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -154,7 +161,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)vector.X; dest.G = (byte)vector.Y; diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index db798e053..fa03683c6 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// /// Pixel type containing three 8-bit unsigned normalized values ranging from 0 to 255. - /// The color components are stored in red, green, blue order. + /// The color components are stored in red, green, blue order (least significant to most significant byte). /// /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. /// @@ -92,6 +92,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.B; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PackFromScaledVector4(Vector4 vector) @@ -137,7 +146,8 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { dest.R = this.R; dest.G = this.G; dest.B = this.B; diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 1d161b6ff..166936d5e 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -125,6 +125,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -148,7 +155,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + 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); diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index a948a2c6c..f6979aad8 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.PixelFormats { /// /// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255. - /// The color components are stored in red, green, blue, and alpha order. + /// The color components are stored in red, green, blue, and alpha order (least significant to most significant byte). /// /// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form. /// @@ -161,16 +161,10 @@ namespace SixLabors.ImageSharp.PixelFormats public uint Rgba { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return Unsafe.As(ref this); - } + get => Unsafe.As(ref this); [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - Unsafe.As(ref this) = value; - } + set => Unsafe.As(ref this) = value; } /// @@ -179,16 +173,10 @@ namespace SixLabors.ImageSharp.PixelFormats public Rgb24 Rgb { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return Unsafe.As(ref this); - } + get => Unsafe.As(ref this); [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - Unsafe.As(ref this) = value; - } + set => Unsafe.As(ref this) = value; } /// @@ -197,10 +185,7 @@ namespace SixLabors.ImageSharp.PixelFormats public Bgr24 Bgr { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - return new Bgr24(this.R, this.G, this.B); - } + get => new Bgr24(this.R, this.G, this.B); [MethodImpl(MethodImplOptions.AggressiveInlining)] set @@ -285,13 +270,23 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 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. /// /// A hexadecimal string representation of the value. public string ToHex() { - uint hexOrder = Pack(this.A, this.B, this.G, this.R); + uint hexOrder = (uint)(this.A << 0 | this.B << 8 | this.G << 16 | this.R << 24); return hexOrder.ToString("X8"); } @@ -372,10 +367,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// A value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Bgra32 ToBgra32() - { - return new Bgra32(this.R, this.G, this.B, this.A); - } + public Bgra32 ToBgra32() => new Bgra32(this.R, this.G, this.B, this.A); /// /// Gets the value of this struct as . @@ -383,10 +375,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// A value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Argb32 ToArgb32() - { - return new Argb32(this.R, this.G, this.B, this.A); - } + public Argb32 ToArgb32() => new Argb32(this.R, this.G, this.B, this.A); + + /// + /// Converts the pixel to format. + /// + /// The RGBA value + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Rgba32 ToRgba32() => this; /// public override bool Equals(object obj) @@ -428,20 +424,6 @@ namespace SixLabors.ImageSharp.PixelFormats return new Vector4(this.R, this.G, this.B, this.A); } - /// - /// Packs the four floats into a . - /// - /// The x-component - /// The y-component - /// The z-component - /// The w-component - /// The - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Pack(byte x, byte y, byte z, byte w) - { - return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift); - } - /// /// Packs a into a color returning a new instance as a result. /// diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 6d7162992..1507a258c 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -124,6 +124,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackFromVector4(source.ToVector4()); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.PackFromVector4(source.ToVector4()); + } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgb24(ref Rgb24 dest) @@ -147,7 +154,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + 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); diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index 7609b4149..6eaf69214 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -225,6 +225,13 @@ namespace SixLabors.ImageSharp.PixelFormats this.backingVector = source.ToVector4(); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 source) + { + this.backingVector = source.ToVector4(); + } + /// /// Converts the value of this instance to a hexadecimal string. /// @@ -261,7 +268,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)MathF.Round(vector.X); dest.G = (byte)MathF.Round(vector.Y); diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index cb3b51e7e..abe653e88 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -144,6 +144,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackedValue = Pack(vector.X, vector.Y); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 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) @@ -167,7 +177,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector2 vector = this.ToByteScaledVector2(); dest.R = (byte)MathF.Round(vector.X); dest.G = (byte)MathF.Round(vector.Y); diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 786eaf74b..d3bb891d9 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -150,6 +150,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); } + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PackFromBgra32(Bgra32 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) @@ -173,7 +183,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ToArgb32(ref Argb32 dest) { + public void ToArgb32(ref Argb32 dest) + { Vector4 vector = this.ToByteScaledVector4(); dest.R = (byte)MathF.Round(vector.X); dest.G = (byte)MathF.Round(vector.Y); diff --git a/tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs b/tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs index ad8297fbb..c9a1c8fe7 100644 --- a/tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs @@ -28,16 +28,16 @@ namespace SixLabors.ImageSharp.Tests.Colors { float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - yield return new object[] { new Argb32(), vector4Components }; - yield return new object[] { new Bgra4444(), vector4Components }; - yield return new object[] { new Bgra5551(), vector4Components }; - yield return new object[] { new Byte4(), vector4Components }; - yield return new object[] { new HalfVector4(), vector4Components }; - yield return new object[] { new NormalizedByte4(), vector4Components }; - yield return new object[] { new NormalizedShort4(), vector4Components }; - yield return new object[] { new Rgba1010102(), vector4Components }; - yield return new object[] { new Rgba64(), vector4Components }; - yield return new object[] { new Short4(), vector4Components }; + yield return new object[] { default(Argb32), vector4Components }; + yield return new object[] { default(Bgra4444), vector4Components }; + yield return new object[] { default(Bgra5551), vector4Components }; + yield return new object[] { default(Byte4), vector4Components }; + yield return new object[] { default(HalfVector4), vector4Components }; + yield return new object[] { default(NormalizedByte4), vector4Components }; + yield return new object[] { default(NormalizedShort4), vector4Components }; + yield return new object[] { default(Rgba1010102), vector4Components }; + yield return new object[] { default(Rgba64), vector4Components }; + yield return new object[] { default(Short4), vector4Components }; } } } @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Tests.Colors { float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W }; - yield return new object[] { new Argb32(), vector4Components }; + yield return new object[] { default(Argb32), vector4Components }; yield return new object[] { new Bgr565(), vector4Components }; } } diff --git a/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs b/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs index 028153142..546d675c1 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs @@ -47,27 +47,31 @@ namespace SixLabors.ImageSharp.Tests.Colors Assert.Equal(.5F, scaled.W, 2); // Test PackFromScaledVector4. - var pixel = default(Alpha8); - pixel.PackFromScaledVector4(scaled); - Assert.Equal(128, pixel.PackedValue); + Alpha8 alpha = default; + alpha.PackFromScaledVector4(scaled); + Assert.Equal(128, alpha.PackedValue); // Test Rgb conversion - var rgb = default(Rgb24); - var rgba = default(Rgba32); - var bgr = default(Bgr24); - var bgra = default(Bgra32); + Rgb24 rgb = default; + Rgba32 rgba = default; + Bgr24 bgr = default; + Bgra32 bgra = default; + Argb32 argb = default; - new Alpha8(.5F).ToRgb24(ref rgb); + alpha.ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(0, 0, 0)); - new Alpha8(.5F).ToRgba32(ref rgba); + alpha.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(0, 0, 0, 128)); - new Alpha8(.5F).ToBgr24(ref bgr); + alpha.ToBgr24(ref bgr); Assert.Equal(bgr, new Bgr24(0, 0, 0)); - new Alpha8(.5F).ToBgra32(ref bgra); + alpha.ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(0, 0, 0, 128)); + + alpha.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(0, 0, 0, 128)); } [Fact] @@ -113,19 +117,40 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); - + var argb2 = default(Argb32); argb.ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(0x1a, 0, 0x80)); argb.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0)); + Assert.Equal(rgba, argb.ToRgba32()); argb.ToBgr24(ref bgr); Assert.Equal(bgr, new Bgr24(0x1a, 0, 0x80)); argb.ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0)); + Assert.Equal(bgra, argb.ToBgra32()); + + argb.ToArgb32(ref argb2); + Assert.Equal(argb2, new Argb32(0x1a, 0, 0x80, 0)); + Assert.Equal(argb2, argb.ToArgb32()); + + var r = default(Argb32); + r.PackFromRgba32(new Rgba32(0x1a, 0, 0x80, 0)); + r.ToRgba32(ref rgba); + Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0)); + + r = default(Argb32); + r.PackFromBgra32(new Bgra32(0x1a, 0, 0x80, 0)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0)); + + r = default(Argb32); + r.PackFromArgb32(new Argb32(0x1a, 0, 0x80, 0)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(0x1a, 0, 0x80, 0)); } [Fact] @@ -173,6 +198,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new Bgr565(x, y, z).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(25, 0, 132)); @@ -185,6 +211,9 @@ namespace SixLabors.ImageSharp.Tests.Colors new Bgr565(x, y, z).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(25, 0, 132, 255)); + + new Bgr565(x, y, z).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(25, 0, 132, 255)); } [Fact] @@ -235,6 +264,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new Bgra4444(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(34, 0, 136)); @@ -247,6 +277,24 @@ namespace SixLabors.ImageSharp.Tests.Colors new Bgra4444(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(34, 0, 136, 0)); + + new Bgra4444(x, y, z, w).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(34, 0, 136, 0)); + + var r = default(Bgra4444); + r.PackFromRgba32(new Rgba32(34, 0, 136, 0)); + r.ToRgba32(ref rgba); + Assert.Equal(rgba, new Rgba32(34, 0, 136, 0)); + + r = default(Bgra4444); + r.PackFromBgra32(new Bgra32(34, 0, 136, 0)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(34, 0, 136, 0)); + + r = default(Bgra4444); + r.PackFromArgb32(new Argb32(34, 0, 136, 0)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(34, 0, 136, 0)); } [Fact] @@ -293,6 +341,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new Bgra5551(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(24, 0, 131)); @@ -305,6 +354,24 @@ namespace SixLabors.ImageSharp.Tests.Colors new Bgra5551(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(24, 0, 131, 0)); + + new Bgra5551(x, y, z, w).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(24, 0, 131, 0)); + + var r = default(Bgra5551); + r.PackFromRgba32(new Rgba32(24, 0, 131, 0)); + r.ToRgba32(ref rgba); + Assert.Equal(rgba, new Rgba32(24, 0, 131, 0)); + + r = default(Bgra5551); + r.PackFromBgra32(new Bgra32(24, 0, 131, 0)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(24, 0, 131, 0)); + + r = default(Bgra5551); + r.PackFromArgb32(new Argb32(24, 0, 131, 0)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(24, 0, 131, 0)); } [Fact] @@ -356,6 +423,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new Byte4(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(128, 0, 0)); @@ -369,10 +437,23 @@ namespace SixLabors.ImageSharp.Tests.Colors new Byte4(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(128, 0, 0, 0)); - var r = new Byte4(); + new Byte4(x, y, z, w).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(128, 0, 0, 0)); + + var r = default(Byte4); r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(20, 38, 0, 255)); + + r = default(Byte4); + r.PackFromBgra32(new Bgra32(20, 38, 0, 255)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(20, 38, 0, 255)); + + r = default(Byte4); + r.PackFromArgb32(new Argb32(20, 38, 0, 255)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(20, 38, 0, 255)); } [Fact] @@ -407,6 +488,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new HalfSingle(x).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(128, 0, 0)); @@ -419,6 +501,9 @@ namespace SixLabors.ImageSharp.Tests.Colors new HalfSingle(x).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(128, 0, 0, 255)); + + new HalfSingle(x).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(128, 0, 0, 255)); } [Fact] @@ -456,6 +541,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new HalfVector2(x, y).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(128, 64, 0)); @@ -468,6 +554,9 @@ namespace SixLabors.ImageSharp.Tests.Colors new HalfVector2(x, y).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(128, 64, 0, 255)); + + new HalfVector2(x, y).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(128, 64, 0, 255)); } [Fact] @@ -514,6 +603,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new HalfVector4(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(64, 128, 191)); @@ -526,6 +616,24 @@ namespace SixLabors.ImageSharp.Tests.Colors new HalfVector4(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(64, 128, 191, 255)); + + new HalfVector4(x, y, z, w).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(64, 128, 191, 255)); + + var r = default(HalfVector4); + r.PackFromRgba32(new Rgba32(64, 128, 191, 255)); + r.ToRgba32(ref rgba); + Assert.Equal(rgba, new Rgba32(64, 128, 191, 255)); + + r = default(HalfVector4); + r.PackFromBgra32(new Bgra32(64, 128, 191, 255)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(64, 128, 191, 255)); + + r = default(HalfVector4); + r.PackFromArgb32(new Argb32(64, 128, 191, 255)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(64, 128, 191, 255)); } [Fact] @@ -571,6 +679,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new NormalizedByte2(x, y).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(141, 90, 0)); @@ -583,6 +692,9 @@ namespace SixLabors.ImageSharp.Tests.Colors new NormalizedByte2(x, y).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(141, 90, 0, 255)); + + new NormalizedByte2(x, y).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(141, 90, 0, 255)); } [Fact] @@ -618,7 +730,7 @@ namespace SixLabors.ImageSharp.Tests.Colors float z = 0.5f; float w = -0.7f; Assert.Equal(0xA740DA0D, new NormalizedByte4(x, y, z, w).PackedValue); - var n = new NormalizedByte4(); + var n = default(NormalizedByte4); n.PackFromRgba32(new Rgba32(141, 90, 192, 39)); Assert.Equal(0xA740DA0D, n.PackedValue); @@ -628,6 +740,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new NormalizedByte4(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(141, 90, 192)); @@ -641,8 +754,11 @@ namespace SixLabors.ImageSharp.Tests.Colors new NormalizedByte4(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(141, 90, 192, 39)); + new NormalizedByte4(x, y, z, w).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(141, 90, 192, 39)); + // http://community.monogame.net/t/normalizedbyte4-texture2d-gives-different-results-from-xna/8012/8 - var r = new NormalizedByte4(); + var r = default(NormalizedByte4); r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); @@ -650,6 +766,16 @@ namespace SixLabors.ImageSharp.Tests.Colors r.PackedValue = 0xff4af389; r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); + + r = default(NormalizedByte4); + r.PackFromArgb32(new Argb32(9, 115, 202, 127)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(9, 115, 202, 127)); + + r = default(NormalizedByte4); + r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); } [Fact] @@ -692,6 +818,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); var n = new NormalizedShort2(); n.PackFromRgba32(new Rgba32(141, 90, 0, 0)); @@ -712,6 +839,9 @@ namespace SixLabors.ImageSharp.Tests.Colors new NormalizedShort2(x, y).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(141, 90, 0, 255)); + + new NormalizedShort2(x, y).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(141, 90, 0, 255)); } [Fact] @@ -753,6 +883,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new NormalizedShort4(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(141, 90, 192)); @@ -766,10 +897,23 @@ namespace SixLabors.ImageSharp.Tests.Colors new NormalizedShort4(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(141, 90, 192, 39)); - var r = new NormalizedShort4(); + new NormalizedShort4(x, y, z, w).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(141, 90, 192, 39)); + + var r = default(NormalizedShort4); r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(9, 115, 202, 127)); + + r = default(NormalizedShort4); + r.PackFromBgra32(new Bgra32(9, 115, 202, 127)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(9, 115, 202, 127)); + + r = default(NormalizedShort4); + r.PackFromArgb32(new Argb32(9, 115, 202, 127)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(9, 115, 202, 127)); } [Fact] @@ -812,6 +956,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new Rg32(x, y).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(25, 0, 0)); @@ -824,6 +969,9 @@ namespace SixLabors.ImageSharp.Tests.Colors new Rg32(x, y).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(25, 0, 0, 255)); + + new Rg32(x, y).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(25, 0, 0, 255)); } [Fact] @@ -869,6 +1017,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new Rgba1010102(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(25, 0, 128)); @@ -883,10 +1032,20 @@ namespace SixLabors.ImageSharp.Tests.Colors Assert.Equal(bgra, new Bgra32(25, 0, 128, 0)); // Alpha component accuracy will be awful. - var r = new Rgba1010102(); + var r = default(Rgba1010102); r.PackFromRgba32(new Rgba32(25, 0, 128, 0)); r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(25, 0, 128, 0)); + + r = default(Rgba1010102); + r.PackFromBgra32(new Bgra32(25, 0, 128, 0)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(25, 0, 128, 0)); + + r = default(Rgba1010102); + r.PackFromArgb32(new Argb32(25, 0, 128, 0)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(25, 0, 128, 0)); } [Fact] @@ -932,18 +1091,40 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); rgba32.ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(0x1a, 0, 0x80)); rgba32.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0)); + Assert.Equal(rgba, rgba.ToRgba32()); rgba32.ToBgr24(ref bgr); Assert.Equal(bgr, new Bgr24(0x1a, 0, 0x80)); rgba32.ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0)); + Assert.Equal(bgra, bgra.ToBgra32()); + + rgba32.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(0x1a, 0, 0x80, 0)); + Assert.Equal(argb, argb.ToArgb32()); + + var r = default(Rgba32); + r.PackFromRgba32(new Rgba32(0x1a, 0, 0x80, 0)); + r.ToRgba32(ref rgba); + Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0)); + + r = default(Rgba32); + r.PackFromBgra32(new Bgra32(0x1a, 0, 0x80, 0)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0)); + + r = default(Rgba32); + r.PackFromArgb32(new Argb32(0x1a, 0, 0x80, 0)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(0x1a, 0, 0x80, 0)); } [Fact] @@ -1008,7 +1189,7 @@ namespace SixLabors.ImageSharp.Tests.Colors new Rgba64(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(20, 38, 76, 115)); - var r = new Rgba64(); + var r = default(Rgba64); r.PackFromRgba32(new Rgba32(20, 38, 76, 115)); r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(20, 38, 76, 115)); @@ -1075,7 +1256,7 @@ namespace SixLabors.ImageSharp.Tests.Colors new Short2(x, y).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(128, 127, 0, 255)); - var r = new Short2(); + var r = default(Short2); r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(20, 38, 0, 255)); @@ -1131,6 +1312,7 @@ namespace SixLabors.ImageSharp.Tests.Colors var rgba = default(Rgba32); var bgr = default(Bgr24); var bgra = default(Bgra32); + var argb = default(Argb32); new Short4(x, y, z, w).ToRgb24(ref rgb); Assert.Equal(rgb, new Rgb24(172, 177, 243)); @@ -1144,10 +1326,23 @@ namespace SixLabors.ImageSharp.Tests.Colors new Short4(x, y, z, w).ToBgra32(ref bgra); Assert.Equal(bgra, new Bgra32(172, 177, 243, 128)); - var r = new Short4(); + new Short4(x, y, z, w).ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(172, 177, 243, 128)); + + var r = default(Short4); r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); r.ToRgba32(ref rgba); Assert.Equal(rgba, new Rgba32(20, 38, 0, 255)); + + r = default(Short4); + r.PackFromBgra32(new Bgra32(20, 38, 0, 255)); + r.ToBgra32(ref bgra); + Assert.Equal(bgra, new Bgra32(20, 38, 0, 255)); + + r = default(Short4); + r.PackFromArgb32(new Argb32(20, 38, 0, 255)); + r.ToArgb32(ref argb); + Assert.Equal(argb, new Argb32(20, 38, 0, 255)); } // Comparison helpers with small tolerance to allow for floating point rounding during computations. diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 4ea179d09..4ae11301d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -383,6 +383,51 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats ); } + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromWzyxBytes(int count) + { + byte[] source = CreateByteTestData(count * 4); + var expected = new TPixel[count]; + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + + expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromArgb32Bytes(s, d.Span, count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToWzyxBytes(int count) + { + TPixel[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 4]; + var argb = default(Argb32); + + for (int i = 0; i < count; i++) + { + int i4 = i * 4; + source[i].ToArgb32(ref argb); + expected[i4] = argb.A; + expected[i4 + 1] = argb.R; + expected[i4 + 2] = argb.G; + expected[i4 + 3] = argb.B; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToArgb32Bytes(s, d.Span, count) + ); + } private class TestBuffers : IDisposable where TSource : struct diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs index a8d38b938..da9ae0858 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs @@ -88,26 +88,22 @@ namespace SixLabors.ImageSharp.Tests [Fact] public void FromAndToHex() { - Rgba32 color = Rgba32.FromHex("#AABBCCDD"); + // 8 digit hex matches css4 spec. RRGGBBAA + var color = Rgba32.FromHex("#AABBCCDD"); // 170, 187, 204, 221 Assert.Equal(170, color.R); Assert.Equal(187, color.G); Assert.Equal(204, color.B); Assert.Equal(221, color.A); - color.A = 170; - color.B = 187; - color.G = 204; - color.R = 221; - - Assert.Equal("DDCCBBAA", color.ToHex()); + Assert.Equal("AABBCCDD", color.ToHex()); color.R = 0; - Assert.Equal("00CCBBAA", color.ToHex()); + Assert.Equal("00BBCCDD", color.ToHex()); color.A = 255; - Assert.Equal("00CCBBFF", color.ToHex()); + Assert.Equal("00BBCCFF", color.ToHex()); } ///