Browse Source

Merge pull request #540 from woutware/issue-532

Issue-532: Added IPixel.PackFromArgb32 and ToArgb32.
af/merge-core
James Jackson-South 8 years ago
committed by GitHub
parent
commit
0aa99d897d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      src/ImageSharp/PixelFormats/Alpha8.cs
  2. 204
      src/ImageSharp/PixelFormats/Argb32.cs
  3. 17
      src/ImageSharp/PixelFormats/Bgr24.cs
  4. 16
      src/ImageSharp/PixelFormats/Bgr565.cs
  5. 19
      src/ImageSharp/PixelFormats/Bgra32.cs
  6. 17
      src/ImageSharp/PixelFormats/Bgra4444.cs
  7. 17
      src/ImageSharp/PixelFormats/Bgra5551.cs
  8. 17
      src/ImageSharp/PixelFormats/Byte4.cs
  9. 157
      src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs
  10. 53
      src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt
  11. 32
      src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs
  12. 3
      src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt
  13. 17
      src/ImageSharp/PixelFormats/HalfSingle.cs
  14. 17
      src/ImageSharp/PixelFormats/HalfVector2.cs
  15. 17
      src/ImageSharp/PixelFormats/HalfVector4.cs
  16. 12
      src/ImageSharp/PixelFormats/IPixel.cs
  17. 22
      src/ImageSharp/PixelFormats/NormalizedByte2.cs
  18. 21
      src/ImageSharp/PixelFormats/NormalizedByte4.cs
  19. 21
      src/ImageSharp/PixelFormats/NormalizedShort2.cs
  20. 22
      src/ImageSharp/PixelFormats/NormalizedShort4.cs
  21. 17
      src/ImageSharp/PixelFormats/Rg32.cs
  22. 17
      src/ImageSharp/PixelFormats/Rgb24.cs
  23. 17
      src/ImageSharp/PixelFormats/Rgba1010102.cs
  24. 42
      src/ImageSharp/PixelFormats/Rgba32.cs
  25. 17
      src/ImageSharp/PixelFormats/Rgba64.cs
  26. 17
      src/ImageSharp/PixelFormats/RgbaVector.cs
  27. 20
      src/ImageSharp/PixelFormats/Short2.cs
  28. 20
      src/ImageSharp/PixelFormats/Short4.cs
  29. 4
      tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
  30. 2
      tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs
  31. 90
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs
  32. 2
      tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs

15
src/ImageSharp/PixelFormats/Alpha8.cs

@ -97,6 +97,12 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackedValue = source.A; this.PackedValue = source.A;
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
this.PackedValue = source.A;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -114,6 +120,15 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = this.PackedValue; dest.A = this.PackedValue;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
dest.R = 0;
dest.G = 0;
dest.B = 0;
dest.A = this.PackedValue;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

204
src/ImageSharp/PixelFormats/Argb32.cs

