Patch Detail
Show a patch.
GET /api/patches/27304/?format=api
{ "id": 27304, "url": "https://patchwork.libcamera.org/api/patches/27304/?format=api", "web_url": "https://patchwork.libcamera.org/patch/27304/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260708141436.119165-4-mzamazal@redhat.com>", "date": "2026-07-08T14:14:31", "name": "[RFC,v6,3/6] ipa: simple: Add LSC algorithm", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "7860337268a40f53b8cb0566cc7cdc008449222b", "submitter": { "id": 177, "url": "https://patchwork.libcamera.org/api/people/177/?format=api", "name": "Milan Zamazal", "email": "mzamazal@redhat.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/27304/mbox/", "series": [ { "id": 6047, "url": "https://patchwork.libcamera.org/api/series/6047/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=6047", "date": "2026-07-08T14:14:28", "name": "LSC for SoftISP simple pipeline", "version": 6, "mbox": "https://patchwork.libcamera.org/series/6047/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/27304/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/27304/checks/", "tags": {}, "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 26542C3318\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 8 Jul 2026 14:15:05 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 80DFB6609E;\n\tWed, 8 Jul 2026 16:15:04 +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 019FD66088\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 8 Jul 2026 16:15:01 +0200 (CEST)", "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-540-RabD9FiAOZK1cvc-w0GW2Q-1;\n\tWed, 08 Jul 2026 10:14:57 -0400", "from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.95])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id CD88B180059A; Wed, 8 Jul 2026 14:14:55 +0000 (UTC)", "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.228])\n\tby mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 9E7CB30A8; Wed, 8 Jul 2026 14:14:52 +0000 (UTC)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"BoKAaqT8\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1783520100;\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\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=KOQzwquw1LMMFgo9qBgVAHw5Z2g4ATnV9iKggD3aJCs=;\n\tb=BoKAaqT8BKO80lH0DYt3wolyQgzyBWJVNW3MVXAIqL2Eomf3Ry7PenSGMRCEEq+uU7xKoz\n\tHFXBi3n1cuo9sbpqwINDGI8MMSeF8iFkYrjSlSMpwwSMp65sjb3qAix06kjTKdxIAp5rVQ\n\tOTTi2uUJvmJsYwPEjWsC4paqBuYJmlo=", "X-MC-Unique": "RabD9FiAOZK1cvc-w0GW2Q-1", "X-Mimecast-MFC-AGG-ID": "RabD9FiAOZK1cvc-w0GW2Q_1783520096", "From": "Milan Zamazal <mzamazal@redhat.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Xander Pronk <xander.c.pronk@gmail.com>,\n\tBryan O'Donoghue <bod.linux@nxsw.ie>,\n\tHans de Goede <johannes.goede@oss.qualcomm.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tRick ten Wolde <rick_libcamera@wolde.info>,\n\tMilan Zamazal <mzamazal@redhat.com>", "Subject": "[RFC PATCH v6 3/6] ipa: simple: Add LSC algorithm", "Date": "Wed, 8 Jul 2026 16:14:31 +0200", "Message-ID": "<20260708141436.119165-4-mzamazal@redhat.com>", "In-Reply-To": "<20260708141436.119165-1-mzamazal@redhat.com>", "References": "<20260708141436.119165-1-mzamazal@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.6 on 10.30.177.95", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "bGyxY7_w3QU6ZJ7_R-CuqwJydUlYjdqt7BT245-UrlI_1783520096", "X-Mimecast-Originator": "redhat.com", "Content-Transfer-Encoding": "8bit", "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true", "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>" }, "content": "From: Xander Pronk <xander.c.pronk@gmail.com>\n\nThe algorithm is based on the common libipa lens shading correction\nimplementation. The grid values obtained from the libipa algorithm are\npassed to debayering in an array to be used as an RGB texture.\n\nNotes to the implementation:\n\n- The overall idea is to keep things simple, to not make the LSC\n computation unnecessarily expensive.\n\n- 16 equally spaced grid positions are used for LscAlgorithm; for no\n particular reason other than that we already use the same number for\n the whole grid sizes.\n\n- LscAlgorithm accepts only quantised types. UQ<2,6> is used, to be\n converted to float for debayering.\n\n- The limit of 100 to consider a temperature change noticeable is\n arbitrary.\n\nCo-developed-by: Rick ten Wolde <rick_libcamera@wolde.info>\nSigned-off-by: Rick ten Wolde <rick_libcamera@wolde.info>\nSigned-off-by: Xander Pronk <xander.c.pronk@gmail.com>\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\n---\n src/ipa/simple/algorithms/lsc.cpp | 87 +++++++++++++++++++++++++++\n src/ipa/simple/algorithms/lsc.h | 50 +++++++++++++++\n src/ipa/simple/algorithms/meson.build | 1 +\n src/ipa/simple/ipa_context.h | 5 ++\n 4 files changed, 143 insertions(+)\n create mode 100644 src/ipa/simple/algorithms/lsc.cpp\n create mode 100644 src/ipa/simple/algorithms/lsc.h", "diff": "diff --git a/src/ipa/simple/algorithms/lsc.cpp b/src/ipa/simple/algorithms/lsc.cpp\nnew file mode 100644\nindex 000000000..6961b95dc\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/lsc.cpp\n@@ -0,0 +1,87 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Lens shading correction\n+ */\n+\n+#include \"lsc.h\"\n+\n+#include <libcamera/base/log.h>\n+\n+namespace libcamera {\n+\n+namespace ipa::soft::algorithms {\n+\n+LOG_DEFINE_CATEGORY(IPASoftLsc)\n+\n+int Lsc::init(IPAContext &context, const ValueNode &tuningData)\n+{\n+\tstatic constexpr unsigned int kGridSize = DebayerParams::kLscGridSize;\n+\n+\tfor (unsigned int i = 0; i < kGridSize; i++)\n+\t\tgridPos_.push_back(static_cast<double>(i) / (kGridSize - 1));\n+\n+\treturn lscAlgo_.init(tuningData, context.ctrlMap,\n+\t\t\t { .keys = { \"r\", \"g\", \"b\" },\n+\t\t\t .numHCells = kGridSize,\n+\t\t\t .numVCells = kGridSize,\n+\t\t\t .sensorSize = context.sensorInfo.activeAreaSize });\n+}\n+\n+int Lsc::configure(IPAContext &context,\n+\t\t [[maybe_unused]] const IPAConfigInfo &configInfo)\n+{\n+\treturn lscAlgo_.configure(context.activeState.lsc,\n+\t\t\t\t context.sensorInfo.analogCrop,\n+\t\t\t\t gridPos_, gridPos_);\n+}\n+\n+void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n+\t\t IPAFrameContext &frameContext, DebayerParams *params)\n+{\n+\tunsigned int ct = context.activeState.awb.automatic.temperatureK;\n+\n+\tparams->lscEnabled = frameContext.lsc.enabled;\n+\n+\tif (!frameContext.lsc.enabled ||\n+\t utils::abs_diff(ct, lastAppliedCt_) < 100)\n+\t\treturn;\n+\n+\tconst lsc::Components<uint8_t> &set = lscAlgo_.interpolateComponents(ct);\n+\n+\tconst auto &red = set.at(\"r\");\n+\tconst auto &green = set.at(\"g\");\n+\tconst auto &blue = set.at(\"b\");\n+\n+\tDebayerParams::LscLookupTable lut;\n+\tconstexpr unsigned int gridSize = DebayerParams::kLscGridSize;\n+\tfor (unsigned int i = 0, j = 0; i < gridSize * gridSize; i++) {\n+\t\tlut[j++] = red[i] / 64.0;\n+\t\tlut[j++] = green[i] / 64.0;\n+\t\tlut[j++] = blue[i] / 64.0;\n+\t}\n+\tparams->lscLut = lut;\n+\n+\tlastAppliedCt_ = ct;\n+}\n+\n+void Lsc::queueRequest(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n+\t\t IPAFrameContext &frameContext, const ControlList &controls)\n+{\n+\tlscAlgo_.queueRequest(context.activeState.lsc, frameContext.lsc,\n+\t\t\t controls);\n+}\n+\n+void Lsc::process([[maybe_unused]] IPAContext &context,\n+\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t IPAFrameContext &frameContext,\n+\t\t [[maybe_unused]] const SwIspStats *stats,\n+\t\t ControlList &metadata)\n+{\n+\tlscAlgo_.process(frameContext.lsc, metadata);\n+}\n+\n+REGISTER_IPA_ALGORITHM(Lsc, \"Lsc\")\n+\n+} /* namespace ipa::soft::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/simple/algorithms/lsc.h b/src/ipa/simple/algorithms/lsc.h\nnew file mode 100644\nindex 000000000..9418fac39\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/lsc.h\n@@ -0,0 +1,50 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Lens shading correction\n+ */\n+\n+#pragma once\n+\n+#include <libipa/interpolator.h>\n+\n+#include \"libipa/fixedpoint.h\"\n+#include \"libipa/lsc.h\"\n+\n+#include \"algorithm.h\"\n+#include \"ipa_context.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa::soft::algorithms {\n+\n+class Lsc : public Algorithm\n+{\n+public:\n+\tLsc() = default;\n+\t~Lsc() = default;\n+\n+\tint init(IPAContext &context, const ValueNode &tuningData) override;\n+\tint configure(IPAContext &context,\n+\t\t const IPAConfigInfo &configInfo) override;\n+\tvoid queueRequest(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n+\t\t\t IPAFrameContext &frameContext, const ControlList &controls) override;\n+\tvoid prepare(IPAContext &context,\n+\t\t const uint32_t frame,\n+\t\t IPAFrameContext &frameContext,\n+\t\t DebayerParams *params) override;\n+\tvoid process([[maybe_unused]] IPAContext &context,\n+\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t IPAFrameContext &frameContext,\n+\t\t [[maybe_unused]] const SwIspStats *stats,\n+\t\t ControlList &metadata) override;\n+\n+private:\n+\tLscAlgorithm<UQ<2, 6>> lscAlgo_;\n+\tstd::vector<double> gridPos_;\n+\n+\tunsigned int lastAppliedCt_ = 0;\n+};\n+\n+} /* namespace ipa::soft::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\nindex 73c637220..c9f6e5590 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+ 'lsc.cpp',\n ])\ndiff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\nindex ff312ae8f..23c2cfd0a 100644\n--- a/src/ipa/simple/ipa_context.h\n+++ b/src/ipa/simple/ipa_context.h\n@@ -19,6 +19,7 @@\n #include <libipa/awb.h>\n #include <libipa/ccm.h>\n #include <libipa/fc_queue.h>\n+#include \"libipa/lsc.h\"\n \n #include \"core_ipa_interface.h\"\n \n@@ -61,6 +62,8 @@ struct IPAActiveState {\n \t\tstd::optional<float> contrast;\n \t\tstd::optional<float> saturation;\n \t} knobs;\n+\n+\tipa::lsc::ActiveState lsc;\n };\n \n struct IPAFrameContext : public FrameContext {\n@@ -75,6 +78,7 @@ struct IPAFrameContext : public FrameContext {\n \tfloat gamma;\n \tstd::optional<float> contrast;\n \tstd::optional<float> saturation;\n+\tipa::lsc::FrameContext lsc;\n };\n \n struct IPAContext {\n@@ -89,6 +93,7 @@ struct IPAContext {\n \tFCQueue<IPAFrameContext> frameContexts;\n \tControlInfoMap::Map ctrlMap;\n \tbool ccmEnabled = false;\n+\tipa::lsc::ActiveState lsc;\n };\n \n } /* namespace ipa::soft */\n", "prefixes": [ "RFC", "v6", "3/6" ] }