[{"id":38172,"web_url":"https://patchwork.libcamera.org/comment/38172/","msgid":"<85v7g3wfju.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-02-11T13:55:17","subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi,\n\nI wonder whether this possibly fixes the pink cast Kieran gets in bright\nareas.  If not, there may be other issues, not necessarily libcamera\nbugs (I find this video quite explanatory regarding colours in bright\nareas: https://www.youtube.com/watch?v=ZFGxdb2pH8g).\n\nAs for the place where black level is applied in GPU ISP, I think we are\nOK in the packed shader as it just computes averages.  The order doesn't\nmatter in such a case:\n\n  (A * (x - black) + B * (y - black)) / (A + B) =\n  (A * x + B * y - (A + B) * black) / (A + B) =\n  (A * x + B * y) / (A + B) - (A + B) * black / (A + B) =\n  (A * x + B * y) / (A + B) - black\n\nBut note that if the divisor were C rather than A + B, the equality\nwould no longer hold.  I'm afraid the order may matter in the unpacked\nshader as it probably mixes different colour channels.  I must look into\nit deeper, perhaps with the help of the corresponding paper.\n\nThe proposed lens shading correction patches perform their computations\nafter black level subtraction.\n\nMilan Zamazal <mzamazal@redhat.com> writes:\n\n> There is an omission when applying black level in GPU ISP: the black\n> level is subtracted but the resulting pixel values are not spread back\n> to the whole 0..1 range.  This prevents reaching maximum brightness with\n> non-zero black level and can also lead to pinkish bright areas or other\n> colour shifts.\n>\n> Milan Zamazal (2):\n>   ipa: simple: Limit the black level value\n>   libcamera: software_isp: Fix black level application in GPU ISP\n>\n>  src/ipa/simple/algorithms/blc.cpp          | 7 ++++---\n>  src/libcamera/shaders/bayer_1x_packed.frag | 2 +-\n>  src/libcamera/shaders/bayer_unpacked.frag  | 2 +-\n>  3 files changed, 6 insertions(+), 5 deletions(-)","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 697FBBDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 11 Feb 2026 13:55:25 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8A357620C9;\n\tWed, 11 Feb 2026 14:55:24 +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 391CD620C9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 14:55:23 +0100 (CET)","from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n\t[209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-653-2nxU3fYFM4KeZfDfYCR_Hw-1; Wed, 11 Feb 2026 08:55:21 -0500","by mail-wr1-f69.google.com with SMTP id\n\tffacd0b85a97d-43591aacca2so1621955f8f.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 05:55:20 -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-43783d325f7sm4825357f8f.8.2026.02.11.05.55.17\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 11 Feb 2026 05:55:18 -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=\"J5yQWOOX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1770818122;\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=jO3jcq+1h7qZahVK42r2b4nSCRiDhJkciCj1g/rRVAY=;\n\tb=J5yQWOOXLOimr9Znr2Nofw68NkPoqFt8OU1+SmRw4Tdvb0ciIvElFBf/y8/V8C34EWcNhs\n\t+vWrDHKJziFFk/MEUPuJtvgCbcW5bFb6LshCx71TtqQjK3mSpPzRm13+oX6t96nN4Xiv2X\n\tuhDUo9AszrhUEaiJUMN8tVK2m6l/mMQ=","X-MC-Unique":"2nxU3fYFM4KeZfDfYCR_Hw-1","X-Mimecast-MFC-AGG-ID":"2nxU3fYFM4KeZfDfYCR_Hw_1770818120","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1770818119; x=1771422919;\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=jO3jcq+1h7qZahVK42r2b4nSCRiDhJkciCj1g/rRVAY=;\n\tb=mXxQkYEh2nYqSrLvfIQwdtcBI+0/w9kx+Px4RjI5jgiBtfD8eMlmDc4e3JG9I64X0I\n\tN4Yly4BRi/xGCaMGYfXN3ZVuDzQPISaU7COlPOP+p1cSygROWszQXfgerxOCBQBliocQ\n\t5NLwH71WN40yeo2r79/3ZBQMyq/92ob1RbafRFaDRuQUhpdO+NBrC+qaT8buftVwRfDy\n\tOmJKdKyiOVa+D/zq6oLNTAHkXR/CtbuprUDvv0aYItHQp2MTDL9KW+6lqW3K+bpgykoQ\n\t5qAh8kJn0X59RE043ZHCXWQCfHNQCWnadBOz1PZtg4liQFxVC4HDs5tngs9sr41zKk7W\n\tac/Q==","X-Gm-Message-State":"AOJu0YylUpM9pO5Z20G5VRtWqkrtTpGf+U+f2gPnekVh/43eywrsGPhp\n\tpejybQn+g+6ltbWo//1TioyYn75Ux3xBX4s7VA4h9YbI07hb4Otiyo80IfOCRRETrrr1bsIk6bj\n\tfnyAm1OubJXG4hFPNnyJqHqWikUT0AmTXkJ8OIzZuFF77uvAzKzoMsVAv+u0Xa6x7ZWTVJRS3tn\n\twbzZ2WjcTX8cw4YpymcNBt51wArIKE3dFZoRAO/pkFYmigOxt8/Fw2kB5TTGw=","X-Gm-Gg":"AZuq6aJT1T1/54rPQfN4jmChoKgkMdbWBj31RaRM3XBgbe0rggdyWPGEX0VSnhAJEjf\n\t1WFhLf+I/N3b+jwv9/ID0NZ28yadj6mrFeEMRXoxD091/3t+b3bgJKH5d6O6XL1Or0U4l+EATkI\n\tSTNarqzLpcuoeTC7/P9G2XnOtqM4lNBsuMZm3BDHOr289l5uodFj3AI5ZQXbt0q1tRsILM3szDT\n\t1ENMdF/TGchJQOVfGTdn7nPwsKclVimSqVHQKKZK5O9BKvKi9F4blE4wvYT9fIASmwrd6ZkW9wl\n\t8sOnqkmpuiGzFLGfoM+y7jLzsjlM7SqUTxDSZkVvB8vd/UwFXAaT3QUuRvXT3+2bCZnktCBTbBi\n\tjeT8tQ3563Y8S6CS/pBk85s4y4SAOSWMn5vxSRbP4y6cqtYm5Dxm0ci37QsLZR5412MfyYpORdC\n\t0=","X-Received":["by 2002:a05:6000:248a:b0:436:8058:449 with SMTP id\n\tffacd0b85a97d-436805809e9mr23718668f8f.45.1770818119275; \n\tWed, 11 Feb 2026 05:55:19 -0800 (PST)","by 2002:a05:6000:248a:b0:436:8058:449 with SMTP id\n\tffacd0b85a97d-436805809e9mr23718612f8f.45.1770818118683; \n\tWed, 11 Feb 2026 05:55:18 -0800 (PST)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>, Bryan O'Donoghue\n\t<bryan.odonoghue@linaro.org>","Cc":"libcamera-devel@lists.libcamera.org,","Subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","In-Reply-To":"<20260211131728.96413-1-mzamazal@redhat.com> (Milan Zamazal's\n\tmessage of \"Wed, 11 Feb 2026 14:17:26 +0100\")","References":"<20260211131728.96413-1-mzamazal@redhat.com>","Date":"Wed, 11 Feb 2026 14:55:17 +0100","Message-ID":"<85v7g3wfju.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":"R8h7iM-jNtieGZHBMWQDxr5HnzNwhekoFjrhRDpGLFg_1770818120","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>"}},{"id":38174,"web_url":"https://patchwork.libcamera.org/comment/38174/","msgid":"<12204344.nUPlyArG6x@pliszka>","date":"2026-02-11T15:08:15","subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","submitter":{"id":256,"url":"https://patchwork.libcamera.org/api/people/256/","name":"Sebastian Krzyszkowiak","email":"sebastian.krzyszkowiak@puri.sm"},"content":"On środa, 11 lutego 2026 14:55:17 czas środkowoeuropejski standardowy Milan \nZamazal wrote:\n> Hi,\n> \n> I wonder whether this possibly fixes the pink cast Kieran gets in bright\n> areas.  If not, there may be other issues, not necessarily libcamera\n> bugs (I find this video quite explanatory regarding colours in bright\n> areas: https://www.youtube.com/watch?v=ZFGxdb2pH8g).\n\nI don't see any code for handling clipped highlights in GPU ISP's shaders, so \nhaving pink highlights would be an expected result of applying white balance, \nwouldn't it? (or is it hiding somewhere else?) Any pixels with clipped values \nhave to be recolored heuristically to get rid of magenta casts.\n\nIn darktable, that would match to its \"highlight reconstruction\" module; in \ndcraw, that's the -H option. As far as I can see, this video talks about much \nmore subtle issues that are being solved with various tone mapping curves \n(where libcamera applies a basic S-curve right now) that will only start to \nmatter once the basics are done right.\n\nWhen I played with writing an ISP for video recording (https://\nsource.puri.sm/-/snippets/1223) I used a very basic and not entirely correct \nyet effective way to deal with highlights:\n\nvec3 clip_highlights(vec3 color) {\n  vec3 ratio = color / whitepoint;\n  return whitepoint * mix(ratio, vec3(1.0), smoothstep(0.96, 1.0, ratio));\n}\n\nwhere \"whitepoint\" is vec3(1.0) multiplied by the inverse of the white \nbalanced color correction matrix (this happens after subtracting black level, \nbut before lens shading correction and CCM application). But that's mostly \nbecause I haven't researched how proper highlight reconstruction methods \nactually work:)\n\n> As for the place where black level is applied in GPU ISP, I think we are\n> OK in the packed shader as it just computes averages.  The order doesn't\n> matter in such a case:\n> \n>   (A * (x - black) + B * (y - black)) / (A + B) =\n>   (A * x + B * y - (A + B) * black) / (A + B) =\n>   (A * x + B * y) / (A + B) - (A + B) * black / (A + B) =\n>   (A * x + B * y) / (A + B) - black\n> \n> But note that if the divisor were C rather than A + B, the equality\n> would no longer hold.  I'm afraid the order may matter in the unpacked\n> shader as it probably mixes different colour channels.  I must look into\n> it deeper, perhaps with the help of the corresponding paper.\n> \n> The proposed lens shading correction patches perform their computations\n> after black level subtraction.\n> \n> Milan Zamazal <mzamazal@redhat.com> writes:\n> > There is an omission when applying black level in GPU ISP: the black\n> > level is subtracted but the resulting pixel values are not spread back\n> > to the whole 0..1 range.  This prevents reaching maximum brightness with\n> > non-zero black level and can also lead to pinkish bright areas or other\n> > colour shifts.\n> > \n> > Milan Zamazal (2):\n> >   ipa: simple: Limit the black level value\n> >   libcamera: software_isp: Fix black level application in GPU ISP\n> >  \n> >  src/ipa/simple/algorithms/blc.cpp          | 7 ++++---\n> >  src/libcamera/shaders/bayer_1x_packed.frag | 2 +-\n> >  src/libcamera/shaders/bayer_unpacked.frag  | 2 +-\n> >  3 files changed, 6 insertions(+), 5 deletions(-)","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 D4FC9BD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 11 Feb 2026 15:08:20 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 29472621BC;\n\tWed, 11 Feb 2026 16:08:20 +0100 (CET)","from ms.puri.sm (ms.puri.sm [135.181.196.210])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CF406620C9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 16:08:17 +0100 (CET)","from pliszka.localnet (83.24.20.251.ipv4.supernova.orange.pl\n\t[83.24.20.251]) by ms.puri.sm (Postfix) with ESMTPSA id E83601FC4C;\n\tWed, 11 Feb 2026 07:08:16 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=puri.sm header.i=@puri.sm header.b=\"vI24jwLA\";\n\tdkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=puri.sm; s=smtp2;\n\tt=1770822497; bh=jGXrjqUj5bin9UvkzqdgcOYIYDSvki58v4H2f2yAl3k=;\n\th=From:To:Subject:Date:In-Reply-To:References;\n\tb=vI24jwLAmTSvs7tjHwqhNxGMegiYfRak26hY5IKclL5l5aJ87J1kBokj2OchEAzi7\n\tT7rroiOz6NxcwdHyInXEPSgN/CzWdFLlT8Gf2GtJT2M10G2/Ol1C9RLXSWwQW5M0bB\n\tfXBAXo8K8VkeqCVZGWhKV0Nwbi7HPgWuINA6o/A4xzTo6s5izahKL04pW0eqA8X1ho\n\tubvd0lMFEWQ6mP+UKoNb+UsWyj5zMSJW0reh7/uuUs64YquWQaxma7ncEeVRuQ/1uO\n\tQHYExLOUO5qU0rwBme4qhrsnMNkY6rIXkx4r0RymcENZF6szCqT497yXkUkmurNJIF\n\tB+OWjtYdENPaA==","From":"Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tBryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tlibcamera-devel@lists.libcamera.org, Milan Zamazal <mzamazal@redhat.com>","Subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","Date":"Wed, 11 Feb 2026 16:08:15 +0100","Message-ID":"<12204344.nUPlyArG6x@pliszka>","In-Reply-To":"<85v7g3wfju.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","References":"<20260211131728.96413-1-mzamazal@redhat.com>\n\t<85v7g3wfju.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","Content-Type":"text/plain; charset=\"utf-8\"","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>"}},{"id":38180,"web_url":"https://patchwork.libcamera.org/comment/38180/","msgid":"<85fr77w7ok.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-02-11T16:45:15","subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi Sebastian,\n\nSebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm> writes:\n\n> On środa, 11 lutego 2026 14:55:17 czas środkowoeuropejski standardowy Milan \n> Zamazal wrote:\n>> Hi,\n>> \n>\n>> I wonder whether this possibly fixes the pink cast Kieran gets in bright\n>> areas.  If not, there may be other issues, not necessarily libcamera\n>> bugs (I find this video quite explanatory regarding colours in bright\n>> areas: https://www.youtube.com/watch?v=ZFGxdb2pH8g).\n>\n> I don't see any code for handling clipped highlights in GPU ISP's\n> shaders, \n\nRight.\n\n> so having pink highlights would be an expected result of applying\n> white balance, wouldn't it? (or is it hiding somewhere else?) Any\n> pixels with clipped values have to be recolored heuristically to get\n> rid of magenta casts.\n\nI guess so.  But while the casts may possibly occur in many cases, I\ndon't get them too often with, well, my uncalibrated sensor; others may\nhave a similar experience.  At this stage when other problems can be\npresent, we must be somewhat careful not to blame everything on\nclipping.\n\n> In darktable, that would match to its \"highlight reconstruction\" module; in \n> dcraw, that's the -H option. As far as I can see, this video talks about much \n> more subtle issues that are being solved with various tone mapping curves \n> (where libcamera applies a basic S-curve right now) that will only start to \n> matter once the basics are done right.\n>\n> When I played with writing an ISP for video recording (https://\n> source.puri.sm/-/snippets/1223) I used a very basic and not entirely correct \n> yet effective way to deal with highlights:\n>\n> vec3 clip_highlights(vec3 color) {\n>   vec3 ratio = color / whitepoint;\n>   return whitepoint * mix(ratio, vec3(1.0), smoothstep(0.96, 1.0, ratio));\n> }\n>\n> where \"whitepoint\" is vec3(1.0) multiplied by the inverse of the white \n> balanced color correction matrix (this happens after subtracting black level, \n> but before lens shading correction and CCM application). But that's mostly \n> because I haven't researched how proper highlight reconstruction methods \n> actually work:)\n\nWith GPU ISP merged, there are certainly opportunities to submit patches\nfor improvements. :-)\n\n>> As for the place where black level is applied in GPU ISP, I think we are\n>> OK in the packed shader as it just computes averages.  The order doesn't\n>> matter in such a case:\n>> \n>>   (A * (x - black) + B * (y - black)) / (A + B) =\n>>   (A * x + B * y - (A + B) * black) / (A + B) =\n>>   (A * x + B * y) / (A + B) - (A + B) * black / (A + B) =\n>>   (A * x + B * y) / (A + B) - black\n>> \n>> But note that if the divisor were C rather than A + B, the equality\n>> would no longer hold.  I'm afraid the order may matter in the unpacked\n>> shader as it probably mixes different colour channels.  I must look into\n>> it deeper, perhaps with the help of the corresponding paper.\n>> \n>> The proposed lens shading correction patches perform their computations\n>> after black level subtraction.\n>> \n>> Milan Zamazal <mzamazal@redhat.com> writes:\n>> > There is an omission when applying black level in GPU ISP: the black\n>> > level is subtracted but the resulting pixel values are not spread back\n>> > to the whole 0..1 range.  This prevents reaching maximum brightness with\n>> > non-zero black level and can also lead to pinkish bright areas or other\n>> > colour shifts.\n>> > \n>> > Milan Zamazal (2):\n>> >   ipa: simple: Limit the black level value\n>> >   libcamera: software_isp: Fix black level application in GPU ISP\n>> >  \n>> >  src/ipa/simple/algorithms/blc.cpp          | 7 ++++---\n>> >  src/libcamera/shaders/bayer_1x_packed.frag | 2 +-\n>> >  src/libcamera/shaders/bayer_unpacked.frag  | 2 +-\n>> >  3 files changed, 6 insertions(+), 5 deletions(-)","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 02731BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 11 Feb 2026 16:45:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F2822621B9;\n\tWed, 11 Feb 2026 17:45:22 +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 CF960620C9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 17:45:21 +0100 (CET)","from mail-wr1-f71.google.com (mail-wr1-f71.google.com\n\t[209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-638-486jmaTROp-t-7NYfAVfVA-1; Wed, 11 Feb 2026 11:45:19 -0500","by mail-wr1-f71.google.com with SMTP id\n\tffacd0b85a97d-435add03f12so3675454f8f.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 08:45:19 -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-43783e39c6asm5827213f8f.28.2026.02.11.08.45.15\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 11 Feb 2026 08:45:16 -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=\"ZV9e7U+F\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1770828320;\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=1Bwy3dP8c2DKmEGaXE6GnlcnWBEgPaChrDgpu3i3G38=;\n\tb=ZV9e7U+FVsAuIACeBYfjbTawJKgZ1g1NftIysO7rBBnPKDFat/Yi5cAfBzvcyX7zCIDLQ3\n\tBzD+cOgY1uQ/D0cpL2yIdRve2EhRGPB+9O+Zv329DkZbSjbeXo1OlJQ3lsNvplnfczbYPb\n\tzGxRUiPfFNLnos4BZPFRarRqkgmC3PQ=","X-MC-Unique":"486jmaTROp-t-7NYfAVfVA-1","X-Mimecast-MFC-AGG-ID":"486jmaTROp-t-7NYfAVfVA_1770828318","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1770828317; x=1771433117;\n\th=content-transfer-encoding:mime-version:user-agent:message-id:date\n\t:references:in-reply-to:subject:cc:to:from:x-gm-gg\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=AmQ4DUaGo/N4cAdPECsvG6sbE1vZZ0sYLIgz2hgOeWY=;\n\tb=pMcs3LSVJjfeKQEWCljPrJspIkWyRVf5pBu3ugjLv8x0MEBKx4VrbdbOk50TuSlCAP\n\tsmmsawXc4N6nRQWnwf5JjD0ymvEZHL14/kUcwO5Yl4KNTenRZqAX4nIv5yIDWBV+LtZN\n\tlWS5qwAnPWbaMY2nltl9ltX4yeSypU4nf6+EPbnj1BQRVIGFpBSzrmrkNO8ikLjOhEUg\n\t0msnjl7fYeGdW3QWAJu8i1mGszJjo3j5c/Y0R1uVdqW6fadmxandUzZa9gr7hhu7gKHW\n\thbMqwPDV8y6lzRWqHECTcQGfJmfuyFkgbr+iPfz0myjV2VSfZEgqMaXT8VfjG8ostXdR\n\t/gzg==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCUwYGpI9iGcOrd3Qq6t+A4dGexqmx0xlCqABHdbmljEc0/x/VNVurKGhzqIMWPEYrcdo2wAfaUBFRZn8djv3nc=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YxZbkoWNXxu5dnRHqn4pR3nmPtPa7pnUJJT5LEKVnwnASFVHzsB\n\tb0uz2MxnqV8I5KJRXdtlT7JPxVIAAynX2OpFt7pOMtreNVe9p/ih8wm3TWvxwrXQXbIcQuOq/K6\n\tSTVhH+ol9I3kNBhNaFE1TfAXy1WDUfnLVov4eIH1FkPv2pKmJi8soloNuyYKDhHLnABNTLeHtsB\n\tzCQF0tYxBHCzFi91bW91Ld8np5qi9poNmrLaizLNCA+NfigDyAn5JLPEL7kKE=","X-Gm-Gg":"AZuq6aJxgjuL7aQeXQZNK0F8hAuSNpeSqtpvO/t9zwCRxu4UnViczycoOtsJ82r8paf\n\t11Jxg4fQTPOjYdtUahD+7s1SzVFRhNn5E335V779sOWVEn8veBuk+oBNe13PqGWEh3+I4VjJY3d\n\t5vjTS+TNtZq3Lp6L3FbjXUpa3hDCSnNLmYYtYFgoqBfiESCBcmSzEFUiVwWsaNxDVnoWY27kNT8\n\tkWhzcvUATFOkWkujJrngrK8wVEX1Q4jTUPq6XUEbguZ5MUgEwdRaDtX9WdW4wLYs7QJ3oKEsROi\n\toZno7FB+6yemyujnaJFp+j+H/L2kuz+UKAbhEq8HBg/BOtiZp8m8rZzbvw9saRnX5OuhGlCXP5B\n\tubH5PAm/zXlG3+XjmaS8OW5ihfUzfJodXGAu3XFnUptCdWjRHwnp3FQl6c0JySC/TL7JldqP3Uc\n\t4=","X-Received":["by 2002:a05:6000:2585:b0:437:8123:b5e9 with SMTP id\n\tffacd0b85a97d-4378ac994a7mr82376f8f.45.1770828317537; \n\tWed, 11 Feb 2026 08:45:17 -0800 (PST)","by 2002:a05:6000:2585:b0:437:8123:b5e9 with SMTP id\n\tffacd0b85a97d-4378ac994a7mr82300f8f.45.1770828316845; \n\tWed, 11 Feb 2026 08:45:16 -0800 (PST)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>,  Bryan O'Donoghue\n\t<bryan.odonoghue@linaro.org>,  libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","In-Reply-To":"<12204344.nUPlyArG6x@pliszka> (Sebastian Krzyszkowiak's message\n\tof \"Wed, 11 Feb 2026 16:08:15 +0100\")","References":"<20260211131728.96413-1-mzamazal@redhat.com>\n\t<85v7g3wfju.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>\n\t<12204344.nUPlyArG6x@pliszka>","Date":"Wed, 11 Feb 2026 17:45:15 +0100","Message-ID":"<85fr77w7ok.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":"sXQp9wVdHC0KJn9NZGoIyGnmrp0lBdtpZhLftl3zAY4_1770828318","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"quoted-printable","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>"}},{"id":38183,"web_url":"https://patchwork.libcamera.org/comment/38183/","msgid":"<20260211175603.GH2553356@killaraus.ideasonboard.com>","date":"2026-02-11T17:56:03","subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Wed, Feb 11, 2026 at 05:45:15PM +0100, Milan Zamazal wrote:\n> Sebastian Krzyszkowiak writes:\n> > On środa, 11 lutego 2026 14:55:17 czas środkowoeuropejski standardowy Milan Zamazal wrote:\n> >> Hi,\n> >> \n> >> I wonder whether this possibly fixes the pink cast Kieran gets in bright\n> >> areas.  If not, there may be other issues, not necessarily libcamera\n> >> bugs (I find this video quite explanatory regarding colours in bright\n> >> areas: https://www.youtube.com/watch?v=ZFGxdb2pH8g).\n> >\n> > I don't see any code for handling clipped highlights in GPU ISP's\n> > shaders, \n> \n> Right.\n> \n> > so having pink highlights would be an expected result of applying\n> > white balance, wouldn't it? (or is it hiding somewhere else?) Any\n> > pixels with clipped values have to be recolored heuristically to get\n> > rid of magenta casts.\n> \n> I guess so.  But while the casts may possibly occur in many cases, I\n> don't get them too often with, well, my uncalibrated sensor; others may\n> have a similar experience.\n\nThat's normal, as the colour casts are caused by applying colour gains\non saturated pixel values.\n\n> At this stage when other problems can be\n> present, we must be somewhat careful not to blame everything on\n> clipping.\n\nWhen pixels are saturated, information about their colour is lost.\nThere's no way around that. As Sebastian mentioned, the best we can do\nis to try to apply heuristics to guess what the colour was, and hope the\nresult will be visually pleasing. Performing histogram equialization at\nthe BLC stage may produce more pleasing results in some cases, but it's\na hack and not a proper solution. I'd rather not go in that direction,\nand instead work on handling the issue correctly.\n\n> > In darktable, that would match to its \"highlight reconstruction\" module; in \n> > dcraw, that's the -H option. As far as I can see, this video talks about much \n> > more subtle issues that are being solved with various tone mapping curves \n> > (where libcamera applies a basic S-curve right now) that will only start to \n> > matter once the basics are done right.\n> >\n> > When I played with writing an ISP for video recording (https://\n> > source.puri.sm/-/snippets/1223) I used a very basic and not entirely correct \n> > yet effective way to deal with highlights:\n> >\n> > vec3 clip_highlights(vec3 color) {\n> >   vec3 ratio = color / whitepoint;\n> >   return whitepoint * mix(ratio, vec3(1.0), smoothstep(0.96, 1.0, ratio));\n> > }\n> >\n> > where \"whitepoint\" is vec3(1.0) multiplied by the inverse of the white \n> > balanced color correction matrix (this happens after subtracting black level, \n> > but before lens shading correction and CCM application). But that's mostly \n> > because I haven't researched how proper highlight reconstruction methods \n> > actually work:)\n> \n> With GPU ISP merged, there are certainly opportunities to submit patches\n> for improvements. :-)\n> \n> >> As for the place where black level is applied in GPU ISP, I think we are\n> >> OK in the packed shader as it just computes averages.  The order doesn't\n> >> matter in such a case:\n> >> \n> >>   (A * (x - black) + B * (y - black)) / (A + B) =\n> >>   (A * x + B * y - (A + B) * black) / (A + B) =\n> >>   (A * x + B * y) / (A + B) - (A + B) * black / (A + B) =\n> >>   (A * x + B * y) / (A + B) - black\n> >> \n> >> But note that if the divisor were C rather than A + B, the equality\n> >> would no longer hold.  I'm afraid the order may matter in the unpacked\n> >> shader as it probably mixes different colour channels.  I must look into\n> >> it deeper, perhaps with the help of the corresponding paper.\n> >> \n> >> The proposed lens shading correction patches perform their computations\n> >> after black level subtraction.\n> >> \n> >> Milan Zamazal <mzamazal@redhat.com> writes:\n> >> > There is an omission when applying black level in GPU ISP: the black\n> >> > level is subtracted but the resulting pixel values are not spread back\n> >> > to the whole 0..1 range.  This prevents reaching maximum brightness with\n> >> > non-zero black level and can also lead to pinkish bright areas or other\n> >> > colour shifts.\n> >> > \n> >> > Milan Zamazal (2):\n> >> >   ipa: simple: Limit the black level value\n> >> >   libcamera: software_isp: Fix black level application in GPU ISP\n> >> >  \n> >> >  src/ipa/simple/algorithms/blc.cpp          | 7 ++++---\n> >> >  src/libcamera/shaders/bayer_1x_packed.frag | 2 +-\n> >> >  src/libcamera/shaders/bayer_unpacked.frag  | 2 +-\n> >> >  3 files changed, 6 insertions(+), 5 deletions(-)","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 21DD2BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 11 Feb 2026 17:56:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F2C98621C1;\n\tWed, 11 Feb 2026 18:56:06 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 56C99620C9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 11 Feb 2026 18:56:05 +0100 (CET)","from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 9A47AC6F;\n\tWed, 11 Feb 2026 18:55:17 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"MoNM9BhB\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1770832517;\n\tbh=B/6m8MJgN8XshK4sVIf7E5+ee09G+Q63IGm4D1FP5XM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=MoNM9BhB/jkEVGrHEzdepgOovT+DRHlpsjIs25J166eSFFdRMjC9YQll2bNa8jbNQ\n\t4FSZbpAiGU57vAAVEgQP0nEmsrGSBfUVt7qQWCNVKwdTNdTsYX00GPGrQH5mTrJ4kM\n\tiLkvabzn/UtCQdXyvEq3Iqf7juemlZlYzdSfW33U=","Date":"Wed, 11 Feb 2026 19:56:03 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tBryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 0/2] Fix black level handling in GPU ISP","Message-ID":"<20260211175603.GH2553356@killaraus.ideasonboard.com>","References":"<20260211131728.96413-1-mzamazal@redhat.com>\n\t<85v7g3wfju.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>\n\t<12204344.nUPlyArG6x@pliszka>\n\t<85fr77w7ok.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<85fr77w7ok.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","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>"}}]