@ -1,9 +1,9 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.PixelFormats namespace SixLabors.ImageSharp.PixelFormats
{ {
@ -18,27 +18,28 @@ namespace SixLabors.ImageSharp.PixelFormats
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance, /// 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. /// as it avoids the need to create new values for modification operations.
/// </remarks> /// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct Argb32 : IPixel<Argb32>, IPackedVector<uint> public struct Argb32 : IPixel<Argb32>, IPackedVector<uint>
{ {
/// <summary> /// <summary>
/// The shift count for the blue component /// Gets or sets the alpha component.
/// </summary> /// </summary>
private const int BlueShift = 0; public byte A;
/// <summary> /// <summary>
/// The shift count for the green component /// Gets or sets the red component.
/// </summary> /// </summary>
private const int GreenShift = 8; public byte R;
/// <summary> /// <summary>
/// The shift count for the red component /// Gets or sets the green component.
/// </summary> /// </summary>
private const int RedShift = 16; public byte G;
/// <summary> /// <summary>
/// The shift count for the alpha component /// Gets or sets the blue component.
/// </summary> /// </summary>
private const int AlphaShift = 24; public byte B;
/// <summary> /// <summary>
/// The maximum byte value. /// The maximum byte value.
@ -56,11 +57,13 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="r">The red component.</param> /// <param name="r">The red component.</param>
/// <param name="g">The green component.</param> /// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param> /// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(byte r, byte g, byte b, byte a) public Argb32(byte r, byte g, byte b)
{ {
this.PackedValue = Pack(r, g, b, a); this.R = r;
this.G = g;
this.B = b;
this.A = 255;
} }
/// <summary> /// <summary>
@ -69,10 +72,14 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="r">The red component.</param> /// <param name="r">The red component.</param>
/// <param name="g">The green component.</param> /// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param> /// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(byte r, byte g, byte b) public Argb32(byte r, byte g, byte b, byte a)
{ {
this.PackedValue = Pack(r, g, b, 255); this.R = r;
this.G = g;
this.B = b;
this.A = a;
} }
/// <summary> /// <summary>
@ -82,9 +89,11 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="g">The green component.</param> /// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param> /// <param name="b">The blue component.</param>
/// <param name="a">The alpha component.</param> /// <param name="a">The alpha component.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(float r, float g, float b, float a = 1) public Argb32(float r, float g, float b, float a = 1)
: this()
{ {
this.PackedValue = Pack(r, g, b, a); this.Pack(r, g, b, a);
} }
/// <summary> /// <summary>
@ -93,9 +102,11 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="vector"> /// <param name="vector">
/// The vector containing the components for the packed vector. /// The vector containing the components for the packed vector.
/// </param> /// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(Vector3 vector) public Argb32(Vector3 vector)
: this()
{ {
this.PackedValue = Pack(ref vector); this.Pack(ref vector);
} }
/// <summary> /// <summary>
@ -104,9 +115,11 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="vector"> /// <param name="vector">
/// The vector containing the components for the packed vector. /// The vector containing the components for the packed vector.
/// </param> /// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32(Vector4 vector) public Argb32(Vector4 vector)
: this()
{ {
this.PackedValue = Pack(ref vector); this.Pack(ref vector);
} }
/// <summary> /// <summary>
@ -115,84 +128,36 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="packed"> /// <param name="packed">
/// The packed value. /// The packed value.
/// </param> /// </param>
public Argb32(uint packed = 0) [MethodImpl(MethodImplOptions.AggressiveInlining)]
{ public Argb32(uint packed)
this.PackedValue = packed; : this()
}
/// <inheritdoc/>
public uint PackedValue { get; set; }
/// <summary>
/// Gets or sets the red component.
/// </summary>
public byte R
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return (byte)(this.PackedValue >> RedShift);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
this.PackedValue = this.PackedValue & 0xFF00FFFF | (uint)value << RedShift;
}
}
/// <summary>
/// Gets or sets the green component.
/// </summary>
public byte G
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] this.Argb = packed;
get
{
return (byte)(this.PackedValue >> GreenShift);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
this.PackedValue = this.PackedValue & 0xFFFF00FF | (uint)value << GreenShift;
}
} }
/// <summary> /// <summary>
/// Gets or sets the blue component. /// Gets or sets the packed representation of the Argb32 struct.
/// </summary> /// </summary>
public byte B public uint Argb
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get get
{ {
return (byte)(this.PackedValue >> BlueShift); return Unsafe.As<Argb32, uint>(ref this);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
set set
{ {
this.PackedValue = this.PackedValue & 0xFFFFFF00 | (uint)value << BlueShift; Unsafe.As<Argb32, uint>(ref this) = value;
} }
} }
/// <summary> /// <inheritdoc/>
/// Gets or sets the alpha component. public uint PackedValue
/// </summary>
public byte A
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] get => this.Argb;
get set => this.Argb = value;
{
return (byte)(this.PackedValue >> AlphaShift);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
this.PackedValue = this.PackedValue & 0x00FFFFFF | (uint)value << AlphaShift;
}
} }
/// <summary> /// <summary>
@ -210,7 +175,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Argb32 left, Argb32 right) public static bool operator ==(Argb32 left, Argb32 right)
{ {
return left.PackedValue == right.PackedValue; return left.Argb == right.Argb;
} }
/// <summary> /// <summary>
@ -224,14 +189,14 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Argb32 left, Argb32 right) public static bool operator !=(Argb32 left, Argb32 right)
{ {
return left.PackedValue != right.PackedValue; return left.Argb != right.Argb;
} }
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromVector4(Vector4 vector) public void PackFromVector4(Vector4 vector)
{ {
this.PackedValue = Pack(ref vector); this.Pack(ref vector);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -262,7 +227,17 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromRgba32(Rgba32 source) public void PackFromRgba32(Rgba32 source)
{ {
this.PackedValue = Pack(source.R, source.G, source.B, source.A); this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackedValue = source.PackedValue;
} }
/// <inheritdoc /> /// <inheritdoc />
@ -284,6 +259,13 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = this.A; dest.A = this.A;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest)
{
dest = this;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)
@ -303,6 +285,13 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = this.A; dest.A = this.A;
} }
/// <summary>
/// Converts the pixel to <see cref="Rgba32"/> format.
/// </summary>
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A);
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
@ -313,7 +302,16 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Argb32 other) public bool Equals(Argb32 other)
{ {
return this.PackedValue == other.PackedValue; return this.Argb == other.Argb;
}
/// <summary>
/// Gets a string representation of the packed vector.
/// </summary>
/// <returns>A string representation of the packed vector.</returns>
public override string ToString()
{
return $"({this.R},{this.G},{this.B},{this.A})";
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -321,65 +319,59 @@ namespace SixLabors.ImageSharp.PixelFormats
public override int GetHashCode() public override int GetHashCode()
{ {
// ReSharper disable once NonReadonlyMemberInGetHashCode // ReSharper disable once NonReadonlyMemberInGetHashCode
return this.PackedValue.GetHashCode(); return this.Argb.GetHashCode();
} }
/// <summary> /// <summary>
/// Packs the four floats into a <see cref="uint"/>. /// Gets the <see cref="Vector4"/> representation without normalizing to [0, 1]
/// </summary> /// </summary>
/// <param name="x">The x-component</param> /// <returns>A <see cref="Vector4"/> of values in [0, 255] </returns>
/// <param name="y">The y-component</param>
/// <param name="z">The z-component</param>
/// <param name="w">The w-component</param>
/// <returns>The <see cref="uint"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(float x, float y, float z, float w) internal Vector4 ToByteScaledVector4()
{ {
var value = new Vector4(x, y, z, w); return new Vector4(this.R, this.G, this.B, this.A);
return Pack(ref value);
} }
/// <summary> /// <summary>
/// Packs the four floats into a <see cref="uint"/>. /// Packs the four floats into a color.
/// </summary> /// </summary>
/// <param name="x">The x-component</param> /// <param name="x">The x-component</param>
/// <param name="y">The y-component</param> /// <param name="y">The y-component</param>
/// <param name="z">The z-component</param> /// <param name="z">The z-component</param>
/// <param name="w">The w-component</param> /// <param name="w">The w-component</param>
/// <returns>The <see cref="uint"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(byte x, byte y, byte z, byte w) private void Pack(float x, float y, float z, float w)
{ {
return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift); var value = new Vector4(x, y, z, w);
this.Pack(ref value);
} }
/// <summary> /// <summary>
/// Packs a <see cref="Vector3"/> into a uint. /// Packs a <see cref="Vector3"/> into a uint.
/// </summary> /// </summary>
/// <param name="vector">The vector containing the values to pack.</param> /// <param name="vector">The vector containing the values to pack.</param>
/// <returns>The <see cref="uint"/> containing the packed values.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(ref Vector3 vector) private void Pack(ref Vector3 vector)
{ {
var value = new Vector4(vector, 1); var value = new Vector4(vector, 1);
return Pack(ref value); this.Pack(ref value);
} }
/// <summary> /// <summary>
/// Packs a <see cref="Vector4"/> into a uint. /// Packs a <see cref="Vector4"/> into a color.
/// </summary> /// </summary>
/// <param name="vector">The vector containing the values to pack.</param> /// <param name="vector">The vector containing the values to pack.</param>
/// <returns>The <see cref="uint"/> containing the packed values.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static uint Pack(ref Vector4 vector) private void Pack(ref Vector4 vector)
{ {
vector *= MaxBytes; vector *= MaxBytes;
vector += Half; vector += Half;
vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
return (uint)(((byte)vector.X << RedShift)
| ((byte)vector.Y << GreenShift) this.R = (byte)vector.X;
| ((byte)vector.Z << BlueShift) this.G = (byte)vector.Y;
| (byte)vector.W << AlphaShift); this.B = (byte)vector.Z;
this.A = (byte)vector.W;
} }
} }
} }

17
src/ImageSharp/PixelFormats/Bgr24.cs

