Browse Source

Unify sRGB companding

af/merge-core
James Jackson-South 8 years ago
parent
commit
01a6d8b285
  1. 78
      src/ImageSharp/Common/Extensions/Vector4Extensions.cs
  2. 2
      tests/ImageSharp.Tests/Helpers/Vector4ExtensionsTests.cs

78
src/ImageSharp/Common/Extensions/Vector4Extensions.cs

@ -5,7 +5,7 @@ using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
@ -55,8 +55,10 @@ namespace SixLabors.ImageSharp
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
var s = new Vector4(v.W);
s.W = 1;
var s = new Vector4(v.W)
{
W = 1
};
v *= s;
}
}
@ -73,8 +75,10 @@ namespace SixLabors.ImageSharp
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
var s = new Vector4(1 / v.W);
s.W = 1;
var s = new Vector4(1 / v.W)
{
W = 1
};
v *= s;
}
}
@ -90,7 +94,11 @@ namespace SixLabors.ImageSharp
public static Vector4 Compress(this Vector4 linear)
{
// TODO: Is there a faster way to do this?
return new Vector4(Compress(linear.X), Compress(linear.Y), Compress(linear.Z), linear.W);
return new Vector4(
SRgbCompanding.Compress(linear.X),
SRgbCompanding.Compress(linear.Y),
SRgbCompanding.Compress(linear.Z),
linear.W);
}
/// <summary>
@ -104,7 +112,11 @@ namespace SixLabors.ImageSharp
public static Vector4 Expand(this Vector4 gamma)
{
// TODO: Is there a faster way to do this?
return new Vector4(Expand(gamma.X), Expand(gamma.Y), Expand(gamma.Z), gamma.W);
return new Vector4(
SRgbCompanding.Expand(gamma.X),
SRgbCompanding.Expand(gamma.Y),
SRgbCompanding.Expand(gamma.Z),
gamma.W);
}
/// <summary>
@ -118,9 +130,9 @@ namespace SixLabors.ImageSharp
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
v.X = Compress(v.X);
v.Y = Compress(v.Y);
v.Z = Compress(v.Z);
v.X = SRgbCompanding.Compress(v.X);
v.Y = SRgbCompanding.Compress(v.Y);
v.Z = SRgbCompanding.Compress(v.Z);
}
}
@ -135,50 +147,10 @@ namespace SixLabors.ImageSharp
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
v.X = Expand(v.X);
v.Y = Expand(v.Y);
v.Z = Expand(v.Z);
}
}
/// <summary>
/// Gets the compressed sRGB value from an linear signal.
/// <see href="http://www.4p8.com/eric.brasseur/gamma.html#formulas"/>
/// <see href="http://entropymine.com/imageworsener/srgbformula/"/>
/// </summary>
/// <param name="signal">The signal value to compress.</param>
/// <returns>
/// The <see cref="float"/>.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static float Compress(float signal)
{
if (signal <= 0.0031308F)
{
return signal * 12.92F;
v.X = SRgbCompanding.Expand(v.X);
v.Y = SRgbCompanding.Expand(v.Y);
v.Z = SRgbCompanding.Expand(v.Z);
}
return (1.055F * MathF.Pow(signal, 0.41666666F)) - 0.055F;
}
/// <summary>
/// Gets the expanded linear value from an sRGB signal.
/// <see href="http://www.4p8.com/eric.brasseur/gamma.html#formulas"/>
/// <see href="http://entropymine.com/imageworsener/srgbformula/"/>
/// </summary>
/// <param name="signal">The signal value to expand.</param>
/// <returns>
/// The <see cref="float"/>.
/// </returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static float Expand(float signal)
{
if (signal <= 0.04045F)
{
return signal / 12.92F;
}
return MathF.Pow((signal + 0.055F) / 1.055F, 2.4F);
}
}
}

2
tests/ImageSharp.Tests/Helpers/Vector4ExtensionsTests.cs

@ -70,7 +70,5 @@ namespace SixLabors.ImageSharp.Tests.Helpers
Assert.Equal(expected, source, new ApproximateFloatComparer(1e-6f));
}
}
}

Loading…
Cancel
Save