Browse Source

Merge pull request #543 from woutware/pr/540

Pr/540 Added IPixel.PackFromBgra32 definition/implementations.
pull/547/head
James Jackson-South 8 years ago
committed by GitHub
parent
commit
1deb2c59e3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      src/ImageSharp/PixelFormats/Alpha8.cs
  2. 38
      src/ImageSharp/PixelFormats/Argb32.cs
  3. 17
      src/ImageSharp/PixelFormats/Bgr24.cs
  4. 13
      src/ImageSharp/PixelFormats/Bgr565.cs
  5. 46
      src/ImageSharp/PixelFormats/Bgra32.cs
  6. 10
      src/ImageSharp/PixelFormats/Bgra4444.cs
  7. 10
      src/ImageSharp/PixelFormats/Bgra5551.cs
  8. 10
      src/ImageSharp/PixelFormats/Byte4.cs
  9. 6
      src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs
  10. 44
      src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt
  11. 10
      src/ImageSharp/PixelFormats/HalfSingle.cs
  12. 10
      src/ImageSharp/PixelFormats/HalfVector2.cs
  13. 10
      src/ImageSharp/PixelFormats/HalfVector4.cs
  14. 8
      src/ImageSharp/PixelFormats/IPixel.cs
  15. 15
      src/ImageSharp/PixelFormats/NormalizedByte2.cs
  16. 18
      src/ImageSharp/PixelFormats/NormalizedByte4.cs
  17. 18
      src/ImageSharp/PixelFormats/NormalizedShort2.cs
  18. 15
      src/ImageSharp/PixelFormats/NormalizedShort4.cs
  19. 5
      src/ImageSharp/PixelFormats/README.md
  20. 10
      src/ImageSharp/PixelFormats/Rg32.cs
  21. 14
      src/ImageSharp/PixelFormats/Rgb24.cs
  22. 10
      src/ImageSharp/PixelFormats/Rgba1010102.cs
  23. 70
      src/ImageSharp/PixelFormats/Rgba32.cs
  24. 10
      src/ImageSharp/PixelFormats/Rgba64.cs
  25. 10
      src/ImageSharp/PixelFormats/RgbaVector.cs
  26. 13
      src/ImageSharp/PixelFormats/Short2.cs
  27. 13
      src/ImageSharp/PixelFormats/Short4.cs
  28. 22
      tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs
  29. 235
      tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs
  30. 45
      tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs
  31. 14
      tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs

13
src/ImageSharp/PixelFormats/Alpha8.cs

@ -99,7 +99,15 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
public void PackFromArgb32(Argb32 source)
{
this.PackedValue = source.A;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackedValue = source.A;
}
@ -122,7 +130,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
dest.R = 0;
dest.G = 0;
dest.B = 0;

38
src/ImageSharp/PixelFormats/Argb32.cs

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// The color components are stored in alpha, red, green, and blue order.
/// The color components are stored in alpha, red, green, and blue order (least significant to most significant byte).
/// <para>
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
@ -141,16 +141,10 @@ namespace SixLabors.ImageSharp.PixelFormats
public uint Argb
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return Unsafe.As<Argb32, uint>(ref this);
}
get => Unsafe.As<Argb32, uint>(ref this);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
Unsafe.As<Argb32, uint>(ref this) = value;
}
set => Unsafe.As<Argb32, uint>(ref this) = value;
}
/// <inheritdoc/>
@ -240,6 +234,16 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackedValue = source.PackedValue;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -292,10 +296,24 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A);
/// <summary>
/// Converts the pixel to <see cref="Bgra32"/> format.
/// </summary>
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Bgra32 ToBgra32() => new Bgra32(this.R, this.G, this.B, this.A);
/// <summary>
/// Converts the pixel to <see cref="Argb32"/> format.
/// </summary>
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32 ToArgb32() => this;
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is Argb32 && this.Equals((Argb32)obj);
return obj is Argb32 argb32 && this.Equals(argb32);
}
/// <inheritdoc/>