@ -82,6 +82,14 @@ namespace SixLabors.ImageSharp.PixelFormats
this = source.Bgr; this = source.Bgr;
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromScaledVector4(Vector4 vector) public void PackFromScaledVector4(Vector4 vector)
@ -131,6 +139,15 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = 255; dest.A = 255;
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = 255;
}
/// <inheritdoc/> /// <inheritdoc/>
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)
{ {

16
src/ImageSharp/PixelFormats/Bgr565.cs

@ -120,6 +120,12 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -141,6 +147,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)MathF.Round(vector.W); dest.A = (byte)MathF.Round(vector.W);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = (byte)MathF.Round(vector.Z);
dest.A = (byte)MathF.Round(vector.W);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

19
src/ImageSharp/PixelFormats/Bgra32.cs

@ -159,6 +159,16 @@ namespace SixLabors.ImageSharp.PixelFormats
this.A = source.A; this.A = source.A;
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -178,6 +188,15 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = this.A; dest.A = this.A;
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = this.A;
}
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/Bgra4444.cs

@ -111,6 +111,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -132,6 +139,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)vector.W; dest.A = (byte)vector.W;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = (byte)vector.Z;
dest.A = (byte)vector.W;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/Bgra5551.cs

@ -111,6 +111,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -132,6 +139,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)vector.W; dest.A = (byte)vector.W;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = (byte)vector.Z;
dest.A = (byte)vector.W;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/Byte4.cs

@ -112,6 +112,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToByteScaledVector4()); this.PackFromVector4(source.ToByteScaledVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToByteScaledVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -133,6 +140,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)vector.W; dest.A = (byte)vector.W;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
var vector = this.ToVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = (byte)vector.Z;
dest.A = (byte)vector.W;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

157
src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs

