diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h index 3c986018..d9d0d9be 100644 --- a/include/libcamera/internal/software_isp/swisp_stats.h +++ b/include/libcamera/internal/software_isp/swisp_stats.h @@ -10,6 +10,8 @@ #include #include +#include "libcamera/internal/vector.h" + namespace libcamera { /** @@ -26,17 +28,9 @@ struct SwIspStats { */ bool valid; /** - * \brief Holds the sum of all sampled red pixels + * \brief Sums of colour channels of all the sampled pixels */ - uint64_t sumR_; - /** - * \brief Holds the sum of all sampled green pixels - */ - uint64_t sumG_; - /** - * \brief Holds the sum of all sampled blue pixels - */ - uint64_t sumB_; + RGB sum_; /** * \brief Number of bins in the yHistogram */ @@ -46,7 +40,7 @@ struct SwIspStats { */ using Histogram = std::array; /** - * \brief A histogram of luminance values + * \brief A histogram of luminance values of all the sampled pixels */ Histogram yHistogram; }; diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp index 0080865a..50565fe8 100644 --- a/src/ipa/simple/algorithms/awb.cpp +++ b/src/ipa/simple/algorithms/awb.cpp @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2024, Red Hat Inc. + * Copyright (C) 2024-2026 Red Hat Inc. * * Auto white balance */ @@ -73,9 +73,11 @@ void Awb::process(IPAContext &context, histogram.begin(), histogram.end(), uint64_t(0)); const uint64_t offset = blackLevel * nPixels; const uint64_t minValid = 1; - const uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid; - const uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid; - const uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid; + /* + * Make sure the sums are at least minValid, while preventing unsigned + * integer underflow. + */ + const RGB sum = stats->sum_.max(offset + minValid) - offset; /* * Calculate red and blue gains for AWB. @@ -83,9 +85,9 @@ void Awb::process(IPAContext &context, */ auto &gains = context.activeState.awb.gains; gains = { { - sumR <= sumG / 4 ? 4.0f : static_cast(sumG) / sumR, + sum.r() <= sum.g() / 4 ? 4.0f : static_cast(sum.g()) / sum.r(), 1.0, - sumB <= sumG / 4 ? 4.0f : static_cast(sumG) / sumB, + sum.b() <= sum.g() / 4 ? 4.0f : static_cast(sum.g()) / sum.b(), } }; RGB rgbGains{ { 1 / gains.r(), 1 / gains.g(), 1 / gains.b() } }; diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp index c931edb4..5c3011a7 100644 --- a/src/libcamera/software_isp/swstats_cpu.cpp +++ b/src/libcamera/software_isp/swstats_cpu.cpp @@ -185,9 +185,9 @@ static constexpr unsigned int kBlueYMul = 29; /* 0.114 * 256 */ stats_.yHistogram[yVal * SwIspStats::kYHistogramSize / (256 * 256 * (div))]++; #define SWSTATS_FINISH_LINE_STATS() \ - stats_.sumR_ += sumR; \ - stats_.sumG_ += sumG; \ - stats_.sumB_ += sumB; + stats_.sum_.r() += sumR; \ + stats_.sum_.g() += sumG; \ + stats_.sum_.b() += sumB; void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[]) { @@ -332,9 +332,7 @@ void SwStatsCpu::startFrame(uint32_t frame) if (window_.width == 0) LOG(SwStatsCpu, Error) << "Calling startFrame() without setWindow()"; - stats_.sumR_ = 0; - stats_.sumB_ = 0; - stats_.sumG_ = 0; + stats_.sum_ = RGB({ 0, 0, 0 }); stats_.yHistogram.fill(0); }