17
src/ImageSharp/PixelFormats/Bgr24.cs

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// Pixel type containing three 8-bit unsigned normalized values ranging from 0 to 255.
/// The color components are stored in blue, green, red order.
/// The color components are stored in blue, green, red order (least significant to most significant byte).
/// <para>
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
/// </para>
@ -84,7 +84,17 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
public void PackFromArgb32(Argb32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
@ -141,7 +151,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;

13
src/ImageSharp/PixelFormats/Bgr565.cs

@ -122,7 +122,15 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
public void PackFromArgb32(Argb32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
@ -149,7 +157,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

46
src/ImageSharp/PixelFormats/Bgra32.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// The color components are stored in blue, green, red, and alpha order.
/// The color components are stored in blue, green, red, and alpha order (least significant to most significant byte).
/// <para>
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
@ -75,16 +75,10 @@ namespace SixLabors.ImageSharp.PixelFormats
public uint Bgra
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return Unsafe.As<Bgra32, uint>(ref this);
}
get => Unsafe.As<Bgra32, uint>(ref this);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
Unsafe.As<Bgra32, uint>(ref this) = value;
}
set => Unsafe.As<Bgra32, uint>(ref this) = value;
}
/// <inheritdoc/>
@ -119,6 +113,16 @@ namespace SixLabors.ImageSharp.PixelFormats
}
}
/// <summary>
/// Gets the <see cref="Vector4"/> representation without normalizing to [0, 1]
/// </summary>
/// <returns>A <see cref="Vector4"/> of values in [0, 255] </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Vector4 ToByteScaledVector4()
{
return new Vector4(this.R, this.G, this.B, this.A);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromScaledVector4(Vector4 vector)
@ -169,6 +173,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.A = source.A;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackedValue = source.PackedValue;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -190,7 +201,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
@ -217,5 +229,19 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A);
/// <summary>
/// Converts the pixel to <see cref="Argb32"/> format.
/// </summary>
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Argb32 ToArgb32() => new Argb32(this.R, this.G, this.B, this.A);
/// <summary>
/// Converts the pixel to <see cref="Bgra32"/> format.
/// </summary>
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Bgra32 ToBgra32() => this;
}
}

10
src/ImageSharp/PixelFormats/Bgra4444.cs

@ -118,6 +118,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -141,7 +148,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

10
src/ImageSharp/PixelFormats/Bgra5551.cs

@ -118,6 +118,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -141,7 +148,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

10
src/ImageSharp/PixelFormats/Byte4.cs

@ -119,6 +119,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToByteScaledVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToByteScaledVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -142,7 +149,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
var vector = this.ToVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

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

@ -95,13 +95,13 @@ namespace SixLabors.ImageSharp.PixelFormats
ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source);
ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels);
var rgba = new Rgba32(0, 0, 0, 255);
var bgra = new Bgra32(0, 0, 0, 255);
for (int i = 0; i < count; i++)
{
ref TPixel dp = ref Unsafe.Add(ref destRef, i);
rgba = Unsafe.Add(ref sourceRef, i).ToRgba32();
dp.PackFromRgba32(rgba);
bgra = Unsafe.Add(ref sourceRef, i);
dp.PackFromBgra32(bgra);
}
}

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

@ -135,6 +135,48 @@
<#
}
void GeneratePackFromMethodUsingPackFromBgra32(string pixelType, string bgraOperationCode)
{
#>
/// <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 bgra = new Bgra32(0, 0, 0, 255);
for (int i = 0; i < count; i++)
{
ref TPixel dp = ref Unsafe.Add(ref destRef, i);
<#=bgraOperationCode#>
dp.PackFromBgra32(bgra);
}
}
/// <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);
}
<#
}
#>
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
@ -153,7 +195,7 @@ namespace SixLabors.ImageSharp.PixelFormats
GeneratePackFromMethodUsingPackFromRgba32("Rgba32", "rgba = Unsafe.Add(ref sourceRef, i);");
GenerateToDestFormatMethods("Rgba32");
GeneratePackFromMethodUsingPackFromRgba32("Bgra32", "rgba = Unsafe.Add(ref sourceRef, i).ToRgba32();");
GeneratePackFromMethodUsingPackFromBgra32("Bgra32", "bgra = Unsafe.Add(ref sourceRef, i);");
GenerateToDestFormatMethods("Bgra32");
GeneratePackFromMethodUsingPackFromRgba32("Rgb24", "rgba.Rgb = Unsafe.Add(ref sourceRef, i);");

