From patchwork Fri Nov 7 15:20:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 24984 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id DBEB8BDE4C for ; Fri, 7 Nov 2025 15:20:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DB409608CF; Fri, 7 Nov 2025 16:20:35 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="TuWeDPV9"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5A275608CF for ; Fri, 7 Nov 2025 16:20:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762528833; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=A9Kb1mfgtnt5C6hD3ZfwCW9mX9y3jA/zo5lRUGy9wFM=; b=TuWeDPV9R18EywsRMWZHcSVAKQ6xKTWdVGE7cFjUwBu9yUovfQz2vhaUWocorxvoxJGfE5 /zVo0zPgsC8wbW7jlhLn7zCMdG9SSiybFJ0hXTrod/RhpOTRQEZkpDL2vgkVBnTbcCfR6V tC9XWc4rLV6O9Vj/zk0Rly9pMKfloLY= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-653-YmxudqN7OZmq99gR4qLe3Q-1; Fri, 07 Nov 2025 10:20:31 -0500 X-MC-Unique: YmxudqN7OZmq99gR4qLe3Q-1 X-Mimecast-MFC-AGG-ID: YmxudqN7OZmq99gR4qLe3Q_1762528830 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BDFCB1955F44 for ; Fri, 7 Nov 2025 15:20:30 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.33.41]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A0A601800298; Fri, 7 Nov 2025 15:20:29 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal Subject: [PATCH] libcamera: software_isp: Fix gamma table when CCM is used Date: Fri, 7 Nov 2025 16:20:25 +0100 Message-ID: <20251107152025.18434-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: U-Kt29uuclvwzek2x3rC9YiCDSHDLeymrTz8-COmSv8_1762528830 X-Mimecast-Originator: redhat.com 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Software CPU ISP computes a gamma lookup table. The table incorporates black level and contrast. All entries in the table below the black level are set to 0. This is not necessarily correct all the time. Let's consider this case: The CCM is [1 0 0] [0 1 0] [0 0 0] and contrast is set to zero. The gamma table has all the entries above the black level set to 186 (due to zero contrast) and all the entries below the black level set to 0. CCM is applied before gamma, a non-black level pixel has the blue component set to 0 with the CCM above. Now, when the gamma lookup is applied, the red and green components are set to 186, while the blue component is set to 0. The resulting pixel is then yellow rather than grey (as it should be with zero contrast). There are two ways to fix this: Either clamping pixel colour channels to the black level in debayering or setting the below black level entries in the gamma lookup table to the lowest value of the gamma table rather than 0. Both should have the same effect. Let's opt for the latter for its simplicity. Signed-off-by: Milan Zamazal Reviewed-by: Hans de Goede --- src/ipa/simple/algorithms/lut.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp index d1d5f7271..d4a79e101 100644 --- a/src/ipa/simple/algorithms/lut.cpp +++ b/src/ipa/simple/algorithms/lut.cpp @@ -61,7 +61,6 @@ void Lut::updateGammaTable(IPAContext &context) const unsigned int blackIndex = blackLevel * gammaTable.size() / 256; const auto contrast = context.activeState.knobs.contrast.value_or(1.0); - std::fill(gammaTable.begin(), gammaTable.begin() + blackIndex, 0); const float divisor = gammaTable.size() - blackIndex - 1.0; for (unsigned int i = blackIndex; i < gammaTable.size(); i++) { double normalized = (i - blackIndex) / divisor; @@ -75,6 +74,14 @@ void Lut::updateGammaTable(IPAContext &context) gammaTable[i] = UINT8_MAX * std::pow(normalized, context.configuration.gamma); } + /* + * Due to CCM operations, the table lookup may reach indices below the black + * level. Let's set the table values below black level to the minimum + * non-black value to prevent problems when the minimum value is + * significantly non-zero (for example, when the image should be all grey). + */ + std::fill(gammaTable.begin(), gammaTable.begin() + blackIndex, + gammaTable[blackIndex]); context.activeState.gamma.blackLevel = blackLevel; context.activeState.gamma.contrast = contrast;