@ -10,8 +10,8 @@ namespace SixLabors.ImageSharp.PixelFormats
public partial class PixelOperations<TPixel> public partial class PixelOperations<TPixel>
{ {
/// <summary> /// <summary>
/// Converts 'count' elements in 'source` span of <see cref="Rgba32"/> data to a span of <typeparamref name="TPixel"/>-s. /// Converts 'count' elements in 'source` span of <see cref="Rgba32"/> data to a span of <typeparamref name="TPixel"/>-s.
/// </summary> /// </summary>
/// <param name="source">The source <see cref="Span{T}"/> of <see cref="Rgba32"/> data.</param> /// <param name="source">The source <see cref="Span{T}"/> of <see cref="Rgba32"/> data.</param>
@ -19,12 +19,12 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromRgba32(ReadOnlySpan<Rgba32> source, Span<TPixel> destPixels, int count) internal virtual void PackFromRgba32(ReadOnlySpan<Rgba32> source, Span<TPixel> destPixels, int count)
{ {
GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(source); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
Rgba32 rgba = new Rgba32(0, 0, 0, 255); var rgba = new Rgba32(0, 0, 0, 255);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@ -33,8 +33,8 @@ namespace SixLabors.ImageSharp.PixelFormats
dp.PackFromRgba32(rgba); dp.PackFromRgba32(rgba);
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="PackFromRgba32(ReadOnlySpan{Rgba32}, Span{TPixel}, int)"/> that expects a byte span. /// A helper for <see cref="PackFromRgba32(ReadOnlySpan{Rgba32}, Span{TPixel}, int)"/> that expects a byte span.
/// The layout of the data in 'sourceBytes' must be compatible with <see cref="Rgba32"/> layout. /// The layout of the data in 'sourceBytes' must be compatible with <see cref="Rgba32"/> layout.
/// </summary> /// </summary>
@ -46,8 +46,8 @@ namespace SixLabors.ImageSharp.PixelFormats
{ {
this.PackFromRgba32(MemoryMarshal.Cast<byte, Rgba32>(sourceBytes), destPixels, count); this.PackFromRgba32(MemoryMarshal.Cast<byte, Rgba32>(sourceBytes), destPixels, count);
} }
/// <summary> /// <summary>
/// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Rgba32"/>-s. /// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Rgba32"/>-s.
/// Bulk version of <see cref="IPixel.ToRgba32(ref Rgba32)"/>. /// Bulk version of <see cref="IPixel.ToRgba32(ref Rgba32)"/>.
/// </summary> /// </summary>
@ -69,20 +69,20 @@ namespace SixLabors.ImageSharp.PixelFormats
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="ToRgba32(ReadOnlySpan{TPixel}, Span{Rgba32}, int)"/> that expects a byte span as destination. /// A helper for <see cref="ToRgba32(ReadOnlySpan{TPixel}, Span{Rgba32}, int)"/> that expects a byte span as destination.
/// The layout of the data in 'destBytes' must be compatible with <see cref="Rgba32"/> layout. /// The layout of the data in 'destBytes' must be compatible with <see cref="Rgba32"/> layout.
/// </summary> /// </summary>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param> /// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param> /// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ToRgba32Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count) internal void ToRgba32Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count)
{ {
this.ToRgba32(sourceColors, MemoryMarshal.Cast<byte, Rgba32>(destBytes), count); this.ToRgba32(sourceColors, MemoryMarshal.Cast<byte, Rgba32>(destBytes), count);
} }
/// <summary> /// <summary>
/// Converts 'count' elements in 'source` span of <see cref="Bgra32"/> data to a span of <typeparamref name="TPixel"/>-s. /// Converts 'count' elements in 'source` span of <see cref="Bgra32"/> data to a span of <typeparamref name="TPixel"/>-s.
/// </summary> /// </summary>
/// <param name="source">The source <see cref="Span{T}"/> of <see cref="Bgra32"/> data.</param> /// <param name="source">The source <see cref="Span{T}"/> of <see cref="Bgra32"/> data.</param>
@ -90,8 +90,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromBgra32(ReadOnlySpan<Bgra32> source, Span<TPixel> destPixels, int count) internal virtual void PackFromBgra32(ReadOnlySpan<Bgra32> source, Span<TPixel> destPixels, int count)
{ {
GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
@ -104,8 +104,8 @@ namespace SixLabors.ImageSharp.PixelFormats
dp.PackFromRgba32(rgba); dp.PackFromRgba32(rgba);
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="PackFromBgra32(ReadOnlySpan{Bgra32}, Span{TPixel}, int)"/> that expects a byte span. /// A helper for <see cref="PackFromBgra32(ReadOnlySpan{Bgra32}, Span{TPixel}, int)"/> that expects a byte span.
/// The layout of the data in 'sourceBytes' must be compatible with <see cref="Bgra32"/> layout. /// The layout of the data in 'sourceBytes' must be compatible with <see cref="Bgra32"/> layout.
/// </summary> /// </summary>
@ -117,8 +117,8 @@ namespace SixLabors.ImageSharp.PixelFormats
{ {
this.PackFromBgra32(MemoryMarshal.Cast<byte, Bgra32>(sourceBytes), destPixels, count); this.PackFromBgra32(MemoryMarshal.Cast<byte, Bgra32>(sourceBytes), destPixels, count);
} }
/// <summary> /// <summary>
/// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Bgra32"/>-s. /// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Bgra32"/>-s.
/// Bulk version of <see cref="IPixel.ToBgra32(ref Bgra32)"/>. /// Bulk version of <see cref="IPixel.ToBgra32(ref Bgra32)"/>.
/// </summary> /// </summary>
@ -140,20 +140,20 @@ namespace SixLabors.ImageSharp.PixelFormats
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="ToBgra32(ReadOnlySpan{TPixel}, Span{Bgra32}, int)"/> that expects a byte span as destination. /// A helper for <see cref="ToBgra32(ReadOnlySpan{TPixel}, Span{Bgra32}, int)"/> that expects a byte span as destination.
/// The layout of the data in 'destBytes' must be compatible with <see cref="Bgra32"/> layout. /// The layout of the data in 'destBytes' must be compatible with <see cref="Bgra32"/> layout.
/// </summary> /// </summary>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param> /// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param> /// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ToBgra32Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count) internal void ToBgra32Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count)
{ {
this.ToBgra32(sourceColors, MemoryMarshal.Cast<byte, Bgra32>(destBytes), count); this.ToBgra32(sourceColors, MemoryMarshal.Cast<byte, Bgra32>(destBytes), count);
} }
/// <summary> /// <summary>
/// Converts 'count' elements in 'source` span of <see cref="Rgb24"/> data to a span of <typeparamref name="TPixel"/>-s. /// Converts 'count' elements in 'source` span of <see cref="Rgb24"/> data to a span of <typeparamref name="TPixel"/>-s.
/// </summary> /// </summary>
/// <param name="source">The source <see cref="Span{T}"/> of <see cref="Rgb24"/> data.</param> /// <param name="source">The source <see cref="Span{T}"/> of <see cref="Rgb24"/> data.</param>
@ -161,8 +161,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromRgb24(ReadOnlySpan<Rgb24> source, Span<TPixel> destPixels, int count) internal virtual void PackFromRgb24(ReadOnlySpan<Rgb24> source, Span<TPixel> destPixels, int count)
{ {
GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
@ -175,8 +175,8 @@ namespace SixLabors.ImageSharp.PixelFormats
dp.PackFromRgba32(rgba); dp.PackFromRgba32(rgba);
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="PackFromRgb24(ReadOnlySpan{Rgb24}, Span{TPixel}, int)"/> that expects a byte span. /// A helper for <see cref="PackFromRgb24(ReadOnlySpan{Rgb24}, Span{TPixel}, int)"/> that expects a byte span.
/// The layout of the data in 'sourceBytes' must be compatible with <see cref="Rgb24"/> layout. /// The layout of the data in 'sourceBytes' must be compatible with <see cref="Rgb24"/> layout.
/// </summary> /// </summary>
@ -188,8 +188,8 @@ namespace SixLabors.ImageSharp.PixelFormats
{ {
this.PackFromRgb24(MemoryMarshal.Cast<byte, Rgb24>(sourceBytes), destPixels, count); this.PackFromRgb24(MemoryMarshal.Cast<byte, Rgb24>(sourceBytes), destPixels, count);
} }
/// <summary> /// <summary>
/// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Rgb24"/>-s. /// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Rgb24"/>-s.
/// Bulk version of <see cref="IPixel.ToRgb24(ref Rgb24)"/>. /// Bulk version of <see cref="IPixel.ToRgb24(ref Rgb24)"/>.
/// </summary> /// </summary>
@ -211,20 +211,20 @@ namespace SixLabors.ImageSharp.PixelFormats
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="ToRgb24(ReadOnlySpan{TPixel}, Span{Rgb24}, int)"/> that expects a byte span as destination. /// A helper for <see cref="ToRgb24(ReadOnlySpan{TPixel}, Span{Rgb24}, int)"/> that expects a byte span as destination.
/// The layout of the data in 'destBytes' must be compatible with <see cref="Rgb24"/> layout. /// The layout of the data in 'destBytes' must be compatible with <see cref="Rgb24"/> layout.
/// </summary> /// </summary>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param> /// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param> /// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ToRgb24Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count) internal void ToRgb24Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count)
{ {
this.ToRgb24(sourceColors, MemoryMarshal.Cast<byte, Rgb24>(destBytes), count); this.ToRgb24(sourceColors, MemoryMarshal.Cast<byte, Rgb24>(destBytes), count);
} }
/// <summary> /// <summary>
/// Converts 'count' elements in 'source` span of <see cref="Bgr24"/> data to a span of <typeparamref name="TPixel"/>-s. /// Converts 'count' elements in 'source` span of <see cref="Bgr24"/> data to a span of <typeparamref name="TPixel"/>-s.
/// </summary> /// </summary>
/// <param name="source">The source <see cref="Span{T}"/> of <see cref="Bgr24"/> data.</param> /// <param name="source">The source <see cref="Span{T}"/> of <see cref="Bgr24"/> data.</param>
@ -232,12 +232,12 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromBgr24(ReadOnlySpan<Bgr24> source, Span<TPixel> destPixels, int count) internal virtual void PackFromBgr24(ReadOnlySpan<Bgr24> source, Span<TPixel> destPixels, int count)
{ {
GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
Rgba32 rgba = new Rgba32(0, 0, 0, 255); var rgba = new Rgba32(0, 0, 0, 255);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@ -246,8 +246,8 @@ namespace SixLabors.ImageSharp.PixelFormats
dp.PackFromRgba32(rgba); dp.PackFromRgba32(rgba);
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="PackFromBgr24(ReadOnlySpan{Bgr24}, Span{TPixel}, int)"/> that expects a byte span. /// A helper for <see cref="PackFromBgr24(ReadOnlySpan{Bgr24}, Span{TPixel}, int)"/> that expects a byte span.
/// The layout of the data in 'sourceBytes' must be compatible with <see cref="Bgr24"/> layout. /// The layout of the data in 'sourceBytes' must be compatible with <see cref="Bgr24"/> layout.
/// </summary> /// </summary>
@ -259,8 +259,8 @@ namespace SixLabors.ImageSharp.PixelFormats
{ {
this.PackFromBgr24(MemoryMarshal.Cast<byte, Bgr24>(sourceBytes), destPixels, count); this.PackFromBgr24(MemoryMarshal.Cast<byte, Bgr24>(sourceBytes), destPixels, count);
} }
/// <summary> /// <summary>
/// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Bgr24"/>-s. /// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Bgr24"/>-s.
/// Bulk version of <see cref="IPixel.ToBgr24(ref Bgr24)"/>. /// Bulk version of <see cref="IPixel.ToBgr24(ref Bgr24)"/>.
/// </summary> /// </summary>
@ -282,18 +282,89 @@ namespace SixLabors.ImageSharp.PixelFormats
} }
} }
/// <summary> /// <summary>
/// A helper for <see cref="ToBgr24(ReadOnlySpan{TPixel}, Span{Bgr24}, int)"/> that expects a byte span as destination. /// A helper for <see cref="ToBgr24(ReadOnlySpan{TPixel}, Span{Bgr24}, int)"/> that expects a byte span as destination.
/// The layout of the data in 'destBytes' must be compatible with <see cref="Bgr24"/> layout. /// The layout of the data in 'destBytes' must be compatible with <see cref="Bgr24"/> layout.
/// </summary> /// </summary>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param> /// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param> /// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ToBgr24Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count) internal void ToBgr24Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count)
{ {
this.ToBgr24(sourceColors, MemoryMarshal.Cast<byte, Bgr24>(destBytes), count); this.ToBgr24(sourceColors, MemoryMarshal.Cast<byte, Bgr24>(destBytes), count);
} }
/// <summary>
/// Converts 'count' elements in 'source` span of <see cref="Argb32"/> data to a span of <typeparamref name="TPixel"/>-s.
/// </summary>
/// <param name="source">The source <see cref="Span{T}"/> of <see cref="Argb32"/> data.</param>
/// <param name="destPixels">The <see cref="Span{T}"/> to the destination pixels.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromArgb32(ReadOnlySpan<Argb32> source, Span<TPixel> destPixels, int count)
{
GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
var argb = new Argb32(0, 0, 0, 255);
for (int i = 0; i < count; i++)
{
ref TPixel dp = ref Unsafe.Add(ref destRef, i);
argb = Unsafe.Add(ref sourceRef, i);
dp.PackFromArgb32(argb);
}
}
/// <summary>
/// A helper for <see cref="PackFromArgb32(ReadOnlySpan{Argb32}, Span{TPixel}, int)"/> that expects a byte span.
/// The layout of the data in 'sourceBytes' must be compatible with <see cref="Argb32"/> layout.
/// </summary>
/// <param name="sourceBytes">The <see cref="ReadOnlySpan{T}"/> to the source bytes.</param>
/// <param name="destPixels">The <see cref="Span{T}"/> to the destination pixels.</param>
/// <param name="count">The number of pixels to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void PackFromArgb32Bytes(ReadOnlySpan<byte> sourceBytes, Span<TPixel> destPixels, int count)
{
this.PackFromArgb32(MemoryMarshal.Cast<byte, Argb32>(sourceBytes), destPixels, count);
}
/// <summary>
/// Converts 'count' pixels in 'sourcePixels` span to a span of <see cref="Argb32"/>-s.
/// Bulk version of <see cref="IPixel.ToArgb32(ref Argb32)"/>.
/// </summary>
/// <param name="sourcePixels">The span of source pixels</param>
/// <param name="dest">The destination span of <see cref="Argb32"/> data.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void ToArgb32(ReadOnlySpan<TPixel> sourcePixels, Span<Argb32> dest, int count)
{
GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels);
ref Argb32 destBaseRef = ref MemoryMarshal.GetReference(dest);
for (int i = 0; i < count; i++)
{
ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i);
ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i);
sp.ToArgb32(ref dp);
}
}
} /// <summary>
/// A helper for <see cref="ToArgb32(ReadOnlySpan{TPixel}, Span{Argb32}, int)"/> that expects a byte span as destination.
/// The layout of the data in 'destBytes' must be compatible with <see cref="Argb32"/> layout.
/// </summary>
/// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param>
/// <param name="destBytes">The <see cref="Span{T}"/> to the destination bytes.</param>
/// <param name="count">The number of pixels to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ToArgb32Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count)
{
this.ToArgb32(sourceColors, MemoryMarshal.Cast<byte, Argb32>(destBytes), count);
}
}
} }