10
src/ImageSharp/PixelFormats/HalfSingle.cs

@ -132,6 +132,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -155,7 +162,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

10
src/ImageSharp/PixelFormats/HalfVector2.cs

@ -147,6 +147,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -170,7 +177,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

10
src/ImageSharp/PixelFormats/HalfVector4.cs

@ -140,6 +140,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -163,7 +170,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

8
src/ImageSharp/PixelFormats/IPixel.cs

@ -8,6 +8,8 @@ namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// An interface that represents a generic pixel type.
/// The naming convention of each pixel format is to order the color components from least significant to most significant, reading from left to right.
/// For example in the <see cref="Rgba32"/> pixel format the R component is the least significant byte, and the A component is the most significant.
/// </summary>
/// <typeparam name="TSelf">The type implementing this interface</typeparam>
public interface IPixel<TSelf> : IPixel, IEquatable<TSelf>
@ -65,6 +67,12 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="source">The <see cref="Argb32"/> value.</param>
void PackFromArgb32(Argb32 source);
/// <summary>
/// Packs the pixel from an <see cref="Bgra32"/> value.
/// </summary>
/// <param name="source">The <see cref="Bgra32"/> value.</param>
void PackFromBgra32(Bgra32 source);
/// <summary>
/// Converts the pixel to <see cref="Rgb24"/> format.
/// </summary>

15
src/ImageSharp/PixelFormats/NormalizedByte2.cs

@ -161,6 +161,18 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(vector);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -184,7 +196,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

18
src/ImageSharp/PixelFormats/NormalizedByte4.cs

