[{"id":37975,"web_url":"https://patchwork.libcamera.org/comment/37975/","msgid":"<20260127164458.GB2512313@killaraus>","date":"2026-01-27T16:44:58","subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Tue, Jan 27, 2026 at 05:29:23PM +0100, Milan Zamazal wrote:\n> The black level offset subtracted in AWB is wrong.  It assumes that the\n> stats contain sums of the individual colour pixels.  But they actually\n> contain sums of the colour channels of larger \"superpixels\" consisting\n> of the individual colour pixels.  Each of the RGB colour values and the\n> computed luminosity (a histogram entry) are added once to the stats per\n> such a superpixel.  This means the offset computed from the black level\n> and the number of pixels should be used as it is, not divided.\n> \n> The patch fixes the subtracted offset.  Since the evaluation is the same\n> for all the three colours now, the individual class variables are\n> replaced with a single RGB variable.\n> \n> Fixes: 4e13c6f55bd667 (\"Honor black level in AWB\")\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  .../internal/software_isp/swisp_stats.h          | 16 +++++-----------\n>  src/ipa/simple/algorithms/awb.cpp                | 10 ++++------\n>  src/libcamera/software_isp/swstats_cpu.cpp       | 10 ++++------\n>  3 files changed, 13 insertions(+), 23 deletions(-)\n> \n> diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h\n> index 3c9860185..d9d0d9be8 100644\n> --- a/include/libcamera/internal/software_isp/swisp_stats.h\n> +++ b/include/libcamera/internal/software_isp/swisp_stats.h\n> @@ -10,6 +10,8 @@\n>  #include <array>\n>  #include <stdint.h>\n>  \n> +#include \"libcamera/internal/vector.h\"\n> +\n>  namespace libcamera {\n>  \n>  /**\n> @@ -26,17 +28,9 @@ struct SwIspStats {\n>  \t */\n>  \tbool valid;\n>  \t/**\n> -\t * \\brief Holds the sum of all sampled red pixels\n> -\t */\n> -\tuint64_t sumR_;\n> -\t/**\n> -\t * \\brief Holds the sum of all sampled green pixels\n> -\t */\n> -\tuint64_t sumG_;\n> -\t/**\n> -\t * \\brief Holds the sum of all sampled blue pixels\n> +\t * \\brief Sums of colour channels of all the sampled pixels\n>  \t */\n> -\tuint64_t sumB_;\n> +\tRGB<uint64_t> sum_;\n>  \t/**\n>  \t * \\brief Number of bins in the yHistogram\n>  \t */\n> @@ -46,7 +40,7 @@ struct SwIspStats {\n>  \t */\n>  \tusing Histogram = std::array<uint32_t, kYHistogramSize>;\n>  \t/**\n> -\t * \\brief A histogram of luminance values\n> +\t * \\brief A histogram of luminance values of all the sampled pixels\n>  \t */\n>  \tHistogram yHistogram;\n>  };\n> diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp\n> index 0080865aa..75e4ae4a4 100644\n> --- a/src/ipa/simple/algorithms/awb.cpp\n> +++ b/src/ipa/simple/algorithms/awb.cpp\n> @@ -1,6 +1,6 @@\n>  /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>  /*\n> - * Copyright (C) 2024, Red Hat Inc.\n> + * Copyright (C) 2024-2026 Red Hat Inc.\n>   *\n>   * Auto white balance\n>   */\n> @@ -73,9 +73,7 @@ void Awb::process(IPAContext &context,\n>  \t\thistogram.begin(), histogram.end(), uint64_t(0));\n>  \tconst uint64_t offset = blackLevel * nPixels;\n>  \tconst uint64_t minValid = 1;\n> -\tconst uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid;\n> -\tconst uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid;\n> -\tconst uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid;\n> +\tconst RGB<uint64_t> sum = (stats->sum_ - offset).max(minValid);\n>  \n>  \t/*\n>  \t * Calculate red and blue gains for AWB.\n> @@ -83,9 +81,9 @@ void Awb::process(IPAContext &context,\n>  \t */\n>  \tauto &gains = context.activeState.awb.gains;\n>  \tgains = { {\n> -\t\tsumR <= sumG / 4 ? 4.0f : static_cast<float>(sumG) / sumR,\n> +\t\tsum.r() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.r(),\n>  \t\t1.0,\n> -\t\tsumB <= sumG / 4 ? 4.0f : static_cast<float>(sumG) / sumB,\n> +\t\tsum.b() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.b(),\n>  \t} };\n>  \n>  \tRGB<double> rgbGains{ { 1 / gains.r(), 1 / gains.g(), 1 / gains.b() } };\n> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n> index c931edb41..5c3011a7f 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n> @@ -185,9 +185,9 @@ static constexpr unsigned int kBlueYMul = 29; /* 0.114 * 256 */\n>  \tstats_.yHistogram[yVal * SwIspStats::kYHistogramSize / (256 * 256 * (div))]++;\n>  \n>  #define SWSTATS_FINISH_LINE_STATS() \\\n> -\tstats_.sumR_ += sumR;       \\\n> -\tstats_.sumG_ += sumG;       \\\n> -\tstats_.sumB_ += sumB;\n> +\tstats_.sum_.r() += sumR;    \\\n> +\tstats_.sum_.g() += sumG;    \\\n> +\tstats_.sum_.b() += sumB;\n>  \n>  void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[])\n>  {\n> @@ -332,9 +332,7 @@ void SwStatsCpu::startFrame(uint32_t frame)\n>  \tif (window_.width == 0)\n>  \t\tLOG(SwStatsCpu, Error) << \"Calling startFrame() without setWindow()\";\n>  \n> -\tstats_.sumR_ = 0;\n> -\tstats_.sumB_ = 0;\n> -\tstats_.sumG_ = 0;\n> +\tstats_.sum_ = RGB<uint64_t>({ 0, 0, 0 });\n>  \tstats_.yHistogram.fill(0);\n>  }\n>","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 0588DC3200\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 27 Jan 2026 16:45:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 51BFE61FC8;\n\tTue, 27 Jan 2026 17:45:01 +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 E2EE761FBF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 17:44:59 +0100 (CET)","from pendragon.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 6C96D465;\n\tTue, 27 Jan 2026 17:44:23 +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=\"ZCiY5re/\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769532263;\n\tbh=qUOzKLlyBT4GTmFq0mHDUAHKnc+c8UJhW6AQ5ieNHjE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=ZCiY5re/5U/Bc31vWXngmBPku1mXrhxUUUyGMPXtf442Xn6kGmBzoFtPy9NmqTixA\n\tVpb+6X243rqjxywHbbcz3DRR2nUFdWPcVKXd7pg6NeFp0J0upGrgkDYWpgOIKX6bBn\n\tBWcWJPR+c74tiQZHz5HeoKZaV/inOV+9SUUk8J8Q=","Date":"Tue, 27 Jan 2026 18:44:58 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tRobert Mader <robert.mader@collabora.com>","Subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","Message-ID":"<20260127164458.GB2512313@killaraus>","References":"<20260127162923.112675-1-mzamazal@redhat.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20260127162923.112675-1-mzamazal@redhat.com>","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":37976,"web_url":"https://patchwork.libcamera.org/comment/37976/","msgid":"<14b9d127-bd84-4823-813c-9149bf4054ba@collabora.com>","date":"2026-01-27T16:50:21","subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/","name":"Robert Mader","email":"robert.mader@collabora.com"},"content":"On 27.01.26 17:29, Milan Zamazal wrote:\n> The black level offset subtracted in AWB is wrong.  It assumes that the\n> stats contain sums of the individual colour pixels.  But they actually\n> contain sums of the colour channels of larger \"superpixels\" consisting\n> of the individual colour pixels.  Each of the RGB colour values and the\n> computed luminosity (a histogram entry) are added once to the stats per\n> such a superpixel.  This means the offset computed from the black level\n> and the number of pixels should be used as it is, not divided.\n>\n> The patch fixes the subtracted offset.  Since the evaluation is the same\n> for all the three colours now, the individual class variables are\n> replaced with a single RGB variable.\n>\n> Fixes: 4e13c6f55bd667 (\"Honor black level in AWB\")\n> Signed-off-by: Milan Zamazal<mzamazal@redhat.com>\n\nReviewed-by: Robert Mader<robert.mader@collabora.com>\n\nTested-by: Robert Mader<robert.mader@collabora.com>\n\n> ---\n>   .../internal/software_isp/swisp_stats.h          | 16 +++++-----------\n>   src/ipa/simple/algorithms/awb.cpp                | 10 ++++------\n>   src/libcamera/software_isp/swstats_cpu.cpp       | 10 ++++------\n>   3 files changed, 13 insertions(+), 23 deletions(-)\n>\n> diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h\n> index 3c9860185..d9d0d9be8 100644\n> --- a/include/libcamera/internal/software_isp/swisp_stats.h\n> +++ b/include/libcamera/internal/software_isp/swisp_stats.h\n> @@ -10,6 +10,8 @@\n>   #include <array>\n>   #include <stdint.h>\n>   \n> +#include \"libcamera/internal/vector.h\"\n> +\n>   namespace libcamera {\n>   \n>   /**\n> @@ -26,17 +28,9 @@ struct SwIspStats {\n>   \t */\n>   \tbool valid;\n>   \t/**\n> -\t * \\brief Holds the sum of all sampled red pixels\n> -\t */\n> -\tuint64_t sumR_;\n> -\t/**\n> -\t * \\brief Holds the sum of all sampled green pixels\n> -\t */\n> -\tuint64_t sumG_;\n> -\t/**\n> -\t * \\brief Holds the sum of all sampled blue pixels\n> +\t * \\brief Sums of colour channels of all the sampled pixels\n>   \t */\n> -\tuint64_t sumB_;\n> +\tRGB<uint64_t> sum_;\n>   \t/**\n>   \t * \\brief Number of bins in the yHistogram\n>   \t */\n> @@ -46,7 +40,7 @@ struct SwIspStats {\n>   \t */\n>   \tusing Histogram = std::array<uint32_t, kYHistogramSize>;\n>   \t/**\n> -\t * \\brief A histogram of luminance values\n> +\t * \\brief A histogram of luminance values of all the sampled pixels\n>   \t */\n>   \tHistogram yHistogram;\n>   };\n> diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp\n> index 0080865aa..75e4ae4a4 100644\n> --- a/src/ipa/simple/algorithms/awb.cpp\n> +++ b/src/ipa/simple/algorithms/awb.cpp\n> @@ -1,6 +1,6 @@\n>   /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>   /*\n> - * Copyright (C) 2024, Red Hat Inc.\n> + * Copyright (C) 2024-2026 Red Hat Inc.\n>    *\n>    * Auto white balance\n>    */\n> @@ -73,9 +73,7 @@ void Awb::process(IPAContext &context,\n>   \t\thistogram.begin(), histogram.end(), uint64_t(0));\n>   \tconst uint64_t offset = blackLevel * nPixels;\n>   \tconst uint64_t minValid = 1;\n> -\tconst uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid;\n> -\tconst uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid;\n> -\tconst uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid;\n> +\tconst RGB<uint64_t> sum = (stats->sum_ - offset).max(minValid);\n>   \n>   \t/*\n>   \t * Calculate red and blue gains for AWB.\n> @@ -83,9 +81,9 @@ void Awb::process(IPAContext &context,\n>   \t */\n>   \tauto &gains = context.activeState.awb.gains;\n>   \tgains = { {\n> -\t\tsumR <= sumG / 4 ? 4.0f : static_cast<float>(sumG) / sumR,\n> +\t\tsum.r() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.r(),\n>   \t\t1.0,\n> -\t\tsumB <= sumG / 4 ? 4.0f : static_cast<float>(sumG) / sumB,\n> +\t\tsum.b() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.b(),\n>   \t} };\n>   \n>   \tRGB<double> rgbGains{ { 1 / gains.r(), 1 / gains.g(), 1 / gains.b() } };\n> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n> index c931edb41..5c3011a7f 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n> @@ -185,9 +185,9 @@ static constexpr unsigned int kBlueYMul = 29; /* 0.114 * 256 */\n>   \tstats_.yHistogram[yVal * SwIspStats::kYHistogramSize / (256 * 256 * (div))]++;\n>   \n>   #define SWSTATS_FINISH_LINE_STATS() \\\n> -\tstats_.sumR_ += sumR;       \\\n> -\tstats_.sumG_ += sumG;       \\\n> -\tstats_.sumB_ += sumB;\n> +\tstats_.sum_.r() += sumR;    \\\n> +\tstats_.sum_.g() += sumG;    \\\n> +\tstats_.sum_.b() += sumB;\n>   \n>   void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[])\n>   {\n> @@ -332,9 +332,7 @@ void SwStatsCpu::startFrame(uint32_t frame)\n>   \tif (window_.width == 0)\n>   \t\tLOG(SwStatsCpu, Error) << \"Calling startFrame() without setWindow()\";\n>   \n> -\tstats_.sumR_ = 0;\n> -\tstats_.sumB_ = 0;\n> -\tstats_.sumG_ = 0;\n> +\tstats_.sum_ = RGB<uint64_t>({ 0, 0, 0 });\n>   \tstats_.yHistogram.fill(0);\n>   }\n>","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 F377BC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 27 Jan 2026 16:50:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E514061FC9;\n\tTue, 27 Jan 2026 17:50:31 +0100 (CET)","from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com\n\t[136.143.188.112])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E3C0161FC4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 17:50:29 +0100 (CET)","by mx.zohomail.com with SMTPS id 1769532625447783.5075588525947;\n\tTue, 27 Jan 2026 08:50:25 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=collabora.com\n\theader.i=robert.mader@collabora.com header.b=\"NO4iG9pF\"; \n\tdkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1769532627; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=N95YLqw/Feho79xtTqIamxJRgRq4DqfovtSSxDQeN0tjCRtG8OKGhj/+ARuO3LTwG/8sNBWewQEdLEGQCLcVSdMJyGnrMNZrdLGhMB5PkkM4s1RJ86CBW3SxfoGdDe7TtUWAj6BRF/IvVPHEDvTAm4gYcjpURWjXxl0cx2ZYpwk=","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1769532627;\n\th=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To;\n\tbh=CfVMWX847b7seE12X5k2yengTFNgtZnKRr2JKgnqwsE=; \n\tb=XS2ouSJWDxd7EXxrAYTh9/zybXTSUWFYJgh16PuuPF6gur4awMppamJmPVCwZkBVFB32G4fhbV1lGRMsIf1WTJa0uKlVo2QJzOvR+DHwU62FW/Hn/aBhceQ5qv27nE/yZbv0FRYdWw8avSkOiNuJ+suLPMctv1x81ZegAbOKWV8=","ARC-Authentication-Results":"i=1; mx.zohomail.com;\n\tdkim=pass  header.i=collabora.com;\n\tspf=pass  smtp.mailfrom=robert.mader@collabora.com;\n\tdmarc=pass header.from=<robert.mader@collabora.com>","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1769532627;\n\ts=zohomail; d=collabora.com; i=robert.mader@collabora.com;\n\th=Content-Type:Message-ID:Date:Date:MIME-Version:Subject:Subject:To:To:Cc:Cc:References:From:From:In-Reply-To:Message-Id:Reply-To;\n\tbh=CfVMWX847b7seE12X5k2yengTFNgtZnKRr2JKgnqwsE=;\n\tb=NO4iG9pFKpf0GT0KXXKvzFbt6weVMTtIZdGEE9bQUnlGNqL5Qx1kt7Nn+nN50rHW\n\trs5kTYzT5XlA94LmuZi4h7lmbyif0N8VZBNyP3Z0Ig244ZfQk0DzYXACK+MggisfPP7\n\tOvlkqlfiI+v2YsEmi1pb9BeVrtvDLZq9DVD0rxJ8=","Content-Type":"multipart/alternative;\n\tboundary=\"------------78FINnhxvqLrxovQixhUIZym\"","Message-ID":"<14b9d127-bd84-4823-813c-9149bf4054ba@collabora.com>","Date":"Tue, 27 Jan 2026 17:50:21 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","To":"Milan Zamazal <mzamazal@redhat.com>, libcamera-devel@lists.libcamera.org","Cc":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20260127162923.112675-1-mzamazal@redhat.com>","Content-Language":"en-US, de-DE","From":"Robert Mader <robert.mader@collabora.com>","In-Reply-To":"<20260127162923.112675-1-mzamazal@redhat.com>","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":37977,"web_url":"https://patchwork.libcamera.org/comment/37977/","msgid":"<fb3e330c-9aa1-473d-a045-d855795349dd@ideasonboard.com>","date":"2026-01-27T17:09:43","subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2026. 01. 27. 17:29 keltezéssel, Milan Zamazal írta:\n> The black level offset subtracted in AWB is wrong.  It assumes that the\n> stats contain sums of the individual colour pixels.  But they actually\n> contain sums of the colour channels of larger \"superpixels\" consisting\n> of the individual colour pixels.  Each of the RGB colour values and the\n> computed luminosity (a histogram entry) are added once to the stats per\n> such a superpixel.  This means the offset computed from the black level\n> and the number of pixels should be used as it is, not divided.\n> \n> The patch fixes the subtracted offset.  Since the evaluation is the same\n> for all the three colours now, the individual class variables are\n> replaced with a single RGB variable.\n> \n> Fixes: 4e13c6f55bd667 (\"Honor black level in AWB\")\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>   .../internal/software_isp/swisp_stats.h          | 16 +++++-----------\n>   src/ipa/simple/algorithms/awb.cpp                | 10 ++++------\n>   src/libcamera/software_isp/swstats_cpu.cpp       | 10 ++++------\n>   3 files changed, 13 insertions(+), 23 deletions(-)\n> \n> diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h\n> index 3c9860185..d9d0d9be8 100644\n> --- a/include/libcamera/internal/software_isp/swisp_stats.h\n> +++ b/include/libcamera/internal/software_isp/swisp_stats.h\n> @@ -10,6 +10,8 @@\n>   #include <array>\n>   #include <stdint.h>\n>   \n> +#include \"libcamera/internal/vector.h\"\n> +\n>   namespace libcamera {\n>   \n>   /**\n> @@ -26,17 +28,9 @@ struct SwIspStats {\n>   \t */\n>   \tbool valid;\n>   \t/**\n> -\t * \\brief Holds the sum of all sampled red pixels\n> -\t */\n> -\tuint64_t sumR_;\n> -\t/**\n> -\t * \\brief Holds the sum of all sampled green pixels\n> -\t */\n> -\tuint64_t sumG_;\n> -\t/**\n> -\t * \\brief Holds the sum of all sampled blue pixels\n> +\t * \\brief Sums of colour channels of all the sampled pixels\n>   \t */\n> -\tuint64_t sumB_;\n> +\tRGB<uint64_t> sum_;\n>   \t/**\n>   \t * \\brief Number of bins in the yHistogram\n>   \t */\n> @@ -46,7 +40,7 @@ struct SwIspStats {\n>   \t */\n>   \tusing Histogram = std::array<uint32_t, kYHistogramSize>;\n>   \t/**\n> -\t * \\brief A histogram of luminance values\n> +\t * \\brief A histogram of luminance values of all the sampled pixels\n>   \t */\n>   \tHistogram yHistogram;\n>   };\n> diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp\n> index 0080865aa..75e4ae4a4 100644\n> --- a/src/ipa/simple/algorithms/awb.cpp\n> +++ b/src/ipa/simple/algorithms/awb.cpp\n> @@ -1,6 +1,6 @@\n>   /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>   /*\n> - * Copyright (C) 2024, Red Hat Inc.\n> + * Copyright (C) 2024-2026 Red Hat Inc.\n>    *\n>    * Auto white balance\n>    */\n> @@ -73,9 +73,7 @@ void Awb::process(IPAContext &context,\n>   \t\thistogram.begin(), histogram.end(), uint64_t(0));\n>   \tconst uint64_t offset = blackLevel * nPixels;\n>   \tconst uint64_t minValid = 1;\n> -\tconst uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid;\n> -\tconst uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid;\n> -\tconst uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid;\n> +\tconst RGB<uint64_t> sum = (stats->sum_ - offset).max(minValid);\n\nWhat happens if the subtraction wraps around? Previously that was avoided\nby the removed check. Or is wraparound actually impossible now?\n\n\n> [...]","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 88A37C3200\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 27 Jan 2026 17:09:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 90CDC61FCF;\n\tTue, 27 Jan 2026 18:09:50 +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 D321C61FBF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 18:09:48 +0100 (CET)","from [192.168.33.37] (185.221.142.123.nat.pool.zt.hu\n\t[185.221.142.123])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 9AD5778E;\n\tTue, 27 Jan 2026 18:09:11 +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=\"X5cvvi/g\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769533752;\n\tbh=ghbNc+VJf6w/rFhAgVAvP7ZLOvDgw8slCSUtyGaxv3M=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=X5cvvi/gVSF3cjwBCn7/YtTba4UgYUGrBNMine3nnRlTWkNlUZgHAEqTE5daC8DGy\n\tTgUHk8gzZ9bnNO+x013uUST+wkk8hEnEEeW7GTXWDgJuTb/eh5W7hfJdCf2hiYosV5\n\tPaQ5if3NQwJEiQAPDP6D/BU+B7+TYjIkp5wn06Mk=","Message-ID":"<fb3e330c-9aa1-473d-a045-d855795349dd@ideasonboard.com>","Date":"Tue, 27 Jan 2026 18:09:43 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","To":"Milan Zamazal <mzamazal@redhat.com>, libcamera-devel@lists.libcamera.org","Cc":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tRobert Mader <robert.mader@collabora.com>","References":"<20260127162923.112675-1-mzamazal@redhat.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260127162923.112675-1-mzamazal@redhat.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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":37979,"web_url":"https://patchwork.libcamera.org/comment/37979/","msgid":"<85jyx3t1g5.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-01-27T17:22:50","subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:\n\n> Hi\n>\n> 2026. 01. 27. 17:29 keltezéssel, Milan Zamazal írta:\n>> The black level offset subtracted in AWB is wrong.  It assumes that the\n>> stats contain sums of the individual colour pixels.  But they actually\n>> contain sums of the colour channels of larger \"superpixels\" consisting\n>> of the individual colour pixels.  Each of the RGB colour values and the\n>> computed luminosity (a histogram entry) are added once to the stats per\n>> such a superpixel.  This means the offset computed from the black level\n>> and the number of pixels should be used as it is, not divided.\n>> The patch fixes the subtracted offset.  Since the evaluation is the same\n>> for all the three colours now, the individual class variables are\n>> replaced with a single RGB variable.\n>> Fixes: 4e13c6f55bd667 (\"Honor black level in AWB\")\n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>   .../internal/software_isp/swisp_stats.h          | 16 +++++-----------\n>>   src/ipa/simple/algorithms/awb.cpp                | 10 ++++------\n>>   src/libcamera/software_isp/swstats_cpu.cpp       | 10 ++++------\n>>   3 files changed, 13 insertions(+), 23 deletions(-)\n>> diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h\n>> index 3c9860185..d9d0d9be8 100644\n>> --- a/include/libcamera/internal/software_isp/swisp_stats.h\n>> +++ b/include/libcamera/internal/software_isp/swisp_stats.h\n>> @@ -10,6 +10,8 @@\n>>   #include <array>\n>>   #include <stdint.h>\n>>   +#include \"libcamera/internal/vector.h\"\n>> +\n>>   namespace libcamera {\n>>     /**\n>> @@ -26,17 +28,9 @@ struct SwIspStats {\n>>   \t */\n>>   \tbool valid;\n>>   \t/**\n>> -\t * \\brief Holds the sum of all sampled red pixels\n>> -\t */\n>> -\tuint64_t sumR_;\n>> -\t/**\n>> -\t * \\brief Holds the sum of all sampled green pixels\n>> -\t */\n>> -\tuint64_t sumG_;\n>> -\t/**\n>> -\t * \\brief Holds the sum of all sampled blue pixels\n>> +\t * \\brief Sums of colour channels of all the sampled pixels\n>>   \t */\n>> -\tuint64_t sumB_;\n>> +\tRGB<uint64_t> sum_;\n>>   \t/**\n>>   \t * \\brief Number of bins in the yHistogram\n>>   \t */\n>> @@ -46,7 +40,7 @@ struct SwIspStats {\n>>   \t */\n>>   \tusing Histogram = std::array<uint32_t, kYHistogramSize>;\n>>   \t/**\n>> -\t * \\brief A histogram of luminance values\n>> +\t * \\brief A histogram of luminance values of all the sampled pixels\n>>   \t */\n>>   \tHistogram yHistogram;\n>>   };\n>> diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp\n>> index 0080865aa..75e4ae4a4 100644\n>> --- a/src/ipa/simple/algorithms/awb.cpp\n>> +++ b/src/ipa/simple/algorithms/awb.cpp\n>> @@ -1,6 +1,6 @@\n>>   /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>>   /*\n>> - * Copyright (C) 2024, Red Hat Inc.\n>> + * Copyright (C) 2024-2026 Red Hat Inc.\n>>    *\n>>    * Auto white balance\n>>    */\n>> @@ -73,9 +73,7 @@ void Awb::process(IPAContext &context,\n>>   \t\thistogram.begin(), histogram.end(), uint64_t(0));\n>>   \tconst uint64_t offset = blackLevel * nPixels;\n>>   \tconst uint64_t minValid = 1;\n>> -\tconst uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid;\n>> -\tconst uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid;\n>> -\tconst uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid;\n>> +\tconst RGB<uint64_t> sum = (stats->sum_ - offset).max(minValid);\n>\n> What happens if the subtraction wraps around? Previously that was avoided\n> by the removed check. Or is wraparound actually impossible now?\n\nOops, I've forgotten about that trap again, thank you for the reminder.\nI'll fix it some way in v3.","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 53181C3200\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 27 Jan 2026 17:22:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8DC2361FC8;\n\tTue, 27 Jan 2026 18:22:57 +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 3837761FBF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 18:22:56 +0100 (CET)","from mail-wm1-f70.google.com (mail-wm1-f70.google.com\n\t[209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-582-gauAPQcPN5m6xruXe_YHfg-1; Tue, 27 Jan 2026 12:22:53 -0500","by mail-wm1-f70.google.com with SMTP id\n\t5b1f17b1804b1-47edf8ba319so55131765e9.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 09:22:53 -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-48066be7413sm67343645e9.3.2026.01.27.09.22.51\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 27 Jan 2026 09:22:51 -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=\"Xm+kbg+j\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1769534575;\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=xebsOr5USAQwOk3PacvAabeFB8bCRD92GVvJEAoTpsw=;\n\tb=Xm+kbg+jLDHhjH2Fj7IUZu0TCbDFLEnjK7XYSJF5m338YfGFci+1rHe9KT/SGKwzbiG1MV\n\tJ7SSOsZU2ym+F9uPRK0eVaiI3FMyUGGrgsqqcfBhyF3l9xkkzVNMoqpFyKqgTxqoN5YA86\n\tKIaNPek6k+bXP4gv18nlBR5RTwvfz/U=","X-MC-Unique":"gauAPQcPN5m6xruXe_YHfg-1","X-Mimecast-MFC-AGG-ID":"gauAPQcPN5m6xruXe_YHfg_1769534573","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1769534572; x=1770139372;\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=ezlFgeklGmd2PWc8ZWQoNbOdY8tWjHvcb2UCeK+0/Ps=;\n\tb=oGX2TYqUOe+MW41PtIajKSaSewsZkHpr7cYECO80VppEtdqPIAg8hwy9Ov+jMlaniy\n\tPtoouLzk5p7fmIpWl2YytTiA4d8hFuH9/yc0/fTi0BRnhOuhe/sQJVxO48CstRpvGw89\n\tp4xQnKJHZ5KmJ2gQmB66VnIzw9gmiQ+ZOyfO0bf24ZclQrcU8RF5YY+HGMpP6KvSzl3E\n\tcYiADAUs6He5UcTCEDxcTq73Heufcb3X/0XGFRaTnN74ScQFLgmZZyLZsuD4ROu/yknP\n\tVn4hHODMJxnYXXstshcPL8L/Y2vcga9YQHZO4nz53h7jdaqn2e/pUcNLtCqD1lSt/Z1N\n\tRIkA==","X-Gm-Message-State":"AOJu0YyHXesc5wBEFh+u2MwOAGOESXHD2nRYttXnAfMMKDXkXqMJEz96\n\t/tFM1c3F+zDsKrhvx8TegDU2Hds9tvsDSD5iluvPw69m7ZqoJOBlq80hv1jvvu0xVYs7C2LrgcZ\n\tNpq1aWfrocLcLreLa8zKby5ndcZyyols7k14QXTxAKMDDzaWK8Qq8xpLwZqeo+l8Amo5fwvcBHN\n\tw=","X-Gm-Gg":"AZuq6aIQb0ttynKoElU6fFigYyiuqJ1OHWtShSd0d3yl20/Q/lq/c9qAVGJ9b0JI8pq\n\t0D/STIoSEf/uFJ10n3lb04s1X03Qk0noPt9cLupd2oOmvx4UWq6SgxQNzg3gRjy9EU88RCQ9hpK\n\tcdsYd/4wD3ocaiN2+VmHa/kFkLwmzBxTkX2r29gx+WfE3L1MKb7zI8e4pwk1Fcwx/RHD64npyL1\n\t32r4E/0Mv4FCW1N4Ea2qJNf+SmB0yZwXUHliU5vVXQej90jhQyDkwxOsGhp7yWrgBz0akbT+Wrk\n\t70NEsqnXjTpXUj6Oi6P502s3VdhA+A9CM/svhmbKMdmBfMwcO4tY3uMn0VKL0XW3N/VLdGnmACV\n\tAi+i/Z4TOO0+8iogChCfiX/4f6L3UiWE+WSl2xq5Z/JNQNwkEHyobVhSRHFZDSV0=","X-Received":["by 2002:a05:600c:8b61:b0:477:7bca:8b34 with SMTP id\n\t5b1f17b1804b1-48069c16356mr31560205e9.6.1769534572536; \n\tTue, 27 Jan 2026 09:22:52 -0800 (PST)","by 2002:a05:600c:8b61:b0:477:7bca:8b34 with SMTP id\n\t5b1f17b1804b1-48069c16356mr31559935e9.6.1769534572117; \n\tTue, 27 Jan 2026 09:22:52 -0800 (PST)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,  Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>,  Robert Mader\n\t<robert.mader@collabora.com>","Subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","In-Reply-To":"<fb3e330c-9aa1-473d-a045-d855795349dd@ideasonboard.com> (\n\t=?utf-8?b?IkJhcm5hYsOhcyBQxZFjemUiJ3M=?= message of \"Tue,\n\t27 Jan 2026  18:09:43 +0100\")","References":"<20260127162923.112675-1-mzamazal@redhat.com>\n\t<fb3e330c-9aa1-473d-a045-d855795349dd@ideasonboard.com>","Date":"Tue, 27 Jan 2026 18:22:50 +0100","Message-ID":"<85jyx3t1g5.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":"7q_dDlB0WDXhC14n3Pjs0_06Hf66wp9Xn7ffccHfl0U_1769534573","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":37980,"web_url":"https://patchwork.libcamera.org/comment/37980/","msgid":"<95779c5e-2b21-4416-9c97-ac4a297c0e59@ideasonboard.com>","date":"2026-01-27T18:59:05","subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 01. 27. 18:22 keltezéssel, Milan Zamazal írta:\n> Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:\n> \n>> Hi\n>>\n>> 2026. 01. 27. 17:29 keltezéssel, Milan Zamazal írta:\n>>> The black level offset subtracted in AWB is wrong.  It assumes that the\n>>> stats contain sums of the individual colour pixels.  But they actually\n>>> contain sums of the colour channels of larger \"superpixels\" consisting\n>>> of the individual colour pixels.  Each of the RGB colour values and the\n>>> computed luminosity (a histogram entry) are added once to the stats per\n>>> such a superpixel.  This means the offset computed from the black level\n>>> and the number of pixels should be used as it is, not divided.\n>>> The patch fixes the subtracted offset.  Since the evaluation is the same\n>>> for all the three colours now, the individual class variables are\n>>> replaced with a single RGB variable.\n>>> Fixes: 4e13c6f55bd667 (\"Honor black level in AWB\")\n>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>>> ---\n>>>    .../internal/software_isp/swisp_stats.h          | 16 +++++-----------\n>>>    src/ipa/simple/algorithms/awb.cpp                | 10 ++++------\n>>>    src/libcamera/software_isp/swstats_cpu.cpp       | 10 ++++------\n>>>    3 files changed, 13 insertions(+), 23 deletions(-)\n>>> diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h\n>>> index 3c9860185..d9d0d9be8 100644\n>>> --- a/include/libcamera/internal/software_isp/swisp_stats.h\n>>> +++ b/include/libcamera/internal/software_isp/swisp_stats.h\n>>> @@ -10,6 +10,8 @@\n>>>    #include <array>\n>>>    #include <stdint.h>\n>>>    +#include \"libcamera/internal/vector.h\"\n>>> +\n>>>    namespace libcamera {\n>>>      /**\n>>> @@ -26,17 +28,9 @@ struct SwIspStats {\n>>>    \t */\n>>>    \tbool valid;\n>>>    \t/**\n>>> -\t * \\brief Holds the sum of all sampled red pixels\n>>> -\t */\n>>> -\tuint64_t sumR_;\n>>> -\t/**\n>>> -\t * \\brief Holds the sum of all sampled green pixels\n>>> -\t */\n>>> -\tuint64_t sumG_;\n>>> -\t/**\n>>> -\t * \\brief Holds the sum of all sampled blue pixels\n>>> +\t * \\brief Sums of colour channels of all the sampled pixels\n>>>    \t */\n>>> -\tuint64_t sumB_;\n>>> +\tRGB<uint64_t> sum_;\n>>>    \t/**\n>>>    \t * \\brief Number of bins in the yHistogram\n>>>    \t */\n>>> @@ -46,7 +40,7 @@ struct SwIspStats {\n>>>    \t */\n>>>    \tusing Histogram = std::array<uint32_t, kYHistogramSize>;\n>>>    \t/**\n>>> -\t * \\brief A histogram of luminance values\n>>> +\t * \\brief A histogram of luminance values of all the sampled pixels\n>>>    \t */\n>>>    \tHistogram yHistogram;\n>>>    };\n>>> diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp\n>>> index 0080865aa..75e4ae4a4 100644\n>>> --- a/src/ipa/simple/algorithms/awb.cpp\n>>> +++ b/src/ipa/simple/algorithms/awb.cpp\n>>> @@ -1,6 +1,6 @@\n>>>    /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>>>    /*\n>>> - * Copyright (C) 2024, Red Hat Inc.\n>>> + * Copyright (C) 2024-2026 Red Hat Inc.\n>>>     *\n>>>     * Auto white balance\n>>>     */\n>>> @@ -73,9 +73,7 @@ void Awb::process(IPAContext &context,\n>>>    \t\thistogram.begin(), histogram.end(), uint64_t(0));\n>>>    \tconst uint64_t offset = blackLevel * nPixels;\n>>>    \tconst uint64_t minValid = 1;\n>>> -\tconst uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid;\n>>> -\tconst uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid;\n>>> -\tconst uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid;\n>>> +\tconst RGB<uint64_t> sum = (stats->sum_ - offset).max(minValid);\n>>\n>> What happens if the subtraction wraps around? Previously that was avoided\n>> by the removed check. Or is wraparound actually impossible now?\n> \n> Oops, I've forgotten about that trap again, thank you for the reminder.\n> I'll fix it some way in v3.\n> \n\nMaybe\n\n   const RGB<uint64_t> sum = stats->sum_.max(offset + minValid) - offset;\n\n?","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 0342FC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 27 Jan 2026 18:59:14 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EBDDC61FC8;\n\tTue, 27 Jan 2026 19:59:13 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 328FB61FBF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 19:59:12 +0100 (CET)","from [192.168.33.37] (185.221.142.123.nat.pool.zt.hu\n\t[185.221.142.123])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4CC9EE70;\n\tTue, 27 Jan 2026 19:58:34 +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=\"agpRFwte\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769540315;\n\tbh=8rsTJlT9obwfgZ04Ss+8R9gOd1EyGUAkpPDOk3KPI/k=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=agpRFwte5skASIgYjAy4Ag2FGAbXWuISPQeGrMqVIURejzgZiUHYWvt+WKvZbpGhU\n\tOqJmRjcSwqzaf+2DiTtt7VZfMFadqjTzUNr1QT68Br4hqQBptnlAXkyTgMl7RD03RW\n\tfMMc1xoEG4F2BlKqKWfmu13HQyM1BDi5zl3LOEhg=","Message-ID":"<95779c5e-2b21-4416-9c97-ac4a297c0e59@ideasonboard.com>","Date":"Tue, 27 Jan 2026 19:59:05 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tRobert Mader <robert.mader@collabora.com>","References":"<20260127162923.112675-1-mzamazal@redhat.com>\n\t<fb3e330c-9aa1-473d-a045-d855795349dd@ideasonboard.com>\n\t<85jyx3t1g5.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<85jyx3t1g5.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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":37981,"web_url":"https://patchwork.libcamera.org/comment/37981/","msgid":"<85ecnau6jj.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-01-27T20:47:28","subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:\n\n> 2026. 01. 27. 18:22 keltezéssel, Milan Zamazal írta:\n>> Barnabás Pőcze <barnabas.pocze@ideasonboard.com> writes:\n>> \n>>> Hi\n>>>\n>>> 2026. 01. 27. 17:29 keltezéssel, Milan Zamazal írta:\n>>>> The black level offset subtracted in AWB is wrong.  It assumes that the\n>>>> stats contain sums of the individual colour pixels.  But they actually\n>>>> contain sums of the colour channels of larger \"superpixels\" consisting\n>>>> of the individual colour pixels.  Each of the RGB colour values and the\n>>>> computed luminosity (a histogram entry) are added once to the stats per\n>>>> such a superpixel.  This means the offset computed from the black level\n>>>> and the number of pixels should be used as it is, not divided.\n>>>> The patch fixes the subtracted offset.  Since the evaluation is the same\n>>>> for all the three colours now, the individual class variables are\n>>>> replaced with a single RGB variable.\n>>>> Fixes: 4e13c6f55bd667 (\"Honor black level in AWB\")\n>>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>>>> ---\n>>>>    .../internal/software_isp/swisp_stats.h          | 16 +++++-----------\n>>>>    src/ipa/simple/algorithms/awb.cpp                | 10 ++++------\n>>>>    src/libcamera/software_isp/swstats_cpu.cpp       | 10 ++++------\n>>>>    3 files changed, 13 insertions(+), 23 deletions(-)\n>>>> diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h\n>>>> index 3c9860185..d9d0d9be8 100644\n>>>> --- a/include/libcamera/internal/software_isp/swisp_stats.h\n>>>> +++ b/include/libcamera/internal/software_isp/swisp_stats.h\n>>>> @@ -10,6 +10,8 @@\n>>>>    #include <array>\n>>>>    #include <stdint.h>\n>>>>    +#include \"libcamera/internal/vector.h\"\n>>>> +\n>>>>    namespace libcamera {\n>>>>      /**\n>>>> @@ -26,17 +28,9 @@ struct SwIspStats {\n>>>>    \t */\n>>>>    \tbool valid;\n>>>>    \t/**\n>>>> -\t * \\brief Holds the sum of all sampled red pixels\n>>>> -\t */\n>>>> -\tuint64_t sumR_;\n>>>> -\t/**\n>>>> -\t * \\brief Holds the sum of all sampled green pixels\n>>>> -\t */\n>>>> -\tuint64_t sumG_;\n>>>> -\t/**\n>>>> -\t * \\brief Holds the sum of all sampled blue pixels\n>>>> +\t * \\brief Sums of colour channels of all the sampled pixels\n>>>>    \t */\n>>>> -\tuint64_t sumB_;\n>>>> +\tRGB<uint64_t> sum_;\n>>>>    \t/**\n>>>>    \t * \\brief Number of bins in the yHistogram\n>>>>    \t */\n>>>> @@ -46,7 +40,7 @@ struct SwIspStats {\n>>>>    \t */\n>>>>    \tusing Histogram = std::array<uint32_t, kYHistogramSize>;\n>>>>    \t/**\n>>>> -\t * \\brief A histogram of luminance values\n>>>> +\t * \\brief A histogram of luminance values of all the sampled pixels\n>>>>    \t */\n>>>>    \tHistogram yHistogram;\n>>>>    };\n>>>> diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp\n>>>> index 0080865aa..75e4ae4a4 100644\n>>>> --- a/src/ipa/simple/algorithms/awb.cpp\n>>>> +++ b/src/ipa/simple/algorithms/awb.cpp\n>>>> @@ -1,6 +1,6 @@\n>>>>    /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>>>>    /*\n>>>> - * Copyright (C) 2024, Red Hat Inc.\n>>>> + * Copyright (C) 2024-2026 Red Hat Inc.\n>>>>     *\n>>>>     * Auto white balance\n>>>>     */\n>>>> @@ -73,9 +73,7 @@ void Awb::process(IPAContext &context,\n>>>>    \t\thistogram.begin(), histogram.end(), uint64_t(0));\n>>>>    \tconst uint64_t offset = blackLevel * nPixels;\n>>>>    \tconst uint64_t minValid = 1;\n>>>> -\tconst uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid;\n>>>> -\tconst uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid;\n>>>> -\tconst uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid;\n>>>> +\tconst RGB<uint64_t> sum = (stats->sum_ - offset).max(minValid);\n>>>\n>>> What happens if the subtraction wraps around? Previously that was avoided\n>>> by the removed check. Or is wraparound actually impossible now?\n>> Oops, I've forgotten about that trap again, thank you for the reminder.\n>> I'll fix it some way in v3.\n>> \n>\n> Maybe\n>\n>   const RGB<uint64_t> sum = stats->sum_.max(offset + minValid) - offset;\n>\n> ?\n\nNice, thanks.  Applied in v3 + added a source comment there for\nclarification and not to repeat the mistake again.","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 CFB31C3200\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 27 Jan 2026 20:47:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 82BC761FCB;\n\tTue, 27 Jan 2026 21:47:36 +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 2066761FBF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 21:47:35 +0100 (CET)","from mail-wr1-f72.google.com (mail-wr1-f72.google.com\n\t[209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-218-GJfJfForMa-AClP2qFz2qA-1; Tue, 27 Jan 2026 15:47:32 -0500","by mail-wr1-f72.google.com with SMTP id\n\tffacd0b85a97d-4358f90fe8dso305864f8f.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 27 Jan 2026 12:47:32 -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-435e10e4824sm1447915f8f.1.2026.01.27.12.47.29\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 27 Jan 2026 12:47:29 -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=\"E9YkCnRU\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1769546854;\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=ShLiV3pcNG7R2KFCeYDQK9wOChL2ZjmvFyElD5xqhl0=;\n\tb=E9YkCnRU076U4j4H4j84rRe+F2xwJ3bF4NKkJssdUkYEbKlWfDpKmwlA+PGJJHI/2GZhIK\n\tjO1PXPObY/EA/r8BNvlqeKBYqnm2g8l9oAkP3LVK9XeaDja/UL9q5u9MpYHLRF4Ntl/1Af\n\tZJTsWr+dtbIiNSoPgOnfjaO/9BUo8mA=","X-MC-Unique":"GJfJfForMa-AClP2qFz2qA-1","X-Mimecast-MFC-AGG-ID":"GJfJfForMa-AClP2qFz2qA_1769546851","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1769546851; x=1770151651;\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=nxGtlIIw5LdqqDcrxbD6eVdlFYbKFlP1KlbKxB9yO+A=;\n\tb=CfgK7cEyYAeLTup//l9pvEbQdyW+UOTbFh+dC0FN3Sz0T8H7Pk+HBnyyB7uJ1+BI+t\n\tFkCqF9sBK5TwPzkrw2+msiB6htqmCdSNlqSKEP7ew/gCVaZKuO7PNnOiX6PDQOAggSbK\n\tDwaPxl3RAAoRxcamZrFLTwuh1AuYF1VkT+6zDsf+9uM4ovjBE0ttY553d+ro4+cykP4Q\n\tk//B6e+dG8n8FI1UiPi6KwZ/zNLgDnCigy18EptXrWtC6KKp7RO7RlMv9QHtzxyJJD5R\n\t0zh9Ph+//Q1mpuOUYX/yLOS074iiaP5d6Gz2Xd11oRgLPz70do4v4CHFbXysEvbMygJe\n\tHQew==","X-Gm-Message-State":"AOJu0YwNWmijrj0RfM1dFiSFVDFdyHOQE2MPESW2TW4lwvPH53FC6ArJ\n\tewfdgOBtG+GY3Yu6IDjRHV68S/3XX3PUv0XohopKZdbcBG6wcvE0HSmPl4E1YUds4TYUGB7rRQ6\n\tjyPGBg6WEJs6jWvjjqrPCeuVdptJRcDNELjMsmz9iB7znWdoB+Z6lXNfzrfW28Rpx+vajL+oUqj\n\t/uf+Zl2E4=","X-Gm-Gg":"AZuq6aIWSKUGs3SM2vv9TI8rhIIePWKyBmt9ARgFnfM89799U3MmVWBApXuJPfvZFyo\n\tZynzY0vWLhjflYqCacfMDoNPd1NqOO5y0oPEL2aXWTEy9FJHkGpWNEhqrSEW7tXSyH7HzIP1eBL\n\t24/SGKV+yFbrlMbkMZvbqfTBcbL0iG95lv0iij77vg6sv4gBZRPk7LvebW5d8vsSJSqV7Y6wT2x\n\t8NiUIj2k+kEvwtrbQWiGxAJrZqrJNchGSwspxVrxt+DFcKjU3rzbln1UYe1O6G2LsP35LST2I9U\n\tHLZdXrgamwpggO2643vI4SYpBlOqnLU7rT2HL/U0NT8yZcIvqsOv733ONTef3x+DTZz7vmW205P\n\ttBweOqIG6HO+L8bf0l2V6ZA5ZTeCw9IrJpW9O7lqidlQuv6QB6XrAGe0NDIlMtaE=","X-Received":["by 2002:a05:6000:1acc:b0:435:9538:939b with SMTP id\n\tffacd0b85a97d-435dd0bdf07mr4397681f8f.8.1769546850603; \n\tTue, 27 Jan 2026 12:47:30 -0800 (PST)","by 2002:a05:6000:1acc:b0:435:9538:939b with SMTP id\n\tffacd0b85a97d-435dd0bdf07mr4397655f8f.8.1769546850126; \n\tTue, 27 Jan 2026 12:47:30 -0800 (PST)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,  Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>,  Robert Mader\n\t<robert.mader@collabora.com>","Subject":"Re: [PATCH v2] libcamera: simple: Fix black level offsets in AWB","In-Reply-To":"<95779c5e-2b21-4416-9c97-ac4a297c0e59@ideasonboard.com> (\n\t=?utf-8?b?IkJhcm5hYsOhcyBQxZFjemUiJ3M=?= message of \"Tue,\n\t27 Jan 2026  19:59:05 +0100\")","References":"<20260127162923.112675-1-mzamazal@redhat.com>\n\t<fb3e330c-9aa1-473d-a045-d855795349dd@ideasonboard.com>\n\t<85jyx3t1g5.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>\n\t<95779c5e-2b21-4416-9c97-ac4a297c0e59@ideasonboard.com>","Date":"Tue, 27 Jan 2026 21:47:28 +0100","Message-ID":"<85ecnau6jj.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":"LTyGIlyrMNsLDX6xQh5ru6cS9JTzah6YitQn30X7Ykc_1769546851","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>"}}]