[04/13] libcamera: software_isp: Apply gains in CPU ISP
diff mbox series

Message ID 20260407-kbingham-awb-split-v1-4-a39af3f4dc20@ideasonboard.com
State New
Headers show
Series
  • ipa: simple: Convert to libipa AWB implementation
Related show

Commit Message

Kieran Bingham April 7, 2026, 10:01 p.m. UTC
From: Milan Zamazal <mzamazal@redhat.com>

One of the preceding patches removed white balance gains from the
combined matrix.  Which is correct but the gains are not applied now in
CPU ISP when a CCM is used.

This patch applies the gains in the CCM table.  It also clamps the pixel
values if they are out of range after applying the gains.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 src/libcamera/software_isp/debayer_cpu.cpp | 45 +++++++++++++++---------------
 1 file changed, 23 insertions(+), 22 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp
index 5356d6bbec11c30fa0b05659d44a91e69e2b79d0..2dc0df5597938cc19317187f7b1ed8a10b1cc111 100644
--- a/src/libcamera/software_isp/debayer_cpu.cpp
+++ b/src/libcamera/software_isp/debayer_cpu.cpp
@@ -911,45 +911,46 @@  void DebayerCpu::updateLookupTables(const DebayerParams &params)
 	};
 	const unsigned int gammaTableSize = gammaTable_.size();
 	RGB<float> blackIndex = params.blackLevel * kRGBLookupSize;
+	RGB<float> gains = params.gains;
+	const RGB<float> div = (RGB<float>(kRGBLookupSize) - blackIndex).max(1.0);
 
 	if (ccmEnabled_) {
 		if (gammaUpdateNeeded ||
-		    matrixChanged(params.combinedMatrix, params_.combinedMatrix)) {
+		    matrixChanged(params.combinedMatrix, params_.combinedMatrix) ||
+		    params.gains != params_.gains) {
 			auto &red = swapRedBlueGains_ ? blueCcm_ : redCcm_;
 			auto &green = greenCcm_;
 			auto &blue = swapRedBlueGains_ ? redCcm_ : blueCcm_;
-			const unsigned int redIndex = swapRedBlueGains_ ? 2 : 0;
-			const unsigned int greenIndex = 1;
-			const unsigned int blueIndex = swapRedBlueGains_ ? 0 : 2;
-			const RGB<float> div =
-				(RGB<float>(kRGBLookupSize) - blackIndex).max(1.0) /
-				kRGBLookupSize;
 			for (unsigned int i = 0; i < kRGBLookupSize; i++) {
-				const RGB<float> rgb = ((RGB<float>(i) - blackIndex) / div).max(0.0);
-				red[i].r = std::round(rgb.r() * params.combinedMatrix[redIndex][0]);
-				red[i].g = std::round(rgb.g() * params.combinedMatrix[greenIndex][0]);
-				red[i].b = std::round(rgb.b() * params.combinedMatrix[blueIndex][0]);
-				green[i].r = std::round(rgb.r() * params.combinedMatrix[redIndex][1]);
-				green[i].g = std::round(rgb.g() * params.combinedMatrix[greenIndex][1]);
-				green[i].b = std::round(rgb.b() * params.combinedMatrix[blueIndex][1]);
-				blue[i].r = std::round(rgb.r() * params.combinedMatrix[redIndex][2]);
-				blue[i].g = std::round(rgb.g() * params.combinedMatrix[greenIndex][2]);
-				blue[i].b = std::round(rgb.b() * params.combinedMatrix[blueIndex][2]);
+				const RGB<float> rgb =
+					(gains * (RGB<float>(i) - blackIndex) * kRGBLookupSize / div)
+						.min(kRGBLookupSize - 1)
+						.max(0.0);
+				red[i].r = std::round(rgb.r() * params.combinedMatrix[0][0]);
+				red[i].g = std::round(rgb.g() * params.combinedMatrix[1][0]);
+				red[i].b = std::round(rgb.b() * params.combinedMatrix[2][0]);
+				green[i].r = std::round(rgb.r() * params.combinedMatrix[0][1]);
+				green[i].g = std::round(rgb.g() * params.combinedMatrix[1][1]);
+				green[i].b = std::round(rgb.b() * params.combinedMatrix[2][1]);
+				blue[i].r = std::round(rgb.r() * params.combinedMatrix[0][2]);
+				blue[i].g = std::round(rgb.g() * params.combinedMatrix[1][2]);
+				blue[i].b = std::round(rgb.b() * params.combinedMatrix[2][2]);
+				if (swapRedBlueGains_) {
+					std::swap(red[i].r, red[i].b);
+					std::swap(green[i].r, green[i].b);
+					std::swap(blue[i].r, blue[i].b);
+				}
 				gammaLut_[i] = gammaTable_[i * gammaTableSize / kRGBLookupSize];
 			}
 		}
 	} else {
 		if (gammaUpdateNeeded || params.gains != params_.gains) {
-			auto &gains = params.gains;
 			auto &red = swapRedBlueGains_ ? blue_ : red_;
 			auto &green = green_;
 			auto &blue = swapRedBlueGains_ ? red_ : blue_;
-			const RGB<float> div =
-				(RGB<float>(kRGBLookupSize) - blackIndex).max(1.0) /
-				gammaTableSize;
 			for (unsigned int i = 0; i < kRGBLookupSize; i++) {
 				const RGB<float> lutGains =
-					(gains * (RGB<float>(i) - blackIndex) / div)
+					(gains * (RGB<float>(i) - blackIndex) * gammaTableSize / div)
 						.min(gammaTableSize - 1)
 						.max(0.0);
 				red[i] = gammaTable_[lutGains.r()];