From 9d61c09462e93106954e8c358506add3e719b48b Mon Sep 17 00:00:00 2001 From: Stefan Klug Date: Tue, 24 Sep 2024 16:06:41 +0200 Subject: libcamera: Copy Matrix class from libipa to libcamera 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 ++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 include/libcamera/internal/matrix.h (limited to 'include') diff --git a/include/libcamera/internal/matrix.h b/include/libcamera/internal/matrix.h new file mode 100644 index 00000000..5471e697 --- /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 */ -- cgit v1.2.1