diff --git a/src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHybridLogGammaTransferFunctionBase.cs b/src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHlgTransferFunction.cs
similarity index 52%
rename from src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHybridLogGammaTransferFunctionBase.cs
rename to src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHlgTransferFunction.cs
index 795db106c3..053a2a5cfb 100644
--- a/src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHybridLogGammaTransferFunctionBase.cs
+++ b/src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHlgTransferFunction.cs
@@ -1,33 +1,78 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
+using System.Numerics;
+using SixLabors.ImageSharp.Formats.Jxl.Processing;
+
namespace SixLabors.ImageSharp.Formats.Jxl.Cms.TransferFunctions;
///
-/// Base class for HLG transfer function.
+/// Hybrid Log Gamma transfer function.
///
-internal abstract class JxlHybridLogGammaTransferFunctionBase
+internal sealed class JxlHlgTransferFunction
{
// Shared constants used by transfer functions
- protected const float A = 0.17883277f;
- protected const float RA = 1.0f / A;
- protected const float B = 1 - (4 * A);
- protected const float C = 0.5599107295f;
- protected const float Inverse12 = 1.0f / 12.0f;
+ private const float A = 0.17883277f;
+ private const float RA = 1.0f / A;
+ private const float B = 1 - (4 * A);
+ private const float C = 0.5599107295f;
+ private const float Inverse12 = 1.0f / 12.0f;
+ private const float HiAdd = B * Inverse12;
+ private const float HiMul = 0.003639807079052639f; // MathF.Exp(-C * RA) * Inverse12
+ private const float HiPow = 8.067285659607931f; // RA * JxlMath.InverseLog2E
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Use static methods. Don't instantiate this class.
+ ///
+ private JxlHlgTransferFunction()
+ {
+ }
+
+ public static Vector EncodedFromDisplay(Vector x)
+ {
+ Vector sign = Vector.Create(0x80000000u).As();
+ Vector originalSign = x & sign;
+ x = Vector.AndNot(sign, x);
+ Vector belowInverse12 = Vector.LessThan(x, Vector.Create(Inverse12));
+
+ Vector lo = Vector.SquareRoot(Vector.Create(3.0f) * x);
+ Vector hi = (Vector.Create(A * JxlMath.InverseLog2E) * Vector.Log2((Vector.Create(12f) * x) + Vector.Create(-B))) + Vector.Create(C);
+ Vector magnitude = Vector.ConditionalSelect(belowInverse12, lo, hi);
+ return Vector.AndNot(sign, magnitude) | originalSign;
+ }
+
+ public static Vector DisplayFromEncoded(Vector x)
+ {
+ Vector sign = Vector.Create(0x80000000u).As();
+ Vector originalSign = x & sign;
+ x = Vector.AndNot(sign, x);
+ Vector below05 = Vector.LessThan(x, Vector.Create(0.5f));
+
+ Vector lo = x * (x * Vector.Create(1f / 3f));
+ Vector hi = (Pow2(x * Vector.Create(HiPow)) * Vector.Create(HiMul)) + Vector.Create(HiAdd);
+ Vector magnitude = Vector.ConditionalSelect(below05, lo, hi);
+
+ return Vector.AndNot(sign, magnitude) | originalSign;
+ }
+
+ private static Vector Pow2(Vector x) => JxlSimdUtils.FastPow2f(x);
///
/// Converts encoded signal to display signal.
///
/// The encoded signal
/// The display signal
- protected static double DisplayFromEncoded(double encoded) => Ootf(InverseOotf(encoded));
+ public static double DisplayFromEncoded(double encoded) => Ootf(InverseOotf(encoded));
///
/// Converts display signal to encoded signal.
///
/// The display signal
/// The encoded signal
- protected static double EncodedFromDisplay(double display) => Oetf(InverseOetf(display));
+ public static double EncodedFromDisplay(double display) => Oetf(InverseOetf(display));
///
/// Opto-Electronic Transfer Function - converts
@@ -39,7 +84,7 @@ internal abstract class JxlHybridLogGammaTransferFunctionBase
///
/// Scene light
/// Digital video signal
- private static double Oetf(double s)
+ public static double Oetf(double s)
{
if (s == 0)
{
@@ -70,7 +115,7 @@ internal abstract class JxlHybridLogGammaTransferFunctionBase
///
/// Digital video signal
/// Scene light
- private static double InverseOetf(double e)
+ public static double InverseOetf(double e)
{
if (e == 0)
{
@@ -100,7 +145,7 @@ internal abstract class JxlHybridLogGammaTransferFunctionBase
///
/// Input signal
/// Digital video signal
- private static double Ootf(double s) => s;
+ public static double Ootf(double s) => s;
///
/// Inverse Opto-Optical Transfer Function - as-is.
@@ -110,5 +155,5 @@ internal abstract class JxlHybridLogGammaTransferFunctionBase
///
/// Digital video signal
/// Scene light
- private static double InverseOotf(double s) => s;
+ public static double InverseOotf(double s) => s;
}
diff --git a/src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHybridLogGammaTransferFunction.cs b/src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHybridLogGammaTransferFunction.cs
deleted file mode 100644
index 3957c3ac7b..0000000000
--- a/src/ImageSharp/Formats/Jxl/Cms/TransferFunctions/JxlHybridLogGammaTransferFunction.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) Six Labors.
-// Licensed under the Six Labors Split License.
-
-using System.Numerics;
-using SixLabors.ImageSharp.Formats.Jxl.Processing;
-
-namespace SixLabors.ImageSharp.Formats.Jxl.Cms.TransferFunctions;
-
-internal sealed class JxlHybridLogGammaTransferFunction : JxlHybridLogGammaTransferFunctionBase
-{
- private const float HiAdd = B * Inverse12;
- private const float HiMul = 0.003639807079052639f; // MathF.Exp(-C * RA) * Inverse12
- private const float HiPow = 8.067285659607931f; // RA * JxlMath.InverseLog2E
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// Use static methods. Don't instantiate this class.
- ///
- private JxlHybridLogGammaTransferFunction()
- {
- }
-
- public static Vector EncodedFromDisplay(Vector x)
- {
- Vector sign = Vector.Create(0x80000000u).As();
- Vector originalSign = x & sign;
- x = Vector.AndNot(sign, x);
- Vector belowInverse12 = Vector.LessThan(x, Vector.Create(Inverse12));
-
- Vector lo = Vector.SquareRoot(Vector.Create(3.0f) * x);
- Vector hi = (Vector.Create(A * JxlMath.InverseLog2E) * Vector.Log2((Vector.Create(12f) * x) + Vector.Create(-B))) + Vector.Create(C);
- Vector magnitude = Vector.ConditionalSelect(belowInverse12, lo, hi);
- return Vector.AndNot(sign, magnitude) | originalSign;
- }
-
- public static Vector DisplayFromEncoded(Vector x)
- {
- Vector sign = Vector.Create(0x80000000u).As();
- Vector originalSign = x & sign;
- x = Vector.AndNot(sign, x);
- Vector below05 = Vector.LessThan(x, Vector.Create(0.5f));
-
- Vector lo = x * (x * Vector.Create(1f / 3f));
- Vector hi = (Pow2(x * Vector.Create(HiPow)) * Vector.Create(HiMul)) + Vector.Create(HiAdd);
- Vector magnitude = Vector.ConditionalSelect(below05, lo, hi);
-
- return Vector.AndNot(sign, magnitude) | originalSign;
- }
-
- private static Vector Pow2(Vector x) => x * x;
-}