@ -144,7 +144,20 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
public void PackFromArgb32(Argb32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
@ -176,7 +189,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

18
src/ImageSharp/PixelFormats/NormalizedShort2.cs

@ -138,7 +138,20 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromArgb32(Argb32 source) {
public void PackFromArgb32(Argb32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
@ -170,7 +183,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

15
src/ImageSharp/PixelFormats/NormalizedShort4.cs

@ -156,6 +156,18 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(vector);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
Vector4 vector = source.ToByteScaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
vector /= Half;
this.PackFromVector4(vector);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -179,7 +191,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

5
src/ImageSharp/PixelFormats/README.md

@ -4,4 +4,7 @@ https://github.com/MonoGame/MonoGame
Rgba32 is our default format. As such it positioned within the ImageSharp root namespace to ensure visibility of the format.
All other pixel formats should be positioned within ImageSharp.PixelFormats to reduce intellisense burden.
All other pixel formats should be positioned within ImageSharp.PixelFormats to reduce intellisense burden.
The naming convention of each pixel format is to order the color components from least significant to most significant, reading from left to right.
For example in the Rgba32 pixel format the R component is the least significant byte, and the A component is the most significant.

10
src/ImageSharp/PixelFormats/Rg32.cs

@ -131,6 +131,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -154,7 +161,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)vector.X;
dest.G = (byte)vector.Y;

14
src/ImageSharp/PixelFormats/Rgb24.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// Pixel type containing three 8-bit unsigned normalized values ranging from 0 to 255.
/// The color components are stored in red, green, blue order.
/// The color components are stored in red, green, blue order (least significant to most significant byte).
/// <para>
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
/// </para>
@ -92,6 +92,15 @@ namespace SixLabors.ImageSharp.PixelFormats
this.B = source.B;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromScaledVector4(Vector4 vector)
@ -137,7 +146,8 @@ namespace SixLabors.ImageSharp.PixelFormats
}
/// <inheritdoc/>
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
dest.R = this.R;
dest.G = this.G;
dest.B = this.B;

10
src/ImageSharp/PixelFormats/Rgba1010102.cs

@ -125,6 +125,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -148,7 +155,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

70
src/ImageSharp/PixelFormats/Rgba32.cs

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// The color components are stored in red, green, blue, and alpha order.
/// The color components are stored in red, green, blue, and alpha order (least significant to most significant byte).
/// <para>
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
@ -161,16 +161,10 @@ namespace SixLabors.ImageSharp.PixelFormats
public uint Rgba
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return Unsafe.As<Rgba32, uint>(ref this);
}
get => Unsafe.As<Rgba32, uint>(ref this);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
Unsafe.As<Rgba32, uint>(ref this) = value;
}
set => Unsafe.As<Rgba32, uint>(ref this) = value;
}
/// <summary>
@ -179,16 +173,10 @@ namespace SixLabors.ImageSharp.PixelFormats
public Rgb24 Rgb
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return Unsafe.As<Rgba32, Rgb24>(ref this);
}
get => Unsafe.As<Rgba32, Rgb24>(ref this);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
Unsafe.As<Rgba32, Rgb24>(ref this) = value;
}
set => Unsafe.As<Rgba32, Rgb24>(ref this) = value;
}
/// <summary>
@ -197,10 +185,7 @@ namespace SixLabors.ImageSharp.PixelFormats
public Bgr24 Bgr
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new Bgr24(this.R, this.G, this.B);
}
get => new Bgr24(this.R, this.G, this.B);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
@ -285,13 +270,23 @@ namespace SixLabors.ImageSharp.PixelFormats
this.A = source.A;
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.R = source.R;
this.G = source.G;
this.B = source.B;
this.A = source.A;
}
/// <summary>
/// Converts the value of this instance to a hexadecimal string.
/// </summary>
/// <returns>A hexadecimal string representation of the value.</returns>
public string ToHex()
{
uint hexOrder = Pack(this.A, this.B, this.G, this.R);
uint hexOrder = (uint)(this.A << 0 | this.B << 8 | this.G << 16 | this.R << 24);
return hexOrder.ToString("X8");
}
@ -372,10 +367,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// </summary>
/// <returns>A <see cref="Bgra32"/> value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Bgra32 ToBgra32()
{
return new Bgra32(this.R, this.G, this.B, this.A);
}
public Bgra32 ToBgra32() => new Bgra32(this.R, this.G, this.B, this.A);
/// <summary>
/// Gets the value of this struct as <see cref="Argb32"/>.
@ -383,10 +375,14 @@ namespace SixLabors.ImageSharp.PixelFormats
/// </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);
}
public Argb32 ToArgb32() => new Argb32(this.R, this.G, this.B, this.A);
/// <summary>
/// Converts the pixel to <see cref="Rgba32"/> format.
/// </summary>
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32 ToRgba32() => this;
/// <inheritdoc/>
public override bool Equals(object obj)
@ -428,20 +424,6 @@ namespace SixLabors.ImageSharp.PixelFormats
return new Vector4(this.R, this.G, this.B, this.A);
}
/// <summary>
/// Packs the four floats into a <see cref="uint"/>.
/// </summary>
/// <param name="x">The x-component</param>
/// <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)]
private static uint Pack(byte x, byte y, byte z, byte w)
{
return (uint)(x << RedShift | y << GreenShift | z << BlueShift | w << AlphaShift);
}
/// <summary>
/// Packs a <see cref="Vector4"/> into a color returning a new instance as a result.
/// </summary>

10
src/ImageSharp/PixelFormats/Rgba64.cs

@ -124,6 +124,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.PackFromVector4(source.ToVector4());
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -147,7 +154,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

10
src/ImageSharp/PixelFormats/RgbaVector.cs

@ -225,6 +225,13 @@ namespace SixLabors.ImageSharp.PixelFormats
this.backingVector = source.ToVector4();
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
this.backingVector = source.ToVector4();
}
/// <summary>
/// Converts the value of this instance to a hexadecimal string.
/// </summary>
@ -261,7 +268,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

13
src/ImageSharp/PixelFormats/Short2.cs

@ -144,6 +144,16 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackedValue = Pack(vector.X, vector.Y);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
Vector2 vector = new Vector2(source.R, source.G) / 255;
vector *= 65534;
vector -= new Vector2(32767);
this.PackedValue = Pack(vector.X, vector.Y);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -167,7 +177,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector2 vector = this.ToByteScaledVector2();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

13
src/ImageSharp/PixelFormats/Short4.cs

