summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGfx
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2023-04-11 08:54:15 -0400
committerLinus Groh <mail@linusgroh.de>2023-04-11 18:23:07 +0200
commitdf6b47609ad7c6d16ee23a5928cd243cd788832c (patch)
tree3200ba2c883e9ffa4fbb8906c91c4df3c4858715 /Userland/Libraries/LibGfx
parent5df35d030fce99ea0926d773630cc5d3e9c40752 (diff)
downloadserenity-df6b47609ad7c6d16ee23a5928cd243cd788832c.zip
LibGfx/ICC: Add evaluate() member functions to both curve types
Diffstat (limited to 'Userland/Libraries/LibGfx')
-rw-r--r--Userland/Libraries/LibGfx/ICC/TagTypes.h49
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;