[{"id":37200,"web_url":"https://patchwork.libcamera.org/comment/37200/","msgid":"<85iken1j04.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-12-03T19:07:55","subject":"Re: [PATCH v6 10/24] libcamera: shaders: Add support for contrast","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes:\n\n> Apply contrast after black-level and CCM operations.\n>\n> Suggested-by: Milan Zamazal <mzamazal@redhat.com>\n> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> ---\n>  src/libcamera/shaders/bayer_1x_packed.frag | 19 +++++++++++++++++++\n>  src/libcamera/shaders/bayer_unpacked.frag  | 19 +++++++++++++++++++\n>  2 files changed, 38 insertions(+)\n>\n> diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag\n> index 77d9fbfa7..2fc9952e2 100644\n> --- a/src/libcamera/shaders/bayer_1x_packed.frag\n> +++ b/src/libcamera/shaders/bayer_1x_packed.frag\n> @@ -68,6 +68,19 @@ uniform sampler2D tex_y;\n>  uniform mat3 ccm;\n>  uniform vec3 blacklevel;\n>  uniform float gamma;\n> +uniform float contrast;\n> +\n> +float apply_contrast(float normalise, float contrast_in)\n\nThe argument names look somewhat confusing.  How about simply\n\n  float apply_contrast(float value, float contrast)\n\n?\n\n(The same for the unpacked shader.)\n\n> +{\n> +\t// Convert 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2)\n> +\tfloat contrastExp = tan(clamp(contrast_in * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001));\n\nThis is computed 3 times per each pixel, while the value can be computed\njust once per the whole image.  It doesn't seem to have an obvious\nimpact on performance, but still...\n\n(The same for the unpacked shader.)\n\n> +\n> +\t// Apply simple S-curve\n> +\tif (normalise < 0.5)\n> +\t\treturn 0.5 * pow(normalise / 0.5, contrastExp);\n> +\telse\n> +\t\treturn 1.0 - 0.5 * pow((1.0 - normalise) / 0.5, contrastExp);\n> +}\n>  \n>  void main(void)\n>  {\n> @@ -261,6 +274,12 @@ void main(void)\n>  \trgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);\n>  \trgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);\n>  \n> +\t/* Contrast */\n\nIt would be nice to use either \"/* ... */\" or \"// ...\" single line\ncomments consistently.\n\n> +\trgb = clamp(rgb, 0.0, 1.0);\n> +\trgb.r = apply_contrast(rgb.r, contrast);\n> +\trgb.g = apply_contrast(rgb.g, contrast);\n> +\trgb.b = apply_contrast(rgb.b, contrast);\n> +\n>  \t/* Apply gamma after colour correction */\n>  \trgb = pow(rgb, vec3(gamma));\n>  \n> diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag\n> index aba11a87f..caa0ba15d 100644\n> --- a/src/libcamera/shaders/bayer_unpacked.frag\n> +++ b/src/libcamera/shaders/bayer_unpacked.frag\n> @@ -27,6 +27,19 @@ varying vec4            xCoord;\n>  uniform mat3            ccm;\n>  uniform vec3            blacklevel;\n>  uniform float           gamma;\n> +uniform float           contrast;\n> +\n> +float apply_contrast(float normalise, float contrast_in)\n> +{\n> +    // Convert 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2)\n> +    float contrastExp = tan(clamp(contrast_in * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001));\n> +\n> +    // Apply simple S-curve\n> +    if (normalise < 0.5)\n> +        return 0.5 * pow(normalise / 0.5, contrastExp);\n> +    else\n> +        return 1.0 - 0.5 * pow((1.0 - normalise) / 0.5, contrastExp);\n> +}\n>  \n>  void main(void) {\n>      vec3 rgb;\n> @@ -156,6 +169,12 @@ void main(void) {\n>      rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);\n>      rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);\n>  \n> +    /* Contrast */\n> +    rgb = clamp(rgb, 0.0, 1.0);\n> +    rgb.r = apply_contrast(rgb.r, contrast);\n> +    rgb.g = apply_contrast(rgb.g, contrast);\n> +    rgb.b = apply_contrast(rgb.b, contrast);\n> +\n>      /* Apply gamma after colour correction */\n>      rgb = pow(rgb, vec3(gamma));","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 E9339C3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  3 Dec 2025 19:08:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2282D60F7C;\n\tWed,  3 Dec 2025 20:08:21 +0100 (CET)","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 F3094609D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  3 Dec 2025 20:08:19 +0100 (CET)","from mail-wm1-f72.google.com (mail-wm1-f72.google.com\n\t[209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-204-XgXjuSpGPemmNK5HTfAAUQ-1; Wed, 03 Dec 2025 14:07:59 -0500","by mail-wm1-f72.google.com with SMTP id\n\t5b1f17b1804b1-4779d8fd4ecso469095e9.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 03 Dec 2025 11:07:59 -0800 (PST)","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-42e1ca1a2easm42282469f8f.23.2025.12.03.11.07.56\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 03 Dec 2025 11:07:56 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"M+c27JAo\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1764788898;\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=nOJ+HgjMqJTUWyDm7Mj7rdkzE/mYojREhBQjt+HBUt8=;\n\tb=M+c27JAojtQ265kQBJkALkzDLEaKlfkHBGW8pTKcE21HAX5Ef42ofhFiL4BRlzlgliB6+B\n\tJUmxliOmBgyL3cFGu7SsEUBbMFC2DgDb8mYMyYPSo1ElBVtcb4ACy/Zf2aWBsrpnbkdBWh\n\tbyt9ZLeBG0Ii3JhvcmZSyhTvj6nNmY4=","X-MC-Unique":"XgXjuSpGPemmNK5HTfAAUQ-1","X-Mimecast-MFC-AGG-ID":"XgXjuSpGPemmNK5HTfAAUQ_1764788878","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1764788878; x=1765393678;\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=nOJ+HgjMqJTUWyDm7Mj7rdkzE/mYojREhBQjt+HBUt8=;\n\tb=RIi+aXhODu8VXeIv1KH49R2zCMM++fcDj/02aH2fHtJuQw0VcnPqkp7dKolr6BCftn\n\tCuJ3UjxRia0UJxStvyxzCSmuRJIKExrF6+2eYbfX1Q9pj/JYbSz+DhCapuxmZFpx0hwY\n\tYtSqZJ4mL+RLj2DkoSgVzo5wZh9C+eIR844k9B8rojDVWvkw3NemfI1zaMcuOncDcPwr\n\t9dafXOnx21RC6AUopGZqpYpk7lb6KQJ7hU9rkm5fDZGqTGqWqZWTdVDRu7twZJMGiQZ7\n\tTPF/kFHNMo+sViLoUCJumCUmCNHNkIHN4UKh5OofbBdv7HzqOJMmB94gu4b0x63S4yQ8\n\t5lLw==","X-Gm-Message-State":"AOJu0Yz2DBjLzpOrTPXbi+T+maL6weHwfjkHsrfrnNKmRAnrkNpTX3Vd\n\t7CNmEWM+P/quFWt87FfWA/qCZ3k8+zGvPYqoNa7V8JUsVIcWCLqe8iteimAEUDaC1qP7675rNPB\n\tvg/VLMDOFjeJEc1jy+PkeLuGOH4BJyaCdQaoyQV7hQzb1+jsG/pHW5VBQFqyubya6Uspd1gmK5V\n\t+VDRLWyE8=","X-Gm-Gg":"ASbGncvFbQDMpULGiEM8iMowwQPkaQ+tbWxvLOqcrU3AG2t1gy9Rq/izqDrSKWpzPEU\n\tihSO/d0Ia0QZvoZfqJXwd8OfkzBCDCcc409OwFs8VK46ZB62hkvxRTXvvxnIlygaDyuUuQ7y18q\n\tPsN46iUQ3H3dg1x6TkRHyBnq0VO+gRaobHCVdBScd249K/zrni3U6z0+3u2m+DLBy6d2dsm2os3\n\tRR3+iBJiIotjBkKRaCqXEGD5/X5hW+jEZiz8SMKclmmGWgZmB5M1zeZ3C+9zP/DzLL05IGr/Uxn\n\txDO+VwTzOfYJ5MU0kDADb+Qu7NQNhyKqTLBOh9IM3iwwVpXF0evd5ZPdWhf2gdm8G3kxBSQR3OG\n\twOo7qVb88n6TJDQml6o7NLvVNUjzs8z8HmAEdxmU7ZwZFk98YZpTCgKw588v6QgA=","X-Received":["by 2002:a7b:c7c4:0:b0:477:9890:4528 with SMTP id\n\t5b1f17b1804b1-4792eb05eddmr3908595e9.2.1764788877759; \n\tWed, 03 Dec 2025 11:07:57 -0800 (PST)","by 2002:a7b:c7c4:0:b0:477:9890:4528 with SMTP id\n\t5b1f17b1804b1-4792eb05eddmr3908385e9.2.1764788877349; \n\tWed, 03 Dec 2025 11:07:57 -0800 (PST)"],"X-Google-Smtp-Source":"AGHT+IGKMTfIkbZFY6Q54W27bPgEE5aX5zJMOjzWDqeFPsB1zFesEdgNHIdQolGvK03MeIYFptle4A==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>","Cc":"libcamera-devel@lists.libcamera.org,  pavel@ucw.cz","Subject":"Re: [PATCH v6 10/24] libcamera: shaders: Add support for contrast","In-Reply-To":"<20251202134544.662446-11-bryan.odonoghue@linaro.org> (Bryan\n\tO'Donoghue's message of \"Tue, 2 Dec 2025 13:45:30 +0000\")","References":"<20251202134544.662446-1-bryan.odonoghue@linaro.org>\n\t<20251202134544.662446-11-bryan.odonoghue@linaro.org>","Date":"Wed, 03 Dec 2025 20:07:55 +0100","Message-ID":"<85iken1j04.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":"r9NtJcRiYqSA4rmMW62KQc50l-4AdMUgadDTUQcwx6A_1764788878","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>"}}]