@ -150,6 +150,16 @@ namespace SixLabors.ImageSharp.PixelFormats
this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBgra32(Bgra32 source)
{
var vector = source.ToVector4();
vector *= 65534;
vector -= new Vector4(32767);
this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgb24(ref Rgb24 dest)
@ -173,7 +183,8 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToArgb32(ref Argb32 dest) {
public void ToArgb32(ref Argb32 dest)
{
Vector4 vector = this.ToByteScaledVector4();
dest.R = (byte)MathF.Round(vector.X);
dest.G = (byte)MathF.Round(vector.Y);

22
tests/ImageSharp.Tests/PixelFormats/ColorPackingTests.cs

@ -28,16 +28,16 @@ namespace SixLabors.ImageSharp.Tests.Colors
{
float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W };
yield return new object[] { new Argb32(), vector4Components };
yield return new object[] { new Bgra4444(), vector4Components };
yield return new object[] { new Bgra5551(), vector4Components };
yield return new object[] { new Byte4(), vector4Components };
yield return new object[] { new HalfVector4(), vector4Components };
yield return new object[] { new NormalizedByte4(), vector4Components };
yield return new object[] { new NormalizedShort4(), vector4Components };
yield return new object[] { new Rgba1010102(), vector4Components };
yield return new object[] { new Rgba64(), vector4Components };
yield return new object[] { new Short4(), vector4Components };
yield return new object[] { default(Argb32), vector4Components };
yield return new object[] { default(Bgra4444), vector4Components };
yield return new object[] { default(Bgra5551), vector4Components };
yield return new object[] { default(Byte4), vector4Components };
yield return new object[] { default(HalfVector4), vector4Components };
yield return new object[] { default(NormalizedByte4), vector4Components };
yield return new object[] { default(NormalizedShort4), vector4Components };
yield return new object[] { default(Rgba1010102), vector4Components };
yield return new object[] { default(Rgba64), vector4Components };
yield return new object[] { default(Short4), vector4Components };
}
}
}
@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
{
float[] vector4Components = new float[] { vector4.X, vector4.Y, vector4.Z, vector4.W };
yield return new object[] { new Argb32(), vector4Components };
yield return new object[] { default(Argb32), vector4Components };
yield return new object[] { new Bgr565(), vector4Components };
}
}

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

