<div dir="ltr"><div dir="ltr">Hi Stefan,<div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 20 Nov 2024 at 14:28, Stefan Klug <<a href="mailto:stefan.klug@ideasonboard.com">stefan.klug@ideasonboard.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The RaspberryPi IPA contains a private Matrix3x3 class inside the ccm<br>
algorithm. Replace it with the Matrix class available in<br>
libcamera/internal.<br>
<br>
While at it, mark the matrices RGB2Y and Y2RGB as static const.<br>
<br>
Signed-off-by: Stefan Klug <<a href="mailto:stefan.klug@ideasonboard.com" target="_blank">stefan.klug@ideasonboard.com</a>><br>
Reviewed-by: Laurent Pinchart <<a href="mailto:laurent.pinchart@ideasonboard.com" target="_blank">laurent.pinchart@ideasonboard.com</a>><br></blockquote><div><br></div><div>Acked-by: Naushir Patuck <<a href="mailto:naush@raspberrypi.com">naush@raspberrypi.com</a>></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
---<br>
Changes in v3:<br>
- Collected tags<br>
- Reformatted matrices<br>
- Tested on actual device<br>
---<br>
 src/ipa/rpi/controller/rpi/ccm.cpp | 59 ++++++++++--------------------<br>
 src/ipa/rpi/controller/rpi/ccm.h   | 35 +-----------------<br>
 2 files changed, 22 insertions(+), 72 deletions(-)<br>
<br>
diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp<br>
index 7f63f3fdb702..8607f1521b5a 100644<br>
--- a/src/ipa/rpi/controller/rpi/ccm.cpp<br>
+++ b/src/ipa/rpi/controller/rpi/ccm.cpp<br>
@@ -29,34 +29,7 @@ LOG_DEFINE_CATEGORY(RPiCcm)<br>
<br>
 #define NAME "rpi.ccm"<br>
<br>
-Matrix3x3::Matrix3x3()<br>
-{<br>
-       memset(m, 0, sizeof(m));<br>
-}<br>
-Matrix3x3::Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5,<br>
-              double m6, double m7, double m8)<br>
-{<br>
-       m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] = m4,<br>
-       m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8;<br>
-}<br>
-int Matrix3x3::read(const libcamera::YamlObject &params)<br>
-{<br>
-       double *ptr = (double *)m;<br>
-<br>
-       if (params.size() != 9) {<br>
-               LOG(RPiCcm, Error) << "Wrong number of values in CCM";<br>
-               return -EINVAL;<br>
-       }<br>
-<br>
-       for (const auto &param : params.asList()) {<br>
-               auto value = param.get<double>();<br>
-               if (!value)<br>
-                       return -EINVAL;<br>
-               *ptr++ = *value;<br>
-       }<br>
-<br>
-       return 0;<br>
-}<br>
+using Matrix3x3 = Matrix<double, 3, 3>;<br>
<br>
 Ccm::Ccm(Controller *controller)<br>
        : CcmAlgorithm(controller), saturation_(1.0) {}<br>
