[{"id":37347,"web_url":"https://patchwork.libcamera.org/comment/37347/","msgid":"<85ecozqwio.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-12-12T20:23:59","subject":"Re: [PATCH v8 10/26] 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\nReviewed-by: Milan Zamazal <mzamazal@redhat.com>\n\n> ---\n>  src/libcamera/shaders/bayer_1x_packed.frag | 21 +++++++++++++++++++++\n>  src/libcamera/shaders/bayer_unpacked.frag  | 21 +++++++++++++++++++++\n>  2 files changed, 42 insertions(+)\n>\n> diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag\n> index 77d9fbfa7..0b730070e 100644\n> --- a/src/libcamera/shaders/bayer_1x_packed.frag\n> +++ b/src/libcamera/shaders/bayer_1x_packed.frag\n> @@ -68,6 +68,16 @@ 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 value, float contrastExp)\n> +{\n> +\t// Apply simple S-curve\n> +\tif (value < 0.5)\n> +\t\treturn 0.5 * pow(value / 0.5, contrastExp);\n> +\telse\n> +\t\treturn 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp);\n> +}\n>  \n>  void main(void)\n>  {\n> @@ -261,6 +271,17 @@ 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/*\n> +\t * Contrast\n> +\t * contrastExp 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2)\n> +\t */\n> +\tfloat contrastExp = tan(clamp(contrast * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001));\n> +\n> +\trgb = clamp(rgb, 0.0, 1.0);\n> +\trgb.r = apply_contrast(rgb.r, contrastExp);\n> +\trgb.g = apply_contrast(rgb.g, contrastExp);\n> +\trgb.b = apply_contrast(rgb.b, contrastExp);\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..114e32058 100644\n> --- a/src/libcamera/shaders/bayer_unpacked.frag\n> +++ b/src/libcamera/shaders/bayer_unpacked.frag\n> @@ -27,6 +27,16 @@ 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 value, float contrastExp)\n> +{\n> +    // Apply simple S-curve\n> +    if (value < 0.5)\n> +        return 0.5 * pow(value / 0.5, contrastExp);\n> +    else\n> +        return 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp);\n> +}\n>  \n>  void main(void) {\n>      vec3 rgb;\n> @@ -156,6 +166,17 @@ 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> +    /*\n> +     * Contrast\n> +     * Convert 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2)\n> +     */\n> +    float contrastExp = tan(clamp(contrast * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001));\n> +\n> +    rgb = clamp(rgb, 0.0, 1.0);\n> +    rgb.r = apply_contrast(rgb.r, contrastExp);\n> +    rgb.g = apply_contrast(rgb.g, contrastExp);\n> +    rgb.b = apply_contrast(rgb.b, contrastExp);\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 20F76BD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 12 Dec 2025 20:24:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 363DC61893;\n\tFri, 12 Dec 2025 21:24:06 +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 53C266142F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 12 Dec 2025 21:24:05 +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-629-Ci363lgXMaSNS_mQEJigAw-1; Fri, 12 Dec 2025 15:24:02 -0500","by mail-wm1-f72.google.com with SMTP id\n\t5b1f17b1804b1-47a83800743so7539715e9.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 12 Dec 2025 12:24:02 -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\t5b1f17b1804b1-47a8f4ae4d3sm17584425e9.5.2025.12.12.12.24.00\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 12 Dec 2025 12:24:00 -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=\"GodLlGeY\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1765571044;\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=e24KuE/7KVwORRzfQ02IRNndSdy3ikFH/0weoy/2uHQ=;\n\tb=GodLlGeYIerY9D25qwz9byPYuiQe+qHK7HMgoTLU1Qdu0jwn4kOUZAPBRYXViOhdIwHJ+Q\n\tGYoRWitMkytkVGbzBn0IpsWPJOgHHCLEtixtKMWpLw6hYlDtzRSQYH3QIIQ9BLKhKpYAox\n\tcD7Fd1/3uGFpFQcW/OunMWUktzfObkE=","X-MC-Unique":"Ci363lgXMaSNS_mQEJigAw-1","X-Mimecast-MFC-AGG-ID":"Ci363lgXMaSNS_mQEJigAw_1765571042","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1765571041; x=1766175841;\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=e24KuE/7KVwORRzfQ02IRNndSdy3ikFH/0weoy/2uHQ=;\n\tb=VOwF89vZRaPj+qAq16n8Busbyt/2Wx4oh3OribE4F8ANgdG9snylgSUu8q9gBIGBLw\n\tsy4VbgPCdm6ZspS3qQUQU6+U2mmMKT2wItHfJGNwCj4+NmcyEyvnTs5X5SQysegTwnP8\n\tq9LaL+7JKv7DD01sFvXAqp1EPwf4nBebJxKHr4RjvBcDM9ooaioxoXxwQD7xM8ytb3u5\n\t4wJ5PDqzQQ2c7AgbU6ud6tgmjmuviEkU17C+StgRSePJWQT37596xuLCUH+09u3e6Ba5\n\tlPC/T7yTCsDLY1fhrTkwTddGUKQ2oOP0PaffCtbQyMKkUkJVHP4Pg7X9iKsCCud3SMzz\n\tZBCw==","X-Gm-Message-State":"AOJu0YzYCnXXdDustfczdrdzPGxzxLtvHpdXHajIu+MQNJS3quC5rWf8\n\tia3rybw5QAKkba77ozuou7vFHNd+gya0aNu9MeW9ER75nWncvDlI8DvWaiolD+vDThwH/9JutEl\n\ttHvrpRX7hNEngysEMxLiyELIsmJbsMk218eRWPJcEXnH5uq/XXSbrXSvjbTJ3FlO8BKt02i/mMz\n\tQ=","X-Gm-Gg":"AY/fxX4lv/jwVAr6evTX5VX5Be0S7+SsT1VCVDdy5Us4vAim02W0mZVcGVjqHRbrSpa\n\tQg5vGoMCM8TI1qppU3DqIXhS+pTdf81/gINiaGRO7CJA4UvntaGOq1Y29rz8uJSWPo1/6Gd7IgS\n\tvzbGZLRjmB65uJYFp02PJslhvLbFE2kXBgXKmJcjaMUrDrNNlfdRkVTjJasPnXBiGKV67uVAfuK\n\tP2JkzCRXTj30pXuV8T7TapcswMBRM9xv0w4W3MyAcdeHhgY5M30D8TEVhd9D4yFzR1kyyf5cUoF\n\tqZ5eBnChJWt9Z8UopqfYGb5TnimqOAZDRR12AHNDfO1j45uwFclnRyONPFDHH5r9eWW9WYmESxo\n\t7OZgF3yfn3jsiSyV/J+opeE4XIOc1kucCsglthG0lgtX9FygzogTMmIiRsHQN4zY=","X-Received":["by 2002:a05:600c:46cb:b0:471:665:e688 with SMTP id\n\t5b1f17b1804b1-47a8f2cacf3mr37407095e9.17.1765571041583; \n\tFri, 12 Dec 2025 12:24:01 -0800 (PST)","by 2002:a05:600c:46cb:b0:471:665:e688 with SMTP id\n\t5b1f17b1804b1-47a8f2cacf3mr37406955e9.17.1765571041204; \n\tFri, 12 Dec 2025 12:24:01 -0800 (PST)"],"X-Google-Smtp-Source":"AGHT+IEbjpSnkVcbDBWo8nrLG2exmN6ue5qjowvY5KCp3nKP74qZ5aIau1RP/QPYlQzVPxT9Wl/dTQ==","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 v8 10/26] libcamera: shaders: Add support for contrast","In-Reply-To":"<20251212002937.3118-11-bryan.odonoghue@linaro.org> (Bryan\n\tO'Donoghue's message of \"Fri, 12 Dec 2025 00:29:21 +0000\")","References":"<20251212002937.3118-1-bryan.odonoghue@linaro.org>\n\t<20251212002937.3118-11-bryan.odonoghue@linaro.org>","Date":"Fri, 12 Dec 2025 21:23:59 +0100","Message-ID":"<85ecozqwio.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":"38Pz54xWbyLb4Cr5WOQXkKyBic3JCGdke_L0F4fKJIk_1765571042","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>"}}]