Browse Source

Update individual pixel implementations

pull/2645/head
James Jackson-South 2 years ago
parent
commit
acaebd94d7
  1. 6
      src/ImageSharp/Color/Color.cs
  2. 37
      src/ImageSharp/Common/Helpers/ColorNumerics.cs
  3. 2
      src/ImageSharp/PixelFormats/IPackedVector{TPacked}.cs
  4. 116
      src/ImageSharp/PixelFormats/IPixel.cs
  5. 98
      src/ImageSharp/PixelFormats/PixelImplementations/A8.cs
  6. 238
      src/ImageSharp/PixelFormats/PixelImplementations/Abgr32.cs
  7. 242
      src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs
  8. 199
      src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs
  9. 116
      src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs
  10. 206
      src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs
  11. 110
      src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs
  12. 112
      src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs
  13. 125
      src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs
  14. 114
      src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs
  15. 110
      src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs
  16. 118
      src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs
  17. 150
      src/ImageSharp/PixelFormats/PixelImplementations/L16.cs
  18. 144
      src/ImageSharp/PixelFormats/PixelImplementations/L8.cs
  19. 214
      src/ImageSharp/PixelFormats/PixelImplementations/La16.cs
  20. 237
      src/ImageSharp/PixelFormats/PixelImplementations/La32.cs
  21. 131
      src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs
  22. 128
      src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs
  23. 126
      src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs
  24. 124
      src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs
  25. 4
      src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/RgbaVector.PixelOperations.cs
  26. 119
      src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs
  27. 225
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs
  28. 161
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs
  29. 106
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs
  30. 269
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs
  31. 302
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs
  32. 146
      src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs
  33. 126
      src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs
  34. 134
      src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs
  35. 2
      src/ImageSharp/PixelFormats/README.md
  36. 26
      tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs
  37. 4
      tests/ImageSharp.Tests/PixelFormats/L16Tests.cs
  38. 4
      tests/ImageSharp.Tests/PixelFormats/La32Tests.cs
  39. 2
      tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.ReferenceImplementations.cs

6
src/ImageSharp/Color/Color.cs

@ -98,10 +98,8 @@ public readonly partial struct Color : IEquatable<Color>
{
return new(pixel.ToScaledVector4());
}
else
{
return new(pixel);
}
return new(pixel);
}
/// <summary>

37
src/ImageSharp/Common/Helpers/ColorNumerics.cs

