[{"id":38538,"web_url":"https://patchwork.libcamera.org/comment/38538/","msgid":"<851pgpbkxh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-04-08T14:12:26","subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi Kieran,\n\nKieran Bingham <kieran.bingham@ideasonboard.com> writes:\n\n> Utilise the lux component of libipa to map in the lux estimate\n> process using the yHistgram of the Soft ISP statistics.\n\ns/yHistgram/yHistogram/\n\nI suppose the algorithm is supposed to be enabled manually, in case the\ncorresponding tuning data is available?  It would be worth to explain\nits purpose and use here.\n\n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  src/ipa/simple/algorithms/lux.cpp     | 93 +++++++++++++++++++++++++++++++++++\n>  src/ipa/simple/algorithms/lux.h       | 39 +++++++++++++++\n>  src/ipa/simple/algorithms/meson.build |  1 +\n>  src/ipa/simple/ipa_context.h          |  5 ++\n>  4 files changed, 138 insertions(+)\n>\n> diff --git a/src/ipa/simple/algorithms/lux.cpp b/src/ipa/simple/algorithms/lux.cpp\n> new file mode 100644\n> index 0000000000000000000000000000000000000000..03b44ac584ae141509e79954159272504cdba17d\n> --- /dev/null\n> +++ b/src/ipa/simple/algorithms/lux.cpp\n> @@ -0,0 +1,93 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Ideas On Board\n> + *\n> + * Simple Lux control\n> + */\n> +\n> +#include \"lux.h\"\n> +\n> +#include <libcamera/base/log.h>\n> +\n> +#include <libcamera/control_ids.h>\n> +\n> +#include \"libipa/histogram.h\"\n> +#include \"libipa/lux.h\"\n> +\n> +/**\n> + * \\file lux.h\n> + */\n> +\n> +namespace libcamera {\n> +\n> +namespace ipa::soft::algorithms {\n> +\n> +/**\n> + * \\class Lux\n> + * \\brief SoftISP Lux control\n> + *\n> + * The Lux algorithm is responsible for estimating the lux level of the image.\n> + * It doesn't take or generate any controls, but it provides a lux level for\n> + * other algorithms (such as AGC) to use.\n> + */\n> +\n> +/**\n> + * \\brief Construct a SoftISP Lux algo module\n> + */\n> +Lux::Lux()\n> +{\n> +}\n> +\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::init\n> + */\n> +int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)\n> +{\n> +\treturn lux_.parseTuningData(tuningData);\n> +}\n> +\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::prepare\n> + */\n> +void Lux::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n> +\t\t  IPAFrameContext &frameContext,\n> +\t\t  [[maybe_unused]] DebayerParams *params)\n> +{\n> +\tframeContext.lux.lux = context.activeState.lux.lux;\n> +}\n> +\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::process\n> + */\n> +void Lux::process(IPAContext &context,\n> +\t\t  [[maybe_unused]] const uint32_t frame,\n> +\t\t  IPAFrameContext &frameContext,\n> +\t\t  const SwIspStats *stats,\n> +\t\t  ControlList &metadata)\n> +{\n> +\t/*\n> +\t * Report the lux level used by algorithms to prepare this frame\n> +\t * not the lux level *of* this frame.\n> +\t */\n> +\tmetadata.set(controls::Lux, frameContext.lux.lux);\n\nShould this be reported before the lux value is determined for the first\ntime?\n\n> +\tif (!stats)\n> +\t\treturn;\n> +\n> +\t/* Todo: Sensor configuration should move out of AGC */\n\nTodo: -> \\todo\n\nThe comment is a bit confusing here, it might be better to attach it to\nthe sensor configuration in AGC.\n\n> +\tutils::Duration exposureTime = context.configuration.agc.lineDuration *\n> +\t\t\t\t       frameContext.sensor.exposure;\n> +\tdouble gain = frameContext.sensor.gain;\n> +\tdouble digitalGain = 1.0;\n> +\n> +\tHistogram yHist(stats->yHistogram);\n> +\n> +\tcontext.activeState.lux.lux =\n> +\t\tlux_.estimateLux(exposureTime, gain, digitalGain, yHist);\n> +}\n> +\n> +REGISTER_IPA_ALGORITHM(Lux, \"Lux\")\n> +\n> +} /* namespace ipa::soft::algorithms */\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/ipa/simple/algorithms/lux.h b/src/ipa/simple/algorithms/lux.h\n> new file mode 100644\n> index 0000000000000000000000000000000000000000..04ec4c163ede422369977017cca70d12a8d361fb\n> --- /dev/null\n> +++ b/src/ipa/simple/algorithms/lux.h\n> @@ -0,0 +1,39 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Ideas On Board\n> + *\n> + * Simple Lux control\n> + */\n> +\n> +#pragma once\n> +\n> +#include <sys/types.h>\n> +\n> +#include \"libipa/lux.h\"\n> +\n> +#include \"algorithm.h\"\n> +\n> +namespace libcamera {\n> +\n> +namespace ipa::soft::algorithms {\n> +\n> +class Lux : public Algorithm\n> +{\n> +public:\n> +\tLux();\n> +\n> +\tint init(IPAContext &context, const YamlObject &tuningData) override;\n> +\tvoid prepare(IPAContext &context, const uint32_t frame,\n> +\t\t     IPAFrameContext &frameContext,\n> +\t\t     DebayerParams *params) override;\n> +\tvoid process(IPAContext &context, const uint32_t frame,\n> +\t\t     IPAFrameContext &frameContext,\n> +\t\t     const SwIspStats *stats,\n> +\t\t     ControlList &metadata) override;\n> +\n> +private:\n> +\tipa::Lux lux_;\n> +};\n> +\n> +} /* namespace ipa::soft::algorithms */\n> +} /* namespace libcamera */\n> diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\n> index 73c63722083ff92147253c6b10440ce50743988d..27e73c9a0eea2241cc4a4cefd1594c976fb59318 100644\n> --- a/src/ipa/simple/algorithms/meson.build\n> +++ b/src/ipa/simple/algorithms/meson.build\n> @@ -6,4 +6,5 @@ soft_simple_ipa_algorithms = files([\n>      'agc.cpp',\n>      'blc.cpp',\n>      'ccm.cpp',\n> +    'lux.cpp',\n>  ])\n> diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n> index 8ccfacb46a59cedb5a0ad051d67f7c1f40af4b52..2bd7c4642b118d7bb94b1b16cdf4ede5fb2554b5 100644\n> --- a/src/ipa/simple/ipa_context.h\n> +++ b/src/ipa/simple/ipa_context.h\n> @@ -17,6 +17,7 @@\n>  #include \"libcamera/internal/vector.h\"\n>  \n>  #include <libipa/fc_queue.h>\n> +#include <libipa/lux.h>\n>  \n>  #include \"core_ipa_interface.h\"\n>  \n> @@ -36,6 +37,8 @@ struct IPASessionConfiguration {\n>  };\n>  \n>  struct IPAActiveState {\n> +\tipa::lux::ActiveState lux;\n\nDoes this need setting an initial value some way?\n\n> +\n>  \tstruct {\n>  \t\tint32_t exposure;\n>  \t\tdouble again;\n> @@ -64,6 +67,8 @@ struct IPAActiveState {\n>  };\n>  \n>  struct IPAFrameContext : public FrameContext {\n> +\tipa::lux::FrameContext lux;\n> +\n>  \tMatrix<float, 3, 3> ccm;\n>  \n>  \tstruct {","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 CB453BEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  8 Apr 2026 14:12:37 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D749062DDF;\n\tWed,  8 Apr 2026 16:12:36 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 54AC362CE6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  8 Apr 2026 16:12:35 +0200 (CEST)","from mail-wr1-f72.google.com (mail-wr1-f72.google.com\n\t[209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-511-_Umyw_BsO06ehfqD1RAKZg-1; Wed, 08 Apr 2026 10:12:30 -0400","by mail-wr1-f72.google.com with SMTP id\n\tffacd0b85a97d-43b9a86b9b0so7763278f8f.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 08 Apr 2026 07:12:30 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-488c556bfd2sm31295635e9.3.2026.04.08.07.12.27\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 08 Apr 2026 07:12:27 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"D8L8wNjH\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1775657554;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=qjGwZW/X2nPV6qfoTz/vYqbVI3shkIj5JcuZrNm0tVw=;\n\tb=D8L8wNjHZMxBle25xRETx01A98kNS84xz6fwkCeag77AMs9FTSgQKIWuZCXvxxvhnHE6Fk\n\tVvqTcbv27y8GiaT2H093bvIUyxJh8tt/lmw5bXlYkJr6hEQe7/HEoZi/Rav8hf9y29q4H9\n\tFOamy+fDtekj2lUpUrcTJ+GMiRUzsYE=","X-MC-Unique":"_Umyw_BsO06ehfqD1RAKZg-1","X-Mimecast-MFC-AGG-ID":"_Umyw_BsO06ehfqD1RAKZg_1775657549","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1775657549; x=1776262349;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=qjGwZW/X2nPV6qfoTz/vYqbVI3shkIj5JcuZrNm0tVw=;\n\tb=dEy6Bea2mc7qijQDmJok07t0dCQsQsr/DTdqQ5ZNTB6vocigUoQp1ArpmIvgzz9eE5\n\twZSaAZIHMy5+8qeqT0yPQ99sH9oQ8OK2guHsb1WSTr3KG4sBVj7htBGl2TDABIGJQpEN\n\tusNgYl0SRNwVOhHex1eEix5KtRNgpPOjlabxTAJJwqkid7jUVwEA2sjiHrWZhLsP+Wtt\n\t9Orc7RQUm4CdmQeXT8WyzCesKuih9I++QTYSxIIiSF9Pu8Ncf5CUS2aozEN/x3x3MJqK\n\t0ATkeN3vGMHx2p5CqCZei7RUtVNLiciBm5LGXXuMnKh+P6ganrBsBwPPTolMZsoeIAJx\n\tXzWg==","X-Gm-Message-State":"AOJu0YwSqFdspM9MRsFsIP9bMe53soAwuuG3916dGchfI2hoc5FVJe/d\n\tU5SmF/gQ8or3bJbSvEboT/B+W9PRKVOrB0TAeromznX/cjKbDe3EHfg8adkz2bGvwr2L7A+Q+55\n\tebzaf/BxM1LKoNMytFhVRsUmLaUUER1RxAE64c6CCFifoXKEr1LXIg55N8twjDrsIgeFc/pum4l\n\tT1ywI4UwrAqQcV1h4EuuB4az6tp3ZxkHOC9U23DcMDrWOOLkIqZYeLJNFqZII=","X-Gm-Gg":"AeBDievrO0JKawLD/AcA+OYplKT+YzdkauwUCZ6MIqceg0UZNTjhA0m2TZMxLlvZ93L\n\te6Kf4PbxKm9bb5vymrMEqam8IEYEYSgVQBsGQveEOd1/5Ba5L7KgwhixNn4rBII9ml3ueUMDRdM\n\tdEhVsaKOqlBYoWQjbfKFlCQ7G3qqfRDoA2IfxPe2TQuWeFMEiCXqNxge/i82kFkrsFOpAL+Jv6M\n\t2l+tMyvmSoyH7Dfc7WnfgaEA/GslWb/m4T0aEaY+YydYBYYAa5cOaF9a7JasJVOXPYCq0MUf7SQ\n\tH49y2IkeyXvdnzz1HfFC6xMJT7r1IvVp0Mn7LuYNAD4Y7INGknP+H3DIkLMGjX5S18SxK/OjYyF\n\tqVQuWZbMlvY3dv1iN9GfhrUiiUBv/qO6UQC4QNPQGCJIcfRdbdiUzubdtClWdEYYfEFkMR1RhB8\n\tk=","X-Received":["by 2002:a05:600c:638e:b0:47e:e48b:506d with SMTP id\n\t5b1f17b1804b1-488997b21f4mr305298475e9.16.1775657548892; \n\tWed, 08 Apr 2026 07:12:28 -0700 (PDT)","by 2002:a05:600c:638e:b0:47e:e48b:506d with SMTP id\n\t5b1f17b1804b1-488997b21f4mr305297755e9.16.1775657548280; \n\tWed, 08 Apr 2026 07:12:28 -0700 (PDT)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","In-Reply-To":"<20260407-kbingham-awb-split-v1-7-a39af3f4dc20@ideasonboard.com>\n\t(Kieran Bingham's message of \"Tue, 07 Apr 2026 23:01:10 +0100\")","References":"<20260407-kbingham-awb-split-v1-0-a39af3f4dc20@ideasonboard.com>\n\t<20260407-kbingham-awb-split-v1-7-a39af3f4dc20@ideasonboard.com>","Date":"Wed, 08 Apr 2026 16:12:26 +0200","Message-ID":"<851pgpbkxh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"LTRGOiX5n6fV7565SPf29Z2jgkMPK5cDW6GezxX8CYI_1775657549","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>"}},{"id":38546,"web_url":"https://patchwork.libcamera.org/comment/38546/","msgid":"<177566993453.575056.14646244958754829767@ping.linuxembedded.co.uk>","date":"2026-04-08T17:38:54","subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Milan Zamazal (2026-04-08 15:12:26)\n> Hi Kieran,\n> \n> Kieran Bingham <kieran.bingham@ideasonboard.com> writes:\n> \n> > Utilise the lux component of libipa to map in the lux estimate\n> > process using the yHistgram of the Soft ISP statistics.\n> \n> s/yHistgram/yHistogram/\n> \n> I suppose the algorithm is supposed to be enabled manually, in case the\n> corresponding tuning data is available?  It would be worth to explain\n> its purpose and use here.\n\nNot manually, I think it's just used when there is available tuning\ndata. It helps for AWB ultimately.\n\n\n> \n> > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >  src/ipa/simple/algorithms/lux.cpp     | 93 +++++++++++++++++++++++++++++++++++\n> >  src/ipa/simple/algorithms/lux.h       | 39 +++++++++++++++\n> >  src/ipa/simple/algorithms/meson.build |  1 +\n> >  src/ipa/simple/ipa_context.h          |  5 ++\n> >  4 files changed, 138 insertions(+)\n> >\n> > diff --git a/src/ipa/simple/algorithms/lux.cpp b/src/ipa/simple/algorithms/lux.cpp\n> > new file mode 100644\n> > index 0000000000000000000000000000000000000000..03b44ac584ae141509e79954159272504cdba17d\n> > --- /dev/null\n> > +++ b/src/ipa/simple/algorithms/lux.cpp\n> > @@ -0,0 +1,93 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2024, Ideas On Board\n> > + *\n> > + * Simple Lux control\n> > + */\n> > +\n> > +#include \"lux.h\"\n> > +\n> > +#include <libcamera/base/log.h>\n> > +\n> > +#include <libcamera/control_ids.h>\n> > +\n> > +#include \"libipa/histogram.h\"\n> > +#include \"libipa/lux.h\"\n> > +\n> > +/**\n> > + * \\file lux.h\n> > + */\n> > +\n> > +namespace libcamera {\n> > +\n> > +namespace ipa::soft::algorithms {\n> > +\n> > +/**\n> > + * \\class Lux\n> > + * \\brief SoftISP Lux control\n> > + *\n> > + * The Lux algorithm is responsible for estimating the lux level of the image.\n> > + * It doesn't take or generate any controls, but it provides a lux level for\n> > + * other algorithms (such as AGC) to use.\n> > + */\n> > +\n> > +/**\n> > + * \\brief Construct a SoftISP Lux algo module\n> > + */\n> > +Lux::Lux()\n> > +{\n> > +}\n\nI don't think that's needed when it's empty ;-)\n\n> > +\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::init\n> > + */\n> > +int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)\n> > +{\n> > +     return lux_.parseTuningData(tuningData);\n> > +}\n> > +\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::prepare\n> > + */\n> > +void Lux::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n> > +               IPAFrameContext &frameContext,\n> > +               [[maybe_unused]] DebayerParams *params)\n> > +{\n> > +     frameContext.lux.lux = context.activeState.lux.lux;\n> > +}\n> > +\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::process\n> > + */\n> > +void Lux::process(IPAContext &context,\n> > +               [[maybe_unused]] const uint32_t frame,\n> > +               IPAFrameContext &frameContext,\n> > +               const SwIspStats *stats,\n> > +               ControlList &metadata)\n> > +{\n> > +     /*\n> > +      * Report the lux level used by algorithms to prepare this frame\n> > +      * not the lux level *of* this frame.\n> > +      */\n> > +     metadata.set(controls::Lux, frameContext.lux.lux);\n> \n> Should this be reported before the lux value is determined for the first\n> time?\n\nOhh no good spot, there's some startup ordering errors here...\n\n> \n> > +     if (!stats)\n> > +             return;\n> > +\n> > +     /* Todo: Sensor configuration should move out of AGC */\n> \n> Todo: -> \\todo\n> \n> The comment is a bit confusing here, it might be better to attach it to\n> the sensor configuration in AGC.\n\nMaybe, but this is me explicitly telling myself yet another place that\nneeds to refactor the AEGC into libipa, and split out sensor controls\nfrom the AGC, and have a dedicated sensor context.\n\nBecause even if AEGC isn't \"running\" if we know the stats, and the\nexposure and gain we can know the lux - so the sensor properties\nshouldn't be tied directly into the AGC like they are.\n\nIt's one of the many rabbit holes that have made it harder for me to split out\nAgcMeanLuminance and use it for soft-ipa. I've hoped starting with\nLux/AWB will make it easier to progress and then do the same for AGC./\n\n\n> \n> > +     utils::Duration exposureTime = context.configuration.agc.lineDuration *\n> > +                                    frameContext.sensor.exposure;\n> > +     double gain = frameContext.sensor.gain;\n> > +     double digitalGain = 1.0;\n> > +\n> > +     Histogram yHist(stats->yHistogram);\n> > +\n> > +     context.activeState.lux.lux =\n> > +             lux_.estimateLux(exposureTime, gain, digitalGain, yHist);\n> > +}\n> > +\n> > +REGISTER_IPA_ALGORITHM(Lux, \"Lux\")\n> > +\n> > +} /* namespace ipa::soft::algorithms */\n> > +\n> > +} /* namespace libcamera */\n> > diff --git a/src/ipa/simple/algorithms/lux.h b/src/ipa/simple/algorithms/lux.h\n> > new file mode 100644\n> > index 0000000000000000000000000000000000000000..04ec4c163ede422369977017cca70d12a8d361fb\n> > --- /dev/null\n> > +++ b/src/ipa/simple/algorithms/lux.h\n> > @@ -0,0 +1,39 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2024, Ideas On Board\n> > + *\n> > + * Simple Lux control\n> > + */\n> > +\n> > +#pragma once\n> > +\n> > +#include <sys/types.h>\n> > +\n> > +#include \"libipa/lux.h\"\n> > +\n> > +#include \"algorithm.h\"\n> > +\n> > +namespace libcamera {\n> > +\n> > +namespace ipa::soft::algorithms {\n> > +\n> > +class Lux : public Algorithm\n> > +{\n> > +public:\n> > +     Lux();\n> > +\n> > +     int init(IPAContext &context, const YamlObject &tuningData) override;\n> > +     void prepare(IPAContext &context, const uint32_t frame,\n> > +                  IPAFrameContext &frameContext,\n> > +                  DebayerParams *params) override;\n> > +     void process(IPAContext &context, const uint32_t frame,\n> > +                  IPAFrameContext &frameContext,\n> > +                  const SwIspStats *stats,\n> > +                  ControlList &metadata) override;\n> > +\n> > +private:\n> > +     ipa::Lux lux_;\n> > +};\n> > +\n> > +} /* namespace ipa::soft::algorithms */\n> > +} /* namespace libcamera */\n> > diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\n> > index 73c63722083ff92147253c6b10440ce50743988d..27e73c9a0eea2241cc4a4cefd1594c976fb59318 100644\n> > --- a/src/ipa/simple/algorithms/meson.build\n> > +++ b/src/ipa/simple/algorithms/meson.build\n> > @@ -6,4 +6,5 @@ soft_simple_ipa_algorithms = files([\n> >      'agc.cpp',\n> >      'blc.cpp',\n> >      'ccm.cpp',\n> > +    'lux.cpp',\n> >  ])\n> > diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n> > index 8ccfacb46a59cedb5a0ad051d67f7c1f40af4b52..2bd7c4642b118d7bb94b1b16cdf4ede5fb2554b5 100644\n> > --- a/src/ipa/simple/ipa_context.h\n> > +++ b/src/ipa/simple/ipa_context.h\n> > @@ -17,6 +17,7 @@\n> >  #include \"libcamera/internal/vector.h\"\n> >  \n> >  #include <libipa/fc_queue.h>\n> > +#include <libipa/lux.h>\n> >  \n> >  #include \"core_ipa_interface.h\"\n> >  \n> > @@ -36,6 +37,8 @@ struct IPASessionConfiguration {\n> >  };\n> >  \n> >  struct IPAActiveState {\n> > +     ipa::lux::ActiveState lux;\n> \n> Does this need setting an initial value some way?\n\nIt at least needs to be not reported before we calculate it perhaps...\nI'll think about it when I refresh this series.\n\nThanks\n\nKieran\n\n\n> \n> > +\n> >       struct {\n> >               int32_t exposure;\n> >               double again;\n> > @@ -64,6 +67,8 @@ struct IPAActiveState {\n> >  };\n> >  \n> >  struct IPAFrameContext : public FrameContext {\n> > +     ipa::lux::FrameContext lux;\n> > +\n> >       Matrix<float, 3, 3> ccm;\n> >  \n> >       struct {\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 2CD44BEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  8 Apr 2026 17:39:00 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2E07E62CE6;\n\tWed,  8 Apr 2026 19:38:59 +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 D54D562CE6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  8 Apr 2026 19:38:57 +0200 (CEST)","from monstersaurus.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 655632D5;\n\tWed,  8 Apr 2026 19:37:29 +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=\"BZlwmaxk\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1775669849;\n\tbh=BgzgDRuRWtDP9lgAWPaScv2VIdMMbby3xrT5h64W9Sc=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=BZlwmaxkGX1mnbe7/weawNYRYArQ1uVieb3Qt9cfymSND0+TjMMAdVL+gds2KGLsE\n\tDzpTG5lU86GGo27RmC7jKcxM88pd5wvdjOh68yb396gQ+kkjNmBe93LiR8RSCFLSdt\n\tnPryPB3FJ8HdZmM8kzVTITZStmaP/eqvcIEHPHvE=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<851pgpbkxh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","References":"<20260407-kbingham-awb-split-v1-0-a39af3f4dc20@ideasonboard.com>\n\t<20260407-kbingham-awb-split-v1-7-a39af3f4dc20@ideasonboard.com>\n\t<851pgpbkxh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","Subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","To":"Milan Zamazal <mzamazal@redhat.com>","Date":"Wed, 08 Apr 2026 18:38:54 +0100","Message-ID":"<177566993453.575056.14646244958754829767@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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>"}},{"id":38554,"web_url":"https://patchwork.libcamera.org/comment/38554/","msgid":"<20260408211658.GI1965119@killaraus.ideasonboard.com>","date":"2026-04-08T21:16:58","subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Tue, Apr 07, 2026 at 11:01:10PM +0100, Kieran Bingham wrote:\n> Utilise the lux component of libipa to map in the lux estimate\n> process using the yHistgram of the Soft ISP statistics.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  src/ipa/simple/algorithms/lux.cpp     | 93 +++++++++++++++++++++++++++++++++++\n>  src/ipa/simple/algorithms/lux.h       | 39 +++++++++++++++\n>  src/ipa/simple/algorithms/meson.build |  1 +\n>  src/ipa/simple/ipa_context.h          |  5 ++\n>  4 files changed, 138 insertions(+)\n> \n> diff --git a/src/ipa/simple/algorithms/lux.cpp b/src/ipa/simple/algorithms/lux.cpp\n> new file mode 100644\n> index 0000000000000000000000000000000000000000..03b44ac584ae141509e79954159272504cdba17d\n> --- /dev/null\n> +++ b/src/ipa/simple/algorithms/lux.cpp\n> @@ -0,0 +1,93 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Ideas On Board\n> + *\n> + * Simple Lux control\n> + */\n> +\n> +#include \"lux.h\"\n> +\n> +#include <libcamera/base/log.h>\n> +\n> +#include <libcamera/control_ids.h>\n> +\n> +#include \"libipa/histogram.h\"\n> +#include \"libipa/lux.h\"\n> +\n> +/**\n> + * \\file lux.h\n> + */\n> +\n> +namespace libcamera {\n> +\n> +namespace ipa::soft::algorithms {\n> +\n> +/**\n> + * \\class Lux\n> + * \\brief SoftISP Lux control\n> + *\n> + * The Lux algorithm is responsible for estimating the lux level of the image.\n> + * It doesn't take or generate any controls, but it provides a lux level for\n> + * other algorithms (such as AGC) to use.\n> + */\n> +\n> +/**\n> + * \\brief Construct a SoftISP Lux algo module\n> + */\n> +Lux::Lux()\n> +{\n> +}\n> +\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::init\n> + */\n> +int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)\n> +{\n> +\treturn lux_.parseTuningData(tuningData);\n> +}\n> +\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::prepare\n> + */\n> +void Lux::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n> +\t\t  IPAFrameContext &frameContext,\n> +\t\t  [[maybe_unused]] DebayerParams *params)\n> +{\n> +\tframeContext.lux.lux = context.activeState.lux.lux;\n> +}\n> +\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::process\n> + */\n> +void Lux::process(IPAContext &context,\n> +\t\t  [[maybe_unused]] const uint32_t frame,\n> +\t\t  IPAFrameContext &frameContext,\n> +\t\t  const SwIspStats *stats,\n> +\t\t  ControlList &metadata)\n> +{\n> +\t/*\n> +\t * Report the lux level used by algorithms to prepare this frame\n> +\t * not the lux level *of* this frame.\n> +\t */\n> +\tmetadata.set(controls::Lux, frameContext.lux.lux);\n> +\n> +\tif (!stats)\n> +\t\treturn;\n> +\n> +\t/* Todo: Sensor configuration should move out of AGC */\n> +\tutils::Duration exposureTime = context.configuration.agc.lineDuration *\n> +\t\t\t\t       frameContext.sensor.exposure;\n> +\tdouble gain = frameContext.sensor.gain;\n> +\tdouble digitalGain = 1.0;\n> +\n> +\tHistogram yHist(stats->yHistogram);\n> +\n> +\tcontext.activeState.lux.lux =\n> +\t\tlux_.estimateLux(exposureTime, gain, digitalGain, yHist);\n> +}\n> +\n> +REGISTER_IPA_ALGORITHM(Lux, \"Lux\")\n> +\n> +} /* namespace ipa::soft::algorithms */\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/ipa/simple/algorithms/lux.h b/src/ipa/simple/algorithms/lux.h\n> new file mode 100644\n> index 0000000000000000000000000000000000000000..04ec4c163ede422369977017cca70d12a8d361fb\n> --- /dev/null\n> +++ b/src/ipa/simple/algorithms/lux.h\n> @@ -0,0 +1,39 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2024, Ideas On Board\n> + *\n> + * Simple Lux control\n> + */\n> +\n> +#pragma once\n> +\n> +#include <sys/types.h>\n> +\n> +#include \"libipa/lux.h\"\n> +\n> +#include \"algorithm.h\"\n> +\n> +namespace libcamera {\n> +\n> +namespace ipa::soft::algorithms {\n> +\n> +class Lux : public Algorithm\n> +{\n> +public:\n> +\tLux();\n> +\n> +\tint init(IPAContext &context, const YamlObject &tuningData) override;\n> +\tvoid prepare(IPAContext &context, const uint32_t frame,\n> +\t\t     IPAFrameContext &frameContext,\n> +\t\t     DebayerParams *params) override;\n> +\tvoid process(IPAContext &context, const uint32_t frame,\n> +\t\t     IPAFrameContext &frameContext,\n> +\t\t     const SwIspStats *stats,\n> +\t\t     ControlList &metadata) override;\n> +\n> +private:\n> +\tipa::Lux lux_;\n\nWould it make sense to inherit from ipa::Lux instead, the same way Agc\nin rkisp1 inherits from AgcMeanLuminance ?\n\n> +};\n> +\n> +} /* namespace ipa::soft::algorithms */\n> +} /* namespace libcamera */\n> diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\n> index 73c63722083ff92147253c6b10440ce50743988d..27e73c9a0eea2241cc4a4cefd1594c976fb59318 100644\n> --- a/src/ipa/simple/algorithms/meson.build\n> +++ b/src/ipa/simple/algorithms/meson.build\n> @@ -6,4 +6,5 @@ soft_simple_ipa_algorithms = files([\n>      'agc.cpp',\n>      'blc.cpp',\n>      'ccm.cpp',\n> +    'lux.cpp',\n>  ])\n> diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n> index 8ccfacb46a59cedb5a0ad051d67f7c1f40af4b52..2bd7c4642b118d7bb94b1b16cdf4ede5fb2554b5 100644\n> --- a/src/ipa/simple/ipa_context.h\n> +++ b/src/ipa/simple/ipa_context.h\n> @@ -17,6 +17,7 @@\n>  #include \"libcamera/internal/vector.h\"\n>  \n>  #include <libipa/fc_queue.h>\n> +#include <libipa/lux.h>\n>  \n>  #include \"core_ipa_interface.h\"\n>  \n> @@ -36,6 +37,8 @@ struct IPASessionConfiguration {\n>  };\n>  \n>  struct IPAActiveState {\n> +\tipa::lux::ActiveState lux;\n> +\n>  \tstruct {\n>  \t\tint32_t exposure;\n>  \t\tdouble again;\n> @@ -64,6 +67,8 @@ struct IPAActiveState {\n>  };\n>  \n>  struct IPAFrameContext : public FrameContext {\n> +\tipa::lux::FrameContext lux;\n> +\n>  \tMatrix<float, 3, 3> ccm;\n>  \n>  \tstruct {\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 52CA2BEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  8 Apr 2026 21:17:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 44D0762E39;\n\tWed,  8 Apr 2026 23:17:01 +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 18EC962CE6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  8 Apr 2026 23:17:00 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 3A983241;\n\tWed,  8 Apr 2026 23:15:31 +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=\"Z1eZdojJ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1775682931;\n\tbh=detrPzpeLxp+dmJChz4kli2tc9Ziei+1o2uQU6AQCGM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Z1eZdojJHikMkHZvmo3+L/kXncKGjqJpp+c5Z288G4nG945eDA6BAyNnq6GE5/7jW\n\tZA9WvymLiqfS1bk0lRo5wikjOTyigBhSgULMA06J2rzFSetAa+9iW2d2W0b9ysF66Y\n\tBfVu+p5QZYhNgQEnfvmI2yZ2AyLY/4WhUhNhhg8A=","Date":"Thu, 9 Apr 2026 00:16:58 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","Message-ID":"<20260408211658.GI1965119@killaraus.ideasonboard.com>","References":"<20260407-kbingham-awb-split-v1-0-a39af3f4dc20@ideasonboard.com>\n\t<20260407-kbingham-awb-split-v1-7-a39af3f4dc20@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20260407-kbingham-awb-split-v1-7-a39af3f4dc20@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>"}},{"id":38555,"web_url":"https://patchwork.libcamera.org/comment/38555/","msgid":"<85y0ix8ck3.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-04-08T19:41:32","subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Kieran Bingham <kieran.bingham@ideasonboard.com> writes:\n\n> Quoting Milan Zamazal (2026-04-08 15:12:26)\n>> Hi Kieran,\n>> \n>\n>> Kieran Bingham <kieran.bingham@ideasonboard.com> writes:\n>> \n>> > Utilise the lux component of libipa to map in the lux estimate\n>> > process using the yHistgram of the Soft ISP statistics.\n>> \n>> s/yHistgram/yHistogram/\n>> \n>> I suppose the algorithm is supposed to be enabled manually, in case the\n>> corresponding tuning data is available?  It would be worth to explain\n>> its purpose and use here.\n>\n> Not manually, I think it's just used when there is available tuning\n> data. It helps for AWB ultimately.\n\nOK.\n\n>> \n>> > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>> > ---\n>> >  src/ipa/simple/algorithms/lux.cpp     | 93 +++++++++++++++++++++++++++++++++++\n>> >  src/ipa/simple/algorithms/lux.h       | 39 +++++++++++++++\n>> >  src/ipa/simple/algorithms/meson.build |  1 +\n>> >  src/ipa/simple/ipa_context.h          |  5 ++\n>> >  4 files changed, 138 insertions(+)\n>> >\n>> > diff --git a/src/ipa/simple/algorithms/lux.cpp b/src/ipa/simple/algorithms/lux.cpp\n>> > new file mode 100644\n>> > index 0000000000000000000000000000000000000000..03b44ac584ae141509e79954159272504cdba17d\n>> > --- /dev/null\n>> > +++ b/src/ipa/simple/algorithms/lux.cpp\n>> > @@ -0,0 +1,93 @@\n>> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>> > +/*\n>> > + * Copyright (C) 2024, Ideas On Board\n>> > + *\n>> > + * Simple Lux control\n>> > + */\n>> > +\n>> > +#include \"lux.h\"\n>> > +\n>> > +#include <libcamera/base/log.h>\n>> > +\n>> > +#include <libcamera/control_ids.h>\n>> > +\n>> > +#include \"libipa/histogram.h\"\n>> > +#include \"libipa/lux.h\"\n>> > +\n>> > +/**\n>> > + * \\file lux.h\n>> > + */\n>> > +\n>> > +namespace libcamera {\n>> > +\n>> > +namespace ipa::soft::algorithms {\n>> > +\n>> > +/**\n>> > + * \\class Lux\n>> > + * \\brief SoftISP Lux control\n>> > + *\n>> > + * The Lux algorithm is responsible for estimating the lux level of the image.\n>> > + * It doesn't take or generate any controls, but it provides a lux level for\n>> > + * other algorithms (such as AGC) to use.\n>> > + */\n>> > +\n>> > +/**\n>> > + * \\brief Construct a SoftISP Lux algo module\n>> > + */\n>> > +Lux::Lux()\n>> > +{\n>> > +}\n>\n> I don't think that's needed when it's empty ;-)\n\nThen the declaration in lux.h should be removed too.\n\n>> > +\n>> > +/**\n>> > + * \\copydoc libcamera::ipa::Algorithm::init\n>> > + */\n>> > +int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)\n>> > +{\n>> > +     return lux_.parseTuningData(tuningData);\n>> > +}\n>> > +\n>> > +/**\n>> > + * \\copydoc libcamera::ipa::Algorithm::prepare\n>> > + */\n>> > +void Lux::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n>> > +               IPAFrameContext &frameContext,\n>> > +               [[maybe_unused]] DebayerParams *params)\n>> > +{\n>> > +     frameContext.lux.lux = context.activeState.lux.lux;\n>> > +}\n>> > +\n>> > +/**\n>> > + * \\copydoc libcamera::ipa::Algorithm::process\n>> > + */\n>> > +void Lux::process(IPAContext &context,\n>> > +               [[maybe_unused]] const uint32_t frame,\n>> > +               IPAFrameContext &frameContext,\n>> > +               const SwIspStats *stats,\n>> > +               ControlList &metadata)\n>> > +{\n>> > +     /*\n>> > +      * Report the lux level used by algorithms to prepare this frame\n>> > +      * not the lux level *of* this frame.\n>> > +      */\n>> > +     metadata.set(controls::Lux, frameContext.lux.lux);\n>> \n>> Should this be reported before the lux value is determined for the first\n>> time?\n>\n> Ohh no good spot, there's some startup ordering errors here...\n>\n>> \n>> > +     if (!stats)\n>> > +             return;\n>> > +\n>> > +     /* Todo: Sensor configuration should move out of AGC */\n>> \n>> Todo: -> \\todo\n>> \n>> The comment is a bit confusing here, it might be better to attach it to\n>> the sensor configuration in AGC.\n>\n> Maybe, but this is me explicitly telling myself yet another place that\n> needs to refactor the AEGC into libipa, and split out sensor controls\n> from the AGC, and have a dedicated sensor context.\n>\n> Because even if AEGC isn't \"running\" if we know the stats, and the\n> exposure and gain we can know the lux - so the sensor properties\n> shouldn't be tied directly into the AGC like they are.\n>\n> It's one of the many rabbit holes that have made it harder for me to split out\n> AgcMeanLuminance and use it for soft-ipa. I've hoped starting with\n> Lux/AWB will make it easier to progress and then do the same for AGC./\n\nMakes sense but then I'd suggest to make the comment clearer; well, many\nTODO comments survive much longer than initially expected.\n\n>> \n>> > +     utils::Duration exposureTime = context.configuration.agc.lineDuration *\n>> > +                                    frameContext.sensor.exposure;\n>> > +     double gain = frameContext.sensor.gain;\n>> > +     double digitalGain = 1.0;\n>> > +\n>> > +     Histogram yHist(stats->yHistogram);\n>> > +\n>> > +     context.activeState.lux.lux =\n>> > +             lux_.estimateLux(exposureTime, gain, digitalGain, yHist);\n>> > +}\n>> > +\n>> > +REGISTER_IPA_ALGORITHM(Lux, \"Lux\")\n>> > +\n>> > +} /* namespace ipa::soft::algorithms */\n>> > +\n>> > +} /* namespace libcamera */\n>> > diff --git a/src/ipa/simple/algorithms/lux.h b/src/ipa/simple/algorithms/lux.h\n>> > new file mode 100644\n>> > index 0000000000000000000000000000000000000000..04ec4c163ede422369977017cca70d12a8d361fb\n>> > --- /dev/null\n>> > +++ b/src/ipa/simple/algorithms/lux.h\n>> > @@ -0,0 +1,39 @@\n>> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>> > +/*\n>> > + * Copyright (C) 2024, Ideas On Board\n>> > + *\n>> > + * Simple Lux control\n>> > + */\n>> > +\n>> > +#pragma once\n>> > +\n>> > +#include <sys/types.h>\n>> > +\n>> > +#include \"libipa/lux.h\"\n>> > +\n>> > +#include \"algorithm.h\"\n>> > +\n>> > +namespace libcamera {\n>> > +\n>> > +namespace ipa::soft::algorithms {\n>> > +\n>> > +class Lux : public Algorithm\n>> > +{\n>> > +public:\n>> > +     Lux();\n>> > +\n>> > +     int init(IPAContext &context, const YamlObject &tuningData) override;\n>> > +     void prepare(IPAContext &context, const uint32_t frame,\n>> > +                  IPAFrameContext &frameContext,\n>> > +                  DebayerParams *params) override;\n>> > +     void process(IPAContext &context, const uint32_t frame,\n>> > +                  IPAFrameContext &frameContext,\n>> > +                  const SwIspStats *stats,\n>> > +                  ControlList &metadata) override;\n>> > +\n>> > +private:\n>> > +     ipa::Lux lux_;\n>> > +};\n>> > +\n>> > +} /* namespace ipa::soft::algorithms */\n>> > +} /* namespace libcamera */\n>> > diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\n>> > index 73c63722083ff92147253c6b10440ce50743988d..27e73c9a0eea2241cc4a4cefd1594c976fb59318 100644\n>> > --- a/src/ipa/simple/algorithms/meson.build\n>> > +++ b/src/ipa/simple/algorithms/meson.build\n>> > @@ -6,4 +6,5 @@ soft_simple_ipa_algorithms = files([\n>> >      'agc.cpp',\n>> >      'blc.cpp',\n>> >      'ccm.cpp',\n>> > +    'lux.cpp',\n>> >  ])\n>> > diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n>> > index 8ccfacb46a59cedb5a0ad051d67f7c1f40af4b52..2bd7c4642b118d7bb94b1b16cdf4ede5fb2554b5 100644\n>> > --- a/src/ipa/simple/ipa_context.h\n>> > +++ b/src/ipa/simple/ipa_context.h\n>> > @@ -17,6 +17,7 @@\n>> >  #include \"libcamera/internal/vector.h\"\n>> >  \n>> >  #include <libipa/fc_queue.h>\n>> > +#include <libipa/lux.h>\n>> >  \n>> >  #include \"core_ipa_interface.h\"\n>> >  \n>> > @@ -36,6 +37,8 @@ struct IPASessionConfiguration {\n>> >  };\n>> >  \n>> >  struct IPAActiveState {\n>> > +     ipa::lux::ActiveState lux;\n>> \n>> Does this need setting an initial value some way?\n>\n> It at least needs to be not reported before we calculate it perhaps...\n> I'll think about it when I refresh this series.\n>\n> Thanks\n>\n> Kieran\n>\n>\n>> \n>> > +\n>> >       struct {\n>> >               int32_t exposure;\n>> >               double again;\n>> > @@ -64,6 +67,8 @@ struct IPAActiveState {\n>> >  };\n>> >  \n>> >  struct IPAFrameContext : public FrameContext {\n>> > +     ipa::lux::FrameContext lux;\n>> > +\n>> >       Matrix<float, 3, 3> ccm;\n>> >  \n>> >       struct {\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 1D10FBEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  8 Apr 2026 21:19:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 59CF362E39;\n\tWed,  8 Apr 2026 23:19:06 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 815D862CE6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  8 Apr 2026 23:19:05 +0200 (CEST)","from mail-wm1-f71.google.com (mail-wm1-f71.google.com\n\t[209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-618-y2vF9-oKMsC22IrkIWxnhA-1; Wed, 08 Apr 2026 15:41:36 -0400","by mail-wm1-f71.google.com with SMTP id\n\t5b1f17b1804b1-488bd1ee9e7so548005e9.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 08 Apr 2026 12:41:36 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\tffacd0b85a97d-43d1e4e52a0sm58107367f8f.30.2026.04.08.12.41.33\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 08 Apr 2026 12:41:33 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"RwQGowIf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1775683144;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=+/9rsmqWG4EpIPXpw7tB2+jRul30QRRrN8+ZlWpUmW4=;\n\tb=RwQGowIf/Qej2oyI/JF55b0CdSY6o0Vs+0ZcezRFBQz2hLr6g/3ziuTv8X20pUcuXU4QuG\n\tufCBMlMR/f3dEr7Yo5cwM/9apkSrZkEZaK9qB69eCCUiHUZeNpvtJEwzZw3eyvmpD4sUzy\n\tF4umX8bIBWnj1GquWQ3uzJA3m++JT7I=","X-MC-Unique":"y2vF9-oKMsC22IrkIWxnhA-1","X-Mimecast-MFC-AGG-ID":"y2vF9-oKMsC22IrkIWxnhA_1775677295","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1775677295; x=1776282095;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=+/9rsmqWG4EpIPXpw7tB2+jRul30QRRrN8+ZlWpUmW4=;\n\tb=tRvDzwzZr5VOdM2PZKLTYRZCRS8XRFl1+BX98PM2li11qUcsijGqXG9bQ3LfWlzIhM\n\tDIn2pNJqhNHvTQjSyZ8kV4//3VgijaKE9vKyzCwU7LKLfgvnSV4z5PW1VmQfar87ndr/\n\tZkqX19O4iv2BQGgFUdB5AR4lxiTdwWeQoRL2uaYACDoTfdb058YqsUfSdBV5BhSuS8Bm\n\tL8UkOXPeDCRRjHeCsd3sjKR4PtYmlICH/4mcoaFbnaxcIGXk221hhOEiqXS2hs7UQopN\n\t4iYdUEKz4DH2qh9+4Nd0ETvIOt6T0OjaHJ0/n7mcrTR4BcFgxQ3/Gq9I1RzSHgyu2tMv\n\te3Cg==","X-Gm-Message-State":"AOJu0YyogPnMPSswqyTG5d4G2Dxsox+6XCerFw6DLapGpITeExg7wLM1\n\thEBBLEs58ypVTQdIJ/1s/hMmL3Mau7vSS5wG2dp4YMETpagAMImm33q71JgiFqgUqElFC1sT5Ot\n\tliR0WhcBiDMcaEUT0K3xYp8vVk21NB+TlvTy41AUYrPRo6oIASTjmBKdPqQHQufTMEySiBRA2b9\n\tc9ULrvTO5gw4PQOuzHi+S2ccHSe866Qh3cXJKYbHuRQWWocDdN6OlCHJsml7A=","X-Gm-Gg":"AeBDiesLNSrKRLpcs73HKhr701ktyLt9Jj8Y5ViGo95rVhqZNB+hESglBCAbtICJsTg\n\t1BrX0q98YUFIzJ3mOlegbRb21fG9GNAgsRYa+LBCEkCMpPiwbo/7U/XClXxYDJie7/QosmfgE0h\n\tI8TzwVkreLSIL95tYY7nZMgT+SnfJ1D3aL1p8+y6UoQC65SVIAr/ewZwXGZKeveZbOKr2jzwopX\n\t1TXNBCJlU1fJEjXA1OUzVPeiV7lAyk8yybLSzys6IJZvHo3Lpp/LTIGO5RxNLxBDTUBTA9Vj8dn\n\tiVdzqNePC6UfX5V2NYZtTNlYYxCCzx0tcGOPdOcIGdza2oErchpbjN0hd615jE1cGBxd2NyNGHB\n\t1R+vP1rLyoMvLXnOiU3tcbIURPsJ3FKLclxioIDCR4aAt2TPIjnVzriMeN+41DcGnhHPaxiVfDq\n\tQ=","X-Received":["by 2002:a05:600c:4ec7:b0:485:35a4:939f with SMTP id\n\t5b1f17b1804b1-488997ebfbamr292289475e9.28.1775677294989; \n\tWed, 08 Apr 2026 12:41:34 -0700 (PDT)","by 2002:a05:600c:4ec7:b0:485:35a4:939f with SMTP id\n\t5b1f17b1804b1-488997ebfbamr292289145e9.28.1775677294381; \n\tWed, 08 Apr 2026 12:41:34 -0700 (PDT)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","In-Reply-To":"<177566993453.575056.14646244958754829767@ping.linuxembedded.co.uk>\n\t(Kieran Bingham's message of \"Wed, 08 Apr 2026 18:38:54 +0100\")","References":"<20260407-kbingham-awb-split-v1-0-a39af3f4dc20@ideasonboard.com>\n\t<20260407-kbingham-awb-split-v1-7-a39af3f4dc20@ideasonboard.com>\n\t<851pgpbkxh.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>\n\t<177566993453.575056.14646244958754829767@ping.linuxembedded.co.uk>","Date":"Wed, 08 Apr 2026 21:41:32 +0200","Message-ID":"<85y0ix8ck3.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"abMxu0tKKgcPxdPUj4mV0fmDP8DkvVIAHSJkn2ls8fs_1775677295","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>"}},{"id":38844,"web_url":"https://patchwork.libcamera.org/comment/38844/","msgid":"<177843903769.2475891.18312165068943614577@ping.linuxembedded.co.uk>","date":"2026-05-10T18:50:37","subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Laurent Pinchart (2026-04-08 22:16:58)\n> On Tue, Apr 07, 2026 at 11:01:10PM +0100, Kieran Bingham wrote:\n> > Utilise the lux component of libipa to map in the lux estimate\n> > process using the yHistgram of the Soft ISP statistics.\n> > \n> > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >  src/ipa/simple/algorithms/lux.cpp     | 93 +++++++++++++++++++++++++++++++++++\n> >  src/ipa/simple/algorithms/lux.h       | 39 +++++++++++++++\n> >  src/ipa/simple/algorithms/meson.build |  1 +\n> >  src/ipa/simple/ipa_context.h          |  5 ++\n> >  4 files changed, 138 insertions(+)\n> > \n> > diff --git a/src/ipa/simple/algorithms/lux.cpp b/src/ipa/simple/algorithms/lux.cpp\n> > new file mode 100644\n> > index 0000000000000000000000000000000000000000..03b44ac584ae141509e79954159272504cdba17d\n> > --- /dev/null\n> > +++ b/src/ipa/simple/algorithms/lux.cpp\n> > @@ -0,0 +1,93 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2024, Ideas On Board\n> > + *\n> > + * Simple Lux control\n> > + */\n> > +\n> > +#include \"lux.h\"\n> > +\n> > +#include <libcamera/base/log.h>\n> > +\n> > +#include <libcamera/control_ids.h>\n> > +\n> > +#include \"libipa/histogram.h\"\n> > +#include \"libipa/lux.h\"\n> > +\n> > +/**\n> > + * \\file lux.h\n> > + */\n> > +\n> > +namespace libcamera {\n> > +\n> > +namespace ipa::soft::algorithms {\n> > +\n> > +/**\n> > + * \\class Lux\n> > + * \\brief SoftISP Lux control\n> > + *\n> > + * The Lux algorithm is responsible for estimating the lux level of the image.\n> > + * It doesn't take or generate any controls, but it provides a lux level for\n> > + * other algorithms (such as AGC) to use.\n> > + */\n> > +\n> > +/**\n> > + * \\brief Construct a SoftISP Lux algo module\n> > + */\n> > +Lux::Lux()\n> > +{\n> > +}\n> > +\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::init\n> > + */\n> > +int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)\n> > +{\n> > +     return lux_.parseTuningData(tuningData);\n> > +}\n> > +\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::prepare\n> > + */\n> > +void Lux::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n> > +               IPAFrameContext &frameContext,\n> > +               [[maybe_unused]] DebayerParams *params)\n> > +{\n> > +     frameContext.lux.lux = context.activeState.lux.lux;\n> > +}\n> > +\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::process\n> > + */\n> > +void Lux::process(IPAContext &context,\n> > +               [[maybe_unused]] const uint32_t frame,\n> > +               IPAFrameContext &frameContext,\n> > +               const SwIspStats *stats,\n> > +               ControlList &metadata)\n> > +{\n> > +     /*\n> > +      * Report the lux level used by algorithms to prepare this frame\n> > +      * not the lux level *of* this frame.\n> > +      */\n> > +     metadata.set(controls::Lux, frameContext.lux.lux);\n> > +\n> > +     if (!stats)\n> > +             return;\n> > +\n> > +     /* Todo: Sensor configuration should move out of AGC */\n> > +     utils::Duration exposureTime = context.configuration.agc.lineDuration *\n> > +                                    frameContext.sensor.exposure;\n> > +     double gain = frameContext.sensor.gain;\n> > +     double digitalGain = 1.0;\n> > +\n> > +     Histogram yHist(stats->yHistogram);\n> > +\n> > +     context.activeState.lux.lux =\n> > +             lux_.estimateLux(exposureTime, gain, digitalGain, yHist);\n> > +}\n> > +\n> > +REGISTER_IPA_ALGORITHM(Lux, \"Lux\")\n> > +\n> > +} /* namespace ipa::soft::algorithms */\n> > +\n> > +} /* namespace libcamera */\n> > diff --git a/src/ipa/simple/algorithms/lux.h b/src/ipa/simple/algorithms/lux.h\n> > new file mode 100644\n> > index 0000000000000000000000000000000000000000..04ec4c163ede422369977017cca70d12a8d361fb\n> > --- /dev/null\n> > +++ b/src/ipa/simple/algorithms/lux.h\n> > @@ -0,0 +1,39 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2024, Ideas On Board\n> > + *\n> > + * Simple Lux control\n> > + */\n> > +\n> > +#pragma once\n> > +\n> > +#include <sys/types.h>\n> > +\n> > +#include \"libipa/lux.h\"\n> > +\n> > +#include \"algorithm.h\"\n> > +\n> > +namespace libcamera {\n> > +\n> > +namespace ipa::soft::algorithms {\n> > +\n> > +class Lux : public Algorithm\n> > +{\n> > +public:\n> > +     Lux();\n> > +\n> > +     int init(IPAContext &context, const YamlObject &tuningData) override;\n> > +     void prepare(IPAContext &context, const uint32_t frame,\n> > +                  IPAFrameContext &frameContext,\n> > +                  DebayerParams *params) override;\n> > +     void process(IPAContext &context, const uint32_t frame,\n> > +                  IPAFrameContext &frameContext,\n> > +                  const SwIspStats *stats,\n> > +                  ControlList &metadata) override;\n> > +\n> > +private:\n> > +     ipa::Lux lux_;\n> \n> Would it make sense to inherit from ipa::Lux instead, the same way Agc\n> in rkisp1 inherits from AgcMeanLuminance ?\n\nI don't know about this yet, as I want to reduce duplication in the main\ninterface functions, but we can't inherit init, prepare, and process\nwhich have IPA specific function parameters.\n\nSo I think at the moment (along with my previous efforts to factor out\nAGC for simple/SoftISP as well) that we probably want composition and\nhave the main interface as the wrapper into the libipa implementation on\nthe object directly.\n\nThat means we'll have \n\nsimple:Awb::init(...)\n{\n\treturn awb_->init(...modified...);\n}\n\ninstead of\n\nsimple::Awb::init(...)\n{\n\treturn init(...modified...);\n}\n\n\nAny preferences or specific thoughts ?\n\nWe'll have a lot of 'map this structure through to the component' and\ntrying to massage the data structures seems to be the most awkward part.\n\n--\nKieran\n\n\n> \n> > +};\n> > +\n> > +} /* namespace ipa::soft::algorithms */\n> > +} /* namespace libcamera */\n> > diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\n> > index 73c63722083ff92147253c6b10440ce50743988d..27e73c9a0eea2241cc4a4cefd1594c976fb59318 100644\n> > --- a/src/ipa/simple/algorithms/meson.build\n> > +++ b/src/ipa/simple/algorithms/meson.build\n> > @@ -6,4 +6,5 @@ soft_simple_ipa_algorithms = files([\n> >      'agc.cpp',\n> >      'blc.cpp',\n> >      'ccm.cpp',\n> > +    'lux.cpp',\n> >  ])\n> > diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n> > index 8ccfacb46a59cedb5a0ad051d67f7c1f40af4b52..2bd7c4642b118d7bb94b1b16cdf4ede5fb2554b5 100644\n> > --- a/src/ipa/simple/ipa_context.h\n> > +++ b/src/ipa/simple/ipa_context.h\n> > @@ -17,6 +17,7 @@\n> >  #include \"libcamera/internal/vector.h\"\n> >  \n> >  #include <libipa/fc_queue.h>\n> > +#include <libipa/lux.h>\n> >  \n> >  #include \"core_ipa_interface.h\"\n> >  \n> > @@ -36,6 +37,8 @@ struct IPASessionConfiguration {\n> >  };\n> >  \n> >  struct IPAActiveState {\n> > +     ipa::lux::ActiveState lux;\n> > +\n> >       struct {\n> >               int32_t exposure;\n> >               double again;\n> > @@ -64,6 +67,8 @@ struct IPAActiveState {\n> >  };\n> >  \n> >  struct IPAFrameContext : public FrameContext {\n> > +     ipa::lux::FrameContext lux;\n> > +\n> >       Matrix<float, 3, 3> ccm;\n> >  \n> >       struct {\n> > \n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","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 65C90BDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 10 May 2026 18:50:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 67EA863020;\n\tSun, 10 May 2026 20:50:41 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 64BAC62FE8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 10 May 2026 20:50:40 +0200 (CEST)","from monstersaurus.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D678918BC;\n\tSun, 10 May 2026 20:50:33 +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=\"npV/GVHX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1778439033;\n\tbh=9qLufmSEPzPxw3Ni9Mjc7muoydx6qnj7fl7HG8j0b4w=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=npV/GVHXMKusXh/S7npK291TY4rBoV9wVD94Bdc4reFEF0vkTfNfGSLiXy0taHYQA\n\tbfTPvVHBob9an1DIoYGcYMS3kzqiB6DmmzaKXLIAvqb5isBhWlqMV1/89YZYPXt+XO\n\tkKNS/QT0Xj2hF708g9M3lZSIvmEzl7me9rcieLLI=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260408211658.GI1965119@killaraus.ideasonboard.com>","References":"<20260407-kbingham-awb-split-v1-0-a39af3f4dc20@ideasonboard.com>\n\t<20260407-kbingham-awb-split-v1-7-a39af3f4dc20@ideasonboard.com>\n\t<20260408211658.GI1965119@killaraus.ideasonboard.com>","Subject":"Re: [PATCH 07/13] ipa: simple: Add lux algorithm to the SoftIPA","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Sun, 10 May 2026 19:50:37 +0100","Message-ID":"<177843903769.2475891.18312165068943614577@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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>"}}]