[{"id":39641,"web_url":"https://patchwork.libcamera.org/comment/39641/","msgid":"<ak5q8RTIolE_qhi3@zed>","date":"2026-07-08T15:21:35","subject":"Re: [PATCH v2 09/12] ipa: rkisp1: goc: Re-work to use GammaAlgorithm\n\tclass","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Dan\n\nOn Fri, Jun 26, 2026 at 02:05:56PM +0100, Daniel Scally wrote:\n> Re-work the RkISP1 Gamma Out Correction algorithm to use the new\n> GammaAlgorithm class from libipa, which allows us to share an\n> implementation with the other IPAs.\n>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n\nReviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n\nThanks\n  j\n\n> ---\n> Changes in v2:\n>\n>         - Fixed includes\n> \t- Dropped the comment explaining how gamma correction is\n> \t  implemented - it's on libipa gamma now\n> \t- Dropped unused variable kDefaultGamma\n> ---\n>  src/ipa/rkisp1/algorithms/goc.cpp | 63 +++++++++++----------------------------\n>  src/ipa/rkisp1/algorithms/goc.h   |  7 ++++-\n>  src/ipa/rkisp1/ipa_context.h      | 10 ++-----\n>  3 files changed, 26 insertions(+), 54 deletions(-)\n>\n> diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp\n> index e8f64bf3d5e028c2013d37b7ef9fe90b737fad5f..e3bea4bbef186dde28fdd5a3aa14b7662a9ffe69 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/goc.cpp\n> @@ -6,10 +6,11 @@\n>   */\n>  #include \"goc.h\"\n>\n> +#include <array>\n>  #include <cmath>\n>\n>  #include <libcamera/base/log.h>\n> -#include <libcamera/base/utils.h>\n> +#include <libcamera/base/span.h>\n>\n>  #include <libcamera/control_ids.h>\n>\n> @@ -29,21 +30,13 @@ namespace ipa::rkisp1::algorithms {\n>   * \\class GammaOutCorrection\n>   * \\brief RkISP1 Gamma out correction\n>   *\n> - * This algorithm implements the gamma out curve for the RkISP1. It defaults to\n> - * a gamma value of 2.2.\n> - *\n> - * As gamma is internally represented as a piecewise linear function with only\n> - * 17 knots, the difference between gamma=2.2 and sRGB gamma is minimal.\n> - * Therefore sRGB gamma was not implemented as special case.\n> - *\n> - * Useful links:\n> - * - https://www.cambridgeincolour.com/tutorials/gamma-correction.htm\n> - * - https://en.wikipedia.org/wiki/SRGB\n> + * This algorithm implements the gamma out curve for the RkISP1 using the\n> + * libipa GammaAlgorithm class.\n>   */\n>\n>  LOG_DEFINE_CATEGORY(RkISP1Gamma)\n>\n> -const float kDefaultGamma = 2.2f;\n> +static constexpr unsigned int kNumLutSegments = RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10 - 1;\n>\n>  /**\n>   * \\copydoc libcamera::ipa::Algorithm::init\n> @@ -57,10 +50,12 @@ int GammaOutCorrection::init(IPAContext &context, const ValueNode &tuningData)\n>  \t\treturn -EINVAL;\n>  \t}\n>\n> -\tdefaultGamma_ = tuningData[\"gamma\"].get<double>(kDefaultGamma);\n> -\tcontext.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, defaultGamma_);\n> +\tstd::array<unsigned int, kNumLutSegments> segments = {\n> +\t\t 64,  64,  64,  64, 128, 128, 128, 128,\n> +\t\t256, 256, 256, 512, 512, 512, 512, 512\n> +\t};\n>\n> -\treturn 0;\n> +\treturn gammaAlgo_.init(context.ctrlMap, tuningData, segments);\n>  }\n>\n>  /**\n> @@ -69,7 +64,7 @@ int GammaOutCorrection::init(IPAContext &context, const ValueNode &tuningData)\n>  int GammaOutCorrection::configure(IPAContext &context,\n>  \t\t\t\t  [[maybe_unused]] const IPACameraSensorInfo &configInfo)\n>  {\n> -\tcontext.activeState.goc.gamma = defaultGamma_;\n> +\tgammaAlgo_.configure(context.activeState.gamma);\n>  \treturn 0;\n>  }\n>\n> @@ -80,17 +75,8 @@ void GammaOutCorrection::queueRequest(IPAContext &context, const uint32_t frame,\n>  \t\t\t\t      IPAFrameContext &frameContext,\n>  \t\t\t\t      const ControlList &controls)\n>  {\n> -\tif (frame == 0)\n> -\t\tframeContext.goc.update = true;\n> -\n> -\tconst auto &gamma = controls.get(controls::Gamma);\n> -\tif (gamma) {\n> -\t\tcontext.activeState.goc.gamma = *gamma;\n> -\t\tframeContext.goc.update = true;\n> -\t\tLOG(RkISP1Gamma, Debug) << \"Set gamma to \" << *gamma;\n> -\t}\n> -\n> -\tframeContext.goc.gamma = context.activeState.goc.gamma;\n> +\tgammaAlgo_.queueRequest(context.activeState.gamma, frame,\n> +\t\t\t\tframeContext.gamma, controls);\n>  }\n>\n>  /**\n> @@ -104,29 +90,14 @@ void GammaOutCorrection::prepare(IPAContext &context,\n>  \tASSERT(context.hw.numGammaOutSamples ==\n>  \t       RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);\n>\n> -\tif (!frameContext.goc.update)\n> +\tif (!frameContext.gamma.update)\n>  \t\treturn;\n>\n> -\t/*\n> -\t * The logarithmic segments as specified in the reference.\n> -\t * Plus an additional 0 to make the loop easier\n> -\t */\n> -\tstatic constexpr std::array<unsigned int, RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10> segments = {\n> -\t\t64, 64, 64, 64, 128, 128, 128, 128, 256,\n> -\t\t256, 256, 512, 512, 512, 512, 512, 0\n> -\t};\n> -\n>  \tauto config = params->block<BlockType::Goc>();\n>  \tconfig.setEnabled(true);\n>\n> -\t__u16 *gamma_y = config->gamma_y;\n> -\n> -\tunsigned x = 0;\n> -\tfor (const auto [i, size] : utils::enumerate(segments)) {\n> -\t\tgamma_y[i] = std::pow(x / 4096.0, 1.0 / frameContext.goc.gamma) * 1023.0;\n> -\t\tx += size;\n> -\t}\n> -\n> +\tSpan<uint16_t> lut{ config->gamma_y };\n> +\tgammaAlgo_.prepare(frameContext.gamma, lut);\n>  \tconfig->mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n>  }\n>\n> @@ -139,7 +110,7 @@ void GammaOutCorrection::process([[maybe_unused]] IPAContext &context,\n>  \t\t\t\t [[maybe_unused]] const rkisp1_stat_buffer *stats,\n>  \t\t\t\t ControlList &metadata)\n>  {\n> -\tmetadata.set(controls::Gamma, frameContext.goc.gamma);\n> +\tgammaAlgo_.process(frameContext.gamma, metadata);\n>  }\n>\n>  REGISTER_IPA_ALGORITHM(GammaOutCorrection, \"GammaOutCorrection\")\n> diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h\n> index bd79fe19cc86b8aefa2603e98e9d7130b44105d9..767d707b2758a89db286ab62d8f20d7a01912a2a 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.h\n> +++ b/src/ipa/rkisp1/algorithms/goc.h\n> @@ -9,6 +9,11 @@\n>\n>  #include \"algorithm.h\"\n>\n> +#include <linux/rkisp1-config.h>\n> +\n> +#include <libipa/fixedpoint.h>\n> +#include <libipa/gamma.h>\n> +\n>  namespace libcamera {\n>\n>  namespace ipa::rkisp1::algorithms {\n> @@ -35,7 +40,7 @@ public:\n>  \t\t     ControlList &metadata) override;\n>\n>  private:\n> -\tfloat defaultGamma_;\n> +\tGammaAlgorithm<RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10, UQ<0, 10>> gammaAlgo_;\n>  };\n>\n>  } /* namespace ipa::rkisp1::algorithms */\n> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\n> index 7b4346c54ed2b8850ed147b0ce2b8a20155b80cf..8011c353c4eaade85d0a0007b44de8af7beaa9d6 100644\n> --- a/src/ipa/rkisp1/ipa_context.h\n> +++ b/src/ipa/rkisp1/ipa_context.h\n> @@ -30,6 +30,7 @@\n>  #include \"libipa/ccm.h\"\n>  #include \"libipa/fc_queue.h\"\n>  #include \"libipa/fixedpoint.h\"\n> +#include \"libipa/gamma.h\"\n>  #include \"libipa/lsc.h\"\n>\n>  namespace libcamera {\n> @@ -127,9 +128,7 @@ struct IPAActiveState {\n>  \t\tuint8_t sharpness;\n>  \t} filter;\n>\n> -\tstruct {\n> -\t\tdouble gamma;\n> -\t} goc;\n> +\tipa::gamma::ActiveState gamma;\n>\n>  \tstruct {\n>  \t\tdouble lux;\n> @@ -194,10 +193,7 @@ struct IPAFrameContext : public FrameContext {\n>  \t\tbool update;\n>  \t} filter;\n>\n> -\tstruct {\n> -\t\tdouble gamma;\n> -\t\tbool update;\n> -\t} goc;\n> +\tipa::gamma::FrameContext gamma;\n>\n>  \tstruct {\n>  \t\tuint32_t exposure;\n>\n> --\n> 2.43.0\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id AAA82C3264\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  8 Jul 2026 15:21:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id ACE10660A2;\n\tWed,  8 Jul 2026 17:21:39 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 439296608D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  8 Jul 2026 17:21:38 +0200 (CEST)","from ideasonboard.com (93-46-82-201.ip106.fastwebnet.it\n\t[93.46.82.201])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4CF1DEAA;\n\tWed,  8 Jul 2026 17:20:48 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"qG4CsoT/\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1783524048;\n\tbh=O/JA5B4AdsVogNBnWljnMi0DhfP9DqR6g2ukoz/oy/w=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=qG4CsoT/h6PGakohtyFiwi1XsQCjPGOqwudq8t3DmE2Xd72bNxZM4RFjfGCz8mSGz\n\tPsyzTvupN6Aduqrvv8fsOMEWgzBWYIgaIXheJi+aZ6z4H59SOBchF7rt0mnBmVowzU\n\tNOFdnpEOWeLkO7szay1HmjK6SBTcpLB9mp4FQ9Ts=","Date":"Wed, 8 Jul 2026 17:21:35 +0200","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Daniel Scally <dan.scally@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, \n\tKieran Bingham <kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v2 09/12] ipa: rkisp1: goc: Re-work to use GammaAlgorithm\n\tclass","Message-ID":"<ak5q8RTIolE_qhi3@zed>","References":"<20260626-ipu3-libipa-rework-v2-0-41546e23de3e@ideasonboard.com>\n\t<20260626-ipu3-libipa-rework-v2-9-41546e23de3e@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20260626-ipu3-libipa-rework-v2-9-41546e23de3e@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]