@ -41,6 +41,34 @@ internal static class ColorNumerics
public static byte Get8BitBT709Luminance(byte r, byte g, byte b)
=> (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula
/// as specified by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="byte"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte Get8BitBT709Luminance(ushort r, ushort g, ushort b)
=> (byte)((From16BitTo8Bit(r) * .2126F) +
(From16BitTo8Bit(g) * .7152F) +
(From16BitTo8Bit(b) * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as
/// specified by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="ushort"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort Get16BitBT709Luminance(byte r, byte g, byte b)
=> (ushort)((From8BitTo16Bit(r) * .2126F) +
(From8BitTo16Bit(g) * .7152F) +
(From8BitTo16Bit(b) * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as
/// specified by ITU-R Recommendation BT.709.
@ -72,8 +100,8 @@ internal static class ColorNumerics
/// <param name="component">The 8 bit component value.</param>
/// <returns>The <see cref="byte"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte DownScaleFrom16BitTo8Bit(ushort component)
{
public static byte From16BitTo8Bit(ushort component) =>
// To scale to 8 bits From a 16-bit value V the required value (from the PNG specification) is:
//
// (V * 255) / 65535
@ -102,8 +130,7 @@ internal static class ColorNumerics
// An alternative arithmetic calculation which also gives no errors is:
//
// (V * 255 + 32895) >> 16
return (byte)(((component * 255) + 32895) >> 16);
}
(byte)(((component * 255) + 32895) >> 16);
/// <summary>
/// Scales a value from an 8 bit <see cref="byte"/> to
@ -112,7 +139,7 @@ internal static class ColorNumerics
/// <param name="component">The 8 bit component value.</param>
/// <returns>The <see cref="ushort"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort UpscaleFrom8BitTo16Bit(byte component)
public static ushort From8BitTo16Bit(byte component)
=> (ushort)(component * 257);
/// <summary>

2
src/ImageSharp/PixelFormats/IPackedVector{TPacked}.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.PixelFormats;

116
src/ImageSharp/PixelFormats/IPixel.cs

@ -14,135 +14,151 @@ namespace SixLabors.ImageSharp.PixelFormats;
public interface IPixel<TSelf> : IPixel, IEquatable<TSelf>
where TSelf : unmanaged, IPixel<TSelf>
{
/// <summary>
/// Gets the pixel type information.
/// </summary>
/// <returns>The <see cref="PixelTypeInfo"/>.</returns>
#pragma warning disable CA1000
static abstract PixelTypeInfo GetPixelTypeInfo();
#pragma warning restore CA1000
/// <summary>
/// Creates a <see cref="PixelOperations{TPixel}"/> instance for this pixel type.
/// This method is not intended to be consumed directly. Use <see cref="PixelOperations{TPixel}.Instance"/> instead.
/// </summary>
/// <returns>The <see cref="PixelOperations{TPixel}"/> instance.</returns>
PixelOperations<TSelf> CreatePixelOperations();
}
/// <summary>
/// A base interface for all pixels, defining the mandatory operations to be implemented by a pixel type.
/// </summary>
public interface IPixel
{
/// <summary>
/// Initializes the pixel instance from a generic ("scaled") <see cref="Vector4"/>.
/// </summary>
/// <param name="vector">The vector to load the pixel from.</param>
void FromScaledVector4(Vector4 vector);
#pragma warning disable CA1000 // Do not declare static members on generic types
/// <summary>
/// Expands the pixel into a generic ("scaled") <see cref="Vector4"/> representation
/// with values scaled and clamped between <value>0</value> and <value>1</value>.
/// The vector components are typically expanded in least to greatest significance order.
/// Gets the pixel type information.
/// </summary>
/// <returns>The <see cref="Vector4"/>.</returns>
Vector4 ToScaledVector4();
/// <returns>The <see cref="PixelTypeInfo"/>.</returns>
static abstract PixelTypeInfo GetPixelTypeInfo();
/// <summary>
/// Initializes the pixel instance from a <see cref="Vector4"/> which is specific to the current pixel type.
/// Initializes the pixel instance from a generic scaled <see cref="Vector4"/>.
/// </summary>
/// <param name="vector">The vector to load the pixel from.</param>
void FromVector4(Vector4 vector);
/// <param name="source">The vector to load the pixel from.</param>
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static abstract TSelf FromScaledVector4(Vector4 source);
/// <summary>
/// Expands the pixel into a <see cref="Vector4"/> which is specific to the current pixel type.
/// The vector components are typically expanded in least to greatest significance order.
/// Initializes the pixel instance from a <see cref="Vector4"/> which is specific to the current pixel type.
/// </summary>
/// <returns>The <see cref="Vector4"/>.</returns>
Vector4 ToVector4();
/// <param name="source">The vector to load the pixel from.</param>
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static abstract TSelf FromVector4(Vector4 source);
/// <summary>
/// Initializes the pixel instance from an <see cref="Argb32"/> value.
/// </summary>
/// <param name="source">The <see cref="Argb32"/> value.</param>
void FromArgb32(Argb32 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromArgb32(Argb32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Bgra5551"/> value.
/// </summary>
/// <param name="source">The <see cref="Bgra5551"/> value.</param>
void FromBgra5551(Bgra5551 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromBgra5551(Bgra5551 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Bgr24"/> value.
/// </summary>
/// <param name="source">The <see cref="Bgr24"/> value.</param>
void FromBgr24(Bgr24 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromBgr24(Bgr24 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Bgra32"/> value.
/// </summary>
/// <param name="source">The <see cref="Bgra32"/> value.</param>
void FromBgra32(Bgra32 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromBgra32(Bgra32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Abgr32"/> value.
/// </summary>
/// <param name="source">The <see cref="Abgr32"/> value.</param>
void FromAbgr32(Abgr32 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromAbgr32(Abgr32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="L8"/> value.
/// </summary>
/// <param name="source">The <see cref="L8"/> value.</param>
void FromL8(L8 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromL8(L8 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="L16"/> value.
/// </summary>
/// <param name="source">The <see cref="L16"/> value.</param>
void FromL16(L16 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromL16(L16 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="La16"/> value.
/// </summary>
/// <param name="source">The <see cref="La16"/> value.</param>
void FromLa16(La16 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromLa16(La16 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="La32"/> value.
/// </summary>
/// <param name="source">The <see cref="La32"/> value.</param>
void FromLa32(La32 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromLa32(La32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Rgb24"/> value.
/// </summary>
/// <param name="source">The <see cref="Rgb24"/> value.</param>
void FromRgb24(Rgb24 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromRgb24(Rgb24 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Rgba32"/> value.
/// </summary>
/// <param name="source">The <see cref="Rgba32"/> value.</param>
void FromRgba32(Rgba32 source);
/// <summary>
/// Convert the pixel instance into <see cref="Rgba32"/> representation.
/// </summary>
/// <param name="dest">The reference to the destination <see cref="Rgba32"/> pixel</param>
void ToRgba32(ref Rgba32 dest);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromRgba32(Rgba32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Rgb48"/> value.
/// </summary>
/// <param name="source">The <see cref="Rgb48"/> value.</param>
void FromRgb48(Rgb48 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromRgb48(Rgb48 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Initializes the pixel instance from an <see cref="Rgba64"/> value.
/// </summary>
/// <param name="source">The <see cref="Rgba64"/> value.</param>
void FromRgba64(Rgba64 source);
/// <returns>The <typeparamref name="TSelf"/>.</returns>
static virtual TSelf FromRgba64(Rgba64 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
#pragma warning restore CA1000 // Do not declare static members on generic types
}
/// <summary>
/// A base interface for all pixels, defining the mandatory operations to be implemented by a pixel type.
/// </summary>
public interface IPixel
{
/// <summary>
/// Convert the pixel instance into <see cref="Rgba32"/> representation.
/// </summary>
/// <returns>The <see cref="Rgba32"/></returns>
virtual Rgba32 ToRgba32() => Rgba32.FromScaledVector4(this.ToVector4());
/// <summary>
/// Expands the pixel into a generic ("scaled") <see cref="Vector4"/> representation
/// with values scaled and clamped between <value>0</value> and <value>1</value>.
/// The vector components are typically expanded in least to greatest significance order.
/// </summary>
/// <returns>The <see cref="Vector4"/>.</returns>
Vector4 ToScaledVector4();
/// <summary>
/// Expands the pixel into a <see cref="Vector4"/> which is specific to the current pixel type.
/// The vector components are typically expanded in least to greatest significance order.
/// </summary>
/// <returns>The <see cref="Vector4"/>.</returns>
Vector4 ToVector4();
}

98
src/ImageSharp/PixelFormats/PixelImplementations/A8.cs

@ -41,7 +41,7 @@ public partial struct A8 : IPixel<A8>, IPackedVector<byte>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(A8 left, A8 right) => left.Equals(right);
/// <summary>
@ -52,9 +52,21 @@ public partial struct A8 : IPixel<A8>, IPackedVector<byte>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(A8 left, A8 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => new() { A = this.PackedValue };
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(0, 0, 0, this.PackedValue / 255f);
/// <inheritdoc/>
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<A8>(
@ -66,80 +78,60 @@ public partial struct A8 : IPixel<A8>, IPackedVector<byte>
public readonly PixelOperations<A8> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(vector.W);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new(0, 0, 0, this.PackedValue / 255F);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromVector4(Vector4 source) => new(Pack(source.W));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.PackedValue = source.A;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromArgb32(Argb32 source) => new(source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.PackedValue = byte.MaxValue;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromBgr24(Bgr24 source) => new(byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.PackedValue = source.A;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromBgra32(Bgra32 source) => new(source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.PackedValue = source.A;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromAbgr32(Abgr32 source) => new(source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromL8(L8 source) => new(byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.PackedValue = byte.MaxValue;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromL16(L16 source) => new(byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.PackedValue = byte.MaxValue;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromLa16(La16 source) => new(source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.PackedValue = source.A;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromLa32(La32 source) => new(ColorNumerics.From16BitTo8Bit(source.A));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.PackedValue = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.PackedValue = byte.MaxValue;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.PackedValue = source.A;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromRgb24(Rgb24 source) => new(byte.MaxValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest = default;
dest.A = this.PackedValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromRgba32(Rgba32 source) => new(source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.PackedValue = byte.MaxValue;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromRgb48(Rgb48 source) => new(byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static A8 FromRgba64(Rgba64 source) => new(ColorNumerics.From16BitTo8Bit(source.A));
/// <summary>
/// Compares an object with the packed vector.
@ -153,7 +145,6 @@ public partial struct A8 : IPixel<A8>, IPackedVector<byte>
/// </summary>
/// <param name="other">The A8 packed vector to compare.</param>
/// <returns>True if the packed vectors are equal.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(A8 other) => this.PackedValue.Equals(other.PackedValue);
/// <summary>
@ -163,7 +154,6 @@ public partial struct A8 : IPixel<A8>, IPackedVector<byte>
public override readonly string ToString() => $"A8({this.PackedValue})";
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <summary>
@ -171,6 +161,6 @@ public partial struct A8 : IPixel<A8>, IPackedVector<byte>
/// </summary>
/// <param name="alpha">The float containing the value to pack.</param>
/// <returns>The <see cref="byte"/> containing the packed values.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static byte Pack(float alpha) => (byte)Math.Round(Numerics.Clamp(alpha, 0, 1F) * 255F);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte Pack(float alpha) => (byte)Math.Round(Numerics.Clamp(alpha, 0, 1f) * 255f);
}

238
src/ImageSharp/PixelFormats/PixelImplementations/Abgr32.cs

@ -4,6 +4,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -44,12 +45,12 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <summary>
/// The maximum byte value.
/// </summary>
private static readonly Vector4 MaxBytes = new(255);
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
/// <summary>
/// The half vector value.
/// </summary>
private static readonly Vector4 Half = new(0.5F);
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <summary>
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
@ -57,7 +58,7 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Abgr32(byte r, byte g, byte b)
{
this.R = r;
@ -73,7 +74,7 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Abgr32(byte r, byte g, byte b, byte a)
{
this.R = r;
@ -89,9 +90,9 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Abgr32(float r, float g, float b, float a = 1)
: this() => this.Pack(r, g, b, a);
: this() => Pack(r, g, b, a);
/// <summary>
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
@ -99,9 +100,9 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Abgr32(Vector3 vector)
: this() => this.Pack(ref vector);
: this() => Pack(vector);
/// <summary>
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
@ -109,9 +110,9 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Abgr32(Vector4 vector)
: this() => this.Pack(ref vector);
: this() => Pack(vector);
/// <summary>
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
@ -119,29 +120,29 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <param name="packed">
/// The packed value.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Abgr32(uint packed)
: this() => this.Abgr = packed;
/// <summary>
/// Gets or sets the packed representation of the Abgrb32 struct.
/// Gets or sets the packed representation of the Abgr struct.
/// </summary>
public uint Abgr
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => Unsafe.As<Abgr32, uint>(ref Unsafe.AsRef(in this));
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Abgr32, uint>(ref this) = value;
}
/// <inheritdoc/>
public uint PackedValue
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => this.Abgr;
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => this.Abgr = value;
}
@ -153,7 +154,7 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Abgr32 left, Abgr32 right) => left.Equals(right);
/// <summary>
@ -164,9 +165,21 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Abgr32 left, Abgr32 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => new(this.R, this.G, this.B, this.A);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Abgr32>(
@ -178,157 +191,87 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
public readonly PixelOperations<Abgr32> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromVector4(Vector4 source) => Pack(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.Pack(ref vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromAbgr32(Abgr32 source) => new() { PackedValue = source.PackedValue };
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromBgr24(Bgr24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromArgb32(Argb32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromBgra32(Bgra32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
// We can assign the Bgr24 value directly to last three bytes of this instance.
ref byte thisRef = ref Unsafe.As<Abgr32, byte>(ref this);
ref byte thisRefFromB = ref Unsafe.AddByteOffset(ref thisRef, 1);
Unsafe.As<byte, Bgr24>(ref thisRefFromB) = source;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromL8(L8 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromL16(L16 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
byte rgb = ColorNumerics.From16BitTo8Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromLa16(La16 source) => new(source.L, source.L, source.L, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromLa32(La32 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
this.A = byte.MaxValue;
byte rgb = ColorNumerics.From16BitTo8Bit(source.L);
return new(rgb, rgb, rgb, ColorNumerics.From16BitTo8Bit(source.A));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromRgb24(Rgb24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromRgba32(Rgba32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromRgb48(Rgb48 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = byte.MaxValue
};
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = byte.MaxValue;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = this.A;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = byte.MaxValue;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Abgr32 FromRgba64(Rgba64 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = ColorNumerics.From16BitTo8Bit(source.A)
};
/// <inheritdoc/>
public override readonly bool Equals(object? obj) => obj is Abgr32 abgr32 && this.Equals(abgr32);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Abgr32 other) => this.Abgr == other.Abgr;
/// <summary>
@ -338,7 +281,6 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
public override readonly string ToString() => $"Abgr({this.A}, {this.B}, {this.G}, {this.R})";
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.Abgr.GetHashCode();
/// <summary>
@ -348,38 +290,28 @@ public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint>
/// <param name="y">The y-component</param>
/// <param name="z">The z-component</param>
/// <param name="w">The w-component</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(float x, float y, float z, float w)
{
var value = new Vector4(x, y, z, w);
this.Pack(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Abgr32 Pack(float x, float y, float z, float w) => Pack(new Vector4(x, y, z, w));
/// <summary>
/// Packs a <see cref="Vector3"/> into a uint.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(ref Vector3 vector)
{
var value = new Vector4(vector, 1);
this.Pack(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Abgr32 Pack(Vector3 vector) => Pack(new Vector4(vector, 1));
/// <summary>
/// Packs a <see cref="Vector4"/> into a color.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Abgr32 Pack(Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;
this.B = (byte)vector.Z;
this.A = (byte)vector.W;
Vector128<byte> result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
return new(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
}
}

242
src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs

@ -4,6 +4,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -41,15 +42,8 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// </summary>
public byte B;
/// <summary>
/// The maximum byte value.
/// </summary>
private static readonly Vector4 MaxBytes = new(255);
/// <summary>
/// The half vector value.
/// </summary>
private static readonly Vector4 Half = new(0.5F);
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <summary>
/// Initializes a new instance of the <see cref="Argb32"/> struct.
@ -57,7 +51,7 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(byte r, byte g, byte b)
{
this.R = r;
@ -73,7 +67,7 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(byte r, byte g, byte b, byte a)
{
this.R = r;
@ -89,9 +83,9 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(float r, float g, float b, float a = 1)
: this() => this.Pack(r, g, b, a);
: this() => Pack(r, g, b, a);
/// <summary>
/// Initializes a new instance of the <see cref="Argb32"/> struct.
@ -99,9 +93,9 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(Vector3 vector)
: this() => this.Pack(ref vector);
: this() => Pack(vector);
/// <summary>
/// Initializes a new instance of the <see cref="Argb32"/> struct.
@ -109,9 +103,9 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(Vector4 vector)
: this() => this.Pack(ref vector);
: this() => Pack(vector);
/// <summary>
/// Initializes a new instance of the <see cref="Argb32"/> struct.
@ -119,7 +113,7 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <param name="packed">
/// The packed value.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(uint packed)
: this() => this.Argb = packed;
@ -128,20 +122,20 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// </summary>
public uint Argb
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => Unsafe.As<Argb32, uint>(ref Unsafe.AsRef(in this));
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Argb32, uint>(ref this) = value;
}
/// <inheritdoc/>
public uint PackedValue
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => this.Argb;
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => this.Argb = value;
}
@ -153,7 +147,7 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Argb32 left, Argb32 right) => left.Equals(right);
/// <summary>
@ -164,9 +158,21 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Argb32 left, Argb32 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => new(this.R, this.G, this.B, this.A);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Argb32>(
@ -178,156 +184,87 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
public readonly PixelOperations<Argb32> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.Pack(ref vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromVector4(Vector4 source) => Pack(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromArgb32(Argb32 source) => new() { PackedValue = source.PackedValue };
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.PackedValue = source.PackedValue;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromBgr24(Bgr24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = byte.MaxValue;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromBgra32(Bgra32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromAbgr32(Abgr32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromL8(L8 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromL16(L16 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = byte.MaxValue;
byte rgb = ColorNumerics.From16BitTo8Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromLa16(La16 source) => new(source.L, source.L, source.L, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromLa32(La32 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
byte rgb = ColorNumerics.From16BitTo8Bit(source.L);
return new(rgb, rgb, rgb, ColorNumerics.From16BitTo8Bit(source.A));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromRgb24(Rgb24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = this.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromRgba32(Rgba32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromRgb48(Rgb48 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = byte.MaxValue
};
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argb32 FromRgba64(Rgba64 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = ColorNumerics.From16BitTo8Bit(source.A)
};
/// <inheritdoc/>
public override readonly bool Equals(object? obj) => obj is Argb32 argb32 && this.Equals(argb32);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Argb32 other) => this.Argb == other.Argb;
/// <summary>
@ -337,7 +274,6 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
public override readonly string ToString() => $"Argb({this.A}, {this.R}, {this.G}, {this.B})";
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.Argb.GetHashCode();
/// <summary>
@ -347,38 +283,28 @@ public partial struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
/// <param name="y">The y-component</param>
/// <param name="z">The z-component</param>
/// <param name="w">The w-component</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(float x, float y, float z, float w)
{
var value = new Vector4(x, y, z, w);
this.Pack(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Argb32 Pack(float x, float y, float z, float w) => Pack(new Vector4(x, y, z, w));
/// <summary>
/// Packs a <see cref="Vector3"/> into a uint.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(ref Vector3 vector)
{
var value = new Vector4(vector, 1);
this.Pack(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Argb32 Pack(Vector3 vector) => Pack(new Vector4(vector, 1f));
/// <summary>
/// Packs a <see cref="Vector4"/> into a color.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Argb32 Pack(Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;
this.B = (byte)vector.Z;
this.A = (byte)vector.W;
Vector128<byte> result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
return new(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
}
}

199
src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs

@ -4,6 +4,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -14,40 +15,36 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="Bgr24"/> struct.
/// </remarks>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[StructLayout(LayoutKind.Explicit)]
public partial struct Bgr24 : IPixel<Bgr24>
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
public partial struct Bgr24(byte r, byte g, byte b) : IPixel<Bgr24>
{
/// <summary>
/// The blue component.
/// </summary>
[FieldOffset(0)]
public byte B;
public byte B = b;
/// <summary>
/// The green component.
/// </summary>
[FieldOffset(1)]
public byte G;
public byte G = g;
/// <summary>
/// The red component.
/// </summary>
[FieldOffset(2)]
public byte R;
public byte R = r;
/// <summary>
/// Initializes a new instance of the <see cref="Bgr24"/> struct.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public Bgr24(byte r, byte g, byte b)
{
this.R = r;
this.G = g;
this.B = b;
}
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <summary>
/// Compares two <see cref="Bgr24"/> objects for equality.
@ -57,7 +54,7 @@ public partial struct Bgr24 : IPixel<Bgr24>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Bgr24 left, Bgr24 right) => left.Equals(right);
/// <summary>
@ -68,9 +65,21 @@ public partial struct Bgr24 : IPixel<Bgr24>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Bgr24 left, Bgr24 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => new(this.R, this.G, this.B);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, byte.MaxValue) / MaxBytes;
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Bgr24>(
@ -82,143 +91,90 @@ public partial struct Bgr24 : IPixel<Bgr24>
public readonly PixelOperations<Bgr24> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromVector4(Vector4 source)
{
Rgba32 rgba = default;
rgba.FromVector4(vector);
this.FromRgba32(rgba);
}
source *= MaxBytes;
source += Half;
source = Numerics.Clamp(source, Vector4.Zero, MaxBytes);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Rgba32(this.R, this.G, this.B, byte.MaxValue).ToVector4();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
Vector128<byte> result = Vector128.ConvertToInt32(source.AsVector128()).AsByte();
return new(result.GetElement(0), result.GetElement(4), result.GetElement(8));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromArgb32(Argb32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromBgr24(Bgr24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromBgra32(Bgra32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromL8(L8 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromL16(L16 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
byte rgb = ColorNumerics.From16BitTo8Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromLa16(La16 source) => new(source.L, source.L, source.L);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromLa32(La32 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
byte rgb = ColorNumerics.From16BitTo8Bit(source.L);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromRgb24(Rgb24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
{
// We can assign this instances value directly to last three bytes of the Abgr32.
ref byte sourceRef = ref Unsafe.As<Abgr32, byte>(ref source);
ref byte sourceRefFromB = ref Unsafe.AddByteOffset(ref sourceRef, 1);
this = Unsafe.As<byte, Bgr24>(ref sourceRefFromB);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromAbgr32(Abgr32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this = source.Bgr;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromRgba32(Rgba32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromRgb48(Rgb48 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B)
};
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr24 FromRgba64(Rgba64 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B)
};
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Bgr24 other) => this.R.Equals(other.R) && this.G.Equals(other.G) && this.B.Equals(other.B);
/// <inheritdoc/>
@ -228,6 +184,5 @@ public partial struct Bgr24 : IPixel<Bgr24>
public override readonly string ToString() => $"Bgr24({this.B}, {this.G}, {this.R})";
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => HashCode.Combine(this.R, this.B, this.G);
}

116
src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs

@ -13,7 +13,13 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct Bgr565 : IPixel<Bgr565>, IPackedVector<ushort>
/// <remarks>
/// Initializes a new instance of the <see cref="Bgr565"/> struct.
/// </remarks>
/// <param name="vector">
/// The vector containing the components for the packed value.
/// </param>
public partial struct Bgr565(Vector3 vector) : IPixel<Bgr565>, IPackedVector<ushort>
{
/// <summary>
/// Initializes a new instance of the <see cref="Bgr565"/> struct.
@ -26,16 +32,8 @@ public partial struct Bgr565 : IPixel<Bgr565>, IPackedVector<ushort>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Bgr565"/> struct.
/// </summary>
/// <param name="vector">
/// The vector containing the components for the packed value.
/// </param>
public Bgr565(Vector3 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public ushort PackedValue { get; set; }
public ushort PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="Bgr565"/> objects for equality.
@ -45,7 +43,7 @@ public partial struct Bgr565 : IPixel<Bgr565>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Bgr565 left, Bgr565 right) => left.Equals(right);
/// <summary>
@ -56,9 +54,17 @@ public partial struct Bgr565 : IPixel<Bgr565>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Bgr565 left, Bgr565 right) => !left.Equals(right);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(this.ToVector3(), 1F);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Bgr565>(
@ -70,87 +76,19 @@ public partial struct Bgr565 : IPixel<Bgr565>, IPackedVector<ushort>
public readonly PixelOperations<Bgr565> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
var vector3 = new Vector3(vector.X, vector.Y, vector.Z);
this.PackedValue = Pack(ref vector3);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new(this.ToVector3(), 1F);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromVector4(source.ToVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromVector4(source.ToVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr565 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromVector4(source.ToVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromVector4(source.ToVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromVector4(source.ToVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgr565 FromVector4(Vector4 source) => new() { PackedValue = Pack(new Vector3(source.X, source.Y, source.Z)) };
/// <summary>
/// Expands the packed representation into a <see cref="Vector3"/>.
/// The vector components are typically expanded in least to greatest significance order.
/// </summary>
/// <returns>The <see cref="Vector3"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector3 ToVector3() => new(
((this.PackedValue >> 11) & 0x1F) * (1F / 31F),
((this.PackedValue >> 5) & 0x3F) * (1F / 63F),
@ -160,22 +98,20 @@ public partial struct Bgr565 : IPixel<Bgr565>, IPackedVector<ushort>
public override readonly bool Equals(object? obj) => obj is Bgr565 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Bgr565 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector3();
Vector3 vector = this.ToVector3();
return FormattableString.Invariant($"Bgr565({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##})");
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
private static ushort Pack(ref Vector3 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ushort Pack(Vector3 vector)
{
vector = Vector3.Clamp(vector, Vector3.Zero, Vector3.One);

206
src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs

@ -4,6 +4,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -38,15 +39,8 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
/// </summary>
public byte A;
/// <summary>
/// The maximum byte value.
/// </summary>
private static readonly Vector4 MaxBytes = new(255);
/// <summary>
/// The half vector value.
/// </summary>
private static readonly Vector4 Half = new(0.5F);
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <summary>
/// Initializes a new instance of the <see cref="Bgra32"/> struct.
@ -54,7 +48,7 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Bgra32(byte r, byte g, byte b)
{
this.R = r;
@ -70,7 +64,7 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Bgra32(byte r, byte g, byte b, byte a)
{
this.R = r;
@ -84,10 +78,10 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
/// </summary>
public uint Bgra
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => Unsafe.As<Bgra32, uint>(ref Unsafe.AsRef(in this));
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Bgra32, uint>(ref this) = value;
}
@ -106,7 +100,7 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Bgra32 left, Bgra32 right) => left.Equals(right);
/// <summary>
@ -117,9 +111,21 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Bgra32 left, Bgra32 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => new(this.R, this.G, this.B, this.A);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Bgra32>(
@ -131,150 +137,82 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
public readonly PixelOperations<Bgra32> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.Pack(vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromVector4(Vector4 source) => Pack(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromArgb32(Argb32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromAbgr32(Abgr32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromBgr24(Bgr24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromBgra32(Bgra32 source) => new() { PackedValue = source.PackedValue };
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromL8(L8 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromL16(L16 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = byte.MaxValue;
byte rgb = ColorNumerics.From16BitTo8Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromLa16(La16 source) => new(source.L, source.L, source.L, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromLa32(La32 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
byte rgb = ColorNumerics.From16BitTo8Bit(source.L);
return new(rgb, rgb, rgb, ColorNumerics.From16BitTo8Bit(source.A));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromRgb24(Rgb24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = byte.MaxValue;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = this.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromRgba32(Rgba32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromRgb48(Rgb48 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = byte.MaxValue
};
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra32 FromRgba64(Rgba64 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = ColorNumerics.From16BitTo8Bit(source.A)
};
/// <inheritdoc/>
public override readonly bool Equals(object? obj) => obj is Bgra32 other && this.Equals(other);
@ -292,16 +230,14 @@ public partial struct Bgra32 : IPixel<Bgra32>, IPackedVector<uint>
/// Packs a <see cref="Vector4"/> into a color.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Bgra32 Pack(Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;
this.B = (byte)vector.Z;
this.A = (byte)vector.W;
Vector128<byte> result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
return new(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
}
}

110
src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct Bgra4444 : IPixel<Bgra4444>, IPackedVector<ushort>
/// <remarks>
/// Initializes a new instance of the <see cref="Bgra4444"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the components for the packed vector.</param>
public partial struct Bgra4444(Vector4 vector) : IPixel<Bgra4444>, IPackedVector<ushort>
{
/// <summary>
/// Initializes a new instance of the <see cref="Bgra4444"/> struct.
@ -26,14 +30,8 @@ public partial struct Bgra4444 : IPixel<Bgra4444>, IPackedVector<ushort>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Bgra4444"/> struct.
/// </summary>
/// <param name="vector">The vector containing the components for the packed vector.</param>
public Bgra4444(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public ushort PackedValue { get; set; }
public ushort PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="Bgra4444"/> objects for equality.
@ -43,7 +41,7 @@ public partial struct Bgra4444 : IPixel<Bgra4444>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Bgra4444 left, Bgra4444 right) => left.Equals(right);
/// <summary>
@ -54,120 +52,62 @@ public partial struct Bgra4444 : IPixel<Bgra4444>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Bgra4444 left, Bgra4444 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Bgra4444>(
PixelComponentInfo.Create<Bgra4444>(4, 4, 4, 4, 4),
PixelColorType.BGR | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<Bgra4444> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4()
{
const float Max = 1 / 15F;
const float max = 1 / 15f;
return new Vector4(
(this.PackedValue >> 8) & 0x0F,
(this.PackedValue >> 4) & 0x0F,
this.PackedValue & 0x0F,
(this.PackedValue >> 12) & 0x0F) * Max;
(this.PackedValue >> 12) & 0x0F) * max;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Bgra4444>(
PixelComponentInfo.Create<Bgra4444>(4, 4, 4, 4, 4),
PixelColorType.BGR | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<Bgra4444> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra4444 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra4444 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is Bgra4444 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Bgra4444 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"Bgra4444({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})");
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
private static ushort Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ushort Pack(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One);
return (ushort)((((int)Math.Round(vector.W * 15F) & 0x0F) << 12)

112
src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs

@ -13,7 +13,13 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct Bgra5551 : IPixel<Bgra5551>, IPackedVector<ushort>
/// <remarks>
/// Initializes a new instance of the <see cref="Bgra5551"/> struct.
/// </remarks>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
public partial struct Bgra5551(Vector4 vector) : IPixel<Bgra5551>, IPackedVector<ushort>
{
/// <summary>
/// Initializes a new instance of the <see cref="Bgra5551"/> struct.
@ -27,16 +33,8 @@ public partial struct Bgra5551 : IPixel<Bgra5551>, IPackedVector<ushort>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Bgra5551"/> struct.
/// </summary>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
public Bgra5551(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public ushort PackedValue { get; set; }
public ushort PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="Bgra5551"/> objects for equality.
@ -46,7 +44,7 @@ public partial struct Bgra5551 : IPixel<Bgra5551>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Bgra5551 left, Bgra5551 right) => left.Equals(right);
/// <summary>
@ -57,33 +55,15 @@ public partial struct Bgra5551 : IPixel<Bgra5551>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Bgra5551 left, Bgra5551 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Bgra5551>(
PixelComponentInfo.Create<Bgra5551>(4, 5, 5, 5, 1),
PixelColorType.BGR | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<Bgra5551> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(
((this.PackedValue >> 10) & 0x1F) / 31F,
((this.PackedValue >> 5) & 0x1F) / 31F,
@ -91,81 +71,45 @@ public partial struct Bgra5551 : IPixel<Bgra5551>, IPackedVector<ushort>
(this.PackedValue >> 15) & 0x01);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this = source;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Bgra5551>(
PixelComponentInfo.Create<Bgra5551>(4, 5, 5, 5, 1),
PixelColorType.BGR | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<Bgra5551> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra5551 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra5551 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Bgra5551 FromBgra5551(Bgra5551 source) => new() { PackedValue = source.PackedValue };
/// <inheritdoc />
public override bool Equals(object? obj) => obj is Bgra5551 other && this.Equals(other);
public override readonly bool Equals(object? obj) => obj is Bgra5551 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Bgra5551 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"Bgra5551({vector.Z:#0.##}, {vector.Y:#0.##}, {vector.X:#0.##}, {vector.W:#0.##})");
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
private static ushort Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ushort Pack(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One);
return (ushort)(

125
src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -14,13 +15,18 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// </summary>
public partial struct Byte4 : IPixel<Byte4>, IPackedVector<uint>
{
/// <summary>
/// The maximum byte value.
/// </summary>
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
/// <summary>
/// Initializes a new instance of the <see cref="Byte4"/> struct.
/// </summary>
/// <param name="vector">
/// A vector containing the initial values for the components of the Byte4 structure.
/// </param>
public Byte4(Vector4 vector) => this.PackedValue = Pack(ref vector);
public Byte4(Vector4 vector) => this.PackedValue = Pack(vector);
/// <summary>
/// Initializes a new instance of the <see cref="Byte4"/> struct.
@ -31,8 +37,8 @@ public partial struct Byte4 : IPixel<Byte4>, IPackedVector<uint>
/// <param name="w">The w-component</param>
public Byte4(float x, float y, float z, float w)
{
var vector = new Vector4(x, y, z, w);
this.PackedValue = Pack(ref vector);
Vector4 vector = new(x, y, z, w);
this.PackedValue = Pack(vector);
}
/// <inheritdoc/>
@ -46,7 +52,7 @@ public partial struct Byte4 : IPixel<Byte4>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Byte4 left, Byte4 right) => left.Equals(right);
/// <summary>
@ -57,110 +63,60 @@ public partial struct Byte4 : IPixel<Byte4>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Byte4 left, Byte4 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Byte4>(
PixelComponentInfo.Create<Byte4>(4, 8, 8, 8, 8),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<Byte4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector * 255F);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32 ToRgba32() => new() { PackedValue = this.PackedValue };
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4() / 255F;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4() / 255f;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(
this.PackedValue & 0xFF,
(this.PackedValue >> 0x8) & 0xFF,
(this.PackedValue >> 0x10) & 0xFF,
(this.PackedValue >> 0x18) & 0xFF);
(this.PackedValue >> 8) & 0xFF,
(this.PackedValue >> 16) & 0xFF,
(this.PackedValue >> 24) & 0xFF);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Byte4>(
PixelComponentInfo.Create<Byte4>(4, 8, 8, 8, 8),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<Byte4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Byte4 FromScaledVector4(Vector4 source) => FromVector4(source * 255f);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Byte4 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Byte4 FromRgba32(Rgba32 source) => new() { PackedValue = source.PackedValue };
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is Byte4 byte4 && this.Equals(byte4);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Byte4 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"Byte4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})");
}
@ -169,18 +125,17 @@ public partial struct Byte4 : IPixel<Byte4>, IPackedVector<uint>
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
/// <returns>The <see cref="uint"/> containing the packed values.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(Vector4 vector)
{
const float Max = 255F;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
// Clamp the value between min and max values
vector = Numerics.Clamp(vector, Vector4.Zero, new Vector4(Max));
Vector128<uint> result = Vector128.ConvertToUInt32(vector.AsVector128());
uint byte4 = (uint)Math.Round(vector.X) & 0xFF;
uint byte3 = ((uint)Math.Round(vector.Y) & 0xFF) << 0x8;
uint byte2 = ((uint)Math.Round(vector.Z) & 0xFF) << 0x10;
uint byte1 = ((uint)Math.Round(vector.W) & 0xFF) << 0x18;
uint byte4 = result.GetElement(0) & 0xFF;
uint byte3 = result.GetElement(1) << 8;
uint byte2 = result.GetElement(2) << 16;
uint byte1 = result.GetElement(3) << 24;
return byte4 | byte3 | byte2 | byte1;
}

114
src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs

@ -12,16 +12,14 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-1, 0, 0, 1] to [1, 0, 0, 1] in vector form.
/// </para>
/// </summary>
public partial struct HalfSingle : IPixel<HalfSingle>, IPackedVector<ushort>
/// <remarks>
/// Initializes a new instance of the <see cref="HalfSingle"/> struct.
/// </remarks>
/// <param name="value">The single component value.</param>
public partial struct HalfSingle(float value) : IPixel<HalfSingle>, IPackedVector<ushort>
{
/// <summary>
/// Initializes a new instance of the <see cref="HalfSingle"/> struct.
/// </summary>
/// <param name="value">The single component value.</param>
public HalfSingle(float value) => this.PackedValue = HalfTypeHelper.Pack(value);
/// <inheritdoc/>
public ushort PackedValue { get; set; }
public ushort PackedValue { get; set; } = HalfTypeHelper.Pack(value);
/// <summary>
/// Compares two <see cref="HalfSingle"/> objects for equality.
@ -31,7 +29,7 @@ public partial struct HalfSingle : IPixel<HalfSingle>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(HalfSingle left, HalfSingle right) => left.Equals(right);
/// <summary>
@ -42,31 +40,11 @@ public partial struct HalfSingle : IPixel<HalfSingle>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(HalfSingle left, HalfSingle right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<HalfSingle>(
PixelComponentInfo.Create<HalfSingle>(1, 16),
PixelColorType.Red,
PixelAlphaRepresentation.None);
/// <inheritdoc />
public PixelOperations<HalfSingle> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
{
float scaled = vector.X;
scaled *= 2F;
scaled--;
this.PackedValue = HalfTypeHelper.Pack(scaled);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
float single = this.ToSingle() + 1F;
@ -75,87 +53,49 @@ public partial struct HalfSingle : IPixel<HalfSingle>, IPackedVector<ushort>
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = HalfTypeHelper.Pack(vector.X);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(this.ToSingle(), 0, 0, 1F);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<HalfSingle>(
PixelComponentInfo.Create<HalfSingle>(1, 16),
PixelColorType.Red,
PixelAlphaRepresentation.None);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<HalfSingle> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static HalfSingle FromScaledVector4(Vector4 source)
{
float scaled = source.X;
scaled *= 2F;
scaled--;
return new() { PackedValue = HalfTypeHelper.Pack(scaled) };
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static HalfSingle FromVector4(Vector4 source) => new() { PackedValue = HalfTypeHelper.Pack(source.X) };
/// <summary>
/// Expands the packed representation into a <see cref="float"/>.
/// </summary>
/// <returns>The <see cref="float"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly float ToSingle() => HalfTypeHelper.Unpack(this.PackedValue);
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is HalfSingle other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(HalfSingle other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString() => FormattableString.Invariant($"HalfSingle({this.ToSingle():#0.##})");
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
}

110
src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs

@ -38,7 +38,7 @@ public partial struct HalfVector2 : IPixel<HalfVector2>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(HalfVector2 left, HalfVector2 right) => left.Equals(right);
/// <summary>
@ -49,111 +49,55 @@ public partial struct HalfVector2 : IPixel<HalfVector2>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(HalfVector2 left, HalfVector2 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<HalfVector2>(
PixelComponentInfo.Create<HalfVector2>(2, 16, 16),
PixelColorType.Red | PixelColorType.Green,
PixelAlphaRepresentation.None);
/// <inheritdoc />
public readonly PixelOperations<HalfVector2> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
{
Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F;
scaled -= Vector2.One;
this.PackedValue = Pack(scaled.X, scaled.Y);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector2();
Vector2 scaled = this.ToVector2();
scaled += Vector2.One;
scaled /= 2F;
return new Vector4(scaled, 0F, 1F);
return new(scaled, 0F, 1F);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(vector.X, vector.Y);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4()
{
var vector = this.ToVector2();
return new Vector4(vector.X, vector.Y, 0F, 1F);
Vector2 vector = this.ToVector2();
return new(vector.X, vector.Y, 0F, 1F);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<HalfVector2>(
PixelComponentInfo.Create<HalfVector2>(2, 16, 16),
PixelColorType.Red | PixelColorType.Green,
PixelAlphaRepresentation.None);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<HalfVector2> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static HalfVector2 FromScaledVector4(Vector4 source)
{
Vector2 scaled = new Vector2(source.X, source.Y) * 2F;
scaled -= Vector2.One;
return new() { PackedValue = Pack(scaled.X, scaled.Y) };
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static HalfVector2 FromVector4(Vector4 source) => new() { PackedValue = Pack(source.X, source.Y) };
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// </summary>
/// <returns>The <see cref="Vector2"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector2 ToVector2()
{
Vector2 vector;
@ -166,21 +110,19 @@ public partial struct HalfVector2 : IPixel<HalfVector2>, IPackedVector<uint>
public override readonly bool Equals(object? obj) => obj is HalfVector2 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(HalfVector2 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector2();
Vector2 vector = this.ToVector2();
return FormattableString.Invariant($"HalfVector2({vector.X:#0.##}, {vector.Y:#0.##})");
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(float x, float y)
{
uint num2 = HalfTypeHelper.Pack(x);

118
src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-1, -1, -1, -1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct HalfVector4 : IPixel<HalfVector4>, IPackedVector<ulong>
/// <remarks>
/// Initializes a new instance of the <see cref="HalfVector4"/> struct.
/// </remarks>
/// <param name="vector">A vector containing the initial values for the components</param>
public partial struct HalfVector4(Vector4 vector) : IPixel<HalfVector4>, IPackedVector<ulong>
{
/// <summary>
/// Initializes a new instance of the <see cref="HalfVector4"/> struct.
@ -26,14 +30,8 @@ public partial struct HalfVector4 : IPixel<HalfVector4>, IPackedVector<ulong>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="HalfVector4"/> struct.
/// </summary>
/// <param name="vector">A vector containing the initial values for the components</param>
public HalfVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public ulong PackedValue { get; set; }
public ulong PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="HalfVector4"/> objects for equality.
@ -43,7 +41,7 @@ public partial struct HalfVector4 : IPixel<HalfVector4>, IPackedVector<ulong>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(HalfVector4 left, HalfVector4 right) => left.Equals(right);
/// <summary>
@ -54,44 +52,21 @@ public partial struct HalfVector4 : IPixel<HalfVector4>, IPackedVector<ulong>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(HalfVector4 left, HalfVector4 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<HalfVector4>(
PixelComponentInfo.Create<HalfVector4>(4, 16, 16, 16, 16),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<HalfVector4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
{
vector *= 2F;
vector -= Vector4.One;
this.FromVector4(vector);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector4();
Vector4 scaled = this.ToVector4();
scaled += Vector4.One;
scaled /= 2F;
return scaled;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(
HalfTypeHelper.Unpack((ushort)this.PackedValue),
HalfTypeHelper.Unpack((ushort)(this.PackedValue >> 0x10)),
@ -99,77 +74,42 @@ public partial struct HalfVector4 : IPixel<HalfVector4>, IPackedVector<ulong>
HalfTypeHelper.Unpack((ushort)(this.PackedValue >> 0x30)));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<HalfVector4>(
PixelComponentInfo.Create<HalfVector4>(4, 16, 16, 16, 16),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<HalfVector4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static HalfVector4 FromScaledVector4(Vector4 source)
{
source *= 2F;
source -= Vector4.One;
return FromVector4(source);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static HalfVector4 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is HalfVector4 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(HalfVector4 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"HalfVector4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})");
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <summary>
@ -177,8 +117,8 @@ public partial struct HalfVector4 : IPixel<HalfVector4>, IPackedVector<ulong>
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
/// <returns>The <see cref="ulong"/> containing the packed values.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static ulong Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong Pack(Vector4 vector)
{
ulong num4 = HalfTypeHelper.Pack(vector.X);
ulong num3 = (ulong)HalfTypeHelper.Pack(vector.Y) << 0x10;

150
src/ImageSharp/PixelFormats/PixelImplementations/L16.cs

@ -12,18 +12,16 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct L16 : IPixel<L16>, IPackedVector<ushort>
/// <remarks>
/// Initializes a new instance of the <see cref="L16"/> struct.
/// </remarks>
/// <param name="luminance">The luminance component</param>
public partial struct L16(ushort luminance) : IPixel<L16>, IPackedVector<ushort>
{
private const float Max = ushort.MaxValue;
/// <summary>
/// Initializes a new instance of the <see cref="L16"/> struct.
/// </summary>
/// <param name="luminance">The luminance component</param>
public L16(ushort luminance) => this.PackedValue = luminance;
/// <inheritdoc />
public ushort PackedValue { get; set; }
public ushort PackedValue { get; set; } = luminance;
/// <summary>
/// Compares two <see cref="L16"/> objects for equality.
@ -33,7 +31,7 @@ public partial struct L16 : IPixel<L16>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(L16 left, L16 right) => left.Equals(right);
/// <summary>
@ -44,9 +42,29 @@ public partial struct L16 : IPixel<L16>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(L16 left, L16 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32()
{
byte rgb = ColorNumerics.From16BitTo8Bit(this.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4()
{
float scaled = this.PackedValue / Max;
return new Vector4(scaled, scaled, scaled, 1f);
}
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<L16>(
@ -58,127 +76,77 @@ public partial struct L16 : IPixel<L16>, IPackedVector<ushort>
public readonly PixelOperations<L16> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4()
{
float scaled = this.PackedValue / Max;
return new Vector4(scaled, scaled, scaled, 1F);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromArgb32(Argb32 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromBgr24(Bgr24 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromBgra32(Bgra32 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromAbgr32(Abgr32 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.PackedValue = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromL8(L8 source) => new(ColorNumerics.From8BitTo16Bit(source.PackedValue));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromL16(L16 source) => new(source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.PackedValue = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromLa16(La16 source) => new(ColorNumerics.From8BitTo16Bit(source.L));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.PackedValue = source.L;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromLa32(La32 source) => new(source.L);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromRgb24(Rgb24 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(this.PackedValue);
dest.R = rgb;
dest.G = rgb;
dest.B = rgb;
dest.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromRgba32(Rgba32 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromRgb48(Rgb48 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L16 FromRgba64(Rgba64 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is L16 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(L16 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString() => $"L16({this.PackedValue})";
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ushort Pack(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
vector.X,
vector.Y,
vector.Z);
return ColorNumerics.Get16BitBT709Luminance(vector.X, vector.Y, vector.Z);
}
}

144
src/ImageSharp/PixelFormats/PixelImplementations/L8.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -12,19 +13,24 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct L8 : IPixel<L8>, IPackedVector<byte>
/// <remarks>
/// Initializes a new instance of the <see cref="L8"/> struct.
/// </remarks>
/// <param name="luminance">The luminance component.</param>
public partial struct L8(byte luminance) : IPixel<L8>, IPackedVector<byte>
{
private static readonly Vector4 MaxBytes = new(255F);
private static readonly Vector4 Half = new(0.5F);
/// <summary>
/// The maximum byte value.
/// </summary>
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
/// <summary>
/// Initializes a new instance of the <see cref="L8"/> struct.
/// The half vector value.
/// </summary>
/// <param name="luminance">The luminance component.</param>
public L8(byte luminance) => this.PackedValue = luminance;
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <inheritdoc />
public byte PackedValue { get; set; }
public byte PackedValue { get; set; } = luminance;
/// <summary>
/// Compares two <see cref="L8"/> objects for equality.
@ -34,7 +40,7 @@ public partial struct L8 : IPixel<L8>, IPackedVector<byte>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(L8 left, L8 right) => left.Equals(right);
/// <summary>
@ -45,9 +51,29 @@ public partial struct L8 : IPixel<L8>, IPackedVector<byte>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(L8 left, L8 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32()
{
byte rgb = this.PackedValue;
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4()
{
float rgb = this.PackedValue / 255f;
return new Vector4(rgb, rgb, rgb, 1f);
}
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<L8>(
@ -59,115 +85,81 @@ public partial struct L8 : IPixel<L8>, IPackedVector<byte>
public readonly PixelOperations<L8> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4()
{
float rgb = this.PackedValue / 255F;
return new Vector4(rgb, rgb, rgb, 1F);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromArgb32(Argb32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromBgr24(Bgr24 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromBgra32(Bgra32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromAbgr32(Abgr32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromL8(L8 source) => new(source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromL16(L16 source) => new(ColorNumerics.From16BitTo8Bit(source.PackedValue));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.PackedValue = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromLa16(La16 source) => new(source.L);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.PackedValue = source.L;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromLa32(La32 source) => new(ColorNumerics.From16BitTo8Bit(source.L));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.PackedValue = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromRgb24(Rgb24 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = this.PackedValue;
dest.G = this.PackedValue;
dest.B = this.PackedValue;
dest.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromRgba32(Rgba32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
=> this.PackedValue = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromRgb48(Rgb48 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
=> this.PackedValue = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static L8 FromRgba64(Rgba64 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B));
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is L8 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(L8 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString() => $"L8({this.PackedValue})";
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte Pack(Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.PackedValue = ColorNumerics.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
Vector128<byte> result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
return ColorNumerics.Get8BitBT709Luminance(result.GetElement(0), result.GetElement(4), result.GetElement(8));
}
}

214
src/ImageSharp/PixelFormats/PixelImplementations/La16.cs

@ -4,6 +4,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -13,34 +14,35 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="La16"/> struct.
/// </remarks>
/// <param name="l">The luminance component.</param>
/// <param name="a">The alpha component.</param>
[StructLayout(LayoutKind.Explicit)]
public partial struct La16 : IPixel<La16>, IPackedVector<ushort>
public partial struct La16(byte l, byte a) : IPixel<La16>, IPackedVector<ushort>
{
private static readonly Vector4 MaxBytes = new(255F);
private static readonly Vector4 Half = new(0.5F);
/// <summary>
/// The maximum byte value.
/// </summary>
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
/// <summary>
/// The half vector value.
/// </summary>
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <summary>
/// Gets or sets the luminance component.
/// </summary>
[FieldOffset(0)]
public byte L;
public byte L = l;
/// <summary>
/// Gets or sets the alpha component.
/// </summary>
[FieldOffset(1)]
public byte A;
/// <summary>
/// Initializes a new instance of the <see cref="La16"/> struct.
/// </summary>
/// <param name="l">The luminance component.</param>
/// <param name="a">The alpha component.</param>
public La16(byte l, byte a)
{
this.L = l;
this.A = a;
}
public byte A = a;
/// <inheritdoc/>
public ushort PackedValue
@ -57,7 +59,7 @@ public partial struct La16 : IPixel<La16>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(La16 left, La16 right) => left.Equals(right);
/// <summary>
@ -68,9 +70,26 @@ public partial struct La16 : IPixel<La16>, IPackedVector<ushort>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(La16 left, La16 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => new(this.L, this.L, this.L, this.A);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4()
{
const float max = 255f;
float rgb = this.L / max;
return new Vector4(rgb, rgb, rgb, this.A / max);
}
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<La16>(
@ -82,160 +101,83 @@ public partial struct La16 : IPixel<La16>, IPackedVector<ushort>
public readonly PixelOperations<La16> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(La16 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is La16 other && this.Equals(other);
/// <inheritdoc />
public override readonly string ToString() => $"La16({this.L}, {this.A})";
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromScaledVector4(Vector4 source) => Pack(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromVector4(Vector4 source) => Pack(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromArgb32(Argb32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromBgr24(Bgr24 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromBgra32(Bgra32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromAbgr32(Abgr32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
this.L = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromL16(L16 source) => new(ColorNumerics.From16BitTo8Bit(source.PackedValue), byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.L = source.PackedValue;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromL8(L8 source) => new(source.PackedValue, byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromLa16(La16 source) => new(source.L, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
this.L = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromLa32(La32 source) => new(ColorNumerics.From16BitTo8Bit(source.L), ColorNumerics.From16BitTo8Bit(source.A));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromRgb24(Rgb24 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromRgba32(Rgba32 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La16 FromRgb48(Rgb48 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), byte.MaxValue);
/// <inheritdoc/>
public void FromRgba64(Rgba64 source)
{
this.L = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
public static La16 FromRgba64(Rgba64 source) => new(ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B), ColorNumerics.From16BitTo8Bit(source.A));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is La16 other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
public readonly bool Equals(La16 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = this.L;
dest.G = this.L;
dest.B = this.L;
dest.A = this.A;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
public override readonly string ToString() => $"La16({this.L}, {this.A})";
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4()
{
const float Max = 255F;
float rgb = this.L / Max;
return new Vector4(rgb, rgb, rgb, this.A / Max);
}
/// <inheritdoc />
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static La16 Pack(Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.L = ColorNumerics.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
this.A = (byte)vector.W;
Vector128<byte> result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
byte l = ColorNumerics.Get8BitBT709Luminance(result.GetElement(0), result.GetElement(4), result.GetElement(8));
byte a = result.GetElement(12);
return new(l, a);
}
}

237
src/ImageSharp/PixelFormats/PixelImplementations/La32.cs

@ -13,8 +13,13 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="La32"/> struct.
/// </remarks>
/// <param name="l">The luminance component.</param>
/// <param name="a">The alpha component.</param>
[StructLayout(LayoutKind.Explicit)]
public partial struct La32 : IPixel<La32>, IPackedVector<uint>
public partial struct La32(ushort l, ushort a) : IPixel<La32>, IPackedVector<uint>
{
private const float Max = ushort.MaxValue;
@ -22,32 +27,21 @@ public partial struct La32 : IPixel<La32>, IPackedVector<uint>
/// Gets or sets the luminance component.
/// </summary>
[FieldOffset(0)]
public ushort L;
public ushort L = l;
/// <summary>
/// Gets or sets the alpha component.
/// </summary>
[FieldOffset(2)]
public ushort A;
/// <summary>
/// Initializes a new instance of the <see cref="La32"/> struct.
/// </summary>
/// <param name="l">The luminance component.</param>
/// <param name="a">The alpha component.</param>
public La32(ushort l, ushort a)
{
this.L = l;
this.A = a;
}
public ushort A = a;
/// <inheritdoc/>
public uint PackedValue
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => Unsafe.As<La32, uint>(ref Unsafe.AsRef(in this));
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<La32, uint>(ref this) = value;
}
@ -59,7 +53,7 @@ public partial struct La32 : IPixel<La32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(La32 left, La32 right) => left.Equals(right);
/// <summary>
@ -70,9 +64,29 @@ public partial struct La32 : IPixel<La32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(La32 left, La32 right) => !left.Equals(right);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32()
{
byte rgb = ColorNumerics.From16BitTo8Bit(this.L);
return new(rgb, rgb, rgb, ColorNumerics.From16BitTo8Bit(this.A));
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4()
{
float rgb = this.L / Max;
return new Vector4(rgb, rgb, rgb, this.A / Max);
}
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<La32>(
@ -84,179 +98,108 @@ public partial struct La32 : IPixel<La32>, IPackedVector<uint>
public readonly PixelOperations<La32> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(La32 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is La32 other && this.Equals(other);
/// <inheritdoc />
public override readonly string ToString() => $"La32({this.L}, {this.A})";
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromScaledVector4(Vector4 source) => Pack(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromVector4(Vector4 source) => Pack(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromArgb32(Argb32 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
ushort l = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
ushort a = ColorNumerics.From8BitTo16Bit(source.A);
return new(l, a);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromBgr24(Bgr24 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B), ushort.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromBgra32(Bgra32 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
ushort l = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
ushort a = ColorNumerics.From8BitTo16Bit(source.A);
return new(l, a);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromAbgr32(Abgr32 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
ushort l = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
ushort a = ColorNumerics.From8BitTo16Bit(source.A);
return new(l, a);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
this.L = source.PackedValue;
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromL16(L16 source) => new(source.PackedValue, ushort.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.L = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromL8(L8 source) => new(ColorNumerics.From8BitTo16Bit(source.PackedValue), ushort.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromLa16(La16 source)
{
this.L = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
ushort l = ColorNumerics.From8BitTo16Bit(source.L);
ushort a = ColorNumerics.From8BitTo16Bit(source.A);
return new(l, a);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this = source;
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromLa32(La32 source) => new(source.L, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromRgb24(Rgb24 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B), ushort.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromRgb48(Rgb48 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
ushort l = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
return new(l, ushort.MaxValue);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromRgba32(Rgba32 source)
{
this.L = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
ushort l = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
ushort a = ColorNumerics.From8BitTo16Bit(source.A);
return new(l, a);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static La32 FromRgba64(Rgba64 source) => new(ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B), source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.ConvertFromRgbaScaledVector4(vector);
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is La32 other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(this.L);
dest.R = rgb;
dest.G = rgb;
dest.B = rgb;
dest.A = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
}
public readonly bool Equals(La32 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
public override readonly string ToString() => $"La32({this.L}, {this.A})";
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4()
{
float scaled = this.L / Max;
return new Vector4(scaled, scaled, scaled, this.A / Max);
}
/// <inheritdoc />
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static La32 Pack(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
this.L = ColorNumerics.Get16BitBT709Luminance(
vector.X,
vector.Y,
vector.Z);
this.A = (ushort)MathF.Round(vector.W);
ushort l = ColorNumerics.Get16BitBT709Luminance(vector.X, vector.Y, vector.Z);
ushort a = (ushort)MathF.Round(vector.W);
return new(l, a);
}
}

131
src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs

@ -12,12 +12,15 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-1, -1, 0, 1] to [1, 1, 0, 1] in vector form.
/// </para>
/// </summary>
public partial struct NormalizedByte2 : IPixel<NormalizedByte2>, IPackedVector<ushort>
/// <remarks>
/// Initializes a new instance of the <see cref="NormalizedByte2"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the component values.</param>
public partial struct NormalizedByte2(Vector2 vector) : IPixel<NormalizedByte2>, IPackedVector<ushort>
{
private const float MaxPos = 127F;
private const float MaxPos = 127f;
private static readonly Vector2 Half = new(MaxPos);
private static readonly Vector2 MinusOne = new(-1F);
private static readonly Vector2 MinusOne = new(-1f);
/// <summary>
/// Initializes a new instance of the <see cref="NormalizedByte2"/> struct.
@ -29,14 +32,8 @@ public partial struct NormalizedByte2 : IPixel<NormalizedByte2>, IPackedVector<u
{
}
/// <summary>
/// Initializes a new instance of the <see cref="NormalizedByte2"/> struct.
/// </summary>
/// <param name="vector">The vector containing the component values.</param>
public NormalizedByte2(Vector2 vector) => this.PackedValue = Pack(vector);
/// <inheritdoc/>
public ushort PackedValue { get; set; }
public ushort PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="NormalizedByte2"/> objects for equality.
@ -46,7 +43,7 @@ public partial struct NormalizedByte2 : IPixel<NormalizedByte2>, IPackedVector<u
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(NormalizedByte2 left, NormalizedByte2 right) => left.Equals(right);
/// <summary>
@ -57,9 +54,23 @@ public partial struct NormalizedByte2 : IPixel<NormalizedByte2>, IPackedVector<u
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(NormalizedByte2 left, NormalizedByte2 right) => !left.Equals(right);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
Vector2 scaled = this.ToVector2();
scaled += Vector2.One;
scaled /= 2f;
return new Vector4(scaled, 0f, 1f);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(this.ToVector2(), 0f, 1f);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<NormalizedByte2>(
@ -71,98 +82,24 @@ public partial struct NormalizedByte2 : IPixel<NormalizedByte2>, IPackedVector<u
public readonly PixelOperations<NormalizedByte2> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedByte2 FromScaledVector4(Vector4 source)
{
Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F;
Vector2 scaled = new Vector2(source.X, source.Y) * 2f;
scaled -= Vector2.One;
this.PackedValue = Pack(scaled);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector2();
scaled += Vector2.One;
scaled /= 2F;
return new Vector4(scaled, 0F, 1F);
return new() { PackedValue = Pack(scaled) };
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
var vector2 = new Vector2(vector.X, vector.Y);
this.PackedValue = Pack(vector2);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new(this.ToVector2(), 0F, 1F);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedByte2 FromVector4(Vector4 source) => new() { PackedValue = Pack(new Vector2(source.X, source.Y)) };
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// The vector components are typically expanded in least to greatest significance order.
/// </summary>
/// <returns>The <see cref="Vector2"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector2 ToVector2() => new(
(sbyte)((this.PackedValue >> 0) & 0xFF) / MaxPos,
(sbyte)((this.PackedValue >> 8) & 0xFF) / MaxPos);
@ -171,21 +108,19 @@ public partial struct NormalizedByte2 : IPixel<NormalizedByte2>, IPackedVector<u
public override readonly bool Equals(object? obj) => obj is NormalizedByte2 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(NormalizedByte2 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector2();
Vector2 vector = this.ToVector2();
return FormattableString.Invariant($"NormalizedByte2({vector.X:#0.##}, {vector.Y:#0.##})");
}
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ushort Pack(Vector2 vector)
{
vector = Vector2.Clamp(vector, MinusOne, Vector2.One) * Half;

128
src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -12,12 +13,15 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-1, -1, -1, -1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct NormalizedByte4 : IPixel<NormalizedByte4>, IPackedVector<uint>
/// <remarks>
/// Initializes a new instance of the <see cref="NormalizedByte4"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the component values.</param>
public partial struct NormalizedByte4(Vector4 vector) : IPixel<NormalizedByte4>, IPackedVector<uint>
{
private const float MaxPos = 127F;
private static readonly Vector4 Half = new(MaxPos);
private static readonly Vector4 MinusOne = new(-1F);
private const float MaxPos = 127f;
private static readonly Vector4 Half = Vector128.Create(MaxPos).AsVector4();
private static readonly Vector4 MinusOne = Vector128.Create(-1f).AsVector4();
/// <summary>
/// Initializes a new instance of the <see cref="NormalizedByte4"/> struct.
@ -31,14 +35,8 @@ public partial struct NormalizedByte4 : IPixel<NormalizedByte4>, IPackedVector<u
{
}
/// <summary>
/// Initializes a new instance of the <see cref="NormalizedByte4"/> struct.
/// </summary>
/// <param name="vector">The vector containing the component values.</param>
public NormalizedByte4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public uint PackedValue { get; set; }
public uint PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="NormalizedByte4"/> objects for equality.
@ -48,7 +46,7 @@ public partial struct NormalizedByte4 : IPixel<NormalizedByte4>, IPackedVector<u
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(NormalizedByte4 left, NormalizedByte4 right) => left.Equals(right);
/// <summary>
@ -59,44 +57,21 @@ public partial struct NormalizedByte4 : IPixel<NormalizedByte4>, IPackedVector<u
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(NormalizedByte4 left, NormalizedByte4 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<NormalizedByte4>(
PixelComponentInfo.Create<NormalizedByte4>(4, 8, 8, 8, 8),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<NormalizedByte4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
{
vector *= 2F;
vector -= Vector4.One;
this.FromVector4(vector);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector4();
Vector4 scaled = this.ToVector4();
scaled += Vector4.One;
scaled /= 2F;
scaled /= 2f;
return scaled;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(
(sbyte)((this.PackedValue >> 0) & 0xFF) / MaxPos,
(sbyte)((this.PackedValue >> 8) & 0xFF) / MaxPos,
@ -104,81 +79,46 @@ public partial struct NormalizedByte4 : IPixel<NormalizedByte4>, IPackedVector<u
(sbyte)((this.PackedValue >> 24) & 0xFF) / MaxPos);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<NormalizedByte4>(
PixelComponentInfo.Create<NormalizedByte4>(4, 8, 8, 8, 8),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<NormalizedByte4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedByte4 FromScaledVector4(Vector4 source)
{
source *= 2f;
source -= Vector4.One;
return FromVector4(source);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedByte4 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is NormalizedByte4 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(NormalizedByte4 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"NormalizedByte4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})");
}
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(Vector4 vector)
{
vector = Numerics.Clamp(vector, MinusOne, Vector4.One) * Half;

126
src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-1, -1, 0, 1] to [1, 1, 0, 1] in vector form.
/// </para>
/// </summary>
public partial struct NormalizedShort2 : IPixel<NormalizedShort2>, IPackedVector<uint>
/// <remarks>
/// Initializes a new instance of the <see cref="NormalizedShort2"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the component values.</param>
public partial struct NormalizedShort2(Vector2 vector) : IPixel<NormalizedShort2>, IPackedVector<uint>
{
// Largest two byte positive number 0xFFFF >> 1;
private const float MaxPos = 0x7FFF;
@ -30,14 +34,8 @@ public partial struct NormalizedShort2 : IPixel<NormalizedShort2>, IPackedVector
{
}
/// <summary>
/// Initializes a new instance of the <see cref="NormalizedShort2"/> struct.
/// </summary>
/// <param name="vector">The vector containing the component values.</param>
public NormalizedShort2(Vector2 vector) => this.PackedValue = Pack(vector);
/// <inheritdoc/>
public uint PackedValue { get; set; }
public uint PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="NormalizedShort2"/> objects for equality.
@ -47,7 +45,7 @@ public partial struct NormalizedShort2 : IPixel<NormalizedShort2>, IPackedVector
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(NormalizedShort2 left, NormalizedShort2 right) => left.Equals(right);
/// <summary>
@ -58,9 +56,23 @@ public partial struct NormalizedShort2 : IPixel<NormalizedShort2>, IPackedVector
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(NormalizedShort2 left, NormalizedShort2 right) => !left.Equals(right);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
Vector2 scaled = this.ToVector2();
scaled += Vector2.One;
scaled /= 2f;
return new Vector4(scaled, 0f, 1f);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(this.ToVector2(), 0f, 1f);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<NormalizedShort2>(
@ -72,98 +84,24 @@ public partial struct NormalizedShort2 : IPixel<NormalizedShort2>, IPackedVector
public readonly PixelOperations<NormalizedShort2> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedShort2 FromScaledVector4(Vector4 source)
{
Vector2 scaled = new Vector2(vector.X, vector.Y) * 2F;
Vector2 scaled = new Vector2(source.X, source.Y) * 2f;
scaled -= Vector2.One;
this.PackedValue = Pack(scaled);
return new() { PackedValue = Pack(scaled) };
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector2();
scaled += Vector2.One;
scaled /= 2F;
return new Vector4(scaled, 0F, 1F);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
var vector2 = new Vector2(vector.X, vector.Y);
this.PackedValue = Pack(vector2);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Vector4(this.ToVector2(), 0, 1);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedShort2 FromVector4(Vector4 source) => new() { PackedValue = Pack(new Vector2(source.X, source.Y)) };
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// The vector components are typically expanded in least to greatest significance order.
/// </summary>
/// <returns>The <see cref="Vector2"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector2 ToVector2() => new(
(short)(this.PackedValue & 0xFFFF) / MaxPos,
(short)(this.PackedValue >> 0x10) / MaxPos);
@ -172,21 +110,19 @@ public partial struct NormalizedShort2 : IPixel<NormalizedShort2>, IPackedVector
public override readonly bool Equals(object? obj) => obj is NormalizedShort2 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(NormalizedShort2 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector2();
Vector2 vector = this.ToVector2();
return FormattableString.Invariant($"NormalizedShort2({vector.X:#0.##}, {vector.Y:#0.##})");
}
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(Vector2 vector)
{
vector *= Max;

124
src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs

@ -3,6 +3,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -12,12 +13,15 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-1, -1, -1, -1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct NormalizedShort4 : IPixel<NormalizedShort4>, IPackedVector<ulong>
/// <remarks>
/// Initializes a new instance of the <see cref="NormalizedShort4"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the component values.</param>
public partial struct NormalizedShort4(Vector4 vector) : IPixel<NormalizedShort4>, IPackedVector<ulong>
{
// Largest two byte positive number 0xFFFF >> 1;
private const float MaxPos = 0x7FFF;
private static readonly Vector4 Max = new(MaxPos);
private static readonly Vector4 Max = Vector128.Create(MaxPos).AsVector4();
private static readonly Vector4 Min = Vector4.Negate(Max);
/// <summary>
@ -32,14 +36,8 @@ public partial struct NormalizedShort4 : IPixel<NormalizedShort4>, IPackedVector
{
}
/// <summary>
/// Initializes a new instance of the <see cref="NormalizedShort4"/> struct.
/// </summary>
/// <param name="vector">The vector containing the component values.</param>
public NormalizedShort4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public ulong PackedValue { get; set; }
public ulong PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="NormalizedShort4"/> objects for equality.
@ -49,7 +47,7 @@ public partial struct NormalizedShort4 : IPixel<NormalizedShort4>, IPackedVector
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(NormalizedShort4 left, NormalizedShort4 right) => left.Equals(right);
/// <summary>
@ -60,44 +58,21 @@ public partial struct NormalizedShort4 : IPixel<NormalizedShort4>, IPackedVector
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(NormalizedShort4 left, NormalizedShort4 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<NormalizedShort4>(
PixelComponentInfo.Create<NormalizedShort4>(4, 16, 16, 16, 16),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<NormalizedShort4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
{
vector *= 2F;
vector -= Vector4.One;
this.FromVector4(vector);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector4();
Vector4 scaled = this.ToVector4();
scaled += Vector4.One;
scaled /= 2F;
scaled /= 2f;
return scaled;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(
(short)((this.PackedValue >> 0x00) & 0xFFFF) / MaxPos,
(short)((this.PackedValue >> 0x10) & 0xFFFF) / MaxPos,
@ -105,81 +80,46 @@ public partial struct NormalizedShort4 : IPixel<NormalizedShort4>, IPackedVector
(short)((this.PackedValue >> 0x30) & 0xFFFF) / MaxPos);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<NormalizedShort4>(
PixelComponentInfo.Create<NormalizedShort4>(4, 16, 16, 16, 16),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<NormalizedShort4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedShort4 FromScaledVector4(Vector4 source)
{
source *= 2f;
source -= Vector4.One;
return FromVector4(source);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NormalizedShort4 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is NormalizedShort4 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(NormalizedShort4 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"NormalizedShort4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})");
}
[MethodImpl(InliningOptions.ShortMethod)]
private static ulong Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong Pack(Vector4 vector)
{
vector *= Max;
vector = Numerics.Clamp(vector, Min, Max);

4
src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/RgbaVector.PixelOperations.cs

@ -71,7 +71,7 @@ public partial struct RgbaVector
ref Vector4 sp = ref Unsafe.Add(ref sourceBaseRef, i);
ref L8 dp = ref Unsafe.Add(ref destBaseRef, i);
dp.ConvertFromRgbaScaledVector4(sp);
dp.Pack(sp);
}
}
@ -90,7 +90,7 @@ public partial struct RgbaVector
ref Vector4 sp = ref Unsafe.Add(ref sourceBaseRef, i);
ref L16 dp = ref Unsafe.Add(ref destBaseRef, i);
dp.ConvertFromRgbaScaledVector4(sp);
dp.Pack(sp);
}
}
}

119
src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 1] to [1, 1, 0, 1] in vector form.
/// </para>
/// </summary>
public partial struct Rg32 : IPixel<Rg32>, IPackedVector<uint>
/// <remarks>
/// Initializes a new instance of the <see cref="Rg32"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the component values.</param>
public partial struct Rg32(Vector2 vector) : IPixel<Rg32>, IPackedVector<uint>
{
private static readonly Vector2 Max = new(ushort.MaxValue);
@ -26,14 +30,8 @@ public partial struct Rg32 : IPixel<Rg32>, IPackedVector<uint>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Rg32"/> struct.
/// </summary>
/// <param name="vector">The vector containing the component values.</param>
public Rg32(Vector2 vector) => this.PackedValue = Pack(vector);
/// <inheritdoc/>
public uint PackedValue { get; set; }
public uint PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="Rg32"/> objects for equality.
@ -43,7 +41,7 @@ public partial struct Rg32 : IPixel<Rg32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Rg32 left, Rg32 right) => left.Equals(right);
/// <summary>
@ -54,9 +52,26 @@ public partial struct Rg32 : IPixel<Rg32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Rg32 left, Rg32 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32()
=> new(
ColorNumerics.From16BitTo8Bit((ushort)(this.PackedValue & 0xFFFF)),
ColorNumerics.From16BitTo8Bit((ushort)(this.PackedValue >> 16)),
byte.MinValue,
byte.MaxValue);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(this.ToVector2(), 0f, 1f);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Rg32>(
@ -68,108 +83,86 @@ public partial struct Rg32 : IPixel<Rg32>, IPackedVector<uint>
public readonly PixelOperations<Rg32> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
var vector2 = new Vector2(vector.X, vector.Y);
this.PackedValue = Pack(vector2);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromVector4(Vector4 source) => new() { PackedValue = Pack(new Vector2(source.X, source.Y)) };
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new(this.ToVector2(), 0F, 1F);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromArgb32(Argb32 source) => new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromBgr24(Bgr24 source) => new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromBgra32(Bgra32 source) => new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromAbgr32(Abgr32 source) => new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromL8(L8 source) => new(ColorNumerics.From8BitTo16Bit(source.PackedValue), ColorNumerics.From8BitTo16Bit(source.PackedValue));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromL16(L16 source) => new(source.PackedValue, source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromLa16(La16 source) => new(ColorNumerics.From8BitTo16Bit(source.L), ColorNumerics.From8BitTo16Bit(source.L));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromLa32(La32 source) => new(source.L, source.L);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromRgb24(Rgb24 source) => new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromRgba32(Rgba32 source) => new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromRgb48(Rgb48 source) => new(source.R, source.G);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rg32 FromRgba64(Rgba64 source) => new(source.R, source.G);
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// The vector components are typically expanded in least to greatest significance order.
/// </summary>
/// <returns>The <see cref="Vector2"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector2 ToVector2() => new Vector2(this.PackedValue & 0xFFFF, (this.PackedValue >> 16) & 0xFFFF) / Max;
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is Rg32 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Rg32 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector2();
Vector2 vector = this.ToVector2();
return FormattableString.Invariant($"Rg32({vector.X:#0.##}, {vector.Y:#0.##})");
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(Vector2 vector)
{
vector = Vector2.Clamp(vector, Vector2.Zero, Vector2.One) * Max;

225
src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs

@ -4,6 +4,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -14,43 +15,36 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="Rgb24"/> struct.
/// </remarks>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[StructLayout(LayoutKind.Explicit)]
public partial struct Rgb24 : IPixel<Rgb24>
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
public partial struct Rgb24(byte r, byte g, byte b) : IPixel<Rgb24>
{
/// <summary>
/// The red component.
/// </summary>
[FieldOffset(0)]
public byte R;
public byte R = r;
/// <summary>
/// The green component.
/// </summary>
[FieldOffset(1)]
public byte G;
public byte G = g;
/// <summary>
/// The blue component.
/// </summary>
[FieldOffset(2)]
public byte B;
public byte B = b;
private static readonly Vector4 MaxBytes = new(byte.MaxValue);
private static readonly Vector4 Half = new(0.5F);
/// <summary>
/// Initializes a new instance of the <see cref="Rgb24"/> struct.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public Rgb24(byte r, byte g, byte b)
{
this.R = r;
this.G = g;
this.B = b;
}
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="ColorSpaces.Rgb"/> to a
@ -58,15 +52,8 @@ public partial struct Rgb24 : IPixel<Rgb24>
/// </summary>
/// <param name="color">The instance of <see cref="ColorSpaces.Rgb"/> to convert.</param>
/// <returns>An instance of <see cref="Rgb24"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static implicit operator Rgb24(ColorSpaces.Rgb color)
{
var vector = new Vector4(color.ToVector3(), 1F);
Rgb24 rgb = default;
rgb.FromScaledVector4(vector);
return rgb;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Rgb24(ColorSpaces.Rgb color) => FromScaledVector4(new Vector4(color.ToVector3(), 1f));
/// <summary>
/// Compares two <see cref="Rgb24"/> objects for equality.
@ -76,7 +63,7 @@ public partial struct Rgb24 : IPixel<Rgb24>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Rgb24 left, Rgb24 right) => left.Equals(right);
/// <summary>
@ -87,9 +74,17 @@ public partial struct Rgb24 : IPixel<Rgb24>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Rgb24 left, Rgb24 right) => !left.Equals(right);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Rgba32(this.R, this.G, this.B, byte.MaxValue).ToVector4();
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Rgb24>(
@ -100,163 +95,103 @@ public partial struct Rgb24 : IPixel<Rgb24>
/// <inheritdoc/>
public readonly PixelOperations<Rgb24> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => new(this.R, this.G, this.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.Pack(ref vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromVector4(Vector4 source)
{
source *= MaxBytes;
source += Half;
source = Numerics.Clamp(source, Vector4.Zero, MaxBytes);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Rgba32(this.R, this.G, this.B, byte.MaxValue).ToVector4();
Vector128<byte> result = Vector128.ConvertToInt32(source.AsVector128()).AsByte();
return new(result.GetElement(0), result.GetElement(4), result.GetElement(8));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromArgb32(Argb32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromBgr24(Bgr24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromBgra32(Bgra32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromAbgr32(Abgr32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromL8(L8 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromL16(L16 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
byte rgb = ColorNumerics.From16BitTo8Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromLa16(La16 source) => new(source.L, source.L, source.L);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromLa32(La32 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
byte rgb = ColorNumerics.From16BitTo8Bit(source.L);
return new(rgb, rgb, rgb);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromRgb24(Rgb24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this = source.Rgb;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromRgba32(Rgba32 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromRgb48(Rgb48 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B)
};
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb24 FromRgba64(Rgba64 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B)
};
/// <inheritdoc/>
public override readonly bool Equals(object? obj) => obj is Rgb24 other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Rgb24 other) => this.R.Equals(other.R) && this.G.Equals(other.G) && this.B.Equals(other.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => HashCode.Combine(this.R, this.B, this.G);
/// <inheritdoc/>
public override readonly string ToString() => $"Rgb24({this.R}, {this.G}, {this.B})";
/// <summary>
/// Packs a <see cref="Vector4"/> into a color.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(ref Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;
this.B = (byte)vector.Z;
}
}

161
src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs

@ -55,7 +55,7 @@ public partial struct Rgb48 : IPixel<Rgb48>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Rgb48 left, Rgb48 right) => left.Equals(right);
/// <summary>
@ -66,9 +66,22 @@ public partial struct Rgb48 : IPixel<Rgb48>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Rgb48 left, Rgb48 right) => !left.Equals(right);
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32()
=> new(ColorNumerics.From16BitTo8Bit(this.R), ColorNumerics.From16BitTo8Bit(this.G), ColorNumerics.From16BitTo8Bit(this.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(this.R / Max, this.G / Max, this.B / Max, 1f);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Rgb48>(
@ -80,152 +93,88 @@ public partial struct Rgb48 : IPixel<Rgb48>
public readonly PixelOperations<Rgb48> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromVector4(Vector4 source)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
this.R = (ushort)MathF.Round(vector.X);
this.G = (ushort)MathF.Round(vector.Y);
this.B = (ushort)MathF.Round(vector.Z);
source = Numerics.Clamp(source, Vector4.Zero, Vector4.One) * Max;
return new((ushort)MathF.Round(source.X), (ushort)MathF.Round(source.Y), (ushort)MathF.Round(source.Z));
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new(this.R / Max, this.G / Max, this.B / Max, 1F);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromArgb32(Argb32 source)
=> new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G), ColorNumerics.From8BitTo16Bit(source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromBgr24(Bgr24 source)
=> new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G), ColorNumerics.From8BitTo16Bit(source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromBgra32(Bgra32 source)
=> new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G), ColorNumerics.From8BitTo16Bit(source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this = source.Rgb;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromRgba64(Rgba64 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromL8(L8 source)
{
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
ushort rgb = ColorNumerics.From8BitTo16Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromL16(L16 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromLa16(La16 source)
{
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
ushort rgb = ColorNumerics.From8BitTo16Bit(source.L);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromLa32(La32 source) => new(source.L, source.L, source.L);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromRgb24(Rgb24 source)
=> new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G), ColorNumerics.From8BitTo16Bit(source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromRgba32(Rgba32 source)
=> new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G), ColorNumerics.From8BitTo16Bit(source.B));
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
dest.G = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
dest.B = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
dest.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromAbgr32(Abgr32 source)
=> new(ColorNumerics.From8BitTo16Bit(source.R), ColorNumerics.From8BitTo16Bit(source.G), ColorNumerics.From8BitTo16Bit(source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this = source;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb48 FromRgb48(Rgb48 source) => new(source.R, source.G, source.B);
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is Rgb48 rgb48 && this.Equals(rgb48);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Rgb48 other) => this.R.Equals(other.R) && this.G.Equals(other.G) && this.B.Equals(other.B);
/// <inheritdoc />
public override readonly string ToString() => $"Rgb48({this.R}, {this.G}, {this.B})";
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => HashCode.Combine(this.R, this.G, this.B);
}

106
src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs

@ -13,7 +13,11 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
/// </summary>
public partial struct Rgba1010102 : IPixel<Rgba1010102>, IPackedVector<uint>
/// <remarks>
/// Initializes a new instance of the <see cref="Rgba1010102"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the component values.</param>
public partial struct Rgba1010102(Vector4 vector) : IPixel<Rgba1010102>, IPackedVector<uint>
{
private static readonly Vector4 Multiplier = new(1023F, 1023F, 1023F, 3F);
@ -29,14 +33,8 @@ public partial struct Rgba1010102 : IPixel<Rgba1010102>, IPackedVector<uint>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Rgba1010102"/> struct.
/// </summary>
/// <param name="vector">The vector containing the component values.</param>
public Rgba1010102(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public uint PackedValue { get; set; }
public uint PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="Rgba1010102"/> objects for equality.
@ -46,7 +44,7 @@ public partial struct Rgba1010102 : IPixel<Rgba1010102>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Rgba1010102 left, Rgba1010102 right) => left.Equals(right);
/// <summary>
@ -57,33 +55,15 @@ public partial struct Rgba1010102 : IPixel<Rgba1010102>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Rgba1010102 left, Rgba1010102 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Rgba1010102>(
PixelComponentInfo.Create<Rgba1010102>(4, 10, 10, 10, 2),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<Rgba1010102> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Vector4(
(this.PackedValue >> 0) & 0x03FF,
(this.PackedValue >> 10) & 0x03FF,
@ -91,81 +71,41 @@ public partial struct Rgba1010102 : IPixel<Rgba1010102>, IPackedVector<uint>
(this.PackedValue >> 30) & 0x03) / Multiplier;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Rgba1010102>(
PixelComponentInfo.Create<Rgba1010102>(4, 10, 10, 10, 2),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<Rgba1010102> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba1010102 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba1010102 FromVector4(Vector4 source) => new() { PackedValue = Pack(source) };
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is Rgba1010102 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Rgba1010102 other) => this.PackedValue == other.PackedValue;
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"Rgba1010102({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})");
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
[MethodImpl(InliningOptions.ShortMethod)]
private static uint Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Multiplier;

269
src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs

@ -6,6 +6,7 @@ using System.Globalization;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
namespace SixLabors.ImageSharp.PixelFormats;
@ -43,8 +44,8 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// </summary>
public byte A;
private static readonly Vector4 MaxBytes = new(byte.MaxValue);
private static readonly Vector4 Half = new(0.5F);
private static readonly Vector4 MaxBytes = Vector128.Create(255f).AsVector4();
private static readonly Vector4 Half = Vector128.Create(.5f).AsVector4();
/// <summary>
/// Initializes a new instance of the <see cref="Rgba32"/> struct.
@ -52,7 +53,7 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32(byte r, byte g, byte b)
{
this.R = r;
@ -68,7 +69,7 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32(byte r, byte g, byte b, byte a)
{
this.R = r;
@ -84,9 +85,9 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32(float r, float g, float b, float a = 1)
: this() => this.Pack(r, g, b, a);
: this() => Pack(r, g, b, a);
/// <summary>
/// Initializes a new instance of the <see cref="Rgba32"/> struct.
@ -94,9 +95,9 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32(Vector3 vector)
: this() => this.Pack(ref vector);
: this() => Pack(vector);
/// <summary>
/// Initializes a new instance of the <see cref="Rgba32"/> struct.
@ -104,9 +105,9 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <param name="vector">
/// The vector containing the components for the packed vector.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32(Vector4 vector)
: this() => this = PackNew(ref vector);
: this() => this = Pack(vector);
/// <summary>
/// Initializes a new instance of the <see cref="Rgba32"/> struct.
@ -114,7 +115,7 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <param name="packed">
/// The packed value.
/// </param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32(uint packed)
: this() => this.Rgba = packed;
@ -123,10 +124,10 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// </summary>
public uint Rgba
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => Unsafe.As<Rgba32, uint>(ref Unsafe.AsRef(in this));
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Rgba32, uint>(ref this) = value;
}
@ -135,10 +136,10 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// </summary>
public Rgb24 Rgb
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => new(this.R, this.G, this.B);
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
this.R = value.R;
@ -152,10 +153,10 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// </summary>
public Bgr24 Bgr
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => new(this.R, this.G, this.B);
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
this.R = value.R;
@ -167,10 +168,10 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <inheritdoc/>
public uint PackedValue
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => this.Rgba;
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => this.Rgba = value;
}
@ -180,15 +181,8 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// </summary>
/// <param name="color">The instance of <see cref="ColorSpaces.Rgb"/> to convert.</param>
/// <returns>An instance of <see cref="Rgba32"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static implicit operator Rgba32(ColorSpaces.Rgb color)
{
var vector = new Vector4(color.ToVector3(), 1F);
Rgba32 rgba = default;
rgba.FromScaledVector4(vector);
return rgba;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Rgba32(ColorSpaces.Rgb color) => FromScaledVector4(new Vector4(color.ToVector3(), 1F));
/// <summary>
/// Compares two <see cref="Rgba32"/> objects for equality.
@ -198,7 +192,7 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Rgba32 left, Rgba32 right) => left.Equals(right);
/// <summary>
@ -209,7 +203,7 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Rgba32 left, Rgba32 right) => !left.Equals(right);
/// <summary>
@ -224,7 +218,7 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// The <see cref="Rgba32"/>.
/// </returns>
/// <exception cref="ArgumentException">Hexadecimal string is not in the correct format.</exception>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 ParseHex(string hex)
{
Guard.NotNull(hex, nameof(hex));
@ -249,7 +243,7 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryParseHex(string? hex, out Rgba32 result)
{
result = default;
@ -270,6 +264,18 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
return true;
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32() => this;
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Rgba32>(
@ -281,140 +287,82 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
public readonly PixelOperations<Rgba32> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.Pack(ref vector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromVector4(Vector4 source) => Pack(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromArgb32(Argb32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.Bgr = source;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromBgr24(Bgr24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromBgra32(Bgra32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromAbgr32(Abgr32 source) => new(source.R, source.G, source.B, source.A);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromL8(L8 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromL16(L16 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = byte.MaxValue;
byte rgb = ColorNumerics.From16BitTo8Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
this.A = source.A;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromLa16(La16 source) => new(source.L, source.L, source.L, source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromLa32(La32 source)
{
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
byte rgb = ColorNumerics.From16BitTo8Bit(source.L);
return new(rgb, rgb, rgb, ColorNumerics.From16BitTo8Bit(source.A));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.Rgb = source;
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromRgb24(Rgb24 source) => new(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this = source;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest = this;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromRgba32(Rgba32 source) => new() { PackedValue = source.PackedValue };
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = byte.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromRgb48(Rgb48 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = byte.MaxValue
};
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba32 FromRgba64(Rgba64 source)
=> new()
{
R = ColorNumerics.From16BitTo8Bit(source.R),
G = ColorNumerics.From16BitTo8Bit(source.G),
B = ColorNumerics.From16BitTo8Bit(source.B),
A = ColorNumerics.From16BitTo8Bit(source.A)
};
/// <summary>
/// Converts the value of this instance to a hexadecimal string.
@ -430,31 +378,14 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
public override readonly bool Equals(object? obj) => obj is Rgba32 rgba32 && this.Equals(rgba32);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Rgba32 other) => this.Rgba.Equals(other.Rgba);
/// <inheritdoc/>
public override readonly string ToString() => $"Rgba32({this.R}, {this.G}, {this.B}, {this.A})";
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.Rgba.GetHashCode();
/// <summary>
/// Packs a <see cref="Vector4"/> into a color returning a new instance as a result.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
/// <returns>The <see cref="Rgba32"/></returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static Rgba32 PackNew(ref Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
return new Rgba32((byte)vector.X, (byte)vector.Y, (byte)vector.Z, (byte)vector.W);
}
/// <summary>
/// Packs the four floats into a color.
/// </summary>
@ -462,39 +393,29 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
/// <param name="y">The y-component</param>
/// <param name="z">The z-component</param>
/// <param name="w">The w-component</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(float x, float y, float z, float w)
{
var value = new Vector4(x, y, z, w);
this.Pack(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Rgba32 Pack(float x, float y, float z, float w) => Pack(new Vector4(x, y, z, w));
/// <summary>
/// Packs a <see cref="Vector3"/> into a uint.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(ref Vector3 vector)
{
var value = new Vector4(vector, 1F);
this.Pack(ref value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Rgba32 Pack(Vector3 vector) => Pack(new Vector4(vector, 1f));
/// <summary>
/// Packs a <see cref="Vector4"/> into a color.
/// </summary>
/// <param name="vector">The vector containing the values to pack.</param>
[MethodImpl(InliningOptions.ShortMethod)]
private void Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Rgba32 Pack(Vector4 vector)
{
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.R = (byte)vector.X;
this.G = (byte)vector.Y;
this.B = (byte)vector.Z;
this.A = (byte)vector.W;
Vector128<byte> result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
return new(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
}
/// <summary>
@ -526,10 +447,10 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
return null;
}
char r = hex[0];
char g = hex[1];
char b = hex[2];
char a = hex.Length == 3 ? 'F' : hex[3];
char b = hex[2];
char g = hex[1];
char r = hex[0];
return new string(new[] { r, r, g, g, b, b, a, a });
}

302
src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs

@ -45,7 +45,7 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(ushort r, ushort g, ushort b, ushort a)
{
this.R = r;
@ -58,64 +58,64 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// Initializes a new instance of the <see cref="Rgba64"/> struct.
/// </summary>
/// <param name="source">A structure of 4 bytes in RGBA byte order.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(Rgba32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.From8BitTo16Bit(source.R);
this.G = ColorNumerics.From8BitTo16Bit(source.G);
this.B = ColorNumerics.From8BitTo16Bit(source.B);
this.A = ColorNumerics.From8BitTo16Bit(source.A);
}
/// <summary>
/// Initializes a new instance of the <see cref="Rgba64"/> struct.
/// </summary>
/// <param name="source">A structure of 4 bytes in BGRA byte order.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(Bgra32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.From8BitTo16Bit(source.R);
this.G = ColorNumerics.From8BitTo16Bit(source.G);
this.B = ColorNumerics.From8BitTo16Bit(source.B);
this.A = ColorNumerics.From8BitTo16Bit(source.A);
}
/// <summary>
/// Initializes a new instance of the <see cref="Rgba64"/> struct.
/// </summary>
/// <param name="source">A structure of 4 bytes in ARGB byte order.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(Argb32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.From8BitTo16Bit(source.R);
this.G = ColorNumerics.From8BitTo16Bit(source.G);
this.B = ColorNumerics.From8BitTo16Bit(source.B);
this.A = ColorNumerics.From8BitTo16Bit(source.A);
}
/// <summary>
/// Initializes a new instance of the <see cref="Rgba64"/> struct.
/// </summary>
/// <param name="source">A structure of 4 bytes in ABGR byte order.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(Abgr32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.From8BitTo16Bit(source.R);
this.G = ColorNumerics.From8BitTo16Bit(source.G);
this.B = ColorNumerics.From8BitTo16Bit(source.B);
this.A = ColorNumerics.From8BitTo16Bit(source.A);
}
/// <summary>
/// Initializes a new instance of the <see cref="Rgba64"/> struct.
/// </summary>
/// <param name="source">A structure of 3 bytes in RGB byte order.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(Rgb24 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.From8BitTo16Bit(source.R);
this.G = ColorNumerics.From8BitTo16Bit(source.G);
this.B = ColorNumerics.From8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
@ -123,12 +123,12 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// Initializes a new instance of the <see cref="Rgba64"/> struct.
/// </summary>
/// <param name="source">A structure of 3 bytes in BGR byte order.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(Bgr24 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.From8BitTo16Bit(source.R);
this.G = ColorNumerics.From8BitTo16Bit(source.G);
this.B = ColorNumerics.From8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
@ -136,7 +136,7 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// Initializes a new instance of the <see cref="Rgba64"/> struct.
/// </summary>
/// <param name="vector">The <see cref="Vector4"/>.</param>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba64(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
@ -151,20 +151,20 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// </summary>
public Rgb48 Rgb
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => Unsafe.As<Rgba64, Rgb48>(ref Unsafe.AsRef(in this));
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Rgba64, Rgb48>(ref this) = value;
}
/// <inheritdoc/>
public ulong PackedValue
{
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => Unsafe.As<Rgba64, ulong>(ref Unsafe.AsRef(in this));
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Rgba64, ulong>(ref this) = value;
}
@ -176,7 +176,7 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Rgba64 left, Rgba64 right) => left.PackedValue == right.PackedValue;
/// <summary>
@ -187,9 +187,26 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Rgba64 left, Rgba64 right) => left.PackedValue != right.PackedValue;
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgba32 ToRgba32()
=> new(
ColorNumerics.From16BitTo8Bit(this.R),
ColorNumerics.From16BitTo8Bit(this.G),
ColorNumerics.From16BitTo8Bit(this.B),
ColorNumerics.From16BitTo8Bit(this.A));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / Max;
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Rgba64>(
@ -201,181 +218,80 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
public readonly PixelOperations<Rgba64> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
this.R = (ushort)MathF.Round(vector.X);
this.G = (ushort)MathF.Round(vector.Y);
this.B = (ushort)MathF.Round(vector.Z);
this.A = (ushort)MathF.Round(vector.W);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromVector4(Vector4 source) => new(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / Max;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromArgb32(Argb32 source) => new(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromBgr24(Bgr24 source) => new(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromBgra32(Bgra32 source) => new(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromAbgr32(Abgr32 source) => new(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromL8(L8 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
ushort rgb = ColorNumerics.From8BitTo16Bit(source.PackedValue);
return new(rgb, rgb, rgb, ushort.MaxValue);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ushort.MaxValue;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
this.R = source.PackedValue;
this.G = source.PackedValue;
this.B = source.PackedValue;
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromL16(L16 source) => new(source.PackedValue, source.PackedValue, source.PackedValue, ushort.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromLa16(La16 source)
{
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
ushort rgb = ColorNumerics.From8BitTo16Bit(source.L);
return new(rgb, rgb, rgb, ColorNumerics.From8BitTo16Bit(source.A));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
this.R = source.L;
this.G = source.L;
this.B = source.L;
this.A = source.A;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromLa32(La32 source) => new(source.L, source.L, source.L, source.A);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromRgb24(Rgb24 source) => new(source);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
dest.G = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
dest.B = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
dest.A = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromRgba32(Rgba32 source) => new(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.Rgb = source;
this.A = ushort.MaxValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromRgb48(Rgb48 source) => new(source.R, source.G, source.B, ushort.MaxValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this = source;
/// <summary>
/// Convert to <see cref="Rgba32"/>.
/// </summary>
/// <returns>The <see cref="Rgba32"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Rgba32 ToRgba32()
{
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte a = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
return new Rgba32(r, g, b, a);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgba64 FromRgba64(Rgba64 source) => new(source.R, source.G, source.B, source.A);
/// <summary>
/// Convert to <see cref="Bgra32"/>.
/// </summary>
/// <returns>The <see cref="Bgra32"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Bgra32 ToBgra32()
{
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte a = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
byte r = ColorNumerics.From16BitTo8Bit(this.R);
byte g = ColorNumerics.From16BitTo8Bit(this.G);
byte b = ColorNumerics.From16BitTo8Bit(this.B);
byte a = ColorNumerics.From16BitTo8Bit(this.A);
return new Bgra32(r, g, b, a);
}
@ -383,13 +299,13 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// Convert to <see cref="Argb32"/>.
/// </summary>
/// <returns>The <see cref="Argb32"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Argb32 ToArgb32()
{
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte a = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
byte r = ColorNumerics.From16BitTo8Bit(this.R);
byte g = ColorNumerics.From16BitTo8Bit(this.G);
byte b = ColorNumerics.From16BitTo8Bit(this.B);
byte a = ColorNumerics.From16BitTo8Bit(this.A);
return new Argb32(r, g, b, a);
}
@ -397,13 +313,13 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// Convert to <see cref="Abgr32"/>.
/// </summary>
/// <returns>The <see cref="Abgr32"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Abgr32 ToAbgr32()
{
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte a = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
byte r = ColorNumerics.From16BitTo8Bit(this.R);
byte g = ColorNumerics.From16BitTo8Bit(this.G);
byte b = ColorNumerics.From16BitTo8Bit(this.B);
byte a = ColorNumerics.From16BitTo8Bit(this.A);
return new Abgr32(r, g, b, a);
}
@ -411,12 +327,12 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// Convert to <see cref="Rgb24"/>.
/// </summary>
/// <returns>The <see cref="Rgb24"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Rgb24 ToRgb24()
{
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte r = ColorNumerics.From16BitTo8Bit(this.R);
byte g = ColorNumerics.From16BitTo8Bit(this.G);
byte b = ColorNumerics.From16BitTo8Bit(this.B);
return new Rgb24(r, g, b);
}
@ -424,12 +340,12 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
/// Convert to <see cref="Bgr24"/>.
/// </summary>
/// <returns>The <see cref="Bgr24"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Bgr24 ToBgr24()
{
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte r = ColorNumerics.From16BitTo8Bit(this.R);
byte g = ColorNumerics.From16BitTo8Bit(this.G);
byte b = ColorNumerics.From16BitTo8Bit(this.B);
return new Bgr24(r, g, b);
}
@ -437,13 +353,11 @@ public partial struct Rgba64 : IPixel<Rgba64>, IPackedVector<ulong>
public override readonly bool Equals(object? obj) => obj is Rgba64 rgba64 && this.Equals(rgba64);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Rgba64 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
public override readonly string ToString() => $"Rgba64({this.R}, {this.G}, {this.B}, {this.A})";
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
}

146
src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs

@ -19,49 +19,41 @@ 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.
/// </remarks>
/// <remarks>
/// Initializes a new instance of the <see cref="RgbaVector"/> struct.
/// </remarks>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[StructLayout(LayoutKind.Sequential)]
public partial struct RgbaVector : IPixel<RgbaVector>
[method: MethodImpl(MethodImplOptions.AggressiveInlining)]
public partial struct RgbaVector(float r, float g, float b, float a = 1) : IPixel<RgbaVector>
{
/// <summary>
/// Gets or sets the red component.
/// </summary>
public float R;
public float R = r;
/// <summary>
/// Gets or sets the green component.
/// </summary>
public float G;
public float G = g;
/// <summary>
/// Gets or sets the blue component.
/// </summary>
public float B;
public float B = b;
/// <summary>
/// Gets or sets the alpha component.
/// </summary>
public float A;
public float A = a;
private const float MaxBytes = byte.MaxValue;
private static readonly Vector4 Max = new(MaxBytes);
private static readonly Vector4 Half = new(0.5F);
/// <summary>
/// Initializes a new instance of the <see cref="RgbaVector"/> struct.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public RgbaVector(float r, float g, float b, float a = 1)
{
this.R = r;
this.G = g;
this.B = b;
this.A = a;
}
/// <summary>
/// Compares two <see cref="RgbaVector"/> objects for equality.
/// </summary>
@ -70,7 +62,7 @@ public partial struct RgbaVector : IPixel<RgbaVector>
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(RgbaVector left, RgbaVector right) => left.Equals(right);
/// <summary>
@ -81,20 +73,16 @@ public partial struct RgbaVector : IPixel<RgbaVector>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(RgbaVector left, RgbaVector right) => !left.Equals(right);
/// <summary>
/// Creates a new instance of the <see cref="RgbaVector"/> struct.
/// </summary>
/// <param name="hex">
/// The hexadecimal representation of the combined color components arranged
/// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax.
/// </param>
/// <returns>
/// The <see cref="RgbaVector"/>.
/// </returns>
public static RgbaVector FromHex(string hex) => Color.ParseHex(hex).ToPixel<RgbaVector>();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new(this.R, this.G, this.B, this.A);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
@ -107,83 +95,28 @@ public partial struct RgbaVector : IPixel<RgbaVector>
public readonly PixelOperations<RgbaVector> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4() => this.ToVector4();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static RgbaVector FromScaledVector4(Vector4 source) => FromVector4(source);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static RgbaVector FromVector4(Vector4 source)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One);
this.R = vector.X;
this.G = vector.Y;
this.B = vector.Z;
this.A = vector.W;
source = Numerics.Clamp(source, Vector4.Zero, Vector4.One);
return new(source.X, source.Y, source.Z, source.W);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new(this.R, this.G, this.B, this.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <summary>
/// Creates a new instance of the <see cref="RgbaVector"/> struct.
/// </summary>
/// <param name="hex">
/// The hexadecimal representation of the combined color components arranged
/// in rgb, rgba, rrggbb, or rrggbbaa format to match web syntax.
/// </param>
/// <returns>
/// The <see cref="RgbaVector"/>.
/// </returns>
public static RgbaVector FromHex(string hex) => Color.ParseHex(hex).ToPixel<RgbaVector>();
/// <summary>
/// Converts the value of this instance to a hexadecimal string.
@ -202,7 +135,6 @@ public partial struct RgbaVector : IPixel<RgbaVector>
public override readonly bool Equals(object? obj) => obj is RgbaVector other && this.Equals(other);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(RgbaVector other) =>
this.R.Equals(other.R)
&& this.G.Equals(other.G)

126
src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-32767, -32767, 0, 1] to [32767, 32767, 0, 1] in vector form.
/// </para>
/// </summary>
public partial struct Short2 : IPixel<Short2>, IPackedVector<uint>
/// <remarks>
/// Initializes a new instance of the <see cref="Short2"/> struct.
/// </remarks>
/// <param name="vector">The vector containing the component values.</param>
public partial struct Short2(Vector2 vector) : IPixel<Short2>, IPackedVector<uint>
{
// Largest two byte positive number 0xFFFF >> 1;
private const float MaxPos = 0x7FFF;
@ -33,14 +37,8 @@ public partial struct Short2 : IPixel<Short2>, IPackedVector<uint>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Short2"/> struct.
/// </summary>
/// <param name="vector">The vector containing the component values.</param>
public Short2(Vector2 vector) => this.PackedValue = Pack(vector);
/// <inheritdoc/>
public uint PackedValue { get; set; }
public uint PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="Short2"/> objects for equality.
@ -50,7 +48,7 @@ public partial struct Short2 : IPixel<Short2>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Short2 left, Short2 right) => left.Equals(right);
/// <summary>
@ -61,9 +59,23 @@ public partial struct Short2 : IPixel<Short2>, IPackedVector<uint>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Short2 left, Short2 right) => !left.Equals(right);
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
Vector2 scaled = this.ToVector2();
scaled += new Vector2(32767f);
scaled /= 65534F;
return new Vector4(scaled, 0f, 1f);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4() => new((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10), 0f, 1f);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Short2>(
@ -75,119 +87,43 @@ public partial struct Short2 : IPixel<Short2>, IPackedVector<uint>
public readonly PixelOperations<Short2> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Short2 FromScaledVector4(Vector4 source)
{
Vector2 scaled = new Vector2(vector.X, vector.Y) * 65534F;
Vector2 scaled = new Vector2(source.X, source.Y) * 65534F;
scaled -= new Vector2(32767F);
this.PackedValue = Pack(scaled);
return new() { PackedValue = Pack(scaled) };
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector2();
scaled += new Vector2(32767F);
scaled /= 65534F;
return new Vector4(scaled, 0F, 1F);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector)
{
var vector2 = new Vector2(vector.X, vector.Y);
this.PackedValue = Pack(vector2);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Vector4 ToVector4() => new((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10), 0, 1);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Short2 FromVector4(Vector4 source) => new() { PackedValue = Pack(new Vector2(source.X, source.Y)) };
/// <summary>
/// Expands the packed representation into a <see cref="Vector2"/>.
/// The vector components are typically expanded in least to greatest significance order.
/// </summary>
/// <returns>The <see cref="Vector2"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector2 ToVector2() => new((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10));
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is Short2 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Short2 other) => this.PackedValue.Equals(other.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector2();
Vector2 vector = this.ToVector2();
return FormattableString.Invariant($"Short2({vector.X:#0.##}, {vector.Y:#0.##})");
}
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(Vector2 vector)
{
vector = Vector2.Clamp(vector, Min, Max);

134
src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats;
/// Ranges from [-37267, -37267, -37267, -37267] to [37267, 37267, 37267, 37267] in vector form.
/// </para>
/// </summary>
public partial struct Short4 : IPixel<Short4>, IPackedVector<ulong>
/// <remarks>
/// Initializes a new instance of the <see cref="Short4"/> struct.
/// </remarks>
/// <param name="vector">A vector containing the initial values for the components.</param>
public partial struct Short4(Vector4 vector) : IPixel<Short4>, IPackedVector<ulong>
{
// Largest two byte positive number 0xFFFF >> 1;
private const float MaxPos = 0x7FFF;
@ -20,8 +24,8 @@ public partial struct Short4 : IPixel<Short4>, IPackedVector<ulong>
// Two's complement
private const float MinNeg = ~(int)MaxPos;
private static readonly Vector4 Max = new Vector4(MaxPos);
private static readonly Vector4 Min = new Vector4(MinNeg);
private static readonly Vector4 Max = new(MaxPos);
private static readonly Vector4 Min = new(MinNeg);
/// <summary>
/// Initializes a new instance of the <see cref="Short4"/> struct.
@ -35,14 +39,8 @@ public partial struct Short4 : IPixel<Short4>, IPackedVector<ulong>
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Short4"/> struct.
/// </summary>
/// <param name="vector">A vector containing the initial values for the components.</param>
public Short4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc/>
public ulong PackedValue { get; set; }
public ulong PackedValue { get; set; } = Pack(vector);
/// <summary>
/// Compares two <see cref="Short4"/> objects for equality.
@ -52,7 +50,7 @@ public partial struct Short4 : IPixel<Short4>, IPackedVector<ulong>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Short4 left, Short4 right) => left.Equals(right);
/// <summary>
@ -63,139 +61,75 @@ public partial struct Short4 : IPixel<Short4>, IPackedVector<ulong>
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Short4 left, Short4 right) => !left.Equals(right);
/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Short4>(
PixelComponentInfo.Create<Short4>(4, 16, 16, 16, 16),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
public readonly PixelOperations<Short4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromScaledVector4(Vector4 vector)
{
vector *= 65534F;
vector -= new Vector4(32767F);
this.FromVector4(vector);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToScaledVector4()
{
var scaled = this.ToVector4();
scaled += new Vector4(32767F);
scaled /= 65534F;
Vector4 scaled = this.ToVector4();
scaled += new Vector4(32767f);
scaled /= 65534f;
return scaled;
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromVector4(Vector4 vector) => this.PackedValue = Pack(ref vector);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToVector4()
{
return new Vector4(
=> new(
(short)(this.PackedValue & 0xFFFF),
(short)((this.PackedValue >> 0x10) & 0xFFFF),
(short)((this.PackedValue >> 0x20) & 0xFFFF),
(short)((this.PackedValue >> 0x30) & 0xFFFF));
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Short4>(
PixelComponentInfo.Create<Short4>(4, 16, 16, 16, 16),
PixelColorType.RGB | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.FromScaledVector4(source.ToScaledVector4());
public readonly PixelOperations<Short4> CreatePixelOperations() => new PixelOperations();
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Short4 FromScaledVector4(Vector4 source)
{
dest.FromScaledVector4(this.ToScaledVector4());
source *= 65534F;
source -= new Vector4(32767F);
return FromVector4(source);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.FromScaledVector4(source.ToScaledVector4());
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Short4 FromVector4(Vector4 source) => new(source);
/// <inheritdoc />
public override readonly bool Equals(object? obj) => obj is Short4 other && this.Equals(other);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public readonly bool Equals(Short4 other) => this.PackedValue.Equals(other.PackedValue);
/// <summary>
/// Gets the hash code for the current instance.
/// </summary>
/// <returns>Hash code for the instance.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public override readonly int GetHashCode() => this.PackedValue.GetHashCode();
/// <inheritdoc />
public override readonly string ToString()
{
var vector = this.ToVector4();
Vector4 vector = this.ToVector4();
return FormattableString.Invariant($"Short4({vector.X:#0.##}, {vector.Y:#0.##}, {vector.Z:#0.##}, {vector.W:#0.##})");
}
[MethodImpl(InliningOptions.ShortMethod)]
private static ulong Pack(ref Vector4 vector)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong Pack(Vector4 vector)
{
vector = Numerics.Clamp(vector, Min, Max);
// Clamp the value between min and max values
vector = Numerics.Clamp(vector, Min, Max);
ulong word4 = ((ulong)Convert.ToInt32(Math.Round(vector.X)) & 0xFFFF) << 0x00;
ulong word3 = ((ulong)Convert.ToInt32(Math.Round(vector.Y)) & 0xFFFF) << 0x10;
ulong word2 = ((ulong)Convert.ToInt32(Math.Round(vector.Z)) & 0xFFFF) << 0x20;

2
src/ImageSharp/PixelFormats/README.md

@ -1,4 +1,4 @@
Pixel formats adapted and extended from:
Pixel formats adapted and extended from:
https://github.com/MonoGame/MonoGame

26
tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs

@ -117,12 +117,26 @@ public class PixelConversion_ConvertFromRgba32_Compatible : PixelConversion_Conv
}
}
/* Method | Count | Mean | Error | StdDev | Scaled | ScaledSD |
---------- |------ |---------:|---------:|---------:|-------:|---------:|
ByRef | 256 | 128.5 ns | 1.217 ns | 1.138 ns | 1.00 | 0.00 |
ByVal | 256 | 196.7 ns | 2.792 ns | 2.612 ns | 1.53 | 0.02 |
FromBytes | 256 | 321.7 ns | 2.180 ns | 1.820 ns | 2.50 | 0.03 |
Inline | 256 | 129.9 ns | 2.759 ns | 2.581 ns | 1.01 | 0.02 | */
/*
BenchmarkDotNet v0.13.10, Windows 11 (10.0.22631.3007/23H2/2023Update/SunValley3)
11th Gen Intel Core i7-11370H 3.30GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK 8.0.100
[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
| Method | Count | Mean | Error | StdDev | Ratio |
|---------- |------ |-----------:|--------:|--------:|------:|
| ByRef | 256 | 102.5 ns | 0.44 ns | 0.39 ns | 1.00 |
| ByVal | 256 | 102.2 ns | 0.30 ns | 0.25 ns | 1.00 |
| FromBytes | 256 | 200.5 ns | 1.01 ns | 0.90 ns | 1.96 |
| Inline | 256 | 107.0 ns | 0.90 ns | 0.84 ns | 1.04 |
| | | | | | |
| ByRef | 2048 | 770.8 ns | 3.22 ns | 2.86 ns | 1.00 |
| ByVal | 2048 | 770.3 ns | 2.05 ns | 1.92 ns | 1.00 |
| FromBytes | 2048 | 1,546.8 ns | 7.51 ns | 6.66 ns | 2.01 |
| Inline | 2048 | 797.6 ns | 2.90 ns | 2.26 ns | 1.03 |
*/
}
public class PixelConversion_ConvertFromRgba32_Permuted_RgbaToArgb : PixelConversion_ConvertFromRgba32

4
tests/ImageSharp.Tests/PixelFormats/L16Tests.cs

@ -114,7 +114,7 @@ public class L16Tests
// Arrange
L16 gray = default;
const byte rgb = 128;
ushort scaledRgb = ColorNumerics.UpscaleFrom8BitTo16Bit(rgb);
ushort scaledRgb = ColorNumerics.From8BitTo16Bit(rgb);
ushort expected = ColorNumerics.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb);
// Act
@ -132,7 +132,7 @@ public class L16Tests
public void L16_ToRgba32(ushort input)
{
// Arrange
ushort expected = ColorNumerics.DownScaleFrom16BitTo8Bit(input);
ushort expected = ColorNumerics.From16BitTo8Bit(input);
L16 gray = new(input);
// Act

4
tests/ImageSharp.Tests/PixelFormats/La32Tests.cs

@ -118,7 +118,7 @@ public class La32Tests
// Arrange
La32 gray = default;
const byte rgb = 128;
ushort scaledRgb = ColorNumerics.UpscaleFrom8BitTo16Bit(rgb);
ushort scaledRgb = ColorNumerics.From8BitTo16Bit(rgb);
ushort expected = ColorNumerics.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb);
// Act
@ -137,7 +137,7 @@ public class La32Tests
public void La32_ToRgba32(ushort input)
{
// Arrange
ushort expected = ColorNumerics.DownScaleFrom16BitTo8Bit(input);
ushort expected = ColorNumerics.From16BitTo8Bit(input);
La32 gray = new(input, ushort.MaxValue);
// Act

2
tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.ReferenceImplementations.cs

@ -104,7 +104,7 @@ public abstract partial class PixelConverterTests
{
ref TSourcePixel sp = ref Unsafe.Add(ref sourceRef, i);
ref L16 dp = ref Unsafe.Add(ref l16Ref, i);
dp.ConvertFromRgbaScaledVector4(sp.ToScaledVector4());
dp.Pack(sp.ToScaledVector4());
}
return;

Loading…
Cancel
Save