@ -78,20 +78,26 @@ namespace ImageProcessorCore
if ( hex . Length = = 8 )
{
float r = Convert . ToByte ( hex . Substring ( 2 , 2 ) , 1 6 ) / 2 5 5f ;
float g = Convert . ToByte ( hex . Substring ( 4 , 2 ) , 1 6 ) / 2 5 5f ;
float b = Convert . ToByte ( hex . Substring ( 6 , 2 ) , 1 6 ) / 2 5 5f ;
float a = Convert . ToByte ( hex . Substring ( 0 , 2 ) , 1 6 ) / 2 5 5f ;
float r = Convert . ToByte ( hex . Substring ( 2 , 2 ) , 1 6 ) ;
float g = Convert . ToByte ( hex . Substring ( 4 , 2 ) , 1 6 ) ;
float b = Convert . ToByte ( hex . Substring ( 6 , 2 ) , 1 6 ) ;
float a = Convert . ToByte ( hex . Substring ( 0 , 2 ) , 1 6 ) ;
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 ) / 2 5 5f ;
this . backingVector = FromNonPremultiplied ( this . backingVector , this . A ) ;
}
else if ( hex . Length = = 6 )
{
this . R = Convert . ToByte ( hex . Substring ( 0 , 2 ) , 1 6 ) / 2 5 5f ;
this . G = Convert . ToByte ( hex . Substring ( 2 , 2 ) , 1 6 ) / 2 5 5f ;
this . B = Convert . ToByte ( hex . Substring ( 4 , 2 ) , 1 6 ) / 2 5 5f ;
this . A = 1 ;
float r = Convert . ToByte ( hex . Substring ( 0 , 2 ) , 1 6 ) ;
float g = Convert . ToByte ( hex . Substring ( 2 , 2 ) , 1 6 ) ;
float b = Convert . ToByte ( hex . Substring ( 4 , 2 ) , 1 6 ) ;
float a = 2 5 5f ;
// Do division of Vector4 instead of each component to utilize SIMD optimizations
this . backingVector = new Vector4 ( r , g , b , a ) / 2 5 5f ;
}
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 , 1 6 ) / 2 5 5f ;
this . G = Convert . ToByte ( gh + gh , 1 6 ) / 2 5 5f ;
this . R = Convert . ToByte ( rh + rh , 1 6 ) / 2 5 5f ;
this . A = 1 ;
float r = Convert . ToByte ( rh + rh , 1 6 ) ;
float g = Convert . ToByte ( gh + gh , 1 6 ) ;
float b = Convert . ToByte ( bh + bh , 1 6 ) ;
float a = 2 5 5f ;
this . backingVector = new Vector4 ( r , g , b , a ) / 2 5 5f ;
}
}
@ -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>