diff options
author | Nico Weber <thakis@chromium.org> | 2023-04-11 08:54:15 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-04-11 18:23:07 +0200 |
commit | df6b47609ad7c6d16ee23a5928cd243cd788832c (patch) | |
tree | 3200ba2c883e9ffa4fbb8906c91c4df3c4858715 | |
parent | 5df35d030fce99ea0926d773630cc5d3e9c40752 (diff) | |
download | serenity-df6b47609ad7c6d16ee23a5928cd243cd788832c.zip |
LibGfx/ICC: Add evaluate() member functions to both curve types
-rw-r--r-- | Userland/Libraries/LibGfx/ICC/TagTypes.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/Userland/Libraries/LibGfx/ICC/TagTypes.h b/Userland/Libraries/LibGfx/ICC/TagTypes.h index 64737a4b9c..83007fe403 100644 --- a/Userland/Libraries/LibGfx/ICC/TagTypes.h +++ b/Userland/Libraries/LibGfx/ICC/TagTypes.h @@ -13,6 +13,7 @@ #include <AK/String.h> #include <AK/Vector.h> #include <LibGfx/ICC/DistinctFourCC.h> +#include <math.h> namespace Gfx::ICC { @@ -159,6 +160,26 @@ public: // 65 535). Function values between the entries shall be obtained through linear interpolation." Vector<u16> const& values() const { return m_values; } + // x must be in [0..1]. + float evaluate(float x) const + { + VERIFY(0.f <= x && x <= 1.f); + + if (values().is_empty()) + return x; + + if (values().size() == 1) + return powf(x, values()[0] / (float)0x100); + + size_t i = static_cast<size_t>(x * (values().size() - 1)); + if (i == values().size() - 1) + --i; + + float f = x * (values().size() - 1) - i; + + return (1 - f) * (values()[i] / 65535.f) + f * (values()[i + 1] / 65535.f); + } + private: Vector<u16> m_values; }; @@ -691,6 +712,34 @@ public: return m_parameters[6]; } + // x must be in [0..1]. + float evaluate(float x) const + { + VERIFY(0.f <= x && x <= 1.f); + + switch (function_type()) { + case FunctionType::Type0: + return powf(x, (float)g()); + case FunctionType::Type1: + if (x >= -(float)b() / (float)a()) + return powf((float)a() * x + (float)b(), (float)g()); + return 0; + case FunctionType::Type2: + if (x >= -(float)b() / (float)a()) + return powf((float)a() * x + (float)b(), (float)g()) + (float)c(); + return (float)c(); + case FunctionType::Type3: + if (x >= (float)d()) + return powf((float)a() * x + (float)b(), (float)g()); + return (float)c() * x; + case FunctionType::Type4: + if (x >= (float)d()) + return powf((float)a() * x + (float)b(), (float)g()) + (float)e(); + return (float)c() * x + (float)f(); + } + VERIFY_NOT_REACHED(); + } + private: FunctionType m_function_type; |