[libcamera-devel] [PATCH v2 4/6] src: ipa: raspberrypi: Compute inverse of piecewise linear function

David Plowman david.plowman at raspberrypi.com
Mon Dec 7 19:01:19 CET 2020


Add a method to the piecewise linear function (Pwl) class to compute
the inverse of a given Pwl. If the input function is non-monotonic we
can only produce a best effort "pseudo" inverse, and we signal this to
the caller.

Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
---
 src/ipa/raspberrypi/controller/pwl.cpp | 27 ++++++++++++++++++++++++++
 src/ipa/raspberrypi/controller/pwl.hpp |  3 +++
 2 files changed, 30 insertions(+)

diff --git a/src/ipa/raspberrypi/controller/pwl.cpp b/src/ipa/raspberrypi/controller/pwl.cpp
index aa134a1f..70206418 100644
--- a/src/ipa/raspberrypi/controller/pwl.cpp
+++ b/src/ipa/raspberrypi/controller/pwl.cpp
@@ -114,6 +114,33 @@ Pwl::PerpType Pwl::Invert(Point const &xy, Point &perp, int &span,
 	return PerpType::None;
 }
 
+Pwl Pwl::Inverse(bool *true_inverse, const double eps) const
+{
+	bool appended = false, prepended = false, neither = false;
+	Pwl inverse;
+
+	for (Point const &p : points_) {
+		if (inverse.Empty())
+			inverse.Append(p.y, p.x, eps);
+		else if (p.y > inverse.points_.back().x - eps) {
+			inverse.Append(p.y, p.x, eps);
+			appended = true;
+		} else if (p.y < inverse.points_.front().x + eps) {
+			inverse.Prepend(p.y, p.x, eps);
+			prepended = true;
+		} else
+			neither = true;
+	}
+
+	// This is not a proper inverse if we found ourselves putting points
+	// onto both ends of the inverse, or if there were points that couldn't
+	// go on either.
+	if (true_inverse)
+		*true_inverse = !(neither || (appended && prepended));
+
+	return inverse;
+}
+
 Pwl Pwl::Compose(Pwl const &other, const double eps) const
 {
 	double this_x = points_[0].x, this_y = points_[0].y;
diff --git a/src/ipa/raspberrypi/controller/pwl.hpp b/src/ipa/raspberrypi/controller/pwl.hpp
index 4f168551..484672f6 100644
--- a/src/ipa/raspberrypi/controller/pwl.hpp
+++ b/src/ipa/raspberrypi/controller/pwl.hpp
@@ -80,6 +80,9 @@ public:
 	};
 	PerpType Invert(Point const &xy, Point &perp, int &span,
 			const double eps = 1e-6) const;
+	// Compute the inverse function. Indicate if it is a proper (true)
+	// inverse, or only a best effort (e.g. input was non-monotonic).
+	Pwl Inverse(bool *true_inverse = nullptr, const double eps = 1e-6) const;
 	// Compose two Pwls together, doing "this" first and "other" after.
 	Pwl Compose(Pwl const &other, const double eps = 1e-6) const;
 	// Apply function to (x,y) values at every control point.
-- 
2.20.1



More information about the libcamera-devel mailing list