53
src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt

@ -46,7 +46,7 @@
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void To<#=pixelType#>Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count) internal void To<#=pixelType#>Bytes(ReadOnlySpan<TPixel> sourceColors, Span<byte> destBytes, int count)
{ {
this.To<#=pixelType#>(sourceColors, destBytes.NonPortableCast<byte, <#=pixelType#>>(), count); this.To<#=pixelType#>(sourceColors, MemoryMarshal.Cast<byte, <#=pixelType#>>(destBytes), count);
} }
<# <#
} }
@ -68,13 +68,13 @@
ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
Rgba32 rgba = new Rgba32(0, 0, 0, 255); var rgba = new Rgba32(0, 0, 0, 255);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
ref TPixel dp = ref Unsafe.Add(ref destRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i);
<#=rgbaOperationCode#> <#=rgbaOperationCode#>
dp.PackFromRgba32(rgba); dp.PackFromRgba32(rgba);
} }
} }
@ -88,7 +88,49 @@
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void PackFrom<#=pixelType#>Bytes(ReadOnlySpan<byte> sourceBytes, Span<TPixel> destPixels, int count) internal void PackFrom<#=pixelType#>Bytes(ReadOnlySpan<byte> sourceBytes, Span<TPixel> destPixels, int count)
{ {
this.PackFrom<#=pixelType#>(sourceBytes.NonPortableCast<byte, <#=pixelType#>>(), destPixels, count); this.PackFrom<#=pixelType#>(MemoryMarshal.Cast<byte, <#=pixelType#>>(sourceBytes), destPixels, count);
}
<#
}
void GeneratePackFromMethodUsingPackFromArgb32(string pixelType, string argbOperationCode)
{
#>
/// <summary>
/// Converts 'count' elements in 'source` span of <see cref="<#=pixelType#>"/> data to a span of <typeparamref name="TPixel"/>-s.
/// </summary>
/// <param name="source">The source <see cref="Span{T}"/> of <see cref="<#=pixelType#>"/> data.</param>
/// <param name="destPixels">The <see cref="Span{T}"/> to the destination pixels.</param>
/// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFrom<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span<TPixel> destPixels, int count)
{
GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
var argb = new Argb32(0, 0, 0, 255);
for (int i = 0; i < count; i++)
{
ref TPixel dp = ref Unsafe.Add(ref destRef, i);
<#=argbOperationCode#>
dp.PackFromArgb32(argb);
}
}
/// <summary>
/// A helper for <see cref="PackFrom<#=pixelType#>(ReadOnlySpan{<#=pixelType#>}, Span{TPixel}, int)"/> that expects a byte span.
/// The layout of the data in 'sourceBytes' must be compatible with <see cref="<#=pixelType#>"/> layout.
/// </summary>
/// <param name="sourceBytes">The <see cref="ReadOnlySpan{T}"/> to the source bytes.</param>
/// <param name="destPixels">The <see cref="Span{T}"/> to the destination pixels.</param>
/// <param name="count">The number of pixels to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void PackFrom<#=pixelType#>Bytes(ReadOnlySpan<byte> sourceBytes, Span<TPixel> destPixels, int count)
{
this.PackFrom<#=pixelType#>(MemoryMarshal.Cast<byte, <#=pixelType#>>(sourceBytes), destPixels, count);
} }
<# <#
} }
@ -120,6 +162,9 @@ namespace SixLabors.ImageSharp.PixelFormats
GeneratePackFromMethodUsingPackFromRgba32("Bgr24", "rgba.Bgr = Unsafe.Add(ref sourceRef, i);"); GeneratePackFromMethodUsingPackFromRgba32("Bgr24", "rgba.Bgr = Unsafe.Add(ref sourceRef, i);");
GenerateToDestFormatMethods("Bgr24"); GenerateToDestFormatMethods("Bgr24");
GeneratePackFromMethodUsingPackFromArgb32("Argb32", "argb = Unsafe.Add(ref sourceRef, i);");
GenerateToDestFormatMethods("Argb32");
#> #>
} }