@ -47,27 +47,31 @@ namespace SixLabors.ImageSharp.Tests.Colors
Assert.Equal(.5F, scaled.W, 2);
// Test PackFromScaledVector4.
var pixel = default(Alpha8);
pixel.PackFromScaledVector4(scaled);
Assert.Equal(128, pixel.PackedValue);
Alpha8 alpha = default;
alpha.PackFromScaledVector4(scaled);
Assert.Equal(128, alpha.PackedValue);
// Test Rgb conversion
var rgb = default(Rgb24);
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
Rgb24 rgb = default;
Rgba32 rgba = default;
Bgr24 bgr = default;
Bgra32 bgra = default;
Argb32 argb = default;
new Alpha8(.5F).ToRgb24(ref rgb);
alpha.ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(0, 0, 0));
new Alpha8(.5F).ToRgba32(ref rgba);
alpha.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(0, 0, 0, 128));
new Alpha8(.5F).ToBgr24(ref bgr);
alpha.ToBgr24(ref bgr);
Assert.Equal(bgr, new Bgr24(0, 0, 0));
new Alpha8(.5F).ToBgra32(ref bgra);
alpha.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(0, 0, 0, 128));
alpha.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(0, 0, 0, 128));
}
[Fact]
@ -113,19 +117,40 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb2 = default(Argb32);
argb.ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(0x1a, 0, 0x80));
argb.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0));
Assert.Equal(rgba, argb.ToRgba32());
argb.ToBgr24(ref bgr);
Assert.Equal(bgr, new Bgr24(0x1a, 0, 0x80));
argb.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0));
Assert.Equal(bgra, argb.ToBgra32());
argb.ToArgb32(ref argb2);
Assert.Equal(argb2, new Argb32(0x1a, 0, 0x80, 0));
Assert.Equal(argb2, argb.ToArgb32());
var r = default(Argb32);
r.PackFromRgba32(new Rgba32(0x1a, 0, 0x80, 0));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0));
r = default(Argb32);
r.PackFromBgra32(new Bgra32(0x1a, 0, 0x80, 0));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0));
r = default(Argb32);
r.PackFromArgb32(new Argb32(0x1a, 0, 0x80, 0));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(0x1a, 0, 0x80, 0));
}
[Fact]
@ -173,6 +198,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new Bgr565(x, y, z).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(25, 0, 132));
@ -185,6 +211,9 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Bgr565(x, y, z).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(25, 0, 132, 255));
new Bgr565(x, y, z).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(25, 0, 132, 255));
}
[Fact]
@ -235,6 +264,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new Bgra4444(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(34, 0, 136));
@ -247,6 +277,24 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Bgra4444(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(34, 0, 136, 0));
new Bgra4444(x, y, z, w).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(34, 0, 136, 0));
var r = default(Bgra4444);
r.PackFromRgba32(new Rgba32(34, 0, 136, 0));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(34, 0, 136, 0));
r = default(Bgra4444);
r.PackFromBgra32(new Bgra32(34, 0, 136, 0));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(34, 0, 136, 0));
r = default(Bgra4444);
r.PackFromArgb32(new Argb32(34, 0, 136, 0));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(34, 0, 136, 0));
}
[Fact]
@ -293,6 +341,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new Bgra5551(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(24, 0, 131));
@ -305,6 +354,24 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Bgra5551(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(24, 0, 131, 0));
new Bgra5551(x, y, z, w).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(24, 0, 131, 0));
var r = default(Bgra5551);
r.PackFromRgba32(new Rgba32(24, 0, 131, 0));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(24, 0, 131, 0));
r = default(Bgra5551);
r.PackFromBgra32(new Bgra32(24, 0, 131, 0));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(24, 0, 131, 0));
r = default(Bgra5551);
r.PackFromArgb32(new Argb32(24, 0, 131, 0));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(24, 0, 131, 0));
}
[Fact]
@ -356,6 +423,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new Byte4(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(128, 0, 0));
@ -369,10 +437,23 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Byte4(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(128, 0, 0, 0));
var r = new Byte4();
new Byte4(x, y, z, w).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(128, 0, 0, 0));
var r = default(Byte4);
r.PackFromRgba32(new Rgba32(20, 38, 0, 255));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(20, 38, 0, 255));
r = default(Byte4);
r.PackFromBgra32(new Bgra32(20, 38, 0, 255));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(20, 38, 0, 255));
r = default(Byte4);
r.PackFromArgb32(new Argb32(20, 38, 0, 255));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(20, 38, 0, 255));
}
[Fact]
@ -407,6 +488,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new HalfSingle(x).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(128, 0, 0));
@ -419,6 +501,9 @@ namespace SixLabors.ImageSharp.Tests.Colors
new HalfSingle(x).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(128, 0, 0, 255));
new HalfSingle(x).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(128, 0, 0, 255));
}
[Fact]
@ -456,6 +541,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new HalfVector2(x, y).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(128, 64, 0));
@ -468,6 +554,9 @@ namespace SixLabors.ImageSharp.Tests.Colors
new HalfVector2(x, y).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(128, 64, 0, 255));
new HalfVector2(x, y).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(128, 64, 0, 255));
}
[Fact]
@ -514,6 +603,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new HalfVector4(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(64, 128, 191));
@ -526,6 +616,24 @@ namespace SixLabors.ImageSharp.Tests.Colors
new HalfVector4(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(64, 128, 191, 255));
new HalfVector4(x, y, z, w).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(64, 128, 191, 255));
var r = default(HalfVector4);
r.PackFromRgba32(new Rgba32(64, 128, 191, 255));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(64, 128, 191, 255));
r = default(HalfVector4);
r.PackFromBgra32(new Bgra32(64, 128, 191, 255));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(64, 128, 191, 255));
r = default(HalfVector4);
r.PackFromArgb32(new Argb32(64, 128, 191, 255));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(64, 128, 191, 255));
}
[Fact]
@ -571,6 +679,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new NormalizedByte2(x, y).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(141, 90, 0));
@ -583,6 +692,9 @@ namespace SixLabors.ImageSharp.Tests.Colors
new NormalizedByte2(x, y).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(141, 90, 0, 255));
new NormalizedByte2(x, y).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(141, 90, 0, 255));
}
[Fact]
@ -618,7 +730,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
float z = 0.5f;
float w = -0.7f;
Assert.Equal(0xA740DA0D, new NormalizedByte4(x, y, z, w).PackedValue);
var n = new NormalizedByte4();
var n = default(NormalizedByte4);
n.PackFromRgba32(new Rgba32(141, 90, 192, 39));
Assert.Equal(0xA740DA0D, n.PackedValue);
@ -628,6 +740,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new NormalizedByte4(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(141, 90, 192));
@ -641,8 +754,11 @@ namespace SixLabors.ImageSharp.Tests.Colors
new NormalizedByte4(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(141, 90, 192, 39));
new NormalizedByte4(x, y, z, w).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(141, 90, 192, 39));
// http://community.monogame.net/t/normalizedbyte4-texture2d-gives-different-results-from-xna/8012/8
var r = new NormalizedByte4();
var r = default(NormalizedByte4);
r.PackFromRgba32(new Rgba32(9, 115, 202, 127));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(9, 115, 202, 127));
@ -650,6 +766,16 @@ namespace SixLabors.ImageSharp.Tests.Colors
r.PackedValue = 0xff4af389;
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(9, 115, 202, 127));
r = default(NormalizedByte4);
r.PackFromArgb32(new Argb32(9, 115, 202, 127));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(9, 115, 202, 127));
r = default(NormalizedByte4);
r.PackFromBgra32(new Bgra32(9, 115, 202, 127));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(9, 115, 202, 127));
}
[Fact]
@ -692,6 +818,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
var n = new NormalizedShort2();
n.PackFromRgba32(new Rgba32(141, 90, 0, 0));
@ -712,6 +839,9 @@ namespace SixLabors.ImageSharp.Tests.Colors
new NormalizedShort2(x, y).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(141, 90, 0, 255));
new NormalizedShort2(x, y).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(141, 90, 0, 255));
}
[Fact]
@ -753,6 +883,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new NormalizedShort4(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(141, 90, 192));
@ -766,10 +897,23 @@ namespace SixLabors.ImageSharp.Tests.Colors
new NormalizedShort4(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(141, 90, 192, 39));
var r = new NormalizedShort4();
new NormalizedShort4(x, y, z, w).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(141, 90, 192, 39));
var r = default(NormalizedShort4);
r.PackFromRgba32(new Rgba32(9, 115, 202, 127));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(9, 115, 202, 127));
r = default(NormalizedShort4);
r.PackFromBgra32(new Bgra32(9, 115, 202, 127));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(9, 115, 202, 127));
r = default(NormalizedShort4);
r.PackFromArgb32(new Argb32(9, 115, 202, 127));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(9, 115, 202, 127));
}
[Fact]
@ -812,6 +956,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new Rg32(x, y).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(25, 0, 0));
@ -824,6 +969,9 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Rg32(x, y).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(25, 0, 0, 255));
new Rg32(x, y).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(25, 0, 0, 255));
}
[Fact]
@ -869,6 +1017,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new Rgba1010102(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(25, 0, 128));
@ -883,10 +1032,20 @@ namespace SixLabors.ImageSharp.Tests.Colors
Assert.Equal(bgra, new Bgra32(25, 0, 128, 0));
// Alpha component accuracy will be awful.
var r = new Rgba1010102();
var r = default(Rgba1010102);
r.PackFromRgba32(new Rgba32(25, 0, 128, 0));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(25, 0, 128, 0));
r = default(Rgba1010102);
r.PackFromBgra32(new Bgra32(25, 0, 128, 0));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(25, 0, 128, 0));
r = default(Rgba1010102);
r.PackFromArgb32(new Argb32(25, 0, 128, 0));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(25, 0, 128, 0));
}
[Fact]
@ -932,18 +1091,40 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
rgba32.ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(0x1a, 0, 0x80));
rgba32.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0));
Assert.Equal(rgba, rgba.ToRgba32());
rgba32.ToBgr24(ref bgr);
Assert.Equal(bgr, new Bgr24(0x1a, 0, 0x80));
rgba32.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0));
Assert.Equal(bgra, bgra.ToBgra32());
rgba32.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(0x1a, 0, 0x80, 0));
Assert.Equal(argb, argb.ToArgb32());
var r = default(Rgba32);
r.PackFromRgba32(new Rgba32(0x1a, 0, 0x80, 0));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(0x1a, 0, 0x80, 0));
r = default(Rgba32);
r.PackFromBgra32(new Bgra32(0x1a, 0, 0x80, 0));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(0x1a, 0, 0x80, 0));
r = default(Rgba32);
r.PackFromArgb32(new Argb32(0x1a, 0, 0x80, 0));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(0x1a, 0, 0x80, 0));
}
[Fact]
@ -1008,7 +1189,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Rgba64(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(20, 38, 76, 115));
var r = new Rgba64();
var r = default(Rgba64);
r.PackFromRgba32(new Rgba32(20, 38, 76, 115));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(20, 38, 76, 115));
@ -1075,7 +1256,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Short2(x, y).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(128, 127, 0, 255));
var r = new Short2();
var r = default(Short2);
r.PackFromRgba32(new Rgba32(20, 38, 0, 255));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(20, 38, 0, 255));
@ -1131,6 +1312,7 @@ namespace SixLabors.ImageSharp.Tests.Colors
var rgba = default(Rgba32);
var bgr = default(Bgr24);
var bgra = default(Bgra32);
var argb = default(Argb32);
new Short4(x, y, z, w).ToRgb24(ref rgb);
Assert.Equal(rgb, new Rgb24(172, 177, 243));
@ -1144,10 +1326,23 @@ namespace SixLabors.ImageSharp.Tests.Colors
new Short4(x, y, z, w).ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(172, 177, 243, 128));
var r = new Short4();
new Short4(x, y, z, w).ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(172, 177, 243, 128));
var r = default(Short4);
r.PackFromRgba32(new Rgba32(20, 38, 0, 255));
r.ToRgba32(ref rgba);
Assert.Equal(rgba, new Rgba32(20, 38, 0, 255));
r = default(Short4);
r.PackFromBgra32(new Bgra32(20, 38, 0, 255));
r.ToBgra32(ref bgra);
Assert.Equal(bgra, new Bgra32(20, 38, 0, 255));
r = default(Short4);
r.PackFromArgb32(new Argb32(20, 38, 0, 255));
r.ToArgb32(ref argb);
Assert.Equal(argb, new Argb32(20, 38, 0, 255));
}
// Comparison helpers with small tolerance to allow for floating point rounding during computations.

