[v3,10/35] ipa: libipa: Introduce lsc_base.h
diff mbox series

Message ID 20260706-libipa-algorithms-v3-10-968757b038bb@ideasonboard.com
State New
Headers show
Series
  • ipa: libipa: Introduce libipa algorithms
Related show

Commit Message

Jacopo Mondi July 6, 2026, 8:01 a.m. UTC
Group in an header file part of libipa the definition of the lsc
Components and the LscImplementation interface definition.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 src/ipa/libipa/lsc_base.cpp       | 95 +++++++++++++++++++++++++++++++++++++++
 src/ipa/libipa/lsc_base.h         | 53 ++++++++++++++++++++++
 src/ipa/libipa/meson.build        |  2 +
 src/ipa/rkisp1/algorithms/lsc.cpp | 28 ++++++------
 src/ipa/rkisp1/algorithms/lsc.h   | 29 ++----------
 5 files changed, 167 insertions(+), 40 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/libipa/lsc_base.cpp b/src/ipa/libipa/lsc_base.cpp
new file mode 100644
index 000000000000..d545e9a5f7ed
--- /dev/null
+++ b/src/ipa/libipa/lsc_base.cpp
@@ -0,0 +1,95 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2026 Ideas on Board Oy
+ *
+ * Base classes and types for LSC algorithms implementations
+ */
+
+#include "lsc_base.h"
+
+/**
+ * \file lsc_base.h
+ * \brief Base types and definitions for LscImplementation class hierarchy
+ */
+
+namespace libcamera {
+
+namespace ipa {
+
+namespace lsc {
+
+/**
+ * \struct Components
+ * \brief Associate a colour components with a list of gains
+ *
+ * Lsc tables are defined as a list of gain values associated to a colour
+ * component.
+ *
+ * \var Components::r
+ * \brief The list of gains for the Red colour component
+ *
+ * \var Components::gr
+ * \brief The list of gains for the Green/Red colour component
+ *
+ * \var Components::gb
+ * \brief The list of gains for the Green/Blue colour component
+ *
+ * \var Components::b
+ * \brief The list of gains for the Blue colour component
+ */
+
+/**
+ * \typedef ComponentsMap
+ * \brief Associate a colour temperature to a lsc table
+ *
+ * An lsc table is generated during the tuning phase for a specific light
+ * temperature, and a tuning file usually contains lsc tables generated for
+ * several different colour temperatures.
+ */
+
+} /* namespace lsc */
+
+/**
+ * \class LscImplementation
+ * \brief Pure virtual base class for lsc algorithm implementations
+ *
+ * Defines the interface for the lsc algorithm implementation.
+ */
+
+/**
+ * \fn LscImplementation::~LscImplementation
+ * \brief Virtual class destructor
+ */
+
+/**
+ * \fn LscImplementation::parseLscData
+ * \brief Parse \a tuningData
+ * \param[in] tuningData The tuning data
+ *
+ * \return 0 on success, a negative error number otherwise
+ */
+
+/**
+ * \fn LscImplementation::sampleForCrop
+ * \brief Re-sample the lsc components for \a cropRectangle
+ * \param[in] cropRectangle The sensor analogue crop rectangle
+ * \param[in] xSizes List of horizontal positions of the lsc grid nodes
+ * \param[in] ySizes List of vertical positions of the lsc grid nodes
+ *
+ * Lsc tables have to be re-sampled every time a new sensor configuration is
+ * used, as each streaming session might use a different sensor crop rectangle
+ * \a cropRectangle.
+ *
+ * \a cropRectangle represents the size of the frame on which the Lsc tables
+ * have to be re-sampled on.
+ *
+ * \a xSizes and \a ySizes represent the position of the grid nodes vertexes in
+ * the [0, 1] interval. In example an equally spaced grid of 16 nodes will have
+ * each segment of size 0.0625 and the list of nodes position will be
+ * [0, 0.0625, 0.125, 0.1875, ... , 1]. It is expected that the first position
+ * is 0 and the last position is 1.
+ */
+
+} /* namespace ipa */
+
+} /* namespace libcamera */
diff --git a/src/ipa/libipa/lsc_base.h b/src/ipa/libipa/lsc_base.h
new file mode 100644
index 000000000000..93f819d3c2af
--- /dev/null
+++ b/src/ipa/libipa/lsc_base.h
@@ -0,0 +1,53 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2026 Ideas on Board Oy
+ *
+ * Base classes and types for LSC algorithms implementations
+ */
+
+#pragma once
+
+#include <map>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include <libcamera/base/span.h>
+
+#include <libcamera/geometry.h>
+
+#include "libcamera/internal/value_node.h"
+
+namespace libcamera {
+
+namespace ipa {
+
+namespace lsc {
+
+struct Components {
+	std::vector<uint16_t> r;
+	std::vector<uint16_t> gr;
+	std::vector<uint16_t> gb;
+	std::vector<uint16_t> b;
+};
+
+using ComponentsMap = std::map<unsigned int, Components>;
+
+} /* namespace lsc */
+
+class LscImplementation
+{
+public:
+	virtual ~LscImplementation() {}
+
+	virtual int parseLscData(const ValueNode &tuningData) = 0;
+
+	virtual lsc::ComponentsMap
+	sampleForCrop(const Rectangle &cropRectangle,
+		      Span<const double> xSizes,
+		      Span<const double> ySizes) = 0;
+};
+
+} /* namespace ipa */
+
+} /* namespace libcamera */
diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build
index edf8eabd8b78..96611e90ee1e 100644
--- a/src/ipa/libipa/meson.build
+++ b/src/ipa/libipa/meson.build
@@ -14,6 +14,7 @@  libipa_headers = files([
     'fixedpoint.h',
     'histogram.h',
     'interpolator.h',
+    'lsc_base.h',
     'lsc_polynomial.h',
     'lux.h',
     'module.h',
@@ -36,6 +37,7 @@  libipa_sources = files([
     'fixedpoint.cpp',
     'histogram.cpp',
     'interpolator.cpp',
+    'lsc_base.cpp',
     'lsc_polynomial.cpp',
     'lux.cpp',
     'module.cpp',
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp
index 92001319279e..e4d9f97ad009 100644
--- a/src/ipa/rkisp1/algorithms/lsc.cpp
+++ b/src/ipa/rkisp1/algorithms/lsc.cpp
@@ -38,10 +38,10 @@  void interpolateVector(const std::vector<T> &a, const std::vector<T> &b,
 }
 
 template<>
-void Interpolator<rkisp1::algorithms::LensShadingCorrection::Components>::
-	interpolate(const rkisp1::algorithms::LensShadingCorrection::Components &a,
-		    const rkisp1::algorithms::LensShadingCorrection::Components &b,
-		    rkisp1::algorithms::LensShadingCorrection::Components &dest,
+void Interpolator<lsc::Components>::
+	interpolate(const lsc::Components &a,
+		    const lsc::Components &b,
+		    lsc::Components &dest,
 		    double lambda)
 {
 	interpolateVector(a.r, b.r, dest.r, lambda);
@@ -80,7 +80,7 @@  public:
 
 	int parseLscData(const ValueNode &sets) override;
 
-	LensShadingCorrection::ComponentsMap
+	lsc::ComponentsMap
 	sampleForCrop(const Rectangle &cropRectangle,
 		      Span<const double> xSizes,
 		      Span<const double> ySizes) override;
@@ -138,7 +138,7 @@  int LscPolynomialImpl::parseLscData(const ValueNode &sets)
 	return 0;
 }
 
-LensShadingCorrection::ComponentsMap
+lsc::ComponentsMap
 LscPolynomialImpl::sampleForCrop(const Rectangle &cropRectangle,
 				 Span<const double> xSizes,
 				 Span<const double> ySizes)
@@ -146,7 +146,7 @@  LscPolynomialImpl::sampleForCrop(const Rectangle &cropRectangle,
 	std::vector<double> xPos = sizesListToPositions(xSizes);
 	std::vector<double> yPos = sizesListToPositions(ySizes);
 
-	LensShadingCorrection::ComponentsMap components;
+	lsc::ComponentsMap components;
 
 	for (const auto &[k, p] : lscData_) {
 		components[k] = {
@@ -226,7 +226,7 @@  class LscTableImpl : public LscImplementation
 public:
 	int parseLscData(const ValueNode &sets) override;
 
-	LensShadingCorrection::ComponentsMap
+	lsc::ComponentsMap
 	sampleForCrop([[maybe_unused]] const Rectangle &cropRectangle,
 		      [[maybe_unused]] Span<const double> xSizes,
 		      [[maybe_unused]] Span<const double> ySizes) override
@@ -240,7 +240,7 @@  private:
 	std::vector<uint16_t> parseTable(const ValueNode &tuningData,
 					 const char *prop);
 
-	LensShadingCorrection::ComponentsMap lscData_;
+	lsc::ComponentsMap lscData_;
 };
 
 int LscTableImpl::parseLscData(const ValueNode &sets)
@@ -255,7 +255,7 @@  int LscTableImpl::parseLscData(const ValueNode &sets)
 			return -EINVAL;
 		}
 
-		LensShadingCorrection::Components components;
+		lsc::Components components;
 		components.r = parseTable(set, "r");
 		components.gr = parseTable(set, "gr");
 		components.gb = parseTable(set, "gb");
@@ -435,8 +435,8 @@  int LensShadingCorrection::configure(IPAContext &context,
 	}
 
 	LOG(RkISP1Lsc, Debug) << "Sample LSC data for " << configInfo.analogCrop;
-	ComponentsMap shadingData = algo_->sampleForCrop(configInfo.analogCrop,
-							 xSize_, ySize_);
+	lsc::ComponentsMap shadingData = algo_->sampleForCrop(configInfo.analogCrop,
+							      xSize_, ySize_);
 	sets_.setData(std::move(shadingData));
 
 	context.activeState.lsc.enabled = true;
@@ -452,7 +452,7 @@  void LensShadingCorrection::setParameters(rkisp1_cif_isp_lsc_config &config)
 }
 
 void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,
-				      const Components &set)
+				      const lsc::Components &set)
 {
 	std::copy(set.r.begin(), set.r.end(), &config.r_data_tbl[0][0]);
 	std::copy(set.gr.begin(), set.gr.end(), &config.gr_data_tbl[0][0]);
@@ -518,7 +518,7 @@  void LensShadingCorrection::prepare([[maybe_unused]] IPAContext &context,
 
 	setParameters(*config);
 
-	const Components &set = sets_.getInterpolated(quantizedCt);
+	const lsc::Components &set = sets_.getInterpolated(quantizedCt);
 	copyTable(*config, set);
 
 	lastAppliedCt_ = ct;
diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h
index 3463531f2ab2..b21c91c0d81f 100644
--- a/src/ipa/rkisp1/algorithms/lsc.h
+++ b/src/ipa/rkisp1/algorithms/lsc.h
@@ -11,6 +11,7 @@ 
 #include <memory>
 
 #include "libipa/interpolator.h"
+#include "libipa/lsc_base.h"
 
 #include "algorithm.h"
 
@@ -18,20 +19,9 @@  namespace libcamera {
 
 namespace ipa::rkisp1::algorithms {
 
-class LscImplementation;
-
 class LensShadingCorrection : public Algorithm
 {
 public:
-	struct Components {
-		std::vector<uint16_t> r;
-		std::vector<uint16_t> gr;
-		std::vector<uint16_t> gb;
-		std::vector<uint16_t> b;
-	};
-
-	using ComponentsMap = std::map<unsigned int, Components>;
-
 	LensShadingCorrection();
 	~LensShadingCorrection() = default;
 
@@ -49,7 +39,7 @@  public:
 		     ControlList &metadata) override;
 private:
 	void setParameters(rkisp1_cif_isp_lsc_config &config);
-	void copyTable(rkisp1_cif_isp_lsc_config &config, const Components &set0);
+	void copyTable(rkisp1_cif_isp_lsc_config &config, const lsc::Components &set0);
 
 	std::vector<double> xSize_;
 	std::vector<double> ySize_;
@@ -61,23 +51,10 @@  private:
 	unsigned int lastAppliedCt_;
 	unsigned int lastAppliedQuantizedCt_;
 
-	ipa::Interpolator<Components> sets_;
+	ipa::Interpolator<lsc::Components> sets_;
 
 	std::unique_ptr<LscImplementation> algo_;
 };
 
-class LscImplementation
-{
-public:
-	virtual ~LscImplementation() {}
-
-	virtual int parseLscData(const ValueNode &sets) = 0;
-
-	virtual LensShadingCorrection::ComponentsMap
-	sampleForCrop(const Rectangle &cropRectangle,
-		      Span<const double> xSizes,
-		      Span<const double> ySizes) = 0;
-};
-
 } /* namespace ipa::rkisp1::algorithms */
 } /* namespace libcamera */