From 7fab2062d8274065e870de20382720a0cdb11193 Mon Sep 17 00:00:00 2001 From: Milan Zamazal Date: Fri, 27 Sep 2024 15:46:20 +0200 Subject: libcamera: software_isp: Move color handling to an algorithm module After black level handling has been moved to an algorithm module, white balance and the construction of color tables can be moved to algorithm modules too. This time, the moved code is split between stats processing and parameter construction methods. It is also split to two algorithm modules: - White balance computation. - Gamma table computation and color lookup tables construction. While this applies the color gains computed by the white balance algorithm, it is not directly related to white balance. And we may want to modify the color lookup tables in future according to other parameters than just gamma and white balance gains. Gamma table computation and color lookup tables construction could be split to separate algorithms too. But there is no big need for that now so they are kept together for simplicity. This is the only part of the software ISP algorithms that sets the parameters so emitting setIspParams can be moved to prepare() method. A more natural representation of the gains (and black level) would be floating point numbers. This is not done here in order to minimize changes in code movements. It will be addressed in a followup patch. Signed-off-by: Milan Zamazal Reviewed-by: Kieran Bingham Acked-by: Umang Jain Signed-off-by: Kieran Bingham --- src/ipa/simple/algorithms/lut.cpp | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/ipa/simple/algorithms/lut.cpp (limited to 'src/ipa/simple/algorithms/lut.cpp') diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp new file mode 100644 index 00000000..644b4f84 --- /dev/null +++ b/src/ipa/simple/algorithms/lut.cpp @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Red Hat Inc. + * + * Color lookup tables construction + */ + +#include "lut.h" + +#include +#include +#include + +#include + +#include "simple/ipa_context.h" + +namespace libcamera { + +namespace ipa::soft::algorithms { + +int Lut::configure(IPAContext &context, + [[maybe_unused]] const IPAConfigInfo &configInfo) +{ + /* Gamma value is fixed */ + context.configuration.gamma = 0.5; + updateGammaTable(context); + + return 0; +} + +void Lut::updateGammaTable(IPAContext &context) +{ + auto &gammaTable = context.activeState.gamma.gammaTable; + auto blackLevel = context.activeState.blc.level; + const unsigned int blackIndex = blackLevel * gammaTable.size() / 256; + + std::fill(gammaTable.begin(), gammaTable.begin() + blackIndex, 0); + const float divisor = gammaTable.size() - blackIndex - 1.0; + for (unsigned int i = blackIndex; i < gammaTable.size(); i++) + gammaTable[i] = UINT8_MAX * std::pow((i - blackIndex) / divisor, + context.configuration.gamma); + + context.activeState.gamma.blackLevel = blackLevel; +} + +void Lut::prepare(IPAContext &context, + [[maybe_unused]] const uint32_t frame, + [[maybe_unused]] IPAFrameContext &frameContext, + [[maybe_unused]] DebayerParams *params) +{ + /* + * Update the gamma table if needed. This means if black level changes + * and since the black level gets updated only if a lower value is + * observed, it's not permanently prone to minor fluctuations or + * rounding errors. + */ + if (context.activeState.gamma.blackLevel != context.activeState.blc.level) + updateGammaTable(context); + + auto &gains = context.activeState.gains; + auto &gammaTable = context.activeState.gamma.gammaTable; + const unsigned int gammaTableSize = gammaTable.size(); + + for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) { + const unsigned int div = static_cast(DebayerParams::kRGBLookupSize) * + 256 / gammaTableSize; + /* Apply gamma after gain! */ + unsigned int idx; + idx = std::min({ i * gains.red / div, gammaTableSize - 1 }); + params->red[i] = gammaTable[idx]; + idx = std::min({ i * gains.green / div, gammaTableSize - 1 }); + params->green[i] = gammaTable[idx]; + idx = std::min({ i * gains.blue / div, gammaTableSize - 1 }); + params->blue[i] = gammaTable[idx]; + } +} + +REGISTER_IPA_ALGORITHM(Lut, "Lut") + +} /* namespace ipa::soft::algorithms */ + +} /* namespace libcamera */ -- cgit v1.2.1