Browse Source

Merge pull request #319 from Quintinon/VectorOptimization

Optimized Vector usage in Color just a tiny bit

Former-commit-id: dcbe64ad390061ec34f95bd4632a28a4bd776603
Former-commit-id: 5ea3a80b4d8053b23062a49ab13ea09a44e24bb1
Former-commit-id: e65f6596f5a02f50eefcc5dc4fce369ba5526583
af/merge-core
James Jackson-South 10 years ago
parent
commit
1b6ad47d55
  1. 62
      src/ImageProcessorCore/Colors/Color.cs
  2. 20
      tests/ImageProcessorCore.Tests/Colors/ColorTests.cs

62
src/ImageProcessorCore/Colors/Color.cs

@ -78,20 +78,26 @@ namespace ImageProcessorCore
if (hex.Length == 8)
{
float r = Convert.ToByte(hex.Substring(2, 2), 16) / 255f;
float g = Convert.ToByte(hex.Substring(4, 2), 16) / 255f;
float b = Convert.ToByte(hex.Substring(6, 2), 16) / 255f;
float a = Convert.ToByte(hex.Substring(0, 2), 16) / 255f;
float r = Convert.ToByte(hex.Substring(2, 2), 16);
float g = Convert.ToByte(hex.Substring(4, 2), 16);
float b = Convert.ToByte(hex.Substring(6, 2), 16);
float a = Convert.ToByte(hex.Substring(0, 2), 16);
this.backingVector = FromNonPremultiplied(new Color(r, g, b, a)).ToVector4();
// Do division of Vector4 instead of each component to utilize SIMD optimizations
this.backingVector = new Vector4(r, g, b, a) / 255f;
this.backingVector = FromNonPremultiplied(this.backingVector, this.A);
}
else if (hex.Length == 6)
{
this.R = Convert.ToByte(hex.Substring(0, 2), 16) / 255f;
this.G = Convert.ToByte(hex.Substring(2, 2), 16) / 255f;
this.B = Convert.ToByte(hex.Substring(4, 2), 16) / 255f;
this.A = 1;
float r = Convert.ToByte(hex.Substring(0, 2), 16);
float g = Convert.ToByte(hex.Substring(2, 2), 16);
float b = Convert.ToByte(hex.Substring(4, 2), 16);
float a = 255f;
// Do division of Vector4 instead of each component to utilize SIMD optimizations
this.backingVector = new Vector4(r, g, b, a) / 255f;
}
else
{
@ -99,10 +105,12 @@ namespace ImageProcessorCore
string gh = char.ToString(hex[1]);
string bh = char.ToString(hex[2]);
this.B = Convert.ToByte(bh + bh, 16) / 255f;
this.G = Convert.ToByte(gh + gh, 16) / 255f;
this.R = Convert.ToByte(rh + rh, 16) / 255f;
this.A = 1;
float r = Convert.ToByte(rh + rh, 16);
float g = Convert.ToByte(gh + gh, 16);
float b = Convert.ToByte(bh + bh, 16);
float a = 255f;
this.backingVector = new Vector4(r, g, b, a) / 255f;
}
}
@ -123,7 +131,7 @@ namespace ImageProcessorCore
/// </param>
public Color(Vector3 vector)
{
this.backingVector = new Vector4(vector.X, vector.Y, vector.Z, 1);
this.backingVector = new Vector4(vector, 1);
}
/// <summary>
@ -135,7 +143,7 @@ namespace ImageProcessorCore
/// <param name="alpha">The alpha component.</param>
public Color(Vector3 vector, float alpha)
{
this.backingVector = new Vector4(vector.X, vector.Y, vector.Z, alpha);
this.backingVector = new Vector4(vector, alpha);
}
/// <summary>
@ -367,8 +375,18 @@ namespace ImageProcessorCore
/// <returns>The <see cref="Color"/>.</returns>
public static Color FromNonPremultiplied(Color color)
{
float a = color.A;
return new Color(color.backingVector * new Vector4(a, a, a, 1));
return new Color(FromNonPremultiplied(color.backingVector, color.A));
}
/// <summary>
/// Converts a non-premultiplied alpha Vector4 to a Vector4 that contains premultiplied alpha.
/// </summary>
/// <param name="vector">The vector to convert.</param>
/// <param name="alpha">The alpha to use in conversion.</param>
/// <returns>The Vector4 with premultiplied alpha.</returns>
private static Vector4 FromNonPremultiplied(Vector4 vector, float alpha)
{
return vector * new Vector4(alpha, alpha, alpha, 1);
}
/// <summary>
@ -443,10 +461,12 @@ namespace ImageProcessorCore
/// <inheritdoc/>
public bool AlmostEquals(Color other, float precision)
{
return Math.Abs(this.R - other.R) < precision
&& Math.Abs(this.G - other.G) < precision
&& Math.Abs(this.B - other.B) < precision
&& Math.Abs(this.A - other.A) < precision;
Vector4 result = Vector4.Abs(this.backingVector - other.backingVector);
return result.X < precision
&& result.Y < precision
&& result.Z < precision
&& result.W < precision;
}
/// <summary>

20
tests/ImageProcessorCore.Tests/Colors/ColorTests.cs

@ -8,6 +8,8 @@
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System.Numerics;
namespace ImageProcessorCore.Tests
{
using Xunit;
@ -76,6 +78,24 @@ namespace ImageProcessorCore.Tests
Assert.Equal(0, color3.G, 1);
Assert.Equal(0, color3.B, 3);
Assert.Equal(1, color3.A, 1);
Color color4 = new Color(new Vector3(1, .1f, .133f));
Assert.Equal(1, color4.R, 1);
Assert.Equal(.1f, color4.G, 1);
Assert.Equal(.133f, color4.B, 3);
Assert.Equal(1, color4.A, 1);
Color color5 = new Color(new Vector3(1, .1f, .133f), .5f);
Assert.Equal(1, color5.R, 1);
Assert.Equal(.1f, color5.G, 1);
Assert.Equal(.133f, color5.B, 3);
Assert.Equal(.5f, color5.A, 1);
Color color6 = new Color(new Vector4(1, .1f, .133f, .5f));
Assert.Equal(1, color5.R, 1);
Assert.Equal(.1f, color6.G, 1);
Assert.Equal(.133f, color6.B, 3);
Assert.Equal(.5f, color6.A, 1);
}
/// <summary>

Loading…
Cancel
Save