@@ -68,8 +41,6 @@ char const *Ccm::name() const<br>
<br>
 int Ccm::read(const libcamera::YamlObject &params)<br>
 {<br>
-       int ret;<br>
-<br>
        if (params.contains("saturation")) {<br>
                config_.saturation = params["saturation"].get<ipa::Pwl>(ipa::Pwl{});<br>
                if (config_.saturation.empty())<br>
@@ -83,9 +54,12 @@ int Ccm::read(const libcamera::YamlObject &params)<br>
<br>
                CtCcm ctCcm;<br>
                ctCcm.ct = *value;<br>
-               ret = ctCcm.ccm.read(p["ccm"]);<br>
-               if (ret)<br>
-                       return ret;<br>
+<br>
+               auto ccm = p["ccm"].get<Matrix3x3>();<br>
+               if (!ccm)<br>
+                       return -EINVAL;<br>
+<br>
+               ctCcm.ccm = *ccm;<br>
<br>
                if (!config_.ccms.empty() && ctCcm.ct <= config_.ccms.back().ct) {<br>
                        LOG(RPiCcm, Error)<br>
@@ -143,11 +117,18 @@ Matrix3x3 calculateCcm(std::vector<CtCcm> const &ccms, double ct)<br>
<br>
 Matrix3x3 applySaturation(Matrix3x3 const &ccm, double saturation)<br>
 {<br>
-       Matrix3x3 RGB2Y(0.299, 0.587, 0.114, -0.169, -0.331, 0.500, 0.500, -0.419,<br>
-                    -0.081);<br>
-       Matrix3x3 Y2RGB(1.000, 0.000, 1.402, 1.000, -0.345, -0.714, 1.000, 1.771,<br>
-                    0.000);<br>
-       Matrix3x3 S(1, 0, 0, 0, saturation, 0, 0, 0, saturation);<br>
+       static const Matrix3x3 RGB2Y({ 0.299, 0.587, 0.114,<br>
+                                      -0.169, -0.331, 0.500,<br>
+                                      0.500, -0.419, -0.081 });<br>
+<br>
+       static const Matrix3x3 Y2RGB({ 1.000, 0.000, 1.402,<br>
+                                      1.000, -0.345, -0.714,<br>
+                                      1.000, 1.771, 0.000 });<br>
+<br>
+       Matrix3x3 S({ 1, 0, 0,<br>
+                     0, saturation, 0,<br>
+                     0, 0, saturation });<br>
+<br>
        return Y2RGB * S * RGB2Y * ccm;<br>
 }<br>
<br>
@@ -181,7 +162,7 @@ void Ccm::prepare(Metadata *imageMetadata)<br>
        for (int j = 0; j < 3; j++)<br>
                for (int i = 0; i < 3; i++)<br>
                        ccmStatus.matrix[j * 3 + i] =<br>
-                               std::max(-8.0, std::min(7.9999, ccm.m[j][i]));<br>
+                               std::max(-8.0, std::min(7.9999, ccm[j][i]));<br>
        LOG(RPiCcm, Debug)<br>
                << "colour temperature " << awb.temperatureK << "K";<br>
        LOG(RPiCcm, Debug)<br>
diff --git a/src/ipa/rpi/controller/rpi/ccm.h b/src/ipa/rpi/controller/rpi/ccm.h<br>
index 8e7f9616c2ab..c05dbb17a264 100644<br>
--- a/src/ipa/rpi/controller/rpi/ccm.h<br>
+++ b/src/ipa/rpi/controller/rpi/ccm.h<br>
@@ -8,6 +8,7 @@<br>
<br>
 #include <vector><br>
<br>
+#include "libcamera/internal/matrix.h"<br>
 #include <libipa/pwl.h><br>
<br>
 #include "../ccm_algorithm.h"<br>
@@ -16,41 +17,9 @@ namespace RPiController {<br>
<br>
 /* Algorithm to calculate colour matrix. Should be placed after AWB. */<br>
<br>
-struct Matrix3x3 {<br>
-       Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5,<br>
-              double m6, double m7, double m8);<br>
-       Matrix3x3();<br>
-       double m[3][3];<br>
-       int read(const libcamera::YamlObject &params);<br>
-};<br>
-static inline Matrix3x3 operator*(double d, Matrix3x3 const &m)<br>
-{<br>
-       return Matrix3x3(m.m[0][0] * d, m.m[0][1] * d, m.m[0][2] * d,<br>
-                     m.m[1][0] * d, m.m[1][1] * d, m.m[1][2] * d,<br>
-                     m.m[2][0] * d, m.m[2][1] * d, m.m[2][2] * d);<br>
-}<br>
-static inline Matrix3x3 operator*(Matrix3x3 const &m1, Matrix3x3 const &m2)<br>
-{<br>
-       Matrix3x3 m;<br>
-       for (int i = 0; i < 3; i++)<br>
-               for (int j = 0; j < 3; j++)<br>
-                       m.m[i][j] = m1.m[i][0] * m2.m[0][j] +<br>
-                                   m1.m[i][1] * m2.m[1][j] +<br>
-                                   m1.m[i][2] * m2.m[2][j];<br>
-       return m;<br>
-}<br>
-static inline Matrix3x3 operator+(Matrix3x3 const &m1, Matrix3x3 const &m2)<br>
-{<br>
-       Matrix3x3 m;<br>
-       for (int i = 0; i < 3; i++)<br>
-               for (int j = 0; j < 3; j++)<br>
-                       m.m[i][j] = m1.m[i][j] + m2.m[i][j];<br>
-       return m;<br>
-}<br>
-<br>
 struct CtCcm {<br>
        double ct;<br>
-       Matrix3x3 ccm;<br>
+       libcamera::Matrix<double, 3, 3> ccm;<br>
 };<br>
<br>
 struct CcmConfig {<br>
-- <br>
2.43.0<br>
<br>
</blockquote></div></div>