From patchwork Wed Nov 20 14:27:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22032 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 5D28EC32F8 for ; Wed, 20 Nov 2024 14:28:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F2C4065F54; Wed, 20 Nov 2024 15:28:18 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Y/kXjDdv"; 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 8A68D65F5D for ; Wed, 20 Nov 2024 15:28:16 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 46EA755A; Wed, 20 Nov 2024 15:27:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112878; bh=JvEJqHgV6z9onV0xiUtVoyTE4vTvVwX4RRPlM7hask4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y/kXjDdvL8zcE7/zhLs8/iOdTMUWKITfsDz1HqHeWHbg6uSbkuTCjOe2cAXEF09DV mOcCInQ4wWNzfexzXVR4O6NNVAYJUrDHHxV6Q1YaJ6F9AOJbdH8FivZhEqyBUp/fVJ aNm3hl1xMb6RVS7SYliooVV4rLGbFlU1JDlwH5T8= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 1/9] ipa: rpi: Rename Matrix to Matrix3x3 Date: Wed, 20 Nov 2024 15:27:48 +0100 Message-ID: <20241120142807.2093301-2-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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 upcoming patches will introduce a Matrix class into libcamera/internal. That name clashes with the Matrix class from the RaspberryPi ccm implementation. Rename the rpi version to Matrix3x3 to prevent the name clash. Matrix3x3 will be replaced by the generic implementation later. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- Changes in v3: - Collect tags - Fixed typo in commit msg --- src/ipa/rpi/controller/rpi/ccm.cpp | 18 +++++++++--------- src/ipa/rpi/controller/rpi/ccm.h | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp index aefa580c9a4b..7f63f3fdb702 100644 --- a/src/ipa/rpi/controller/rpi/ccm.cpp +++ b/src/ipa/rpi/controller/rpi/ccm.cpp @@ -29,17 +29,17 @@ LOG_DEFINE_CATEGORY(RPiCcm) #define NAME "rpi.ccm" -Matrix::Matrix() +Matrix3x3::Matrix3x3() { memset(m, 0, sizeof(m)); } -Matrix::Matrix(double m0, double m1, double m2, double m3, double m4, double m5, +Matrix3x3::Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5, double m6, double m7, double m8) { m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] = m4, m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8; } -int Matrix::read(const libcamera::YamlObject ¶ms) +int Matrix3x3::read(const libcamera::YamlObject ¶ms) { double *ptr = (double *)m; @@ -125,7 +125,7 @@ bool getLocked(Metadata *metadata, std::string const &tag, T &value) return true; } -Matrix calculateCcm(std::vector const &ccms, double ct) +Matrix3x3 calculateCcm(std::vector const &ccms, double ct) { if (ct <= ccms.front().ct) return ccms.front().ccm; @@ -141,13 +141,13 @@ Matrix calculateCcm(std::vector const &ccms, double ct) } } -Matrix applySaturation(Matrix const &ccm, double saturation) +Matrix3x3 applySaturation(Matrix3x3 const &ccm, double saturation) { - Matrix RGB2Y(0.299, 0.587, 0.114, -0.169, -0.331, 0.500, 0.500, -0.419, + Matrix3x3 RGB2Y(0.299, 0.587, 0.114, -0.169, -0.331, 0.500, 0.500, -0.419, -0.081); - Matrix Y2RGB(1.000, 0.000, 1.402, 1.000, -0.345, -0.714, 1.000, 1.771, + Matrix3x3 Y2RGB(1.000, 0.000, 1.402, 1.000, -0.345, -0.714, 1.000, 1.771, 0.000); - Matrix S(1, 0, 0, 0, saturation, 0, 0, 0, saturation); + Matrix3x3 S(1, 0, 0, 0, saturation, 0, 0, 0, saturation); return Y2RGB * S * RGB2Y * ccm; } @@ -170,7 +170,7 @@ void Ccm::prepare(Metadata *imageMetadata) LOG(RPiCcm, Warning) << "no colour temperature found"; if (!luxOk) LOG(RPiCcm, Warning) << "no lux value found"; - Matrix ccm = calculateCcm(config_.ccms, awb.temperatureK); + Matrix3x3 ccm = calculateCcm(config_.ccms, awb.temperatureK); double saturation = saturation_; struct CcmStatus ccmStatus; ccmStatus.saturation = saturation; diff --git a/src/ipa/rpi/controller/rpi/ccm.h b/src/ipa/rpi/controller/rpi/ccm.h index 4e5b33fefa4e..8e7f9616c2ab 100644 --- a/src/ipa/rpi/controller/rpi/ccm.h +++ b/src/ipa/rpi/controller/rpi/ccm.h @@ -16,22 +16,22 @@ namespace RPiController { /* Algorithm to calculate colour matrix. Should be placed after AWB. */ -struct Matrix { - Matrix(double m0, double m1, double m2, double m3, double m4, double m5, +struct Matrix3x3 { + Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5, double m6, double m7, double m8); - Matrix(); + Matrix3x3(); double m[3][3]; int read(const libcamera::YamlObject ¶ms); }; -static inline Matrix operator*(double d, Matrix const &m) +static inline Matrix3x3 operator*(double d, Matrix3x3 const &m) { - return Matrix(m.m[0][0] * d, m.m[0][1] * d, m.m[0][2] * d, + return Matrix3x3(m.m[0][0] * d, m.m[0][1] * d, m.m[0][2] * d, m.m[1][0] * d, m.m[1][1] * d, m.m[1][2] * d, m.m[2][0] * d, m.m[2][1] * d, m.m[2][2] * d); } -static inline Matrix operator*(Matrix const &m1, Matrix const &m2) +static inline Matrix3x3 operator*(Matrix3x3 const &m1, Matrix3x3 const &m2) { - Matrix m; + Matrix3x3 m; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) m.m[i][j] = m1.m[i][0] * m2.m[0][j] + @@ -39,9 +39,9 @@ static inline Matrix operator*(Matrix const &m1, Matrix const &m2) m1.m[i][2] * m2.m[2][j]; return m; } -static inline Matrix operator+(Matrix const &m1, Matrix const &m2) +static inline Matrix3x3 operator+(Matrix3x3 const &m1, Matrix3x3 const &m2) { - Matrix m; + Matrix3x3 m; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) m.m[i][j] = m1.m[i][j] + m2.m[i][j]; @@ -50,7 +50,7 @@ static inline Matrix operator+(Matrix const &m1, Matrix const &m2) struct CtCcm { double ct; - Matrix ccm; + Matrix3x3 ccm; }; struct CcmConfig { From patchwork Wed Nov 20 14:27:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22033 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 B19A0C0F2A for ; Wed, 20 Nov 2024 14:28:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5A0C765F61; Wed, 20 Nov 2024 15:28:23 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CltQZLpO"; 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 04D8A65F5F for ; Wed, 20 Nov 2024 15:28:19 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D29C575A; Wed, 20 Nov 2024 15:28:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112880; bh=RIIxk1al0uhlEwqB9fgmsz6oLXMfCQMzWlU9mUD4Xhk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CltQZLpOIjH9pqndBvXJIgUk3LKnnEVcK7ODBbTm3ScOJU7S2cljh/KAmMoH++NUP IHL5nsufr6f1zs5u9Qa2P1HBnM3kLUqSwY0mWw/1tsKYhielskA6xrZ8rma2X1BJyM yC+6vNZX3kleBS1v2HVW5DnsSt4CgAEwmgY0YDZE= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 2/9] libcamera: Copy Matrix class from libipa to libcamera Date: Wed, 20 Nov 2024 15:27:49 +0100 Message-ID: <20241120142807.2093301-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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" In preparation to moving the matrix implementation from libipa to libcamera copy the corresponding files to the new location. The files are copied without modification to make upcoming integration changes easier to see. The new files are not included in the build and therefore have no negative side effects on the build. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- include/libcamera/internal/matrix.h | 203 ++++++++++++++++++++++++++++ src/libcamera/matrix.cpp | 149 ++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 include/libcamera/internal/matrix.h create mode 100644 src/libcamera/matrix.cpp diff --git a/include/libcamera/internal/matrix.h b/include/libcamera/internal/matrix.h new file mode 100644 index 000000000000..5471e6975b74 --- /dev/null +++ b/include/libcamera/internal/matrix.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Paul Elder + * + * Matrix and related operations + */ +#pragma once + +#include +#include +#include + +#include +#include + +#include "libcamera/internal/yaml_parser.h" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(Matrix) + +namespace ipa { + +#ifndef __DOXYGEN__ +template> * = nullptr> +#else +template +#endif /* __DOXYGEN__ */ +class Matrix +{ +public: + Matrix() + { + data_.fill(static_cast(0)); + } + + Matrix(const std::vector &data) + { + std::copy(data.begin(), data.end(), data_.begin()); + } + + static Matrix identity() + { + Matrix ret; + for (size_t i = 0; i < std::min(Rows, Cols); i++) + ret[i][i] = static_cast(1); + return ret; + } + + ~Matrix() = default; + + const std::string toString() const + { + std::stringstream out; + + out << "Matrix { "; + for (unsigned int i = 0; i < Rows; i++) { + out << "[ "; + for (unsigned int j = 0; j < Cols; j++) { + out << (*this)[i][j]; + out << ((j + 1 < Cols) ? ", " : " "); + } + out << ((i + 1 < Rows) ? "], " : "]"); + } + out << " }"; + + return out.str(); + } + + Span operator[](size_t i) const + { + return Span{ &data_.data()[i * Cols], Cols }; + } + + Span operator[](size_t i) + { + return Span{ &data_.data()[i * Cols], Cols }; + } + +#ifndef __DOXYGEN__ + template>> +#else + template +#endif /* __DOXYGEN__ */ + Matrix &operator*=(U d) + { + for (unsigned int i = 0; i < Rows * Cols; i++) + data_[i] *= d; + return *this; + } + +private: + std::array data_; +}; + +#ifndef __DOXYGEN__ +template> * = nullptr> +#else +template +#endif /* __DOXYGEN__ */ +Matrix operator*(T d, const Matrix &m) +{ + Matrix result; + + for (unsigned int i = 0; i < Rows; i++) { + for (unsigned int j = 0; j < Cols; j++) + result[i][j] = d * m[i][j]; + } + + return result; +} + +#ifndef __DOXYGEN__ +template> * = nullptr> +#else +template +#endif /* __DOXYGEN__ */ +Matrix operator*(const Matrix &m, T d) +{ + return d * m; +} + +#ifndef __DOXYGEN__ +template * = nullptr> +#else +template +#endif /* __DOXYGEN__ */ +Matrix operator*(const Matrix &m1, const Matrix &m2) +{ + Matrix result; + + for (unsigned int i = 0; i < R1; i++) { + for (unsigned int j = 0; j < C2; j++) { + T sum = 0; + + for (unsigned int k = 0; k < C1; k++) + sum += m1[i][k] * m2[k][j]; + + result[i][j] = sum; + } + } + + return result; +} + +template +Matrix operator+(const Matrix &m1, const Matrix &m2) +{ + Matrix result; + + for (unsigned int i = 0; i < Rows; i++) { + for (unsigned int j = 0; j < Cols; j++) + result[i][j] = m1[i][j] + m2[i][j]; + } + + return result; +} + +#ifndef __DOXYGEN__ +bool matrixValidateYaml(const YamlObject &obj, unsigned int size); +#endif /* __DOXYGEN__ */ + +} /* namespace ipa */ + +#ifndef __DOXYGEN__ +template +std::ostream &operator<<(std::ostream &out, const ipa::Matrix &m) +{ + out << m.toString(); + return out; +} + +template +struct YamlObject::Getter> { + std::optional> get(const YamlObject &obj) const + { + if (!ipa::matrixValidateYaml(obj, Rows * Cols)) + return std::nullopt; + + ipa::Matrix matrix; + T *data = &matrix[0][0]; + + unsigned int i = 0; + for (const YamlObject &entry : obj.asList()) { + const auto value = entry.get(); + if (!value) + return std::nullopt; + + data[i++] = *value; + } + + return matrix; + } +}; +#endif /* __DOXYGEN__ */ + +} /* namespace libcamera */ diff --git a/src/libcamera/matrix.cpp b/src/libcamera/matrix.cpp new file mode 100644 index 000000000000..8346f0d34160 --- /dev/null +++ b/src/libcamera/matrix.cpp @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Paul Elder + * + * Matrix and related operations + */ + +#include "matrix.h" + +#include + +/** + * \file matrix.h + * \brief Matrix class + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(Matrix) + +namespace ipa { + +/** + * \class Matrix + * \brief Matrix class + * \tparam T Type of numerical values to be stored in the matrix + * \tparam Rows Number of rows in the matrix + * \tparam Cols Number of columns in the matrix + */ + +/** + * \fn Matrix::Matrix() + * \brief Construct a zero matrix + */ + +/** + * \fn Matrix::Matrix(const std::vector &data) + * \brief Construct a matrix from supplied data + * \param[in] data Data from which to construct a matrix + * + * \a data is a one-dimensional vector and will be turned into a matrix in + * row-major order. The size of \a data must be equal to the product of the + * number of rows and columns of the matrix (Rows x Cols). + */ + +/** + * \fn Matrix::identity() + * \brief Construct an identity matrix + */ + +/** + * \fn Matrix::toString() + * \brief Assemble and return a string describing the matrix + * \return A string describing the matrix + */ + +/** + * \fn Span Matrix::operator[](size_t i) const + * \brief Index to a row in the matrix + * \param[in] i Index of row to retrieve + * + * This operator[] returns a Span, which can then be indexed into again with + * another operator[], allowing a convenient m[i][j] to access elements of the + * matrix. Note that the lifetime of the Span returned by this first-level + * operator[] is bound to that of the Matrix itself, so it is not recommended + * to save the Span that is the result of this operator[]. + * + * \return Row \a i from the matrix, as a Span + */ + +/** + * \fn Matrix::operator[](size_t i) + * \copydoc Matrix::operator[](size_t i) const + */ + +/** + * \fn Matrix &Matrix::operator*=(U d) + * \brief Multiply the matrix by a scalar in-place + * \tparam U Type of the numerical scalar value + * \param d The scalar multiplier + * \return Product of this matrix and scalar \a d + */ + +/** + * \fn Matrix::Matrix operator*(T d, const Matrix &m) + * \brief Multiply the matrix by a scalar + * \tparam T Type of the numerical scalar value + * \tparam U Type of numerical values in the matrix + * \tparam Rows Number of rows in the matrix + * \tparam Cols Number of columns in the matrix + * \param d The scalar multiplier + * \param m The matrix + * \return Product of scalar \a d and matrix \a m + */ + +/** + * \fn Matrix::Matrix operator*(const Matrix &m, T d) + * \copydoc operator*(T d, const Matrix &m) + */ + +/** + * \fn Matrix operator*(const Matrix &m1, const Matrix &m2) + * \brief Matrix multiplication + * \tparam T Type of numerical values in the matrices + * \tparam R1 Number of rows in the first matrix + * \tparam C1 Number of columns in the first matrix + * \tparam R2 Number of rows in the second matrix + * \tparam C2 Number of columns in the second matrix + * \param m1 Multiplicand matrix + * \param m2 Multiplier matrix + * \return Matrix product of matrices \a m1 and \a m2 + */ + +/** + * \fn Matrix operator+(const Matrix &m1, const Matrix &m2) + * \brief Matrix addition + * \tparam T Type of numerical values in the matrices + * \tparam Rows Number of rows in the matrices + * \tparam Cols Number of columns in the matrices + * \param m1 Summand matrix + * \param m2 Summand matrix + * \return Matrix sum of matrices \a m1 and \a m2 + */ + +#ifndef __DOXYGEN__ +/* + * The YAML data shall be a list of numerical values. Its size shall be equal + * to the product of the number of rows and columns of the matrix (Rows x + * Cols). The values shall be stored in row-major order. + */ +bool matrixValidateYaml(const YamlObject &obj, unsigned int size) +{ + if (!obj.isList()) + return false; + + if (obj.size() != size) { + LOG(Matrix, Error) + << "Wrong number of values in matrix: expected " + << size << ", got " << obj.size(); + return false; + } + + return true; +} +#endif /* __DOXYGEN__ */ + +} /* namespace ipa */ + +} /* namespace libcamera */ From patchwork Wed Nov 20 14:27:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22034 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 CCC7EC32F9 for ; Wed, 20 Nov 2024 14:28:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 19E9065F67; Wed, 20 Nov 2024 15:28:25 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="De7tNf+C"; 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 522E965F4A for ; Wed, 20 Nov 2024 15:28:21 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 361E0AB5; Wed, 20 Nov 2024 15:28:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112883; bh=cakHjk8du9scU/ZuPpjnr6MJbvnOXeg6PSF9RJyeZW8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=De7tNf+CE7wkPnVG2q/VgIh9w4QpthUlS30EevXl2IySdoWijcIMDGX3N2I7ubpAD CksZBQ3bOeT5KVSnv+Ao9dQZUvWV0cg3DoHc1z0j+5pS93UX6CN2/rXy9SCQiSCvcR w00yZZTJismUg63GFJejvN80uVwEpvdqEFVsLZGI= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 3/9] libcamera: internal: Move Matrix class into libcamera namespace Date: Wed, 20 Nov 2024 15:27:50 +0100 Message-ID: <20241120142807.2093301-4-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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 Matrix class no longer lives inside lipipa. Move it into the libcamera namespace to account for that. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- include/libcamera/internal/matrix.h | 14 +++++--------- src/libcamera/matrix.cpp | 6 +----- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/include/libcamera/internal/matrix.h b/include/libcamera/internal/matrix.h index 5471e6975b74..3701d0ee980b 100644 --- a/include/libcamera/internal/matrix.h +++ b/include/libcamera/internal/matrix.h @@ -19,8 +19,6 @@ namespace libcamera { LOG_DECLARE_CATEGORY(Matrix) -namespace ipa { - #ifndef __DOXYGEN__ template> * = nullptr> @@ -166,24 +164,22 @@ Matrix operator+(const Matrix &m1, const Matrix -std::ostream &operator<<(std::ostream &out, const ipa::Matrix &m) +std::ostream &operator<<(std::ostream &out, const Matrix &m) { out << m.toString(); return out; } template -struct YamlObject::Getter> { - std::optional> get(const YamlObject &obj) const +struct YamlObject::Getter> { + std::optional> get(const YamlObject &obj) const { - if (!ipa::matrixValidateYaml(obj, Rows * Cols)) + if (!matrixValidateYaml(obj, Rows * Cols)) return std::nullopt; - ipa::Matrix matrix; + Matrix matrix; T *data = &matrix[0][0]; unsigned int i = 0; diff --git a/src/libcamera/matrix.cpp b/src/libcamera/matrix.cpp index 8346f0d34160..55359aa206ee 100644 --- a/src/libcamera/matrix.cpp +++ b/src/libcamera/matrix.cpp @@ -5,7 +5,7 @@ * Matrix and related operations */ -#include "matrix.h" +#include "libcamera/internal/matrix.h" #include @@ -18,8 +18,6 @@ namespace libcamera { LOG_DEFINE_CATEGORY(Matrix) -namespace ipa { - /** * \class Matrix * \brief Matrix class @@ -144,6 +142,4 @@ bool matrixValidateYaml(const YamlObject &obj, unsigned int size) } #endif /* __DOXYGEN__ */ -} /* namespace ipa */ - } /* namespace libcamera */ From patchwork Wed Nov 20 14:27:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22035 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 CB55AC330B for ; Wed, 20 Nov 2024 14:28:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3AB1A65F6C; Wed, 20 Nov 2024 15:28:27 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tmKdgyiM"; 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 8CE2F65F67 for ; Wed, 20 Nov 2024 15:28:23 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6EAB0AB5; Wed, 20 Nov 2024 15:28:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112885; bh=ijGutbxbl2X9YnUKzdIB7SeDg9SnLHwr/1Zvs4bqR60=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tmKdgyiMxeCR7y4MvPPxfrdDNO4P+DMtHkiJwxzyrYwnlRdzdhvMp/978Gb6gGtUb 1ZZqMrr0AszWfNXq5wm2HSC8UbixuamEP18DhM8kcc3gcBrnUuuF71YKX2geWFCwkW zupBwo3ssk9hCq4vKatv0kaFMl3s3E2hqbynZoSA= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 4/9] libcamera: internal: matrix: Replace vector with array in constructor Date: Wed, 20 Nov 2024 15:27:51 +0100 Message-ID: <20241120142807.2093301-5-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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 Matrix constructor that takes a std::vector is meant and only used to initialize a Matrix from an initializer list. Using a std::vector is problematic for two reasons. First, it requires constructing a vector, copying the data from the initializer list, which is an expensive operation. Then, the vector size can't be verified at compile time, making the constructor unsafe. The first issue could be solved by replacing the vector with a std::initializer_list or a Span. The second issue would require checking the initializer list size with a static assertion, or restricting usage of the constructor to fixed-extent spans. Unfortunately, even if the size of initializer lists is always known at compile time, the std::initializer_list::size() function is a compile-time constant only for constant initializer lists. Using a span would work better, but construction of a fixed extent span from an initializer list must be explicit, making the API cumbersome. We can solve all those issues by passing an std::array to the constructor. Construction of an array from an initializer list can be implicit and doesn't involve a copy, and the array size is a template parameter and therefore guaranteed to be a compile-time constant. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- Changes in v3: - Collect tags - Update commit msg --- include/libcamera/internal/matrix.h | 2 +- src/libcamera/matrix.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/libcamera/internal/matrix.h b/include/libcamera/internal/matrix.h index 3701d0ee980b..7a71028c473a 100644 --- a/include/libcamera/internal/matrix.h +++ b/include/libcamera/internal/matrix.h @@ -33,7 +33,7 @@ public: data_.fill(static_cast(0)); } - Matrix(const std::vector &data) + Matrix(const std::array &data) { std::copy(data.begin(), data.end(), data_.begin()); } diff --git a/src/libcamera/matrix.cpp b/src/libcamera/matrix.cpp index 55359aa206ee..4d95a19bfbb9 100644 --- a/src/libcamera/matrix.cpp +++ b/src/libcamera/matrix.cpp @@ -32,7 +32,7 @@ LOG_DEFINE_CATEGORY(Matrix) */ /** - * \fn Matrix::Matrix(const std::vector &data) + * \fn Matrix::Matrix(const std::array &data) * \brief Construct a matrix from supplied data * \param[in] data Data from which to construct a matrix * From patchwork Wed Nov 20 14:27:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22036 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 5A59BC32F8 for ; Wed, 20 Nov 2024 14:28:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 015B465F71; Wed, 20 Nov 2024 15:28:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="INLnhebZ"; 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 3831E65F63 for ; Wed, 20 Nov 2024 15:28:26 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1923975A; Wed, 20 Nov 2024 15:28:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112888; bh=IJFm32qjtrg0o+rLBL1jAUNGI9mjdb/ymTjUdh946og=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=INLnhebZy0MmU5j9sjXpDiuy0B/U2aW0J0XYLxWdjISRMVlULMc6Bm02OBex5sbmb skF8XFTqdhwk9ux8sujaNmeuMrU0a2DdVcFKUAyBXQvQAhbct7SLve34DndMGOvcZt +wFxfNv+V8KkUIlGri/tQ0oulPw3s2DEnKR9k/8M= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 5/9] libcamera: internal: Add Matrix class to build Date: Wed, 20 Nov 2024 15:27:52 +0100 Message-ID: <20241120142807.2093301-6-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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 the new Matrix class to the build. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- include/libcamera/internal/meson.build | 1 + src/libcamera/meson.build | 1 + 2 files changed, 2 insertions(+) diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index 1dddcd50c90b..7d6aa8b72bd7 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -29,6 +29,7 @@ libcamera_internal_headers = files([ 'ipc_pipe.h', 'ipc_unixsocket.h', 'mapped_framebuffer.h', + 'matrix.h', 'media_device.h', 'media_object.h', 'pipeline_handler.h', diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 21cae11756d6..57fde8a8fab0 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -40,6 +40,7 @@ libcamera_internal_sources = files([ 'ipc_pipe_unixsocket.cpp', 'ipc_unixsocket.cpp', 'mapped_framebuffer.cpp', + 'matrix.cpp', 'media_device.cpp', 'media_object.cpp', 'pipeline_handler.cpp', From patchwork Wed Nov 20 14:27:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22037 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 20051C330C for ; Wed, 20 Nov 2024 14:28:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AF90265F75; Wed, 20 Nov 2024 15:28:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="G3FeR7lV"; 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 EAB4A65F64 for ; Wed, 20 Nov 2024 15:28:28 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C131D75A; Wed, 20 Nov 2024 15:28:10 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112890; bh=diTts7IBj3aer3sivmN+Zae7t14LNmJMyazAivBc/PY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G3FeR7lVw1no5OooInHDt+X/xUilOtFnyTJQOfEpVgLhy00YUOIInQ8CHzvfwqe+2 kGyzFapuR32iGUEINQM3rp8XPV8Antaq8mgjCrts/jYfKTVTO3l1hGQ2Ff4DGL31ze uGKrdrUVCIDjyQUurWS1O4eVkVzG6Ds/IK7EhzkE= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 6/9] ipa: rpi: ccm: Replace local matrix implementation with the one from libcamera Date: Wed, 20 Nov 2024 15:27:53 +0100 Message-ID: <20241120142807.2093301-7-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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 RaspberryPi IPA contains a private Matrix3x3 class inside the ccm algorithm. Replace it with the Matrix class available in libcamera/internal. While at it, mark the matrices RGB2Y and Y2RGB as static const. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart Acked-by: Naushir Patuck --- Changes in v3: - Collected tags - Reformatted matrices - Tested on actual device --- src/ipa/rpi/controller/rpi/ccm.cpp | 59 ++++++++++-------------------- src/ipa/rpi/controller/rpi/ccm.h | 35 +----------------- 2 files changed, 22 insertions(+), 72 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp index 7f63f3fdb702..8607f1521b5a 100644 --- a/src/ipa/rpi/controller/rpi/ccm.cpp +++ b/src/ipa/rpi/controller/rpi/ccm.cpp @@ -29,34 +29,7 @@ LOG_DEFINE_CATEGORY(RPiCcm) #define NAME "rpi.ccm" -Matrix3x3::Matrix3x3() -{ - memset(m, 0, sizeof(m)); -} -Matrix3x3::Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5, - double m6, double m7, double m8) -{ - m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] = m4, - m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8; -} -int Matrix3x3::read(const libcamera::YamlObject ¶ms) -{ - double *ptr = (double *)m; - - if (params.size() != 9) { - LOG(RPiCcm, Error) << "Wrong number of values in CCM"; - return -EINVAL; - } - - for (const auto ¶m : params.asList()) { - auto value = param.get(); - if (!value) - return -EINVAL; - *ptr++ = *value; - } - - return 0; -} +using Matrix3x3 = Matrix; Ccm::Ccm(Controller *controller) : CcmAlgorithm(controller), saturation_(1.0) {} @@ -68,8 +41,6 @@ char const *Ccm::name() const int Ccm::read(const libcamera::YamlObject ¶ms) { - int ret; - if (params.contains("saturation")) { config_.saturation = params["saturation"].get(ipa::Pwl{}); if (config_.saturation.empty()) @@ -83,9 +54,12 @@ int Ccm::read(const libcamera::YamlObject ¶ms) CtCcm ctCcm; ctCcm.ct = *value; - ret = ctCcm.ccm.read(p["ccm"]); - if (ret) - return ret; + + auto ccm = p["ccm"].get(); + if (!ccm) + return -EINVAL; + + ctCcm.ccm = *ccm; if (!config_.ccms.empty() && ctCcm.ct <= config_.ccms.back().ct) { LOG(RPiCcm, Error) @@ -143,11 +117,18 @@ Matrix3x3 calculateCcm(std::vector const &ccms, double ct) Matrix3x3 applySaturation(Matrix3x3 const &ccm, double saturation) { - Matrix3x3 RGB2Y(0.299, 0.587, 0.114, -0.169, -0.331, 0.500, 0.500, -0.419, - -0.081); - Matrix3x3 Y2RGB(1.000, 0.000, 1.402, 1.000, -0.345, -0.714, 1.000, 1.771, - 0.000); - Matrix3x3 S(1, 0, 0, 0, saturation, 0, 0, 0, saturation); + static const Matrix3x3 RGB2Y({ 0.299, 0.587, 0.114, + -0.169, -0.331, 0.500, + 0.500, -0.419, -0.081 }); + + static const Matrix3x3 Y2RGB({ 1.000, 0.000, 1.402, + 1.000, -0.345, -0.714, + 1.000, 1.771, 0.000 }); + + Matrix3x3 S({ 1, 0, 0, + 0, saturation, 0, + 0, 0, saturation }); + return Y2RGB * S * RGB2Y * ccm; } @@ -181,7 +162,7 @@ void Ccm::prepare(Metadata *imageMetadata) for (int j = 0; j < 3; j++) for (int i = 0; i < 3; i++) ccmStatus.matrix[j * 3 + i] = - std::max(-8.0, std::min(7.9999, ccm.m[j][i])); + std::max(-8.0, std::min(7.9999, ccm[j][i])); LOG(RPiCcm, Debug) << "colour temperature " << awb.temperatureK << "K"; LOG(RPiCcm, Debug) diff --git a/src/ipa/rpi/controller/rpi/ccm.h b/src/ipa/rpi/controller/rpi/ccm.h index 8e7f9616c2ab..c05dbb17a264 100644 --- a/src/ipa/rpi/controller/rpi/ccm.h +++ b/src/ipa/rpi/controller/rpi/ccm.h @@ -8,6 +8,7 @@ #include +#include "libcamera/internal/matrix.h" #include #include "../ccm_algorithm.h" @@ -16,41 +17,9 @@ namespace RPiController { /* Algorithm to calculate colour matrix. Should be placed after AWB. */ -struct Matrix3x3 { - Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5, - double m6, double m7, double m8); - Matrix3x3(); - double m[3][3]; - int read(const libcamera::YamlObject ¶ms); -}; -static inline Matrix3x3 operator*(double d, Matrix3x3 const &m) -{ - return Matrix3x3(m.m[0][0] * d, m.m[0][1] * d, m.m[0][2] * d, - m.m[1][0] * d, m.m[1][1] * d, m.m[1][2] * d, - m.m[2][0] * d, m.m[2][1] * d, m.m[2][2] * d); -} -static inline Matrix3x3 operator*(Matrix3x3 const &m1, Matrix3x3 const &m2) -{ - Matrix3x3 m; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - m.m[i][j] = m1.m[i][0] * m2.m[0][j] + - m1.m[i][1] * m2.m[1][j] + - m1.m[i][2] * m2.m[2][j]; - return m; -} -static inline Matrix3x3 operator+(Matrix3x3 const &m1, Matrix3x3 const &m2) -{ - Matrix3x3 m; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - m.m[i][j] = m1.m[i][j] + m2.m[i][j]; - return m; -} - struct CtCcm { double ct; - Matrix3x3 ccm; + libcamera::Matrix ccm; }; struct CcmConfig { From patchwork Wed Nov 20 14:27:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22038 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 5D12BC330D for ; Wed, 20 Nov 2024 14:28:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CBDDF65F70; Wed, 20 Nov 2024 15:28:34 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="IpZrvrCA"; 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 B93F665F70 for ; Wed, 20 Nov 2024 15:28:31 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8EC9FAB5; Wed, 20 Nov 2024 15:28:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112893; bh=bWXs8axChpcW3jOsr+UwEAy/5Hwqoh3WeoTgsgGgnuE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IpZrvrCAg9wqjn0C78rTot43LJAGo0ZmNtqnO2aAZNEtENaiweKGhFjAHzqwNhfui 2wBOwnma8P0B1bgNuD/Wm82Vmfb15GmWB/5I47LY6c50C2Ebgt1Fg5w728AZ6u3cN4 1D5e8o20uyr5m70UwD9WWq81s5RUsNmoabhduH8w= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 7/9] libipa: Use Matrix class from libcamera Date: Wed, 20 Nov 2024 15:27:54 +0100 Message-ID: <20241120142807.2093301-8-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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" Use the Matrix class from libcamera/internal in libipa so that the one from libipa can be dropped later. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- Changes in v3: - Collected tags - Removed empty line --- src/ipa/libipa/vector.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 8612a06a2ab2..b4aec8ceeeed 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -14,10 +14,9 @@ #include #include +#include "libcamera/internal/matrix.h" #include "libcamera/internal/yaml_parser.h" -#include "matrix.h" - namespace libcamera { LOG_DECLARE_CATEGORY(Vector) From patchwork Wed Nov 20 14:27:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22039 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 0FA3DC0F2A for ; Wed, 20 Nov 2024 14:28:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 89F5465F7B; Wed, 20 Nov 2024 15:28:37 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="URB7ZGYw"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3FCC265F68 for ; Wed, 20 Nov 2024 15:28:34 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 204C155A; Wed, 20 Nov 2024 15:28:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112896; bh=6uRcnGEjc4jL4hQG7g77jgv3Oxl7V7O6yXmgl+XIGXE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=URB7ZGYw29wo9+nyeE5GaW5uySO1hbnJuGDhy2uH73QNrFXkcDIsNX3BIn+COdZsc eJgA7bk0lb+ktW/HkA2aiby+PXBl54M2yJIusAb0HAHQPpl2lBnmP/Ct9Pxm4z+FMJ CMDFXc/vB6ejuawV8aTFy0IVg2dgBNPUUUew9Ja4= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 8/9] rkisp1: Use Matrix class from libcamera Date: Wed, 20 Nov 2024 15:27:55 +0100 Message-ID: <20241120142807.2093301-9-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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" Use the Matrix class from libcamera/internal in the rkisp IPA so that the libipa one can be dropped later. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- src/ipa/rkisp1/algorithms/ccm.h | 3 ++- src/ipa/rkisp1/ipa_context.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/ccm.h b/src/ipa/rkisp1/algorithms/ccm.h index 46a1416e6be5..a5d9a9a45e5d 100644 --- a/src/ipa/rkisp1/algorithms/ccm.h +++ b/src/ipa/rkisp1/algorithms/ccm.h @@ -9,8 +9,9 @@ #include +#include "libcamera/internal/matrix.h" + #include "libipa/interpolator.h" -#include "libipa/matrix.h" #include "algorithm.h" diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 7b93a9e9461d..12b37d1c73b0 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -21,10 +21,10 @@ #include #include "libcamera/internal/debug_controls.h" +#include "libcamera/internal/matrix.h" #include #include -#include namespace libcamera { From patchwork Wed Nov 20 14:27:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22040 X-Patchwork-Delegate: paul.elder@ideasonboard.com 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 B0503C330E for ; Wed, 20 Nov 2024 14:28:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 30E2965F7E; Wed, 20 Nov 2024 15:28:41 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="p7+GuAXu"; 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 0213965F72 for ; Wed, 20 Nov 2024 15:28:37 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bbd:82cc:f3f3:e12e]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D1697928; Wed, 20 Nov 2024 15:28:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1732112898; bh=VD8EWJFf5tkybIjbEssIQunl80bc7lT62TlVQKJRdWs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p7+GuAXuEjiTPuB97xZaJ6/vzB3Rq0vuqOV+/RTrC6yBJP0E/aLDriA07f9uaDVrl +T7giiUP/inaYh1shywQyMDmrNnrbDX2Is6KXBXg4Q194zGMgyn3fjzzZgYEOl7X+F aB93Ciasevnb0CAM+7II/3uPROQlPda0gwY/vG7I= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Laurent Pinchart Subject: [PATCH v3 9/9] libipa: Drop Matrix class Date: Wed, 20 Nov 2024 15:27:56 +0100 Message-ID: <20241120142807.2093301-10-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241120142807.2093301-1-stefan.klug@ideasonboard.com> References: <20241120142807.2093301-1-stefan.klug@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" There are no users of the libipa::Matrix class anymore. Drop it. Signed-off-by: Stefan Klug Reviewed-by: Laurent Pinchart --- src/ipa/libipa/matrix.cpp | 149 --------------------------- src/ipa/libipa/matrix.h | 203 ------------------------------------- src/ipa/libipa/meson.build | 2 - 3 files changed, 354 deletions(-) delete mode 100644 src/ipa/libipa/matrix.cpp delete mode 100644 src/ipa/libipa/matrix.h diff --git a/src/ipa/libipa/matrix.cpp b/src/ipa/libipa/matrix.cpp deleted file mode 100644 index 8346f0d34160..000000000000 --- a/src/ipa/libipa/matrix.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2024, Paul Elder - * - * Matrix and related operations - */ - -#include "matrix.h" - -#include - -/** - * \file matrix.h - * \brief Matrix class - */ - -namespace libcamera { - -LOG_DEFINE_CATEGORY(Matrix) - -namespace ipa { - -/** - * \class Matrix - * \brief Matrix class - * \tparam T Type of numerical values to be stored in the matrix - * \tparam Rows Number of rows in the matrix - * \tparam Cols Number of columns in the matrix - */ - -/** - * \fn Matrix::Matrix() - * \brief Construct a zero matrix - */ - -/** - * \fn Matrix::Matrix(const std::vector &data) - * \brief Construct a matrix from supplied data - * \param[in] data Data from which to construct a matrix - * - * \a data is a one-dimensional vector and will be turned into a matrix in - * row-major order. The size of \a data must be equal to the product of the - * number of rows and columns of the matrix (Rows x Cols). - */ - -/** - * \fn Matrix::identity() - * \brief Construct an identity matrix - */ - -/** - * \fn Matrix::toString() - * \brief Assemble and return a string describing the matrix - * \return A string describing the matrix - */ - -/** - * \fn Span Matrix::operator[](size_t i) const - * \brief Index to a row in the matrix - * \param[in] i Index of row to retrieve - * - * This operator[] returns a Span, which can then be indexed into again with - * another operator[], allowing a convenient m[i][j] to access elements of the - * matrix. Note that the lifetime of the Span returned by this first-level - * operator[] is bound to that of the Matrix itself, so it is not recommended - * to save the Span that is the result of this operator[]. - * - * \return Row \a i from the matrix, as a Span - */ - -/** - * \fn Matrix::operator[](size_t i) - * \copydoc Matrix::operator[](size_t i) const - */ - -/** - * \fn Matrix &Matrix::operator*=(U d) - * \brief Multiply the matrix by a scalar in-place - * \tparam U Type of the numerical scalar value - * \param d The scalar multiplier - * \return Product of this matrix and scalar \a d - */ - -/** - * \fn Matrix::Matrix operator*(T d, const Matrix &m) - * \brief Multiply the matrix by a scalar - * \tparam T Type of the numerical scalar value - * \tparam U Type of numerical values in the matrix - * \tparam Rows Number of rows in the matrix - * \tparam Cols Number of columns in the matrix - * \param d The scalar multiplier - * \param m The matrix - * \return Product of scalar \a d and matrix \a m - */ - -/** - * \fn Matrix::Matrix operator*(const Matrix &m, T d) - * \copydoc operator*(T d, const Matrix &m) - */ - -/** - * \fn Matrix operator*(const Matrix &m1, const Matrix &m2) - * \brief Matrix multiplication - * \tparam T Type of numerical values in the matrices - * \tparam R1 Number of rows in the first matrix - * \tparam C1 Number of columns in the first matrix - * \tparam R2 Number of rows in the second matrix - * \tparam C2 Number of columns in the second matrix - * \param m1 Multiplicand matrix - * \param m2 Multiplier matrix - * \return Matrix product of matrices \a m1 and \a m2 - */ - -/** - * \fn Matrix operator+(const Matrix &m1, const Matrix &m2) - * \brief Matrix addition - * \tparam T Type of numerical values in the matrices - * \tparam Rows Number of rows in the matrices - * \tparam Cols Number of columns in the matrices - * \param m1 Summand matrix - * \param m2 Summand matrix - * \return Matrix sum of matrices \a m1 and \a m2 - */ - -#ifndef __DOXYGEN__ -/* - * The YAML data shall be a list of numerical values. Its size shall be equal - * to the product of the number of rows and columns of the matrix (Rows x - * Cols). The values shall be stored in row-major order. - */ -bool matrixValidateYaml(const YamlObject &obj, unsigned int size) -{ - if (!obj.isList()) - return false; - - if (obj.size() != size) { - LOG(Matrix, Error) - << "Wrong number of values in matrix: expected " - << size << ", got " << obj.size(); - return false; - } - - return true; -} -#endif /* __DOXYGEN__ */ - -} /* namespace ipa */ - -} /* namespace libcamera */ diff --git a/src/ipa/libipa/matrix.h b/src/ipa/libipa/matrix.h deleted file mode 100644 index 5471e6975b74..000000000000 --- a/src/ipa/libipa/matrix.h +++ /dev/null @@ -1,203 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2024, Paul Elder - * - * Matrix and related operations - */ -#pragma once - -#include -#include -#include - -#include -#include - -#include "libcamera/internal/yaml_parser.h" - -namespace libcamera { - -LOG_DECLARE_CATEGORY(Matrix) - -namespace ipa { - -#ifndef __DOXYGEN__ -template> * = nullptr> -#else -template -#endif /* __DOXYGEN__ */ -class Matrix -{ -public: - Matrix() - { - data_.fill(static_cast(0)); - } - - Matrix(const std::vector &data) - { - std::copy(data.begin(), data.end(), data_.begin()); - } - - static Matrix identity() - { - Matrix ret; - for (size_t i = 0; i < std::min(Rows, Cols); i++) - ret[i][i] = static_cast(1); - return ret; - } - - ~Matrix() = default; - - const std::string toString() const - { - std::stringstream out; - - out << "Matrix { "; - for (unsigned int i = 0; i < Rows; i++) { - out << "[ "; - for (unsigned int j = 0; j < Cols; j++) { - out << (*this)[i][j]; - out << ((j + 1 < Cols) ? ", " : " "); - } - out << ((i + 1 < Rows) ? "], " : "]"); - } - out << " }"; - - return out.str(); - } - - Span operator[](size_t i) const - { - return Span{ &data_.data()[i * Cols], Cols }; - } - - Span operator[](size_t i) - { - return Span{ &data_.data()[i * Cols], Cols }; - } - -#ifndef __DOXYGEN__ - template>> -#else - template -#endif /* __DOXYGEN__ */ - Matrix &operator*=(U d) - { - for (unsigned int i = 0; i < Rows * Cols; i++) - data_[i] *= d; - return *this; - } - -private: - std::array data_; -}; - -#ifndef __DOXYGEN__ -template> * = nullptr> -#else -template -#endif /* __DOXYGEN__ */ -Matrix operator*(T d, const Matrix &m) -{ - Matrix result; - - for (unsigned int i = 0; i < Rows; i++) { - for (unsigned int j = 0; j < Cols; j++) - result[i][j] = d * m[i][j]; - } - - return result; -} - -#ifndef __DOXYGEN__ -template> * = nullptr> -#else -template -#endif /* __DOXYGEN__ */ -Matrix operator*(const Matrix &m, T d) -{ - return d * m; -} - -#ifndef __DOXYGEN__ -template * = nullptr> -#else -template -#endif /* __DOXYGEN__ */ -Matrix operator*(const Matrix &m1, const Matrix &m2) -{ - Matrix result; - - for (unsigned int i = 0; i < R1; i++) { - for (unsigned int j = 0; j < C2; j++) { - T sum = 0; - - for (unsigned int k = 0; k < C1; k++) - sum += m1[i][k] * m2[k][j]; - - result[i][j] = sum; - } - } - - return result; -} - -template -Matrix operator+(const Matrix &m1, const Matrix &m2) -{ - Matrix result; - - for (unsigned int i = 0; i < Rows; i++) { - for (unsigned int j = 0; j < Cols; j++) - result[i][j] = m1[i][j] + m2[i][j]; - } - - return result; -} - -#ifndef __DOXYGEN__ -bool matrixValidateYaml(const YamlObject &obj, unsigned int size); -#endif /* __DOXYGEN__ */ - -} /* namespace ipa */ - -#ifndef __DOXYGEN__ -template -std::ostream &operator<<(std::ostream &out, const ipa::Matrix &m) -{ - out << m.toString(); - return out; -} - -template -struct YamlObject::Getter> { - std::optional> get(const YamlObject &obj) const - { - if (!ipa::matrixValidateYaml(obj, Rows * Cols)) - return std::nullopt; - - ipa::Matrix matrix; - T *data = &matrix[0][0]; - - unsigned int i = 0; - for (const YamlObject &entry : obj.asList()) { - const auto value = entry.get(); - if (!value) - return std::nullopt; - - data[i++] = *value; - } - - return matrix; - } -}; -#endif /* __DOXYGEN__ */ - -} /* namespace libcamera */ diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build index 788d037a6fad..93ae25da5e83 100644 --- a/src/ipa/libipa/meson.build +++ b/src/ipa/libipa/meson.build @@ -10,7 +10,6 @@ libipa_headers = files([ 'histogram.h', 'interpolator.h', 'lsc_polynomial.h', - 'matrix.h', 'module.h', 'pwl.h', 'vector.h', @@ -26,7 +25,6 @@ libipa_sources = files([ 'histogram.cpp', 'interpolator.cpp', 'lsc_polynomial.cpp', - 'matrix.cpp', 'module.cpp', 'pwl.cpp', 'vector.cpp',