32
src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs

@ -112,6 +112,38 @@ namespace SixLabors.ImageSharp.PixelFormats
} }
} }
/// <inheritdoc />
internal override void PackFromArgb32(ReadOnlySpan<Argb32> source, Span<Rgba32> destPixels, int count)
{
GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source);
ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels);
for (int i = 0; i < count; i++)
{
ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i);
ref Rgba32 dp = ref Unsafe.Add(ref destRef, i);
dp = sp.ToRgba32();
}
}
/// <inheritdoc />
internal override void ToArgb32(ReadOnlySpan<Rgba32> sourcePixels, Span<Argb32> dest, int count)
{
GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels);
ref Argb32 destRef = ref MemoryMarshal.GetReference(dest);
for (int i = 0; i < count; i++)
{
ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i);
ref Argb32 dp = ref Unsafe.Add(ref destRef, i);
dp = sp.ToArgb32();
}
}
} }
} }
} }

3
src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt

@ -79,6 +79,9 @@ namespace SixLabors.ImageSharp.PixelFormats
GeneratePackFromMethod("Bgra32", "dp = sp.ToRgba32();"); GeneratePackFromMethod("Bgra32", "dp = sp.ToRgba32();");
GenerateConvertToMethod("Bgra32", "dp = sp.ToBgra32();"); GenerateConvertToMethod("Bgra32", "dp = sp.ToBgra32();");
GeneratePackFromMethod("Argb32", "dp = sp.ToRgba32();");
GenerateConvertToMethod("Argb32", "dp = sp.ToArgb32();");
#> #>
} }

17
src/ImageSharp/PixelFormats/HalfSingle.cs

@ -125,6 +125,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -146,6 +153,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)vector.W; dest.A = (byte)vector.W;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = (byte)vector.Z;
dest.A = (byte)vector.W;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/HalfVector2.cs

@ -140,6 +140,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -161,6 +168,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = 255; dest.A = 255;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = 0;
dest.A = 255;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/HalfVector4.cs

@ -133,6 +133,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -154,6 +161,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)vector.W; dest.A = (byte)vector.W;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = (byte)vector.Z;
dest.A = (byte)vector.W;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

12
src/ImageSharp/PixelFormats/IPixel.cs

@ -59,6 +59,12 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="source">The <see cref="Rgba32"/> value.</param> /// <param name="source">The <see cref="Rgba32"/> value.</param>
void PackFromRgba32(Rgba32 source); void PackFromRgba32(Rgba32 source);
/// <summary>
/// Packs the pixel from an <see cref="Argb32"/> value.
/// </summary>
/// <param name="source">The <see cref="Argb32"/> value.</param>
void PackFromArgb32(Argb32 source);
/// <summary> /// <summary>
/// Converts the pixel to <see cref="Rgb24"/> format. /// Converts the pixel to <see cref="Rgb24"/> format.
/// </summary> /// </summary>
@ -71,6 +77,12 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="dest">The destination pixel to write to</param> /// <param name="dest">The destination pixel to write to</param>
void ToRgba32(ref Rgba32 dest); void ToRgba32(ref Rgba32 dest);
/// <summary>
/// Converts the pixel to <see cref="Argb32"/> format.
/// </summary>
/// <param name="dest">The destination pixel to write to</param>
void ToArgb32(ref Argb32 dest);
/// <summary> /// <summary>
/// Converts the pixel to <see cref="Bgr24"/> format. /// Converts the pixel to <see cref="Bgr24"/> format.
/// </summary> /// </summary>

22
src/ImageSharp/PixelFormats/NormalizedByte2.cs

@ -149,6 +149,18 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(vector); this.PackFromVector4(vector);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -170,6 +182,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = 255; dest.A = 255;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = 0;
dest.A = 255;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

21
src/ImageSharp/PixelFormats/NormalizedByte4.cs

@ -142,6 +142,17 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(vector); this.PackFromVector4(vector);
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -163,6 +174,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)vector.W; dest.A = (byte)vector.W;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = (byte)vector.Z;
dest.A = (byte)vector.W;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

21
src/ImageSharp/PixelFormats/NormalizedShort2.cs

@ -136,6 +136,17 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(vector); this.PackFromVector4(vector);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -157,6 +168,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = 255; dest.A = 255;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = 0;
dest.A = 255;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

22
src/ImageSharp/PixelFormats/NormalizedShort4.cs

