From patchwork Mon Nov 18 00:07:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21943 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 B352CC32E7 for ; Mon, 18 Nov 2024 00:07:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3E918658B5; Mon, 18 Nov 2024 01:07:52 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TafKuuuA"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 149226589E for ; Mon, 18 Nov 2024 01:07:49 +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 AFBC175A for ; Mon, 18 Nov 2024 01:07:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888452; bh=qxpBipRmyMvboc8aU50grYWOIz4VLb9CxNU46MGgyyw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TafKuuuApVvsIpS0DyzsQIWdGd1El7TZ4yxiWwKra4MYPRG5ofqwfIt65rVUeYeAD rVIFUlHEBeyVNC7jYwGR42vu2+PtRo/HbQFJKDagOAQ35xIxyjJem5AbxFALF4rFQD FiEqIYszmcK/r6baVXnaii2YpcT5FMaGEIiNZ3g0= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 01/12] ipa: libipa: vector: Add mutable x(), y() and z() accessors Date: Mon, 18 Nov 2024 02:07:27 +0200 Message-ID: <20241118000738.18977-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21944 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 E2E59C32E0 for ; Mon, 18 Nov 2024 00:07:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 64EE4658BA; Mon, 18 Nov 2024 01:07:54 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZJbk3X/O"; 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 DB369600F2 for ; Mon, 18 Nov 2024 01:07:50 +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 0A19775A for ; Mon, 18 Nov 2024 01:07:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888454; bh=bQ7ZbcMrSrv8caa5LEKyJWsdOzVNQkrKgUatyJjxc4E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZJbk3X/OpPRYhyUdraFvWeJlSFCrhTapQKRGscLXFrlRCS9vs1cnOLexgBvr297/6 7MRXz6mXrpIwYEz1jXQX4v9A/zGbDw6riPUfyy9rJiGV3d8NAEAkDe9duICqQ08tV7 peFUXmRNhh2icfuyuf+WGFZGLgWzh7Qa3hQ/9DKo= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 02/12] ipa: libipa: vector: Add r(), g() and b() accessors Date: Mon, 18 Nov 2024 02:07:28 +0200 Message-ID: <20241118000738.18977-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21945 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 3E2F1C32EF for ; Mon, 18 Nov 2024 00:07:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9664E658B5; Mon, 18 Nov 2024 01:07:56 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="M4nLx1Ky"; 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 BD32F658B3 for ; Mon, 18 Nov 2024 01:07:51 +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 5BB2175A for ; Mon, 18 Nov 2024 01:07:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888455; bh=u9dR8L8pQLloFRR66pjmoAU0G54ZdDGmseZUGeLoWa4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=M4nLx1Ky7QiL8RF7IrPx5/46Tzg+lRIIt3q0aj3FQOXhA/Bz2Iao5/1o3zEBOJU2K UkVBvp5YJcV/8Ek/T4wl1LDpKTtJi21/iq4sPL9PA9Z3r2x2d9AtRbb3C+AoF4fH9z txIepTwUxzgPeHNwRR6ldQhQr5UzTeZ+OJmMOdTw= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 03/12] ipa: libipa: vector: Add copy constructor and assignment operator Date: Mon, 18 Nov 2024 02:07:29 +0200 Message-ID: <20241118000738.18977-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21946 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 885E6C32E7 for ; Mon, 18 Nov 2024 00:07:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F3D32658C2; Mon, 18 Nov 2024 01:07:57 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="J0MlWB+7"; 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 27C62658B7 for ; Mon, 18 Nov 2024 01:07:53 +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 BB73E8DB for ; Mon, 18 Nov 2024 01:07:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888456; bh=zj0U/HE1hEYjvElrAo1U+PSICzRsAqaxIBvUOT/Ccpk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=J0MlWB+7rmbqI/AxuNgpDg+1WkfyQhuqp8c5nM6C1+1p+cZohDmqLC+UrfDDHjV7c z6wb62x99e9CrrCAns1u3Ws0aiQiKvP6h4tIXLg5JWNWPIxV3dFRjjPNyWHO62TIBb hbiFQJsyoENw3LBiODzRR/kG+uB39eV3xARu+z3I= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 04/12] ipa: libipa: vector: Rename the dot product operator*() to dot() Date: Mon, 18 Nov 2024 02:07:30 +0200 Message-ID: <20241118000738.18977-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21947 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 E4453C330B for ; Mon, 18 Nov 2024 00:08:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D4B02658B9; Mon, 18 Nov 2024 01:07:59 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vmHVbqXx"; 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 70BE8658BB for ; Mon, 18 Nov 2024 01:07:54 +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 1A30075A for ; Mon, 18 Nov 2024 01:07:38 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888458; bh=gU/DViUqdbRwz7vQMTvWxLxbGsGYNHcOZNJfvv/FUr0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=vmHVbqXxMMkg2Yt9frForW9Sp8gKI+2ZynZqoacCQ0t1Fc1N99rnVGE8OAoq0/NZS HID5U9jFRP9qY8mkWDE02wie5ueqrxNgDEDB2qIfjX2EqwYRkiythaxR7Jdvu8HlUy +BjqaMIjdtgMLNobLGkgipgWvKn8nkCnO32cFjD4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 05/12] ipa: libipa: vector: Generalize arithmetic operators Date: Mon, 18 Nov 2024 02:07:31 +0200 Message-ID: <20241118000738.18977-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21948 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 83BDAC32E0 for ; Mon, 18 Nov 2024 00:08:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 22893658CC; Mon, 18 Nov 2024 01:08:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="J2GKnrlC"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D0B84658B0 for ; Mon, 18 Nov 2024 01:07:55 +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 6C07575A for ; Mon, 18 Nov 2024 01:07:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888459; bh=9MiINevDfChBdv5qVOrHFrk3D/8r4l9JnlU7vz9WSx8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=J2GKnrlCkXwA/1iScAHrIOoj3VkhSLPgGQf/JM03yUl/S1/1oXBjxdJsR0zCJYbWN v89Cz+yRDfbrC44QJg0G9gtBSEQeQcJ2yxKXDEC5+zyGjkvQVtRbHcRuEWUyOpE+Yz XdsOsF2bvssqAsH5+L++aYLPpnRlDiS6WS16g+W0= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 06/12] ipa: libipa: vector: Add missing binary arithemtic operators Date: Mon, 18 Nov 2024 02:07:32 +0200 Message-ID: <20241118000738.18977-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Mon Nov 18 00:07:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21949 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 1DFE6C32EF for ; Mon, 18 Nov 2024 00:08:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C0A09658CF; Mon, 18 Nov 2024 01:08:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="j0hvTAcs"; 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 38795658C1 for ; Mon, 18 Nov 2024 01:07:57 +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 CDC5875A for ; Mon, 18 Nov 2024 01:07:40 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888461; bh=QAK/S9gwY82aAY8vm9NzdTqTdsAVd/YdIyvamp2bUBM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=j0hvTAcsNeqYFQL8BYQPoO82KszA2fDzth1ffgSAdS0JJG2+ZRdoX2eCUYKFoALTc fkrz3vClAzrd8l2brc7lcQU3kRn+xOi5WDprZ0CuWneiC8TM8NVeNhgcFYoVyQ54G7 SKH6OpOoVxZGAekDfv2GsKOvxqWOT2+KFgSUAUqY= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 07/12] ipa: libipa: vector: Add compound assignment operators Date: Mon, 18 Nov 2024 02:07:33 +0200 Message-ID: <20241118000738.18977-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21950 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 0BB21C32E7 for ; Mon, 18 Nov 2024 00:08:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 421EA658C2; Mon, 18 Nov 2024 01:08:08 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="rx4wVH3t"; 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 A1DFF658BA for ; Mon, 18 Nov 2024 01:07:58 +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 3410975A for ; Mon, 18 Nov 2024 01:07:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888462; bh=Pfvlw6UcRF4tk7shykP8t1gr7WG5Qkv7/AxCvP7briM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=rx4wVH3tRht1/cidIuNdpfMmgrc6J8i0hJ6MbrKBvIwlCL59kK4mccq82KtqJFjb1 fOnraPO5VqLY5fGOcBL5uYx+0ks+iMevrq/3IX2PU8+IQlL2dtkBSgWBfeguvJrbkp N86sdb4BEnULtWDFhfBNoEl0YjaPnnqZl78x5zfo= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 08/12] ipa: libipa: vector: Add element-wise min() and max() functions Date: Mon, 18 Nov 2024 02:07:34 +0200 Message-ID: <20241118000738.18977-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21951 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 D29D1C330B for ; Mon, 18 Nov 2024 00:08:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 64C4E658C1; Mon, 18 Nov 2024 01:08:10 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="oSkgGAHp"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F0778658C6 for ; Mon, 18 Nov 2024 01:07:59 +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 8F9D175A for ; Mon, 18 Nov 2024 01:07:43 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888463; bh=PGoQEH+1X1HTjT+lRIMi/goS/WUSGf7J50N8gAibs00=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oSkgGAHpc2Zy7yjIs5UPl8BNwwDn4r9EBwDVErD0ebvlZW0fpP44CUj9CMZCHvf4x ePoECn+d7+2H7UMWqK6kxGok3jLtHtk6XVtkg8XHsSAA9K7cpZzC4xOOmUcy0OIceL +W1ZUa9Y9zAI7w+MeOJQ8i/kqDChSSOjua6OXdCQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 09/12] ipa: libipa: vector: Add sum() function Date: Mon, 18 Nov 2024 02:07:35 +0200 Message-ID: <20241118000738.18977-10-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 a function to calculate the sum of a vector. It will be useful for algorithms. Signed-off-by: Laurent Pinchart Reviewed-by: Milan Zamazal --- Changes since v1: - Drop Vector::normalize() --- src/ipa/libipa/vector.cpp | 12 ++++++++++++ src/ipa/libipa/vector.h | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/src/ipa/libipa/vector.cpp b/src/ipa/libipa/vector.cpp index 14816cdb5d09..19e7537f8a5a 100644 --- a/src/ipa/libipa/vector.cpp +++ b/src/ipa/libipa/vector.cpp @@ -296,6 +296,18 @@ namespace ipa { * \return The length of 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..f55da6476103 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,12 @@ public: return std::sqrt(length2()); } + 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 Mon Nov 18 00:07:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21952 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 5819DC330C for ; Mon, 18 Nov 2024 00:08:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C95E6658D1; Mon, 18 Nov 2024 01:08:11 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="R59YQNtH"; 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 4FAAD658C4 for ; Mon, 18 Nov 2024 01:08:01 +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 E1B4475A for ; Mon, 18 Nov 2024 01:07:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888465; bh=Fz5XuItvBL9UaaL2/Ecb7EvHBPgaedj8P1I2/bjEyhs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=R59YQNtHJZuhijmukbw1j5wQeTrV1o5FClOd3r8fKfQAET80V94MehbrWfMc7l7XB jMQ6Vf/s7mHqy8Uvt8GuzZxTXa/WjKg9ANIXBY94y1rW1hRhkJRFe+9Sg/wsfvtB9w TQnecErEcHpceUPUag8BXulPK2HkVsA6Br1ZSpO4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 10/12] test: libipa: Add Vector class test Date: Mon, 18 Nov 2024 02:07:36 +0200 Message-ID: <20241118000738.18977-11-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 a unit test to exercize the API of the ipa::Vector class. The test binary being called 'vector', implicit includes cause the binary to be picked by '#include ', causing builds to fail. Set implicit_include_directories to false to avoid this, as done in commit 6cd849125888 ("test: Don't add current build directory to include path"). Signed-off-by: Laurent Pinchart --- test/ipa/libipa/meson.build | 2 + test/ipa/libipa/vector.cpp | 100 ++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 test/ipa/libipa/vector.cpp diff --git a/test/ipa/libipa/meson.build b/test/ipa/libipa/meson.build index 4d2427dbd4e7..f9b3c46d000f 100644 --- a/test/ipa/libipa/meson.build +++ b/test/ipa/libipa/meson.build @@ -2,11 +2,13 @@ libipa_test = [ {'name': 'interpolator', 'sources': ['interpolator.cpp']}, + {'name': 'vector', 'sources': ['vector.cpp']}, ] foreach test : libipa_test exe = executable(test['name'], test['sources'], dependencies : [libcamera_private, libipa_dep], + implicit_include_directories : false, link_with : [test_libraries], include_directories : [test_includes_internal, '../../../src/ipa/libipa/']) diff --git a/test/ipa/libipa/vector.cpp b/test/ipa/libipa/vector.cpp new file mode 100644 index 000000000000..5279bc8216b3 --- /dev/null +++ b/test/ipa/libipa/vector.cpp @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024, Ideas on Board Oy + * + * Vector tests + */ + +#include "../src/ipa/libipa/vector.h" + +#include +#include + +#include "test.h" + +using namespace libcamera::ipa; + +#define ASSERT_EQ(a, b) \ +if ((a) != (b)) { \ + std::cout << #a " != " #b << " (line " << __LINE__ << ")" \ + << std::endl; \ + return TestFail; \ +} + +class VectorTest : public Test +{ +protected: + int run() + { + Vector v1; + + ASSERT_EQ(v1[0], 0.0); + ASSERT_EQ(v1[1], 0.0); + ASSERT_EQ(v1[2], 0.0); + + ASSERT_EQ(v1.length(), 0.0); + ASSERT_EQ(v1.length2(), 0.0); + + Vector v2{{ 1.0, 4.0, 8.0 }}; + + ASSERT_EQ(v2[0], 1.0); + ASSERT_EQ(v2[1], 4.0); + ASSERT_EQ(v2[2], 8.0); + + ASSERT_EQ(v2.x(), 1.0); + ASSERT_EQ(v2.y(), 4.0); + ASSERT_EQ(v2.z(), 8.0); + + ASSERT_EQ(v2.r(), 1.0); + ASSERT_EQ(v2.g(), 4.0); + ASSERT_EQ(v2.b(), 8.0); + + ASSERT_EQ(v2.length2(), 81.0); + ASSERT_EQ(v2.length(), 9.0); + ASSERT_EQ(v2.sum(), 13.0); + + Vector v3{ v2 }; + + ASSERT_EQ(v2, v3); + + v3 = Vector{{ 4.0, 4.0, 4.0 }}; + + ASSERT_EQ(v2 + v3, (Vector{{ 5.0, 8.0, 12.0 }})); + ASSERT_EQ(v2 + 4.0, (Vector{{ 5.0, 8.0, 12.0 }})); + ASSERT_EQ(v2 - v3, (Vector{{ -3.0, 0.0, 4.0 }})); + ASSERT_EQ(v2 - 4.0, (Vector{{ -3.0, 0.0, 4.0 }})); + ASSERT_EQ(v2 * v3, (Vector{{ 4.0, 16.0, 32.0 }})); + ASSERT_EQ(v2 * 4.0, (Vector{{ 4.0, 16.0, 32.0 }})); + ASSERT_EQ(v2 / v3, (Vector{{ 0.25, 1.0, 2.0 }})); + ASSERT_EQ(v2 / 4.0, (Vector{{ 0.25, 1.0, 2.0 }})); + + ASSERT_EQ(v2.min(v3), (Vector{{ 1.0, 4.0, 4.0 }})); + ASSERT_EQ(v2.min(4.0), (Vector{{ 1.0, 4.0, 4.0 }})); + ASSERT_EQ(v2.max(v3), (Vector{{ 4.0, 4.0, 8.0 }})); + ASSERT_EQ(v2.max(4.0), (Vector{{ 4.0, 4.0, 8.0 }})); + + ASSERT_EQ(v2.dot(v3), 52.0); + + v2 += v3; + ASSERT_EQ(v2, (Vector{{ 5.0, 8.0, 12.0 }})); + v2 -= v3; + ASSERT_EQ(v2, (Vector{{ 1.0, 4.0, 8.0 }})); + v2 *= v3; + ASSERT_EQ(v2, (Vector{{ 4.0, 16.0, 32.0 }})); + v2 /= v3; + ASSERT_EQ(v2, (Vector{{ 1.0, 4.0, 8.0 }})); + + v2 += 4.0; + ASSERT_EQ(v2, (Vector{{ 5.0, 8.0, 12.0 }})); + v2 -= 4.0; + ASSERT_EQ(v2, (Vector{{ 1.0, 4.0, 8.0 }})); + v2 *= 4.0; + ASSERT_EQ(v2, (Vector{{ 4.0, 16.0, 32.0 }})); + v2 /= 4.0; + ASSERT_EQ(v2, (Vector{{ 1.0, 4.0, 8.0 }})); + + return TestPass; + } +}; + +TEST_REGISTER(VectorTest) From patchwork Mon Nov 18 00:07:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21953 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 45679C32E0 for ; Mon, 18 Nov 2024 00:08:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8D346658D6; Mon, 18 Nov 2024 01:08:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="u1NQO/oH"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 966DE658B9 for ; Mon, 18 Nov 2024 01:08:02 +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 49ACC75A for ; Mon, 18 Nov 2024 01:07:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888466; bh=PKv/OBTdXtT40Qv9Q5UJ+fbeiVATtaeki5ypXOwj+VQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=u1NQO/oHLWUf3CUVK0UrsrZAhl9MGldXum6MDDLi/LA0ReXYr3z/842EbLIb7du6c b/xOXfZ8OsuzSofu5n2HsKAAAbgHVeWQAcRo7yV6LAvVyD7X3fS/k3rGJf43/9OA+I TngRodjJzk6QSkPuz/ZYsY9TtXgCJe7T9e6Nv5Oo= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 11/12] ipa: rkisp1: awb: Use RGB class to store colour gains Date: Mon, 18 Nov 2024 02:07:37 +0200 Message-ID: <20241118000738.18977-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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 Reviewed-by: Milan Zamazal --- 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 Mon Nov 18 00:07:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 21954 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 8178FC330D for ; Mon, 18 Nov 2024 00:08:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E3784658C6; Mon, 18 Nov 2024 01:08:14 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="EaKr/AZl"; 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 E9895658C9 for ; Mon, 18 Nov 2024 01:08:03 +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 8BBA775A for ; Mon, 18 Nov 2024 01:07:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1731888467; bh=WCWQ1ytFDfwIUcJc4NNhZUm+kRukHTBU/uqKoqO54G4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=EaKr/AZlG+h5wuDhrhPNqBfnaGQ+w0KLdWgCaLTYRCTMS5tTFz8bxyiUzBQY0ZVLJ V6uelKE70j1l7fGEeGsSqTiJCVDIu0eMXwpzNjJPqFoAaR9PgbATrSSe1tWztrXO61 z7b9CkpPNs3E7X1fVjUk5mtiSoKg74tsKWwE8RIs= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v2 12/12] ipa: rkisp1: awb: Replace manual calculations with Vector and Matrix Date: Mon, 18 Nov 2024 02:07:38 +0200 Message-ID: <20241118000738.18977-13-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241118000738.18977-1-laurent.pinchart@ideasonboard.com> References: <20241118000738.18977-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: Milan Zamazal --- Changes since v1: - Adapt to Vector::normalize() being dropped --- 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..97163e0fa45c 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 divide by + * the sum of X, Y and Z to calculate the CIE xy chromaticity. + */ + 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 /= xyz.sum(); /* 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