Patch Detail
Show a patch.
GET /api/1.1/patches/22094/?format=api
{ "id": 22094, "url": "https://patchwork.libcamera.org/api/1.1/patches/22094/?format=api", "web_url": "https://patchwork.libcamera.org/patch/22094/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20241126091509.89677-4-mzamazal@redhat.com>", "date": "2024-11-26T09:15:04", "name": "[v4,3/4] libcamera: software_isp: Add support for contrast control", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "7edbe3b9899ba2375011d66e5bd84c00f039d860", "submitter": { "id": 177, "url": "https://patchwork.libcamera.org/api/1.1/people/177/?format=api", "name": "Milan Zamazal", "email": "mzamazal@redhat.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/22094/mbox/", "series": [ { "id": 4821, "url": "https://patchwork.libcamera.org/api/1.1/series/4821/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4821", "date": "2024-11-26T09:15:01", "name": "Add contrast control to software ISP", "version": 4, "mbox": "https://patchwork.libcamera.org/series/4821/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/22094/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/22094/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 388AAC0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 Nov 2024 09:15:33 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9783D65FBF;\n\tTue, 26 Nov 2024 10:15:32 +0100 (CET)", "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 B299965FAB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Nov 2024 10:15:29 +0100 (CET)", "from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-633-K61gQ-oYNKaLg6Mw91WrTQ-1;\n\tTue, 26 Nov 2024 04:15:24 -0500", "from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.40])\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-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id 1EF7C1955E7D; Tue, 26 Nov 2024 09:15:23 +0000 (UTC)", "from nuthatch.brq.redhat.com (unknown [10.43.17.31])\n\tby mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 04F111955F40; Tue, 26 Nov 2024 09:15:21 +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=\"D0f98HXA\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1732612528;\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=YZc6IEAwSFcDS3tALWefsyHUSy6igdBROncfbhqnvxs=;\n\tb=D0f98HXA9YYaMlNWeaffOFw7bev7wrRtmkn1HdQfM5pn1Ys5MDncJQhlcnMoXyud+FH836\n\tInqFV9D23QRjNAS06Jrt99oUAITihTTIWixqlhFYpAR0BAPZKPs53XRIigOqEC5DY6rq0Y\n\tzbZoLFGGWVjP2GVD0rVcp3rBGdriCsQ=", "X-MC-Unique": "K61gQ-oYNKaLg6Mw91WrTQ-1", "X-Mimecast-MFC-AGG-ID": "K61gQ-oYNKaLg6Mw91WrTQ", "From": "Milan Zamazal <mzamazal@redhat.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Milan Zamazal <mzamazal@redhat.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>", "Subject": "[PATCH v4 3/4] libcamera: software_isp: Add support for contrast\n\tcontrol", "Date": "Tue, 26 Nov 2024 10:15:04 +0100", "Message-ID": "<20241126091509.89677-4-mzamazal@redhat.com>", "In-Reply-To": "<20241126091509.89677-1-mzamazal@redhat.com>", "References": "<20241126091509.89677-1-mzamazal@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.40", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "en1ICIrsNCWgs6Q6tZ0VRg2TJj__lmYBCQeT8lgQqbc_1732612523", "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": "Software ISP is currently fully automatic and doesn't allow image\nmodifications by explicitly set control values. The user has no means\nto make the image looking better.\n\nThis patch introduces support for contrast control, which can improve\ne.g. a flat looking image. Based on the provided contrast value with a\nrange 0..infinity and 1.0 being the normal value, it applies a simple\nS-curve modification to the image. The contrast algorithm just handles\nthe provided values, while the S-curve is applied in the gamma algorithm\non the computed gamma curve whenever the contrast value changes. Since\nthe algorithm is applied only on the lookup table already present, its\noverhead is negligible.\n\nThis is a preparation patch without actually providing the control\nitself, which is done in the following patch.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\n---\n src/ipa/simple/algorithms/lut.cpp | 38 +++++++++++++++++++++++++++----\n src/ipa/simple/algorithms/lut.h | 5 ++++\n src/ipa/simple/ipa_context.h | 7 ++++++\n 3 files changed, 45 insertions(+), 5 deletions(-)", "diff": "diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp\nindex 9744e773a..ffded0594 100644\n--- a/src/ipa/simple/algorithms/lut.cpp\n+++ b/src/ipa/simple/algorithms/lut.cpp\n@@ -9,14 +9,19 @@\n \n #include <algorithm>\n #include <cmath>\n+#include <optional>\n #include <stdint.h>\n \n #include <libcamera/base/log.h>\n \n #include \"simple/ipa_context.h\"\n \n+#include \"control_ids.h\"\n+\n namespace libcamera {\n \n+LOG_DEFINE_CATEGORY(IPASoftLut)\n+\n namespace ipa::soft::algorithms {\n \n int Lut::configure(IPAContext &context,\n@@ -24,24 +29,46 @@ int Lut::configure(IPAContext &context,\n {\n \t/* Gamma value is fixed */\n \tcontext.configuration.gamma = 0.5;\n+\tcontext.activeState.knobs.contrast = std::optional<double>();\n \tupdateGammaTable(context);\n \n \treturn 0;\n }\n \n+void Lut::queueRequest(typename Module::Context &context,\n+\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t [[maybe_unused]] typename Module::FrameContext &frameContext,\n+\t\t const ControlList &controls)\n+{\n+\tconst auto &contrast = controls.get(controls::Contrast);\n+\tif (contrast.has_value()) {\n+\t\tcontext.activeState.knobs.contrast = contrast;\n+\t\tLOG(IPASoftLut, Debug) << \"Setting contrast to \" << contrast.value();\n+\t}\n+}\n+\n void Lut::updateGammaTable(IPAContext &context)\n {\n \tauto &gammaTable = context.activeState.gamma.gammaTable;\n-\tauto blackLevel = context.activeState.blc.level;\n+\tconst auto blackLevel = context.activeState.blc.level;\n \tconst unsigned int blackIndex = blackLevel * gammaTable.size() / 256;\n+\tconst auto contrast = context.activeState.knobs.contrast.value_or(1.0);\n \n \tstd::fill(gammaTable.begin(), gammaTable.begin() + blackIndex, 0);\n \tconst float divisor = gammaTable.size() - blackIndex - 1.0;\n-\tfor (unsigned int i = blackIndex; i < gammaTable.size(); i++)\n-\t\tgammaTable[i] = UINT8_MAX * std::pow((i - blackIndex) / divisor,\n-\t\t\t\t\t\t context.configuration.gamma);\n+\tfor (unsigned int i = blackIndex; i < gammaTable.size(); i++) {\n+\t\tdouble normalized = (i - blackIndex) / divisor;\n+\t\t/* Apply simple S-curve */\n+\t\tif (normalized < 0.5)\n+\t\t\tnormalized = 0.5 * std::pow(normalized / 0.5, contrast);\n+\t\telse\n+\t\t\tnormalized = 1.0 - 0.5 * std::pow((1.0 - normalized) / 0.5, contrast);\n+\t\tgammaTable[i] = UINT8_MAX *\n+\t\t\t\tstd::pow(normalized, context.configuration.gamma);\n+\t}\n \n \tcontext.activeState.gamma.blackLevel = blackLevel;\n+\tcontext.activeState.gamma.contrast = contrast;\n }\n \n void Lut::prepare(IPAContext &context,\n@@ -55,7 +82,8 @@ void Lut::prepare(IPAContext &context,\n \t * observed, it's not permanently prone to minor fluctuations or\n \t * rounding errors.\n \t */\n-\tif (context.activeState.gamma.blackLevel != context.activeState.blc.level)\n+\tif (context.activeState.gamma.blackLevel != context.activeState.blc.level ||\n+\t context.activeState.gamma.contrast != context.activeState.knobs.contrast)\n \t\tupdateGammaTable(context);\n \n \tauto &gains = context.activeState.gains;\ndiff --git a/src/ipa/simple/algorithms/lut.h b/src/ipa/simple/algorithms/lut.h\nindex b635987d0..ef2df147c 100644\n--- a/src/ipa/simple/algorithms/lut.h\n+++ b/src/ipa/simple/algorithms/lut.h\n@@ -20,6 +20,11 @@ public:\n \t~Lut() = default;\n \n \tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n+\tvoid queueRequest(typename Module::Context &context,\n+\t\t\t const uint32_t frame,\n+\t\t\t typename Module::FrameContext &frameContext,\n+\t\t\t const ControlList &controls)\n+\t\toverride;\n \tvoid prepare(IPAContext &context,\n \t\t const uint32_t frame,\n \t\t IPAFrameContext &frameContext,\ndiff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\nindex fd7343e91..148052207 100644\n--- a/src/ipa/simple/ipa_context.h\n+++ b/src/ipa/simple/ipa_context.h\n@@ -11,6 +11,8 @@\n #include <optional>\n #include <stdint.h>\n \n+#include <libcamera/controls.h>\n+\n #include <libipa/fc_queue.h>\n \n namespace libcamera {\n@@ -48,7 +50,12 @@ struct IPAActiveState {\n \tstruct {\n \t\tstd::array<double, kGammaLookupSize> gammaTable;\n \t\tuint8_t blackLevel;\n+\t\tdouble contrast;\n \t} gamma;\n+\tstruct {\n+\t\t/* 0..inf range, 1.0 = normal */\n+\t\tstd::optional<double> contrast;\n+\t} knobs;\n };\n \n struct IPAFrameContext : public FrameContext {\n", "prefixes": [ "v4", "3/4" ] }