@ -144,6 +144,18 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(vector); this.PackFromVector4(vector);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -165,6 +177,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)MathF.Round(vector.W); dest.A = (byte)MathF.Round(vector.W);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = (byte)MathF.Round(vector.Z);
dest.A = (byte)MathF.Round(vector.W);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/Rg32.cs

@ -124,6 +124,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -145,6 +152,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)vector.W; dest.A = (byte)vector.W;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;
dest.B = (byte)vector.Z;
dest.A = (byte)vector.W;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/Rgb24.cs

@ -83,6 +83,15 @@ namespace SixLabors.ImageSharp.PixelFormats
this = Unsafe.As<Rgba32, Rgb24>(ref source); this = Unsafe.As<Rgba32, Rgb24>(ref source);
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromScaledVector4(Vector4 vector) public void PackFromScaledVector4(Vector4 vector)
@ -127,6 +136,14 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = 255; dest.A = 255;
} }
/// <inheritdoc/>
public void ToArgb32(ref Argb32 dest) {
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = 255;
}
/// <inheritdoc/> /// <inheritdoc/>
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)
{ {

17
src/ImageSharp/PixelFormats/Rgba1010102.cs

@ -118,6 +118,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -139,6 +146,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)MathF.Round(vector.W); dest.A = (byte)MathF.Round(vector.W);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = (byte)MathF.Round(vector.Z);
dest.A = (byte)MathF.Round(vector.W);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

42
src/ImageSharp/PixelFormats/Rgba32.cs

@ -275,6 +275,16 @@ namespace SixLabors.ImageSharp.PixelFormats
this = source; this = source;
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <summary> /// <summary>
/// Converts the value of this instance to a hexadecimal string. /// Converts the value of this instance to a hexadecimal string.
/// </summary> /// </summary>
@ -299,6 +309,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest = this; dest = this;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = this.A;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)
@ -357,6 +377,17 @@ namespace SixLabors.ImageSharp.PixelFormats
return new Bgra32(this.R, this.G, this.B, this.A); return new Bgra32(this.R, this.G, this.B, this.A);
} }
/// <summary>
/// Gets the value of this struct as <see cref="Argb32"/>.
/// Useful for changing the component order.
/// </summary>
/// <returns>A <see cref="Argb32"/> value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32 ToArgb32()
{
return new Argb32(this.R, this.G, this.B, this.A);
}
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
@ -380,16 +411,11 @@ namespace SixLabors.ImageSharp.PixelFormats
} }
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() public override int GetHashCode()
{ {
unchecked // ReSharper disable once NonReadonlyMemberInGetHashCode
{ return this.Rgba.GetHashCode();
int hashCode = this.R;
hashCode = (hashCode * 397) ^ this.G;
hashCode = (hashCode * 397) ^ this.B;
hashCode = (hashCode * 397) ^ this.A;
return hashCode;
}
} }
/// <summary> /// <summary>

17
src/ImageSharp/PixelFormats/Rgba64.cs

@ -117,6 +117,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4()); this.PackFromVector4(source.ToVector4());
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -138,6 +145,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)MathF.Round(vector.W); dest.A = (byte)MathF.Round(vector.W);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = (byte)MathF.Round(vector.Z);
dest.A = (byte)MathF.Round(vector.W);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

17
src/ImageSharp/PixelFormats/RgbaVector.cs

@ -218,6 +218,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.backingVector = source.ToVector4(); this.backingVector = source.ToVector4();
} }
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
this.backingVector = source.ToVector4();
}
/// <summary> /// <summary>
/// Converts the value of this instance to a hexadecimal string. /// Converts the value of this instance to a hexadecimal string.
/// </summary> /// </summary>
@ -252,6 +259,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)MathF.Round(vector.W); dest.A = (byte)MathF.Round(vector.W);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = (byte)MathF.Round(vector.Z);
dest.A = (byte)MathF.Round(vector.W);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

20
src/ImageSharp/PixelFormats/Short2.cs

@ -134,6 +134,16 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackedValue = Pack(vector.X, vector.Y); this.PackedValue = Pack(vector.X, vector.Y);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
Vector2 vector = new Vector2(source.R, source.G) / 255;
vector *= 65534;
vector -= new Vector2(32767);
this.PackedValue = Pack(vector.X, vector.Y);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -155,6 +165,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = 255; dest.A = 255;
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector2 vector = this.ToByteScaledVector2();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = 0;
dest.A = 255;
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

20
src/ImageSharp/PixelFormats/Short4.cs

@ -140,6 +140,16 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source)
{
var vector = source.ToVector4();
vector *= 65534;
vector -= new Vector4(32767);
this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest) public void ToRgb24(ref Rgb24 dest)
@ -161,6 +171,16 @@ namespace SixLabors.ImageSharp.PixelFormats
dest.A = (byte)MathF.Round(vector.W); dest.A = (byte)MathF.Round(vector.W);
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);
dest.B = (byte)MathF.Round(vector.Z);
dest.A = (byte)MathF.Round(vector.W);
}
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBgr24(ref Bgr24 dest) public void ToBgr24(ref Bgr24 dest)

4
tests/ImageSharp.Tests/Drawing/DrawImageTest.cs

@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal(Rgba32.White, backgroundPixel); Assert.Equal(Rgba32.White, backgroundPixel);
Assert.Equal(overlayPixel, background[0, 0]); Assert.Equal(overlayPixel, background[0, 0]);
background.DebugSave(provider, new[] { "Negative" }); background.DebugSave(provider, testOutputDetails: "Negative");
} }
} }
@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal(Rgba32.White, backgroundPixel); Assert.Equal(Rgba32.White, backgroundPixel);
Assert.Equal(overlayPixel, background[xy, xy]); Assert.Equal(overlayPixel, background[xy, xy]);
background.DebugSave(provider, new[] { "Positive" }); background.DebugSave(provider, testOutputDetails: "Positive");
} }
} }
} }

2
tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs

@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
float z = +0.5f; float z = +0.5f;
float w = -0.7f; float w = -0.7f;
var argb = new Argb32(x, y, z, w); var argb = new Argb32(x, y, z, w);
Assert.Equal(0x001a0080u, argb.PackedValue); Assert.Equal(0x80001a00u, argb.PackedValue);
// Test ordering // Test ordering
var rgb = default(Rgb24); var rgb = default(Rgb24);

90
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs

