@ -25,13 +25,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Normal ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Normal ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
return source ;
return Compose ( backdrop , source , source ) ;
}
}
/// <summary>
/// <summary>
@ -39,13 +37,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Multiply ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Multiply ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
return backdrop * source ;
return Compose ( backdrop , source , backdrop * source ) ;
}
}
/// <summary>
/// <summary>
@ -53,13 +49,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Add ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Add ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
return Vector4 . Min ( Vector4 . One , backdrop + source ) ;
return Compose ( backdrop , source , Vector4 . Min ( Vector4 . One , backdrop + source ) ) ;
}
}
/// <summary>
/// <summary>
@ -67,13 +61,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Subtract ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Subtract ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
return Vector4 . Max ( Vector4 . Zero , backdrop - source ) ;
return Compose ( backdrop , source , Vector4 . Max ( Vector4 . Zero , backdrop - source ) ) ;
}
}
/// <summary>
/// <summary>
@ -81,13 +73,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Screen ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Screen ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
return Vector4 . One - ( ( Vector4 . One - backdrop ) * ( Vector4 . One - source ) ) ;
return Compose ( backdrop , source , Vector4 . One - ( ( Vector4 . One - backdrop ) * ( Vector4 . One - source ) ) ) ;
}
}
/// <summary>
/// <summary>
@ -95,13 +85,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Darken ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Darken ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
return Vector4 . Min ( backdrop , source ) ;
return Compose ( backdrop , source , Vector4 . Min ( backdrop , source ) ) ;
}
}
/// <summary>
/// <summary>
@ -109,13 +97,11 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Lighten ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Lighten ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
return Vector4 . Max ( backdrop , source ) ;
return Compose ( backdrop , source , Vector4 . Max ( backdrop , source ) ) ;
}
}
/// <summary>
/// <summary>
@ -123,17 +109,15 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Overlay ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 Overlay ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
float cr = OverlayValueFunction ( backdrop . X , source . X ) ;
float cr = OverlayValueFunction ( backdrop . X , source . X ) ;
float cg = OverlayValueFunction ( backdrop . Y , source . Y ) ;
float cg = OverlayValueFunction ( backdrop . Y , source . Y ) ;
float cb = OverlayValueFunction ( backdrop . Z , source . Z ) ;
float cb = OverlayValueFunction ( backdrop . Z , source . Z ) ;
return Compose ( backdrop , source , Vector4 . Min ( Vector4 . One , new Vector4 ( cr , cg , cb , 0 ) ) ) ;
return Vector4 . Min ( Vector4 . One , new Vector4 ( cr , cg , cb , 0 ) ) ;
}
}
/// <summary>
/// <summary>
@ -141,17 +125,15 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// </summary>
/// </summary>
/// <param name="backdrop">Backdrop color</param>
/// <param name="backdrop">Backdrop color</param>
/// <param name="source">Source color</param>
/// <param name="source">Source color</param>
/// <param name="opacity">Opacity applied to Source Alpha</param>
/// <returns>Output color</returns>
/// <returns>Output color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 HardLight ( Vector4 backdrop , Vector4 source , float opacity )
public static Vector4 HardLight ( Vector4 backdrop , Vector4 source )
{
{
source . W * = opacity ;
float cr = OverlayValueFunction ( source . X , backdrop . X ) ;
float cr = OverlayValueFunction ( source . X , backdrop . X ) ;
float cg = OverlayValueFunction ( source . Y , backdrop . Y ) ;
float cg = OverlayValueFunction ( source . Y , backdrop . Y ) ;
float cb = OverlayValueFunction ( source . Z , backdrop . Z ) ;
float cb = OverlayValueFunction ( source . Z , backdrop . Z ) ;
return Compose ( backdrop , source , Vector4 . Min ( Vector4 . One , new Vector4 ( cr , cg , cb , 0 ) ) ) ;
return Vector4 . Min ( Vector4 . One , new Vector4 ( cr , cg , cb , 0 ) ) ;
}
}
/// <summary>
/// <summary>
@ -174,7 +156,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
/// <param name="xform">Desired transformed color, without taking Alpha channel in account</param>
/// <param name="xform">Desired transformed color, without taking Alpha channel in account</param>
/// <returns>The final color</returns>
/// <returns>The final color</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 Compos e( Vector4 backdrop , Vector4 source , Vector4 xform )
private static Vector4 SrcOverReferenc e( Vector4 backdrop , Vector4 source , Vector4 xform )
{
{
// calculate weights
// calculate weights
float xw = backdrop . W * source . W ;
float xw = backdrop . W * source . W ;
@ -190,5 +172,86 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
return xform ;
return xform ;
}
}
public static Vector4 Over ( Vector4 dst , Vector4 src , Vector4 blend )
{
// calculate weights
float blendW = dst . W * src . W ;
float dstW = dst . W - blendW ;
float srcW = src . W - blendW ;
// calculate final alpha
float alpha = dstW + srcW + blendW ;
// calculate final color
Vector4 color = ( dst * dstW ) + ( src * srcW ) + ( blend * blendW ) ;
// unpremultiply
color / = MathF . Max ( alpha , Constants . Epsilon ) ;
color . W = alpha ;
return color ;
}
public static Vector4 Atop ( Vector4 dst , Vector4 src , Vector4 blend )
{
// calculate weights
float blendW = dst . W * src . W ;
float dstW = dst . W - blendW ;
// calculate final alpha
float alpha = dstW + blendW ;
// calculate final color
Vector4 color = ( dst * dstW ) + ( blend * blendW ) ;
// unpremultiply
color / = MathF . Max ( alpha , Constants . Epsilon ) ;
color . W = alpha ;
return color ;
}
public static Vector4 In ( Vector4 dst , Vector4 src , Vector4 blend )
{
float alpha = dst . W * src . W ;
Vector4 color = src * alpha ; // premultiply
color / = MathF . Max ( alpha , Constants . Epsilon ) ; // unpremultiply
color . W = alpha ;
return color ;
}
public static Vector4 Out ( Vector4 dst , Vector4 src )
{
float alpha = ( 1 - dst . W ) * src . W ;
Vector4 color = src * alpha ; // premultiply
color / = MathF . Max ( alpha , Constants . Epsilon ) ; // unpremultiply
color . W = alpha ;
return color ;
}
public static Vector4 Xor ( Vector4 dst , Vector4 src )
{
float srcW = 1 - dst . W ;
float dstW = 1 - src . W ;
float alpha = ( src . W * srcW ) + ( dst . W * dstW ) ;
Vector4 color = ( src . W * src * srcW ) + ( dst . W * dst * dstW ) ;
// unpremultiply
color / = MathF . Max ( alpha , Constants . Epsilon ) ;
color . W = alpha ;
return color ;
}
private static Vector4 Clear ( Vector4 backdrop , Vector4 source )
{
return Vector4 . Zero ;
}
}
}
}
}