From patchwork Sun Nov 17 22:17:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21931 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id DCE7EC32DD for ; Sun, 17 Nov 2024 22:17:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 39562658AA; Sun, 17 Nov 2024 23:17:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="oJB/upI4"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6519060580 for ; Sun, 17 Nov 2024 23:17:23 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1BF2E7FE for ; Sun, 17 Nov 2024 23:17:07 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881827; bh=qxpBipRmyMvboc8aU50grYWOIz4VLb9CxNU46MGgyyw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oJB/upI4benv4goaex3hcuP/f1cHKCGohu3xFjYzQ8LTNXHhwqXCmkJjy/ESMneHa noFPovwlSV57/HLPpoTFyKcRh/IBf/JdhjlBJD09ccHYJP9fgzlc9RvaMJ86UhNG+x zK92I1NPAGCN44tAOtX5oRMukGaIWIJa1HnSNnJg= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 01/11] ipa: libipa: vector: Add mutable x(), y() and z() accessors Date: Mon, 18 Nov 2024 00:17:02 +0200 Message-ID: <20241117221712.29616-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The x(), y() and z() functions of the Vector class are convenience accessors for the first, second and third element of the vector respectively, meant to improve readability of class users when a vector represents coordinates in 1D, 2D or 3D space. Those accessors are limited to immutable access to the vector elements, as they return a copy. Extend the API with mutable accessors. The immutable accessors are modified to return a reference to the vector elements instead of a copy for consistency. As they are inline functions, this should make no difference in terms of performance as the compiler can perform the same optimizations in their case. While at it, reorder functions to declare operators before other member functions, to be consistent with the usual coding style. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 51 +++++++++++++++++++++++++-------------- src/ipa/libipa/vector.h | 49 +++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 42 deletions(-) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index bd00b01961d5..8a39bfd27f90 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -52,24 +52,6 @@ namespace ipa { * \copydoc Vector::operator[](size_t i) const */ -/** - * \fn Vector::x() - * \brief Convenience function to access the first element of the vector - * \return The first element of the vector - */ - -/** - * \fn Vector::y() - * \brief Convenience function to access the second element of the vector - * \return The second element of the vector - */ - -/** - * \fn Vector::z() - * \brief Convenience function to access the third element of the vector - * \return The third element of the vector - */ - /** * \fn Vector::operator-() const * \brief Negate a Vector by negating both all of its coordinates @@ -111,6 +93,39 @@ namespace ipa { * \return The vector divided by \a factor */ +/** + * \fn T &Vector::x() + * \brief Convenience function to access the first element of the vector + * \return The first element of the vector + */ + +/** + * \fn T &Vector::y() + * \brief Convenience function to access the second element of the vector + * \return The second element of the vector + */ + +/** + * \fn T &Vector::z() + * \brief Convenience function to access the third element of the vector + * \return The third element of the vector + */ + +/** + * \fn constexpr const T &Vector::x() const + * \copydoc Vector::x() + */ + +/** + * \fn constexpr const T &Vector::y() const + * \copydoc Vector::y() + */ + +/** + * \fn constexpr const T &Vector::z() const + * \copydoc Vector::z() + */ + /** * \fn Vector::length2() * \brief Get the squared length of the vector diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 8612a06a2ab2..1b11a34deee4 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -53,30 +53,6 @@ public: return data_[i]; } -#ifndef __DOXYGEN__ - template= 1>> -#endif /* __DOXYGEN__ */ - constexpr T x() const - { - return data_[0]; - } - -#ifndef __DOXYGEN__ - template= 2>> -#endif /* __DOXYGEN__ */ - constexpr T y() const - { - return data_[1]; - } - -#ifndef __DOXYGEN__ - template= 3>> -#endif /* __DOXYGEN__ */ - constexpr T z() const - { - return data_[2]; - } - constexpr Vector operator-() const { Vector ret; @@ -125,6 +101,31 @@ public: return ret; } +#ifndef __DOXYGEN__ + template= 1>> +#endif /* __DOXYGEN__ */ + constexpr const T &x() const { return data_[0]; } +#ifndef __DOXYGEN__ + template= 2>> +#endif /* __DOXYGEN__ */ + constexpr const T &y() const { return data_[1]; } +#ifndef __DOXYGEN__ + template= 3>> +#endif /* __DOXYGEN__ */ + constexpr const T &z() const { return data_[2]; } +#ifndef __DOXYGEN__ + template= 1>> +#endif /* __DOXYGEN__ */ + T &x() { return data_[0]; } +#ifndef __DOXYGEN__ + template= 2>> +#endif /* __DOXYGEN__ */ + T &y() { return data_[1]; } +#ifndef __DOXYGEN__ + template= 3>> +#endif /* __DOXYGEN__ */ + T &z() { return data_[2]; } + constexpr double length2() const { double ret = 0; From patchwork Sun Nov 17 22:17:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21932 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 9DDB9C32DF for ; Sun, 17 Nov 2024 22:17:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 87F94658B1; Sun, 17 Nov 2024 23:17:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cYRKtF5L"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B5FCE658A4 for ; Sun, 17 Nov 2024 23:17:24 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6CFE17FE for ; Sun, 17 Nov 2024 23:17:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881828; bh=bQ7ZbcMrSrv8caa5LEKyJWsdOzVNQkrKgUatyJjxc4E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cYRKtF5LP7y2B0yE9W0kEJM+2XU8CI4IgYNUdKHI5+cR4iDLQctEbwWyfV7UBLS9+ dQZRojTJRSOTXy/L3o305/c0Ox7qs/p113oSWM8dxEn4PKKTt2JzOP3M9PT61GALju 0Ru6xr8XNDHlElJAGFSqPYxaGOMDQT1IwdeSjH0M= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 02/11] ipa: libipa: vector: Add r(), g() and b() accessors Date: Mon, 18 Nov 2024 00:17:03 +0200 Message-ID: <20241117221712.29616-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Vector class can be useful to represent RGB pixel values. Add r(), g() and b() accessors, similar to x(), y() and z(), along with an RGB type that aliases Vector. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/ipa/libipa/vector.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index 8a39bfd27f90..f14f155216f3 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -126,6 +126,39 @@ namespace ipa { * \copydoc Vector::z() */ +/** + * \fn T &Vector::r() + * \brief Convenience function to access the first element of the vector + * \return The first element of the vector + */ + +/** + * \fn T &Vector::g() + * \brief Convenience function to access the second element of the vector + * \return The second element of the vector + */ + +/** + * \fn T &Vector::b() + * \brief Convenience function to access the third element of the vector + * \return The third element of the vector + */ + +/** + * \fn constexpr const T &Vector::r() const + * \copydoc Vector::r() + */ + +/** + * \fn constexpr const T &Vector::g() const + * \copydoc Vector::g() + */ + +/** + * \fn constexpr const T &Vector::b() const + * \copydoc Vector::b() + */ + /** * \fn Vector::length2() * \brief Get the squared length of the vector @@ -149,6 +182,11 @@ namespace ipa { * \return Product of matrix \a m and vector \a v */ +/** + * \typedef RGB + * \brief A Vector of 3 elements representing an RGB pixel value + */ + /** * \fn bool operator==(const Vector &lhs, const Vector &rhs) * \brief Compare vectors for equality diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 1b11a34deee4..b72ab9851aa3 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -126,6 +126,31 @@ public: #endif /* __DOXYGEN__ */ T &z() { return data_[2]; } +#ifndef __DOXYGEN__ + template= 1>> +#endif /* __DOXYGEN__ */ + constexpr const T &r() const { return data_[0]; } +#ifndef __DOXYGEN__ + template= 2>> +#endif /* __DOXYGEN__ */ + constexpr const T &g() const { return data_[1]; } +#ifndef __DOXYGEN__ + template= 3>> +#endif /* __DOXYGEN__ */ + constexpr const T &b() const { return data_[2]; } +#ifndef __DOXYGEN__ + template= 1>> +#endif /* __DOXYGEN__ */ + T &r() { return data_[0]; } +#ifndef __DOXYGEN__ + template= 2>> +#endif /* __DOXYGEN__ */ + T &g() { return data_[1]; } +#ifndef __DOXYGEN__ + template= 3>> +#endif /* __DOXYGEN__ */ + T &b() { return data_[2]; } + constexpr double length2() const { double ret = 0; @@ -143,6 +168,9 @@ private: std::array data_; }; +template +using RGB = Vector; + template Vector operator*(const Matrix &m, const Vector &v) { From patchwork Sun Nov 17 22:17:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21933 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id B4F36C32DD for ; Sun, 17 Nov 2024 22:17:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5263C657DA; Sun, 17 Nov 2024 23:17:34 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="kXu9jRq5"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 22820657DA for ; Sun, 17 Nov 2024 23:17:26 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C2EDD7FE for ; Sun, 17 Nov 2024 23:17:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881830; bh=u9dR8L8pQLloFRR66pjmoAU0G54ZdDGmseZUGeLoWa4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=kXu9jRq5BcRyjmyGdH47GghTwEu6tflxbtMGbxxbuUROAFwFwXyBXpQU2Rbprk5oh GEIQtTtZJOmbUJSIkvVogYpgkJAhFYLd+XyO7n7+ukTUQ+gHWYB/Qekr0tXMsRmdpy QxcAPkxcPBhRDtR+c58Rk/MvAGfs0pBvrbSmziO4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 03/11] ipa: libipa: vector: Add copy constructor and assignment operator Date: Mon, 18 Nov 2024 00:17:04 +0200 Message-ID: <20241117221712.29616-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" It is useful to assign a value to an existing vector. Define a copy constructor and a copy assignment operator. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 13 +++++++++++++ src/ipa/libipa/vector.h | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index f14f155216f3..df089f8aed9f 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -40,6 +40,19 @@ namespace ipa { * The size of \a data must be equal to the dimension size Rows of the vector. */ +/** + * \fn Vector::Vector(const Vector &other) + * \brief Construct a Vector by copying \a other + * \param[in] other The other Vector value + */ + +/** + * \fn Vector &Vector::operator=(const Vector &other) + * \brief Replace the content of the Vector with a copy of the content of \a other + * \param[in] other The other Vector value + * \return This Vector value + */ + /** * \fn T Vector::operator[](size_t i) const * \brief Index to an element in the vector diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index b72ab9851aa3..50e16250acfd 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -6,6 +6,7 @@ */ #pragma once +#include #include #include #include @@ -41,6 +42,18 @@ public: data_[i] = data[i]; } + Vector(const Vector &other) + : data_(other.data_) + { + } + + Vector &operator=(const Vector &other) + { + data_ = other.data_; + + return *this; + } + const T &operator[](size_t i) const { ASSERT(i < data_.size()); From patchwork Sun Nov 17 22:17:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21934 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id ACFBBC32DF for ; Sun, 17 Nov 2024 22:17:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F0BA3658BB; Sun, 17 Nov 2024 23:17:39 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="wVIKWXM9"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A13F6658AB for ; Sun, 17 Nov 2024 23:17:27 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4E3437FE for ; Sun, 17 Nov 2024 23:17:11 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881831; bh=zj0U/HE1hEYjvElrAo1U+PSICzRsAqaxIBvUOT/Ccpk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=wVIKWXM9T8pL73jNm4DdHYowj/6HFMPcQP98wVy1HCRtvwNPhcmqX+BRMNPMmTbPj BlQhuR/6hdblHDNQHM5KVe4BhP+UW9A3XMJL7tRcm5rkmVuNmk7H+93ffmF4X7R7yg 6y7qAAmKBCupERKHrjUWqe9I9JSFOh+eV461xMiU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 04/11] ipa: libipa: vector: Rename the dot product operator*() to dot() Date: Mon, 18 Nov 2024 00:17:05 +0200 Message-ID: <20241117221712.29616-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Vector class defines a set of arithmetic operators between two vectors or a vector and a scalar. All the operators perform element-wise operations, except for the operator*() that computes the dot product. This is inconsistent and confusing. Replace the operator with a dot() function. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 14 +++++++------- src/ipa/libipa/vector.h | 16 ++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index df089f8aed9f..b2794c200b05 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -85,13 +85,6 @@ namespace ipa { * \return The sum of the two vectors */ -/** - * \fn Vector::operator*(const Vector &other) const - * \brief Compute the dot product - * \param[in] other The other vector - * \return The dot product of the two vectors - */ - /** * \fn Vector::operator*(T factor) const * \brief Multiply the vector by a scalar @@ -106,6 +99,13 @@ namespace ipa { * \return The vector divided by \a factor */ +/** + * \fn Vector::dot(const Vector &other) const + * \brief Compute the dot product + * \param[in] other The other vector + * \return The dot product of the two vectors + */ + /** * \fn T &Vector::x() * \brief Convenience function to access the first element of the vector diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 50e16250acfd..9dabdc28a540 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -90,14 +90,6 @@ public: return ret; } - constexpr T operator*(const Vector &other) const - { - T ret = 0; - for (unsigned int i = 0; i < Rows; i++) - ret += data_[i] * other[i]; - return ret; - } - constexpr Vector operator*(T factor) const { Vector ret; @@ -114,6 +106,14 @@ public: return ret; } + constexpr T dot(const Vector &other) const + { + T ret = 0; + for (unsigned int i = 0; i < Rows; i++) + ret += data_[i] * other[i]; + return ret; + } + #ifndef __DOXYGEN__ template= 1>> #endif /* __DOXYGEN__ */ From patchwork Sun Nov 17 22:17:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21935 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id E08FFC32DD for ; Sun, 17 Nov 2024 22:17:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 614FB658AE; Sun, 17 Nov 2024 23:17:43 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ixw6/TtK"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0924C658AC for ; Sun, 17 Nov 2024 23:17:29 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AA5D37FE for ; Sun, 17 Nov 2024 23:17:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881832; bh=gU/DViUqdbRwz7vQMTvWxLxbGsGYNHcOZNJfvv/FUr0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ixw6/TtK9KIcFGXhYTih32yeRRXLSP+NPqptZTDm6R8r06qQS2RbW8x16Q8wmai7T 3rz/EXwVE1zsKpkq6QSsvnbqDThQQS6mdGtoZuQBp3gT6qrsymeIZOsWyL6Os9IbaD 5ocizDIeHY8NKRaCTWSBB/gbbsYKdkiRG4v3LUXM= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 05/11] ipa: libipa: vector: Generalize arithmetic operators Date: Mon, 18 Nov 2024 00:17:06 +0200 Message-ID: <20241117221712.29616-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Instead of hand-coding all arithmetic operators, implement them based on a generic apply() function that takes an operator-specific std::function. This will simplify adding missing arithmetic operators. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.h | 48 ++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 9dabdc28a540..8c4edfbaf85f 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -74,36 +74,24 @@ public: return ret; } - constexpr Vector operator-(const Vector &other) const + constexpr Vector operator-(const Vector &other) const { - Vector ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] - other[i]; - return ret; + return apply(*this, other, [](T a, T b) { return a - b; }); } - constexpr Vector operator+(const Vector &other) const + constexpr Vector operator+(const Vector &other) const { - Vector ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] + other[i]; - return ret; + return apply(*this, other, [](T a, T b) { return a + b; }); } - constexpr Vector operator*(T factor) const + constexpr Vector operator*(T factor) const { - Vector ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] * factor; - return ret; + return apply(*this, factor, [](T a, T b) { return a * b; }); } - constexpr Vector operator/(T factor) const + constexpr Vector operator/(T factor) const { - Vector ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] / factor; - return ret; + return apply(*this, factor, [](T a, T b) { return a / b; }); } constexpr T dot(const Vector &other) const @@ -178,6 +166,26 @@ public: } private: + static constexpr Vector apply(const Vector &lhs, const Vector &rhs, std::function func) + { + Vector result; + std::transform(lhs.data_.begin(), lhs.data_.end(), + rhs.data_.begin(), result.data_.begin(), + func); + + return result; + } + + static constexpr Vector apply(const Vector &lhs, T rhs, std::function func) + { + Vector result; + std::transform(lhs.data_.begin(), lhs.data_.end(), + result.data_.begin(), + [&func, rhs](T v) { return func(v, rhs); }); + + return result; + } + std::array data_; }; From patchwork Sun Nov 17 22:17:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21936 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 4424DC32DF for ; Sun, 17 Nov 2024 22:17:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7B60C658B7; Sun, 17 Nov 2024 23:17:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Sr+6yPy9"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5898C658AD for ; Sun, 17 Nov 2024 23:17:30 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0B3447FE for ; Sun, 17 Nov 2024 23:17:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881834; bh=9MiINevDfChBdv5qVOrHFrk3D/8r4l9JnlU7vz9WSx8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Sr+6yPy9IrQICMMnT3hftXw16c9TE1LRPKOKuXij/cS1aTsgPHK/UFTo2mMqymQm5 Js4OVgUQmyLJW2iEBaqVDZHf6lgKUUa8KSkcY5WK20sWrWa0lTWqQtQq9gJa8O8ueq s8b9ucZfszlSZPATVH1v3VgaG50WRvNTjD+NDBwk= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 06/11] ipa: libipa: vector: Add missing binary arithemtic operators Date: Mon, 18 Nov 2024 00:17:07 +0200 Message-ID: <20241117221712.29616-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Vector class defines multiple element-wise arithmetic operators between vectors or between a vector and a scalar. A few variants are missing. Add them. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 54 +++++++++++++++++++++++++++++---------- src/ipa/libipa/vector.h | 38 ++++++++++++++++++++------- 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index b2794c200b05..d0e38f402220 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -71,32 +71,60 @@ namespace ipa { * \return The negated vector */ +/** + * \fn Vector::operator+(Vector const &other) const + * \brief Calculate the sum of this vector and \a other element-wise + * \param[in] other The other vector + * \return The element-wise sum of this vector and \a other + */ + +/** + * \fn Vector::operator+(T scalar) const + * \brief Calculate the sum of this vector and \a scalar element-wise + * \param[in] scalar The scalar + * \return The element-wise sum of this vector and \a other + */ + /** * \fn Vector::operator-(Vector const &other) const - * \brief Subtract one vector from another + * \brief Calculate the difference of this vector and \a other element-wise * \param[in] other The other vector - * \return The difference of \a other from this vector + * \return The element-wise subtraction of \a other from this vector */ /** - * \fn Vector::operator+() - * \brief Add two vectors together + * \fn Vector::operator-(T scalar) const + * \brief Calculate the difference of this vector and \a scalar element-wise + * \param[in] scalar The scalar + * \return The element-wise subtraction of \a scalar from this vector + */ + +/** + * \fn Vector::operator*(const Vector &other) const + * \brief Calculate the product of this vector and \a other element-wise * \param[in] other The other vector - * \return The sum of the two vectors + * \return The element-wise product of this vector and \a other */ /** - * \fn Vector::operator*(T factor) const - * \brief Multiply the vector by a scalar - * \param[in] factor The factor - * \return The vector multiplied by \a factor + * \fn Vector::operator*(T scalar) const + * \brief Calculate the product of this vector and \a scalar element-wise + * \param[in] scalar The scalar + * \return The element-wise product of this vector and \a scalar */ /** - * \fn Vector::operator/() - * \brief Divide the vector by a scalar - * \param[in] factor The factor - * \return The vector divided by \a factor + * \fn Vector::operator/(const Vector &other) const + * \brief Calculate the quotient of this vector and \a other element-wise + * \param[in] other The other vector + * \return The element-wise division of this vector by \a other + */ + +/** + * \fn Vector::operator/(T scalar) const + * \brief Calculate the quotient of this vector and \a scalar element-wise + * \param[in] scalar The scalar + * \return The element-wise division of this vector by \a scalar */ /** diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 8c4edfbaf85f..dda49b1f468b 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -74,24 +74,44 @@ public: return ret; } - constexpr Vector operator-(const Vector &other) const - { - return apply(*this, other, [](T a, T b) { return a - b; }); - } - constexpr Vector operator+(const Vector &other) const { return apply(*this, other, [](T a, T b) { return a + b; }); } - constexpr Vector operator*(T factor) const + constexpr Vector operator+(T scalar) const { - return apply(*this, factor, [](T a, T b) { return a * b; }); + return apply(*this, scalar, [](T a, T b) { return a + b; }); } - constexpr Vector operator/(T factor) const + constexpr Vector operator-(const Vector &other) const { - return apply(*this, factor, [](T a, T b) { return a / b; }); + return apply(*this, other, [](T a, T b) { return a - b; }); + } + + constexpr Vector operator-(T scalar) const + { + return apply(*this, scalar, [](T a, T b) { return a - b; }); + } + + constexpr Vector operator*(const Vector &other) const + { + return apply(*this, other, [](T a, T b) { return a * b; }); + } + + constexpr Vector operator*(T scalar) const + { + return apply(*this, scalar, [](T a, T b) { return a * b; }); + } + + constexpr Vector operator/(const Vector &other) const + { + return apply(*this, other, [](T a, T b) { return a / b; }); + } + + constexpr Vector operator/(T scalar) const + { + return apply(*this, scalar, [](T a, T b) { return a / b; }); } constexpr T dot(const Vector &other) const From patchwork Sun Nov 17 22:17:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21937 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 2BBCDC32E7 for ; Sun, 17 Nov 2024 22:17:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8E4A7658C3; Sun, 17 Nov 2024 23:17:46 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="bAa1GrkL"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A688F658A4 for ; Sun, 17 Nov 2024 23:17:31 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5BB587FE for ; Sun, 17 Nov 2024 23:17:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881835; bh=QAK/S9gwY82aAY8vm9NzdTqTdsAVd/YdIyvamp2bUBM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=bAa1GrkL52i0tlo5Vs4yAlfoBWm9QAphFrmkki+PwLTNFnsS+/AHPwchvX9hgxWEd j+moclJr3mklKioG+FheQadq8tGcNikybbtNt3d5dOKPdiRru6j1v6txuUEWTTnN7O lomuXo/MLKvNzSxgwc1n5x+3YxiNIEOJP/3cTSN8= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 07/11] ipa: libipa: vector: Add compound assignment operators Date: Mon, 18 Nov 2024 00:17:08 +0200 Message-ID: <20241117221712.29616-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Extend the Vector class with compound assignment operators that match the binary arithmetic operators. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 56 ++++++++++++++++++++++++++++++++++++++ src/ipa/libipa/vector.h | 57 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index d0e38f402220..a45f08fde493 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -127,6 +127,62 @@ namespace ipa { * \return The element-wise division of this vector by \a scalar */ +/** + * \fn Vector::operator+=(Vector const &other) + * \brief Add \a other element-wise to this vector + * \param[in] other The other vector + * \return This vector + */ + +/** + * \fn Vector::operator+=(T scalar) + * \brief Add \a scalar element-wise to this vector + * \param[in] scalar The scalar + * \return This vector + */ + +/** + * \fn Vector::operator-=(Vector const &other) + * \brief Subtract \a other element-wise from this vector + * \param[in] other The other vector + * \return This vector + */ + +/** + * \fn Vector::operator-=(T scalar) + * \brief Subtract \a scalar element-wise from this vector + * \param[in] scalar The scalar + * \return This vector + */ + +/** + * \fn Vector::operator*=(const Vector &other) + * \brief Multiply this vector by \a other element-wise + * \param[in] other The other vector + * \return This vector + */ + +/** + * \fn Vector::operator*=(T scalar) + * \brief Multiply this vector by \a scalar element-wise + * \param[in] scalar The scalar + * \return This vector + */ + +/** + * \fn Vector::operator/=(const Vector &other) + * \brief Divide this vector by \a other element-wise + * \param[in] other The other vector + * \return This vector + */ + +/** + * \fn Vector::operator/=(T scalar) + * \brief Divide this vector by \a scalar element-wise + * \param[in] scalar The scalar + * \return This vector + */ + /** * \fn Vector::dot(const Vector &other) const * \brief Compute the dot product diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index dda49b1f468b..722ffc57ea45 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -114,6 +114,46 @@ public: return apply(*this, scalar, [](T a, T b) { return a / b; }); } + Vector &operator+=(const Vector &other) + { + return apply(other, [](T a, T b) { return a + b; }); + } + + Vector &operator+=(T scalar) + { + return apply(scalar, [](T a, T b) { return a + b; }); + } + + Vector &operator-=(const Vector &other) + { + return apply(other, [](T a, T b) { return a - b; }); + } + + Vector &operator-=(T scalar) + { + return apply(scalar, [](T a, T b) { return a - b; }); + } + + Vector &operator*=(const Vector &other) + { + return apply(other, [](T a, T b) { return a * b; }); + } + + Vector &operator*=(T scalar) + { + return apply(scalar, [](T a, T b) { return a * b; }); + } + + Vector &operator/=(const Vector &other) + { + return apply(other, [](T a, T b) { return a / b; }); + } + + Vector &operator/=(T scalar) + { + return apply(scalar, [](T a, T b) { return a / b; }); + } + constexpr T dot(const Vector &other) const { T ret = 0; @@ -206,6 +246,23 @@ private: return result; } + Vector &apply(const Vector &other, std::function func) + { + auto itOther = other.data_.begin(); + std::for_each(data_.begin(), data_.end(), + [&func, &itOther](T &v) { v = func(v, *itOther++); }); + + return *this; + } + + Vector &apply(T scalar, std::function func) + { + std::for_each(data_.begin(), data_.end(), + [&func, scalar](T &v) { v = func(v, scalar); }); + + return *this; + } + std::array data_; }; From patchwork Sun Nov 17 22:17:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21938 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 58B15C330B for ; Sun, 17 Nov 2024 22:17:49 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BF2EA658BE; Sun, 17 Nov 2024 23:17:48 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tLYUGWM5"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 163F7658AE for ; Sun, 17 Nov 2024 23:17:33 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AED337FE for ; Sun, 17 Nov 2024 23:17:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881836; bh=Pfvlw6UcRF4tk7shykP8t1gr7WG5Qkv7/AxCvP7briM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tLYUGWM5FbKUU5cb5CPthhBiti8pURxnjyFUcXjaGCZo9scZ81UnD80hBrT2MuTOJ sAM82yGG2zYy4d2yWEwKUrC1SQ7z1IB0XVVxZ3DqaX0e5m2A3//nXvxPY1NyCdc34m M/D2eFuwQs56Gqa+2f9d8oQkpRgniTckza2TTVxE= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 08/11] ipa: libipa: vector: Add element-wise min() and max() functions Date: Mon, 18 Nov 2024 00:17:09 +0200 Message-ID: <20241117221712.29616-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add functions to calculate the element-wise minimum and maximum of two vectors or of a vector and a scalar. This will be used in algorithm implementations. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 28 ++++++++++++++++++++++++++++ src/ipa/libipa/vector.h | 20 ++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index a45f08fde493..14816cdb5d09 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -183,6 +183,34 @@ namespace ipa { * \return This vector */ +/** + * \fn Vector::min(const Vector &other) const + * \brief Calculate the minimum of this vector and \a other element-wise + * \param[in] other The other vector + * \return The element-wise minimum of this vector and \a other + */ + +/** + * \fn Vector::min(T scalar) const + * \brief Calculate the minimum of this vector and \a scalar element-wise + * \param[in] scalar The scalar + * \return The element-wise minimum of this vector and \a scalar + */ + +/** + * \fn Vector::max(const Vector &other) const + * \brief Calculate the maximum of this vector and \a other element-wise + * \param[in] other The other vector + * \return The element-wise maximum of this vector and \a other + */ + +/** + * \fn Vector::max(T scalar) const + * \brief Calculate the maximum of this vector and \a scalar element-wise + * \param[in] scalar The scalar + * \return The element-wise maximum of this vector and \a scalar + */ + /** * \fn Vector::dot(const Vector &other) const * \brief Compute the dot product diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 722ffc57ea45..949dc4650aa4 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -154,6 +154,26 @@ public: return apply(scalar, [](T a, T b) { return a / b; }); } + constexpr Vector min(const Vector &other) const + { + return apply(*this, other, [](T a, T b) { return std::min(a, b); }); + } + + constexpr Vector min(T scalar) const + { + return apply(*this, scalar, [](T a, T b) { return std::min(a, b); }); + } + + constexpr Vector max(const Vector &other) const + { + return apply(*this, other, [](T a, T b) { return std::max(a, b); }); + } + + constexpr Vector max(T scalar) const + { + return apply(*this, scalar, [](T a, T b) -> T { return std::max(a, b); }); + } + constexpr T dot(const Vector &other) const { T ret = 0; From patchwork Sun Nov 17 22:17:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21939 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id AC06FC32DD for ; Sun, 17 Nov 2024 22:17:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 410FF658C3; Sun, 17 Nov 2024 23:17:50 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DVb2nMUc"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 679B7658B7 for ; Sun, 17 Nov 2024 23:17:34 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 16E2CA06 for ; Sun, 17 Nov 2024 23:17:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881838; bh=N4kymlvsO1kcNz1aPnJKStzldZ5qZz+nrHimPlV+m0s=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DVb2nMUcdCScR0VPpWwSNBNoeLWIvPfBJN5qiGfhghOY2CBeSShVyUHqCnnYvZrFz YP9WCHNMhvEZrVC716HmJz0PYGB76zkzfpRCB5bUWx1KL4MGLhFHmz2IbJi3OEsr9E UfyLe3rSLtP7aOFcTKea30E7nyx+Elulhvsk+fCI= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 09/11] ipa: libipa: vector: Add sum() and normalize() functions Date: Mon, 18 Nov 2024 00:17:10 +0200 Message-ID: <20241117221712.29616-10-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add functions to calculate the sum of a vector, and to normalize it. They are useful for algorithms. Signed-off-by: Laurent Pinchart --- src/ipa/libipa/vector.cpp | 17 +++++++++++++++++ src/ipa/libipa/vector.h | 12 ++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index 14816cdb5d09..0662e598c086 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -296,6 +296,23 @@ namespace ipa { * \return The length of the vector */ +/** + * \fn Vector::normalize() + * \brief Normalize the vector + */ + +/** + * \fn Vector::sum() const + * \brief Calculate the sum of all the vector elements + * \tparam R The type of the sum + * + * The type R of the sum defaults to the type T of the elements, but can be set + * explicitly to use a different type in case the type T would risk + * overflowing. + * + * \return The sum of all the vector elements + */ + /** * \fn Vector operator*(const Matrix &m, const Vector &v) * \brief Multiply a matrix by a vector diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 949dc4650aa4..b3a6412497c9 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -245,6 +246,17 @@ public: return std::sqrt(length2()); } + void normalize() + { + *this /= sum(); + } + + template + constexpr R sum() const + { + return std::accumulate(data_.begin(), data_.end(), R{}); + } + private: static constexpr Vector apply(const Vector &lhs, const Vector &rhs, std::function func) { From patchwork Sun Nov 17 22:17:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21940 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 28DFFC330C for ; Sun, 17 Nov 2024 22:17:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EE63D658AD; Sun, 17 Nov 2024 23:17:50 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="MnuV2k5S"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D2A89658B5 for ; Sun, 17 Nov 2024 23:17:35 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6C91DA06 for ; Sun, 17 Nov 2024 23:17:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881839; bh=PKv/OBTdXtT40Qv9Q5UJ+fbeiVATtaeki5ypXOwj+VQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=MnuV2k5SSM4svzALObQP3fi419u7j/i95XnkidN8PKpY50HUFh15LCBzo6NeCsUvj VljkhLGDVqnPkkqjJWzwaIA/S+WY2vJOe3xSMur6brST5oPhAw/1JT6uhgbroaRq7X LdZ7kK6na1okzRG36Ug6I2hqdEnzXce851UM41q0= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 10/11] ipa: rkisp1: awb: Use RGB class to store colour gains Date: Mon, 18 Nov 2024 00:17:11 +0200 Message-ID: <20241117221712.29616-11-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Replace the individual colour gains with instances of the RGB class. This simplifies the code that performs calculations on the gains. Signed-off-by: Laurent Pinchart --- src/ipa/rkisp1/algorithms/awb.cpp | 102 ++++++++++++------------------ src/ipa/rkisp1/algorithms/awb.h | 2 +- src/ipa/rkisp1/ipa_context.cpp | 31 +-------- src/ipa/rkisp1/ipa_context.h | 20 ++---- 4 files changed, 48 insertions(+), 107 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index b3c00bef9b7e..1c572055acdd 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -45,12 +45,8 @@ Awb::Awb() int Awb::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) { - context.activeState.awb.gains.manual.red = 1.0; - context.activeState.awb.gains.manual.blue = 1.0; - context.activeState.awb.gains.manual.green = 1.0; - context.activeState.awb.gains.automatic.red = 1.0; - context.activeState.awb.gains.automatic.blue = 1.0; - context.activeState.awb.gains.automatic.green = 1.0; + context.activeState.awb.gains.manual = RGB({ 1.0, 1.0, 1.0 }); + context.activeState.awb.gains.automatic = RGB({ 1.0, 1.0, 1.0 }); context.activeState.awb.autoEnabled = true; /* @@ -87,21 +83,17 @@ void Awb::queueRequest(IPAContext &context, const auto &colourGains = controls.get(controls::ColourGains); if (colourGains && !awb.autoEnabled) { - awb.gains.manual.red = (*colourGains)[0]; - awb.gains.manual.blue = (*colourGains)[1]; + awb.gains.manual.r() = (*colourGains)[0]; + awb.gains.manual.b() = (*colourGains)[1]; LOG(RkISP1Awb, Debug) - << "Set colour gains to red: " << awb.gains.manual.red - << ", blue: " << awb.gains.manual.blue; + << "Set colour gains to " << awb.gains.manual; } frameContext.awb.autoEnabled = awb.autoEnabled; - if (!awb.autoEnabled) { - frameContext.awb.gains.red = awb.gains.manual.red; - frameContext.awb.gains.green = 1.0; - frameContext.awb.gains.blue = awb.gains.manual.blue; - } + if (!awb.autoEnabled) + frameContext.awb.gains = awb.gains.manual; } /** @@ -114,19 +106,16 @@ void Awb::prepare(IPAContext &context, const uint32_t frame, * This is the latest time we can read the active state. This is the * most up-to-date automatic values we can read. */ - if (frameContext.awb.autoEnabled) { - frameContext.awb.gains.red = context.activeState.awb.gains.automatic.red; - frameContext.awb.gains.green = context.activeState.awb.gains.automatic.green; - frameContext.awb.gains.blue = context.activeState.awb.gains.automatic.blue; - } + if (frameContext.awb.autoEnabled) + frameContext.awb.gains = context.activeState.awb.gains.automatic; auto gainConfig = params->block(); gainConfig.setEnabled(true); - gainConfig->gain_green_b = std::clamp(256 * frameContext.awb.gains.green, 0, 0x3ff); - gainConfig->gain_blue = std::clamp(256 * frameContext.awb.gains.blue, 0, 0x3ff); - gainConfig->gain_red = std::clamp(256 * frameContext.awb.gains.red, 0, 0x3ff); - gainConfig->gain_green_r = std::clamp(256 * frameContext.awb.gains.green, 0, 0x3ff); + gainConfig->gain_green_b = std::clamp(256 * frameContext.awb.gains.g(), 0, 0x3ff); + gainConfig->gain_blue = std::clamp(256 * frameContext.awb.gains.b(), 0, 0x3ff); + gainConfig->gain_red = std::clamp(256 * frameContext.awb.gains.r(), 0, 0x3ff); + gainConfig->gain_green_r = std::clamp(256 * frameContext.awb.gains.g(), 0, 0x3ff); /* If we have already set the AWB measurement parameters, return. */ if (frame > 0) @@ -178,12 +167,12 @@ void Awb::prepare(IPAContext &context, const uint32_t frame, } } -uint32_t Awb::estimateCCT(double red, double green, double blue) +uint32_t Awb::estimateCCT(const RGB &rgb) { /* Convert the RGB values to CIE tristimulus values (XYZ) */ - double X = (-0.14282) * (red) + (1.54924) * (green) + (-0.95641) * (blue); - double Y = (-0.32466) * (red) + (1.57837) * (green) + (-0.73191) * (blue); - double Z = (-0.68202) * (red) + (0.77073) * (green) + (0.56332) * (blue); + double X = -0.14282 * rgb.r() + 1.54924 * rgb.g() - 0.95641 * rgb.b(); + double Y = -0.32466 * rgb.r() + 1.57837 * rgb.g() - 0.73191 * rgb.b(); + double Z = -0.68202 * rgb.r() + 0.77073 * rgb.g() + 0.56332 * rgb.b(); /* Calculate the normalized chromaticity values */ double x = X / (X + Y + Z); @@ -206,14 +195,12 @@ void Awb::process(IPAContext &context, const rkisp1_cif_isp_stat *params = &stats->params; const rkisp1_cif_isp_awb_stat *awb = ¶ms->awb; IPAActiveState &activeState = context.activeState; - double greenMean; - double redMean; - double blueMean; + RGB rgbMeans; metadata.set(controls::AwbEnable, frameContext.awb.autoEnabled); metadata.set(controls::ColourGains, { - static_cast(frameContext.awb.gains.red), - static_cast(frameContext.awb.gains.blue) + static_cast(frameContext.awb.gains.r()), + static_cast(frameContext.awb.gains.b()) }); metadata.set(controls::ColourTemperature, activeState.awb.temperatureK); @@ -223,9 +210,9 @@ void Awb::process(IPAContext &context, } if (rgbMode_) { - greenMean = awb->awb_mean[0].mean_y_or_g; - redMean = awb->awb_mean[0].mean_cr_or_r; - blueMean = awb->awb_mean[0].mean_cb_or_b; + rgbMeans.r() = awb->awb_mean[0].mean_cr_or_r; + rgbMeans.g() = awb->awb_mean[0].mean_y_or_g; + rgbMeans.b() = awb->awb_mean[0].mean_cb_or_b; } else { /* Get the YCbCr mean values */ double yMean = awb->awb_mean[0].mean_y_or_g; @@ -247,9 +234,9 @@ void Awb::process(IPAContext &context, yMean -= 16; cbMean -= 128; crMean -= 128; - redMean = 1.1636 * yMean - 0.0623 * cbMean + 1.6008 * crMean; - greenMean = 1.1636 * yMean - 0.4045 * cbMean - 0.7949 * crMean; - blueMean = 1.1636 * yMean + 1.9912 * cbMean - 0.0250 * crMean; + rgbMeans.r() = 1.1636 * yMean - 0.0623 * cbMean + 1.6008 * crMean; + rgbMeans.g() = 1.1636 * yMean - 0.4045 * cbMean - 0.7949 * crMean; + rgbMeans.b() = 1.1636 * yMean + 1.9912 * cbMean - 0.0250 * crMean; /* * Due to hardware rounding errors in the YCbCr means, the @@ -257,9 +244,7 @@ void Awb::process(IPAContext &context, * negative gains, messing up calculation. Prevent this by * clamping the means to positive values. */ - redMean = std::max(redMean, 0.0); - greenMean = std::max(greenMean, 0.0); - blueMean = std::max(blueMean, 0.0); + rgbMeans = rgbMeans.max(0.0); } /* @@ -267,19 +252,17 @@ void Awb::process(IPAContext &context, * divide by the gains that were used to get the raw means from the * sensor. */ - redMean /= frameContext.awb.gains.red; - greenMean /= frameContext.awb.gains.green; - blueMean /= frameContext.awb.gains.blue; + rgbMeans /= frameContext.awb.gains; /* * If the means are too small we don't have enough information to * meaningfully calculate gains. Freeze the algorithm in that case. */ - if (redMean < kMeanMinThreshold && greenMean < kMeanMinThreshold && - blueMean < kMeanMinThreshold) + if (rgbMeans.r() < kMeanMinThreshold && rgbMeans.g() < kMeanMinThreshold && + rgbMeans.b() < kMeanMinThreshold) return; - activeState.awb.temperatureK = estimateCCT(redMean, greenMean, blueMean); + activeState.awb.temperatureK = estimateCCT(rgbMeans); /* Metadata shall contain the up to date measurement */ metadata.set(controls::ColourTemperature, activeState.awb.temperatureK); @@ -289,8 +272,11 @@ void Awb::process(IPAContext &context, * gain is hardcoded to 1.0. Avoid divisions by zero by clamping the * divisor to a minimum value of 1.0. */ - double redGain = greenMean / std::max(redMean, 1.0); - double blueGain = greenMean / std::max(blueMean, 1.0); + RGB gains({ + rgbMeans.g() / std::max(rgbMeans.r(), 1.0), + 1.0, + rgbMeans.g() / std::max(rgbMeans.b(), 1.0) + }); /* * Clamp the gain values to the hardware, which expresses gains as Q2.8 @@ -298,24 +284,18 @@ void Awb::process(IPAContext &context, * divisions by zero when computing the raw means in subsequent * iterations. */ - redGain = std::clamp(redGain, 1.0 / 256, 1023.0 / 256); - blueGain = std::clamp(blueGain, 1.0 / 256, 1023.0 / 256); + gains = gains.max(1.0 / 256).min(1023.0 / 256); /* Filter the values to avoid oscillations. */ double speed = 0.2; - redGain = speed * redGain + (1 - speed) * activeState.awb.gains.automatic.red; - blueGain = speed * blueGain + (1 - speed) * activeState.awb.gains.automatic.blue; + gains = gains * speed + activeState.awb.gains.automatic * (1 - speed); - activeState.awb.gains.automatic.red = redGain; - activeState.awb.gains.automatic.blue = blueGain; - activeState.awb.gains.automatic.green = 1.0; + activeState.awb.gains.automatic = gains; LOG(RkISP1Awb, Debug) << std::showpoint - << "Means [" << redMean << ", " << greenMean << ", " << blueMean - << "], gains [" << activeState.awb.gains.automatic.red << ", " - << activeState.awb.gains.automatic.green << ", " - << activeState.awb.gains.automatic.blue << "], temp " + << "Means " << rgbMeans << ", gains " + << activeState.awb.gains.automatic << ", temp " << activeState.awb.temperatureK << "K"; } diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h index b3b2c0bbb9ae..058c0fc53490 100644 --- a/src/ipa/rkisp1/algorithms/awb.h +++ b/src/ipa/rkisp1/algorithms/awb.h @@ -32,7 +32,7 @@ public: ControlList &metadata) override; private: - uint32_t estimateCCT(double red, double green, double blue); + uint32_t estimateCCT(const RGB &rgb); bool rgbMode_; }; diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 14d0c02a2b32..8f545cd76d52 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -188,30 +188,12 @@ namespace libcamera::ipa::rkisp1 { * \struct IPAActiveState::awb.gains * \brief White balance gains * - * \struct IPAActiveState::awb.gains.manual + * \var IPAActiveState::awb.gains.manual * \brief Manual white balance gains (set through requests) * - * \var IPAActiveState::awb.gains.manual.red - * \brief Manual white balance gain for R channel - * - * \var IPAActiveState::awb.gains.manual.green - * \brief Manual white balance gain for G channel - * - * \var IPAActiveState::awb.gains.manual.blue - * \brief Manual white balance gain for B channel - * - * \struct IPAActiveState::awb.gains.automatic + * \var IPAActiveState::awb.gains.automatic * \brief Automatic white balance gains (computed by the algorithm) * - * \var IPAActiveState::awb.gains.automatic.red - * \brief Automatic white balance gain for R channel - * - * \var IPAActiveState::awb.gains.automatic.green - * \brief Automatic white balance gain for G channel - * - * \var IPAActiveState::awb.gains.automatic.blue - * \brief Automatic white balance gain for B channel - * * \var IPAActiveState::awb.temperatureK * \brief Estimated color temperature * @@ -333,15 +315,6 @@ namespace libcamera::ipa::rkisp1 { * \struct IPAFrameContext::awb.gains * \brief White balance gains * - * \var IPAFrameContext::awb.gains.red - * \brief White balance gain for R channel - * - * \var IPAFrameContext::awb.gains.green - * \brief White balance gain for G channel - * - * \var IPAFrameContext::awb.gains.blue - * \brief White balance gain for B channel - * * \var IPAFrameContext::awb.temperatureK * \brief Estimated color temperature * diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 7b93a9e9461d..b4dec0c3288d 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace libcamera { @@ -87,16 +88,8 @@ struct IPAActiveState { struct { struct { - struct { - double red; - double green; - double blue; - } manual; - struct { - double red; - double green; - double blue; - } automatic; + RGB manual; + RGB automatic; } gains; unsigned int temperatureK; @@ -140,12 +133,7 @@ struct IPAFrameContext : public FrameContext { } agc; struct { - struct { - double red; - double green; - double blue; - } gains; - + RGB gains; bool autoEnabled; } awb; From patchwork Sun Nov 17 22:17:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21941 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id B2606C330D for ; Sun, 17 Nov 2024 22:17:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EE294658BE; Sun, 17 Nov 2024 23:17:51 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="apKS5xEk"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1A631658B6 for ; Sun, 17 Nov 2024 23:17:37 +0100 (CET) Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BE0FF7FE for ; Sun, 17 Nov 2024 23:17:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731881840; bh=gY1N0wr/j2OIR5CqPCYhbeXK/zUwOmhaUddN+9jd/fw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=apKS5xEkFDjsAKIZY2WQTCKyAkl3MSiZU1mBGnM9A/SMVMkhF2nyOmA4vNGDcIyYp P/5qPVeopxoMcerP4GFW7qU1tdYs3HdlHmCP31x2rOjfHdXmgOWpuk04LKYlNdh6KX 0MyWc2mLTRGL6prtbREC6aWjLu+w+qGJ8cMiAHnU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH 11/11] ipa: rkisp1: awb: Replace manual calculations with Vector and Matrix Date: Mon, 18 Nov 2024 00:17:12 +0200 Message-ID: <20241117221712.29616-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> References: <20241117221712.29616-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Processing of the statistics and estimation of the colour temperature involve linear algebra. Replace the manual calculations with usage of the Vector and Matrix classes. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/ipa/rkisp1/algorithms/awb.cpp | 44 +++++++++++++++++++------------ 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index 1c572055acdd..c089523c8bde 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -169,17 +169,21 @@ void Awb::prepare(IPAContext &context, const uint32_t frame, uint32_t Awb::estimateCCT(const RGB &rgb) { - /* Convert the RGB values to CIE tristimulus values (XYZ) */ - double X = -0.14282 * rgb.r() + 1.54924 * rgb.g() - 0.95641 * rgb.b(); - double Y = -0.32466 * rgb.r() + 1.57837 * rgb.g() - 0.73191 * rgb.b(); - double Z = -0.68202 * rgb.r() + 0.77073 * rgb.g() + 0.56332 * rgb.b(); + /* + * Convert the RGB values to CIE tristimulus values (XYZ) and normalize + * it (xyz). + */ + static const Matrix rgb2xyz({ + -0.14282, 1.54924, -0.95641, + -0.32466, 1.57837, -0.73191, + -0.68202, 0.77073, 0.56332 + }); - /* Calculate the normalized chromaticity values */ - double x = X / (X + Y + Z); - double y = Y / (X + Y + Z); + Vector xyz = rgb2xyz * rgb; + xyz.normalize(); /* Calculate CCT */ - double n = (x - 0.3320) / (0.1858 - y); + double n = (xyz.x() - 0.3320) / (0.1858 - xyz.y()); return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33; } @@ -215,9 +219,11 @@ void Awb::process(IPAContext &context, rgbMeans.b() = awb->awb_mean[0].mean_cb_or_b; } else { /* Get the YCbCr mean values */ - double yMean = awb->awb_mean[0].mean_y_or_g; - double cbMean = awb->awb_mean[0].mean_cb_or_b; - double crMean = awb->awb_mean[0].mean_cr_or_r; + Vector yuvMeans({ + static_cast(awb->awb_mean[0].mean_y_or_g), + static_cast(awb->awb_mean[0].mean_cb_or_b), + static_cast(awb->awb_mean[0].mean_cr_or_r) + }); /* * Convert from YCbCr to RGB. @@ -231,12 +237,16 @@ void Awb::process(IPAContext &context, * [1,1636, -0,4045, -0,7949] * [1,1636, 1,9912, -0,0250]] */ - yMean -= 16; - cbMean -= 128; - crMean -= 128; - rgbMeans.r() = 1.1636 * yMean - 0.0623 * cbMean + 1.6008 * crMean; - rgbMeans.g() = 1.1636 * yMean - 0.4045 * cbMean - 0.7949 * crMean; - rgbMeans.b() = 1.1636 * yMean + 1.9912 * cbMean - 0.0250 * crMean; + static const Matrix yuv2rgbMatrix({ + 1.1636, -0.0623, 1.6008, + 1.1636, -0.4045, -0.7949, + 1.1636, 1.9912, -0.0250 + }); + static const Vector yuv2rgbOffset({ + 16, 128, 128 + }); + + rgbMeans = yuv2rgbMatrix * (yuvMeans - yuv2rgbOffset); /* * Due to hardware rounding errors in the YCbCr means, the