mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 07:19:45 +03:00
Fix a few assorted typographical issues: - Sentences should end with a period. - Paragraphs should be separated by a blank line, and there should be no line break within a paragraph. - Doxygen lists need a list marker ('-' or '*', use '-' here). Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
154 lines
4 KiB
C++
154 lines
4 KiB
C++
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/*
|
|
* Copyright (C) 2024, Ideas On Board
|
|
*
|
|
* RkISP1 Gamma out control
|
|
*/
|
|
#include "goc.h"
|
|
|
|
#include <cmath>
|
|
|
|
#include <libcamera/base/log.h>
|
|
#include <libcamera/base/utils.h>
|
|
|
|
#include <libcamera/control_ids.h>
|
|
|
|
#include "libcamera/internal/yaml_parser.h"
|
|
|
|
#include "linux/rkisp1-config.h"
|
|
|
|
/**
|
|
* \file goc.h
|
|
*/
|
|
|
|
namespace libcamera {
|
|
|
|
namespace ipa::rkisp1::algorithms {
|
|
|
|
/**
|
|
* \class GammaOutCorrection
|
|
* \brief RkISP1 Gamma out correction
|
|
*
|
|
* This algorithm implements the gamma out curve for the RkISP1. It defaults to
|
|
* a gamma value of 2.2.
|
|
*
|
|
* As gamma is internally represented as a piecewise linear function with only
|
|
* 17 knots, the difference between gamma=2.2 and sRGB gamma is minimal.
|
|
* Therefore sRGB gamma was not implemented as special case.
|
|
*
|
|
* Useful links:
|
|
* - https://www.cambridgeincolour.com/tutorials/gamma-correction.htm
|
|
* - https://en.wikipedia.org/wiki/SRGB
|
|
*/
|
|
|
|
LOG_DEFINE_CATEGORY(RkISP1Gamma)
|
|
|
|
const float kDefaultGamma = 2.2f;
|
|
|
|
/**
|
|
* \copydoc libcamera::ipa::Algorithm::init
|
|
*/
|
|
int GammaOutCorrection::init([[maybe_unused]] IPAContext &context,
|
|
[[maybe_unused]] const YamlObject &tuningData)
|
|
{
|
|
if (context.hw->numGammaOutSamples !=
|
|
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10) {
|
|
LOG(RkISP1Gamma, Error)
|
|
<< "Gamma is not implemented for RkISP1 V12";
|
|
return -EINVAL;
|
|
}
|
|
|
|
defaultGamma_ = tuningData["gamma"].get<double>(kDefaultGamma);
|
|
context.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, defaultGamma_);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Configure the Gamma given a configInfo
|
|
* \param[in] context The shared IPA context
|
|
* \param[in] configInfo The IPA configuration data
|
|
*
|
|
* \return 0
|
|
*/
|
|
int GammaOutCorrection::configure(IPAContext &context,
|
|
[[maybe_unused]] const IPACameraSensorInfo &configInfo)
|
|
{
|
|
context.activeState.goc.gamma = defaultGamma_;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* \copydoc libcamera::ipa::Algorithm::queueRequest
|
|
*/
|
|
void GammaOutCorrection::queueRequest([[maybe_unused]] IPAContext &context,
|
|
[[maybe_unused]] const uint32_t frame,
|
|
IPAFrameContext &frameContext,
|
|
const ControlList &controls)
|
|
{
|
|
if (frame == 0)
|
|
frameContext.goc.update = true;
|
|
|
|
const auto &gamma = controls.get(controls::Gamma);
|
|
if (gamma) {
|
|
context.activeState.goc.gamma = *gamma;
|
|
frameContext.goc.update = true;
|
|
LOG(RkISP1Gamma, Debug) << "Set gamma to " << *gamma;
|
|
}
|
|
|
|
frameContext.goc.gamma = context.activeState.goc.gamma;
|
|
}
|
|
|
|
/**
|
|
* \copydoc libcamera::ipa::Algorithm::prepare
|
|
*/
|
|
void GammaOutCorrection::prepare([[maybe_unused]] IPAContext &context,
|
|
[[maybe_unused]] const uint32_t frame,
|
|
[[maybe_unused]] IPAFrameContext &frameContext,
|
|
rkisp1_params_cfg *params)
|
|
{
|
|
ASSERT(context.hw->numGammaOutSamples ==
|
|
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);
|
|
|
|
/*
|
|
* The logarithmic segments as specified in the reference.
|
|
* Plus an additional 0 to make the loop easier
|
|
*/
|
|
std::array<unsigned, RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10> segments = {
|
|
64, 64, 64, 64, 128, 128, 128, 128, 256,
|
|
256, 256, 512, 512, 512, 512, 512, 0
|
|
};
|
|
auto gamma_y = params->others.goc_config.gamma_y;
|
|
|
|
if (!frameContext.goc.update)
|
|
return;
|
|
|
|
unsigned x = 0;
|
|
for (const auto [i, size] : utils::enumerate(segments)) {
|
|
gamma_y[i] = std::pow(x / 4096.0, 1.0 / frameContext.goc.gamma) * 1023.0;
|
|
x += size;
|
|
}
|
|
|
|
params->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;
|
|
params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;
|
|
params->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;
|
|
params->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;
|
|
}
|
|
|
|
/**
|
|
* \copydoc libcamera::ipa::Algorithm::process
|
|
*/
|
|
void GammaOutCorrection::process([[maybe_unused]] IPAContext &context,
|
|
[[maybe_unused]] const uint32_t frame,
|
|
IPAFrameContext &frameContext,
|
|
[[maybe_unused]] const rkisp1_stat_buffer *stats,
|
|
ControlList &metadata)
|
|
{
|
|
metadata.set(controls::Gamma, frameContext.goc.gamma);
|
|
}
|
|
|
|
REGISTER_IPA_ALGORITHM(GammaOutCorrection, "GammaOutCorrection")
|
|
|
|
} /* namespace ipa::rkisp1::algorithms */
|
|
|
|
} /* namespace libcamera */
|