45
tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs

@ -383,6 +383,51 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void PackFromWzyxBytes(int count)
{
byte[] source = CreateByteTestData(count * 4);
var expected = new TPixel[count];
for (int i = 0; i < count; i++)
{
int i4 = i * 4;
expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0]));
}
TestOperation(
source,
expected,
(s, d) => Operations.PackFromArgb32Bytes(s, d.Span, count)
);
}
[Theory]
[MemberData(nameof(ArraySizesData))]
public void ToWzyxBytes(int count)
{
TPixel[] source = CreatePixelTestData(count);
byte[] expected = new byte[count * 4];
var argb = default(Argb32);
for (int i = 0; i < count; i++)
{
int i4 = i * 4;
source[i].ToArgb32(ref argb);
expected[i4] = argb.A;
expected[i4 + 1] = argb.R;
expected[i4 + 2] = argb.G;
expected[i4 + 3] = argb.B;
}
TestOperation(
source,
expected,
(s, d) => Operations.ToArgb32Bytes(s, d.Span, count)
);
}
private class TestBuffers<TSource, TDest> : IDisposable
where TSource : struct

14
tests/ImageSharp.Tests/PixelFormats/Rgba32Tests.cs

@ -88,26 +88,22 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void FromAndToHex()
{
Rgba32 color = Rgba32.FromHex("#AABBCCDD");
// 8 digit hex matches css4 spec. RRGGBBAA
var color = Rgba32.FromHex("#AABBCCDD"); // 170, 187, 204, 221
Assert.Equal(170, color.R);
Assert.Equal(187, color.G);
Assert.Equal(204, color.B);
Assert.Equal(221, color.A);
color.A = 170;
color.B = 187;
color.G = 204;
color.R = 221;
Assert.Equal("DDCCBBAA", color.ToHex());
Assert.Equal("AABBCCDD", color.ToHex());
color.R = 0;
Assert.Equal("00CCBBAA", color.ToHex());
Assert.Equal("00BBCCDD", color.ToHex());
color.A = 255;
Assert.Equal("00CCBBFF", color.ToHex());
Assert.Equal("00BBCCFF", color.ToHex());
}
/// <summary>

Loading…
Cancel
Save