@ -12,72 +12,6 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
{ {
public static class SystemDrawingBridge public static class SystemDrawingBridge
{ {
// TODO: It would be nice to have this method in PixelOperations<T>
private static void ToArgb32<TPixel>(Span<TPixel> source, Span<Argb32> dest)
where TPixel : struct, IPixel<TPixel>
{
int length = source.Length;
Guard.MustBeSizedAtLeast(dest, length, nameof(dest));
using (IBuffer<Rgba32> rgbaBuffer = Configuration.Default.MemoryManager.Allocate<Rgba32>(length))
{
Span<Rgba32> rgbaSpan = rgbaBuffer.Span;
PixelOperations<TPixel>.Instance.ToRgba32(source, rgbaSpan, length);
for (int i = 0; i < length; i++)
{
ref Rgba32 s = ref rgbaSpan[i];
ref Argb32 d = ref dest[i];
d.PackFromRgba32(s);
}
}
}
private static void FromArgb32<TPixel>(Span<Argb32> source, Span<TPixel> dest)
where TPixel : struct, IPixel<TPixel>
{
int length = source.Length;
Guard.MustBeSizedAtLeast(dest, length, nameof(dest));
using (IBuffer<Rgba32> rgbaBuffer = Configuration.Default.MemoryManager.Allocate<Rgba32>(length))
{
Span<Rgba32> rgbaSpan = rgbaBuffer.Span;
PixelOperations<Argb32>.Instance.ToRgba32(source, rgbaSpan, length);
for (int i = 0; i < length; i++)
{
ref Rgba32 s = ref rgbaSpan[i];
ref TPixel d = ref dest[i];
d.PackFromRgba32(s);
}
}
}
private static void FromRgb24<TPixel>(Span<Rgb24> source, Span<TPixel> dest)
where TPixel : struct, IPixel<TPixel>
{
int length = source.Length;
Guard.MustBeSizedAtLeast(dest, length, nameof(dest));
using (IBuffer<Rgb24> rgbBuffer = Configuration.Default.MemoryManager.Allocate<Rgb24>(length))
{
Span<Rgb24> rgbSpan = rgbBuffer.Span;
PixelOperations<Rgb24>.Instance.ToRgb24(source, rgbSpan, length);
for (int i = 0; i < length; i++)
{
ref Rgb24 s = ref rgbSpan[i];
ref TPixel d = ref dest[i];
var rgba = default(Rgba32);
s.ToRgba32(ref rgba);
d.PackFromRgba32(rgba);
}
}
}
internal static unsafe Image<TPixel> FromFromArgb32SystemDrawingBitmap<TPixel>(System.Drawing.Bitmap bmp) internal static unsafe Image<TPixel> FromFromArgb32SystemDrawingBitmap<TPixel>(System.Drawing.Bitmap bmp)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
@ -99,9 +33,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
var image = new Image<TPixel>(w, h); var image = new Image<TPixel>(w, h);
using (IBuffer<Argb32> workBuffer = Configuration.Default.MemoryManager.Allocate<Argb32>(w)) using (IBuffer<Bgra32> workBuffer = Configuration.Default.MemoryManager.Allocate<Bgra32>(w))
{ {
fixed (Argb32* destPtr = &workBuffer.DangerousGetPinnableReference()) fixed (Bgra32* destPtr = &workBuffer.DangerousGetPinnableReference())
{ {
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
{ {
@ -110,8 +44,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
byte* sourcePtr = sourcePtrBase + data.Stride * y; byte* sourcePtr = sourcePtrBase + data.Stride * y;
Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount);
PixelOperations<TPixel>.Instance.PackFromBgra32(workBuffer.Span, row, row.Length);
FromArgb32(workBuffer.Span, row);
} }
} }
} }
@ -139,13 +72,13 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
byte* sourcePtrBase = (byte*)data.Scan0; byte* sourcePtrBase = (byte*)data.Scan0;
long sourceRowByteCount = data.Stride; long sourceRowByteCount = data.Stride;
long destRowByteCount = w * sizeof(Rgb24); long destRowByteCount = w * sizeof(Bgr24);
var image = new Image<TPixel>(w, h); var image = new Image<TPixel>(w, h);
using (IBuffer<Rgb24> workBuffer = Configuration.Default.MemoryManager.Allocate<Rgb24>(w)) using (IBuffer<Bgr24> workBuffer = Configuration.Default.MemoryManager.Allocate<Bgr24>(w))
{ {
fixed (Rgb24* destPtr = &workBuffer.DangerousGetPinnableReference()) fixed (Bgr24* destPtr = &workBuffer.DangerousGetPinnableReference())
{ {
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
{ {
@ -154,8 +87,9 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
byte* sourcePtr = sourcePtrBase + data.Stride * y; byte* sourcePtr = sourcePtrBase + data.Stride * y;
Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount);
PixelOperations<TPixel>.Instance.PackFromBgr24(workBuffer.Span, row, row.Length);
FromRgb24(workBuffer.Span, row); // FromRgb24(workBuffer.Span, row);
} }
} }
} }
@ -175,17 +109,17 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
byte* destPtrBase = (byte*)data.Scan0; byte* destPtrBase = (byte*)data.Scan0;
long destRowByteCount = data.Stride; long destRowByteCount = data.Stride;
long sourceRowByteCount = w * sizeof(Argb32); long sourceRowByteCount = w * sizeof(Bgra32);
using (IBuffer<Argb32> workBuffer = image.GetConfiguration().MemoryManager.Allocate<Argb32>(w)) using (IBuffer<Bgra32> workBuffer = image.GetConfiguration().MemoryManager.Allocate<Bgra32>(w))
{ {
fixed (Argb32* sourcePtr = &workBuffer.DangerousGetPinnableReference()) fixed (Bgra32* sourcePtr = &workBuffer.DangerousGetPinnableReference())
{ {
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
{ {
Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y); Span<TPixel> row = image.Frames.RootFrame.GetPixelRowSpan(y);
ToArgb32(row, workBuffer.Span); PixelOperations<TPixel>.Instance.ToBgra32(row, workBuffer.Span, row.Length);
byte* destPtr = destPtrBase + data.Stride * y; byte* destPtr = destPtrBase + data.Stride * y;
Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount); Buffer.MemoryCopy(sourcePtr, destPtr, destRowByteCount, sourceRowByteCount);

2
tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs

@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Tests
} }
} }
[Theory(Skip = "Doesen't work yet :(")] [Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)] [WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void FromFromRgb24SystemDrawingBitmap2<TPixel>(TestImageProvider<TPixel> provider) public void FromFromRgb24SystemDrawingBitmap2<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>

Loading…
Cancel
Save