Patch Detail
Show a patch.
GET /api/patches/26564/?format=api
{ "id": 26564, "url": "https://patchwork.libcamera.org/api/patches/26564/?format=api", "web_url": "https://patchwork.libcamera.org/patch/26564/", "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": "<20260424200255.356798-5-mzamazal@redhat.com>", "date": "2026-04-24T20:02:50", "name": "[RFC,v3,4/7] ipa: simple: Add LSC algorithm", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "1a84bd5e09a4f5119b326815c75f9cde24558533", "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/26564/mbox/", "series": [ { "id": 5885, "url": "https://patchwork.libcamera.org/api/series/5885/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5885", "date": "2026-04-24T20:02:46", "name": "LSC for SoftISP simple pipeline", "version": 3, "mbox": "https://patchwork.libcamera.org/series/5885/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/26564/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/26564/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 2419FBE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Apr 2026 20:03:24 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D5C8562FB0;\n\tFri, 24 Apr 2026 22:03:23 +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 F128B62E6A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Apr 2026 22:03:21 +0200 (CEST)", "from mx-prod-mc-06.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-561-zDyhLaQDNEyuhoxACZ4uCQ-1;\n\tFri, 24 Apr 2026 16:03:17 -0400", "from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\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-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id E274518005A9; Fri, 24 Apr 2026 20:03:13 +0000 (UTC)", "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.32.33])\n\tby mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id B8ACF3007572; Fri, 24 Apr 2026 20:03:11 +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=\"TCvaDTr+\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1777061000;\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=DIGVeJ4bqKpKRKJEA8DvJ0QJ41ZIivpKRCLH3IYu/XA=;\n\tb=TCvaDTr+ivJPTUbQN6xhWjD7aZaslLddn15vl77tIYJqnfckfLBFm/+Vg6zCHJu7C6OrM8\n\twihiVNrcbXEerWazE4ErF4v9lcigoXi+UP0/TbbdoYOaRjGFyTDVljnN8E/C9s/4GYOs/A\n\t8HGWGkhOqKqNQG/6k8jGzChB/CVf+n8=", "X-MC-Unique": "zDyhLaQDNEyuhoxACZ4uCQ-1", "X-Mimecast-MFC-AGG-ID": "zDyhLaQDNEyuhoxACZ4uCQ_1777060994", "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\tRick ten Wolde <rick_libcamera@wolde.info>,\n\tMilan Zamazal <mzamazal@redhat.com>", "Subject": "[RFC PATCH v3 4/7] ipa: simple: Add LSC algorithm", "Date": "Fri, 24 Apr 2026 22:02:50 +0200", "Message-ID": "<20260424200255.356798-5-mzamazal@redhat.com>", "In-Reply-To": "<20260424200255.356798-1-mzamazal@redhat.com>", "References": "<20260424200255.356798-1-mzamazal@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.30.177.4", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "LFReHKQBc-uLY5numqWNt71sn_GQ8Wdn3XVdra8K_Y0_1777060994", "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 lens shading algorithm uses grid-based interpolation. The grid\nvalues are specified in a tuning file as multiplication factors for each\nof the RGB colours.\n\nThe interpolated grid is transformed to an array to be used as an RGB\ntexture in debayering. The floating point multiplication factors\nspecified in the tuning file are converted to bytes, from 1.0..4.0\nrange (values outside this range are clamped) to 0..255 range. This is\nto make the table smaller and avoiding dealing with floating point\ntextures (for no better reason that we already use byte textures and\nknow how to do it).\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 | 79 +++++++++++++++++++++++++++\n src/ipa/simple/algorithms/lsc.h | 41 ++++++++++++++\n src/ipa/simple/algorithms/meson.build | 1 +\n 3 files changed, 121 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..585957e74\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/lsc.cpp\n@@ -0,0 +1,79 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Lens shading correction\n+ */\n+\n+#include \"lsc.h\"\n+\n+#include <algorithm>\n+#include <cmath>\n+\n+#include <libcamera/base/log.h>\n+\n+#include \"awb.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa::soft::algorithms {\n+\n+LOG_DEFINE_CATEGORY(IPASoftLsc)\n+\n+int Lsc::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)\n+{\n+\tint ret_r = lscR.readYaml(tuningData[\"grids\"], \"ct\", \"r\");\n+\tint ret_g = lscG.readYaml(tuningData[\"grids\"], \"ct\", \"g\");\n+\tint ret_b = lscB.readYaml(tuningData[\"grids\"], \"ct\", \"b\");\n+\n+\tif (ret_r < 0 || ret_g < 0 || ret_b < 0) {\n+\t\tLOG(IPASoftLsc, Error)\n+\t\t\t<< \"Failed to parse 'lsc' parameter from tuning file.\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+int Lsc::configure([[maybe_unused]] IPAContext &context,\n+\t\t [[maybe_unused]] const IPAConfigInfo &configInfo)\n+{\n+\treturn 0;\n+}\n+\n+void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n+\t\t [[maybe_unused]] IPAFrameContext &frameContext, DebayerParams *params)\n+{\n+\tunsigned int ct =\n+\t\tcontext.activeState.awb.temperatureK.value_or(kDefaultTemperature);\n+\n+\tconst LscMatrix matrixR = lscR.getInterpolated(ct);\n+\tconst LscMatrix matrixG = lscG.getInterpolated(ct);\n+\tconst LscMatrix matrixB = lscB.getInterpolated(ct);\n+\n+\t/*\n+\t * The constructed table is compressed by converting from floats to bytes.\n+\t * This makes the texture uploaded to a GPU smaller and we don't have to\n+\t * deal with textures containing float values.\n+\t * The byte range 0..255 represents floating point values 1.0..4.0. Values\n+\t * outside this range are clamped. When accessed in the shader, the byte\n+\t * range is represented by 0.0..1.0 range. Then the resulting pixel value\n+\t * can be computed as\n+\t * rgb + rgb * 3.0 * LUT_VALUE\n+\t */\n+\tDebayerParams::LscLookupTable lut;\n+\tconstexpr unsigned int gridSize = DebayerParams::kLscGridSize;\n+\tauto float2byte = [](float factor) -> uint8_t {\n+\t\treturn std::round((std::clamp(factor, 1.0f, 4.0f) - 1.0) / 3.0 * 255);\n+\t};\n+\tfor (unsigned int i = 0, j = 0; i < gridSize * gridSize; i++) {\n+\t\tlut[j++] = float2byte(matrixR.data()[i]);\n+\t\tlut[j++] = float2byte(matrixG.data()[i]);\n+\t\tlut[j++] = float2byte(matrixB.data()[i]);\n+\t}\n+\tparams->lscLut = lut;\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..ef3474aec\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/lsc.h\n@@ -0,0 +1,41 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Lens shading correction\n+ */\n+\n+#pragma once\n+\n+#include \"libcamera/internal/matrix.h\"\n+\n+#include <libipa/interpolator.h>\n+\n+#include \"algorithm.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 YamlObject &tuningData) override;\n+\tint configure(IPAContext &context,\n+\t\t const IPAConfigInfo &configInfo) 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+\n+private:\n+\tusing LscMatrix = Matrix<float, DebayerParams::kLscGridSize, DebayerParams::kLscGridSize>;\n+\tInterpolator<LscMatrix> lscR;\n+\tInterpolator<LscMatrix> lscG;\n+\tInterpolator<LscMatrix> lscB;\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 ])\n", "prefixes": [ "RFC", "v3", "4/7" ] }