From patchwork Mon Dec 6 15:26:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 15052 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 69D4FBDB13 for ; Mon, 6 Dec 2021 15:27:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 222216087E; Mon, 6 Dec 2021 16:27:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="KdGy/93S"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1677760725 for ; Mon, 6 Dec 2021 16:27:17 +0100 (CET) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A86E5547 for ; Mon, 6 Dec 2021 16:27:16 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1638804436; bh=43LZ5Gae5XpndtQ7zkW9WZrDi1BhsCVfMxoiB4RbMzg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=KdGy/93SMsdINo/rj6g58g1YM1svy/aDq9ZRgrY3gk6k2uoxXX7BPakiZgZ6wCFGX fKQrwMWyQTG6AK7t8kMdO8GXGr3U4io4Xi3fgSNN1u/IV9deMtI6qTafJ2gNBD038l 5VyXyxjqMJThK77noat6usEtZYsbiTBi8KMNGBq8= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 6 Dec 2021 17:26:43 +0200 Message-Id: <20211206152644.4863-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211206152644.4863-1-laurent.pinchart@ideasonboard.com> References: <20211206152644.4863-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/2] libcamera: base: utils: Add abs_diff() utility function X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The abs_diff() function computes the absolute difference of two elements. This may seem trivial at first, but can lead to unexpected results when operating on unsigned operands. A common implementation of the absolute difference of two unsigned int (used through the libcamera code base) is std::abs(static_cast(a - b)) but doesn't return the expected result when either a or b is larger than UINT_MAX / 2 due to overflows. The abs_diff() function offers a safe alternative. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Umang Jain --- include/libcamera/base/utils.h | 9 +++++++++ src/libcamera/base/utils.cpp | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index 3a803176693d..9ab18101cf27 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -346,6 +346,15 @@ public: } }; +template +decltype(auto) abs_diff(const T &a, const T &b) +{ + if (a < b) + return b - a; + else + return a - b; +} + } /* namespace utils */ #ifndef __DOXYGEN__ diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp index 45b92b670837..8cf8a5b2c104 100644 --- a/src/libcamera/base/utils.cpp +++ b/src/libcamera/base/utils.cpp @@ -437,6 +437,23 @@ std::string toAscii(const std::string &str) * \return True if \a Duration is a non-zero time value, False otherwise */ +/** + * \fn abs_diff(const T& a, const T& b) + * \brief Calculates the absolute value of the difference between two elements + * \param[in] a The first element + * \param[in] b The second element + * + * This function calculates the absolute value of the difference between two + * elements of the same type, in such a way that a negative value will never + * occur during the calculation. + * + * This is inspired by the std::abs_diff() candidate proposed in N4318 + * (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4318.pdf). + * + * \return The absolute value of the difference of the two parameters \a a and + * \a b + */ + } /* namespace utils */ #ifndef __DOXYGEN__ From patchwork Mon Dec 6 15:26:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 15053 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 3A296C324B for ; Mon, 6 Dec 2021 15:27:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 89BF560872; Mon, 6 Dec 2021 16:27:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WrQTMAI4"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9097E60725 for ; Mon, 6 Dec 2021 16:27:17 +0100 (CET) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2F40BEE for ; Mon, 6 Dec 2021 16:27:17 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1638804437; bh=GIOM/Vi7n4eFp5C0umwzL4zXPb8iMvz2VZA/H+RrvMQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=WrQTMAI46FxHfmOCYCU7sfABTXh5ETrJEfT6fEIBwjGEhOs6MLUk6hlyj6AFCHEOK d3rAZTKpR0nUXZEj3mce292HeN/BXkplciSE09+v+PnFQ9ubnJBQGcvaVvwB6wym26 cVz4lHwIjkfxOoV0U42EMLd8pRNylJZLNWxpk6kc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 6 Dec 2021 17:26:44 +0200 Message-Id: <20211206152644.4863-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211206152644.4863-1-laurent.pinchart@ideasonboard.com> References: <20211206152644.4863-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/2] libcamera: Use utils::abs_diff() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use the new utils::abs_diff() function where appropriate to replace manual implementations. While at it fix a header ordering issue in src/libcamera/pipeline/raspberrypi/raspberrypi.cpp. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Umang Jain --- src/ipa/ipu3/algorithms/agc.cpp | 3 ++- src/ipa/ipu3/ipu3.cpp | 4 ++-- src/ipa/rkisp1/algorithms/agc.cpp | 3 ++- src/libcamera/pipeline/ipu3/imgu.cpp | 4 ++-- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 5 ++--- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 582f0ae1b54b..8d6f18f60aed 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -12,6 +12,7 @@ #include #include +#include #include @@ -188,7 +189,7 @@ void Agc::computeExposure(IPAFrameContext &frameContext, double yGain, double evGain = std::max(yGain, iqMeanGain); /* Consider within 1% of the target as correctly exposed */ - if (std::abs(evGain - 1.0) < 0.01) + if (utils::abs_diff(evGain, 1.0) < 0.01) LOG(IPU3Agc, Debug) << "We are well exposed (evGain = " << evGain << ")"; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 7618258725a8..3d30770867b9 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -354,7 +354,7 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) kMaxGridWidth); width = width << shift; - uint32_t error = std::abs(static_cast(width - bdsOutputSize.width)); + uint32_t error = utils::abs_diff(width, bdsOutputSize.width); if (error >= minError) continue; @@ -370,7 +370,7 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) kMaxGridHeight); height = height << shift; - uint32_t error = std::abs(static_cast(height - bdsOutputSize.height)); + uint32_t error = utils::abs_diff(height, bdsOutputSize.height); if (error >= minError) continue; diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index d6abdc310f35..dd97afc00813 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -12,6 +12,7 @@ #include #include +#include #include @@ -145,7 +146,7 @@ void Agc::computeExposure(IPAContext &context, double yGain) kMaxAnalogueGain); /* Consider within 1% of the target as correctly exposed. */ - if (std::abs(yGain - 1.0) < 0.01) + if (utils::abs_diff(yGain, 1.0) < 0.01) return; /* extracted from Rpi::Agc::computeTargetExposure. */ diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index 3ef0ef144301..e5bbc3829c68 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -81,7 +81,7 @@ float findScaleFactor(float sf, const std::vector &range, float bestDiff = std::numeric_limits::max(); unsigned int index = 0; for (unsigned int i = 0; i < range.size(); ++i) { - float diff = std::abs(sf - range[i]); + float diff = utils::abs_diff(sf, range[i]); if (diff < bestDiff) { bestDiff = diff; index = i; @@ -99,7 +99,7 @@ bool isSameRatio(const Size &in, const Size &out) float inRatio = static_cast(in.width) / in.height; float outRatio = static_cast(out.width) / out.height; - if (std::abs(inRatio - outRatio) > 0.1) + if (utils::abs_diff(inRatio, outRatio) > 0.1) return false; return true; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 321b72adbbf7..2cb0267ccf4c 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -25,8 +26,6 @@ #include #include -#include - #include #include #include @@ -154,7 +153,7 @@ V4L2SubdeviceFormat findBestFormat(const SensorFormats &formatsMap, const Size & score += penaltyAr * scoreFormat(reqAr, fmtAr); /* Add any penalties... this is not an exact science! */ - score += std::abs(static_cast(info.bitsPerPixel - bitDepth)) * penaltyBitDepth; + score += utils::abs_diff(info.bitsPerPixel, bitDepth) * penaltyBitDepth; if (score <= bestScore) { bestScore = score;