From patchwork Thu Nov 13 12:24:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 25017 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 15480C32DB for ; Thu, 13 Nov 2025 12:25:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 26B9960AA0; Thu, 13 Nov 2025 13:25:01 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="p1MIOeNm"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F0175609E0 for ; Thu, 13 Nov 2025 13:24:54 +0100 (CET) Received: from Monstersaurus.infra.iob (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D2C5ABD2; Thu, 13 Nov 2025 13:22:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1763036574; bh=PhQGFNwJSBWycnkwVvtA+1mUnzMQWB2S4EWDL7u4f0E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p1MIOeNmKmmcxYY29h8UMUa2cXBAJmtl3IIb0eG1sKjz2knMbrsEwM6ECl0Mpw+Za qCHvb63L4632dps4FsntyzhnNXv7/LkGjsFgZOBP8Tqt+lhClZi0fjUJ46gIhBV+I3 mG4o8zSbnBLr4JEW01tV9oYuq7maMLLgRcXTKSsI= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH v3 03/14] ipa: libipa: Provide fixed point quantized traits Date: Thu, 13 Nov 2025 12:24:38 +0000 Message-ID: <20251113122450.287633-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251113122450.287633-1-kieran.bingham@ideasonboard.com> References: <20251113122450.287633-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 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" Extend the new Quantized type infrastructure by providing a FixedPointQTraits template. This allows construction of fixed point types with a Quantized storage that allows easy reading of both the underlying quantized type value and a floating point representation of that same value. Signed-off-by: Kieran Bingham --- src/ipa/libipa/fixedpoint.cpp | 114 ++++++++++++++++++++++++++++++++++ src/ipa/libipa/fixedpoint.h | 43 +++++++++++++ 2 files changed, 157 insertions(+) diff --git a/src/ipa/libipa/fixedpoint.cpp b/src/ipa/libipa/fixedpoint.cpp index 6b698fc5d680..5b5d3721bf85 100644 --- a/src/ipa/libipa/fixedpoint.cpp +++ b/src/ipa/libipa/fixedpoint.cpp @@ -37,6 +37,120 @@ namespace ipa { * \return The converted value */ +/** + * \struct libcamera::ipa::FixedPointQTraits + * \brief Traits type implementing fixed-point quantisation conversions + * + * The FixedPointQTraits structure defines a policy for mapping floating-point + * values to and from fixed-point integer representations. It is parameterised + * by the number of integer bits \a I, fractional bits \a F, and the integral + * storage type \a T. The traits are used with Quantized to create a + * quantised type that stores both the fixed-point representation and the + * corresponding floating-point value. + * + * The trait exposes compile-time constants describing the bit layout, limits, + * and scaling factors used in the fixed-point representation. + * + * \tparam I Number of integer bits + * \tparam F Number of fractional bits + * \tparam T Integral type used to store the quantised value + */ + +/** + * \typedef FixedPointQTraits::QuantizedType + * \brief The integral storage type used for the fixed-point representation + */ + +/** + * \var FixedPointQTraits::Bits + * \brief Total number of bits used in the fixed-point format (I + F) + */ + +/** + * \var FixedPointQTraits::BitMask + * \brief Bit mask selecting all valid bits in the fixed-point representation + */ + +/** + * \var FixedPointQTraits::qmin + * \brief Minimum representable quantised integer value + * + * This corresponds to the most negative value for signed formats or zero for + * unsigned formats. + */ + +/** + * \var FixedPointQTraits::qmax + * \brief Maximum representable quantised integer value + */ + +/** + * \var FixedPointQTraits::min + * \brief Minimum representable floating-point value corresponding to qmin + */ + +/** + * \var FixedPointQTraits::max + * \brief Maximum representable floating-point value corresponding to qmax + */ + +/** + * \fn FixedPointQTraits::fromFloat(float v) + * \brief Convert a floating-point value to a fixed-point integer + * \param[in] v The floating-point value to be converted + * \return The quantised fixed-point integer representation + * + * The conversion rounds the floating-point input \a v to the nearest integer + * according to the scaling factor defined by the number of fractional bits F. + */ + +/** + * \fn FixedPointQTraits::toFloat(QuantizedType q) + * \brief Convert a fixed-point integer to a floating-point value + * \param[in] q The fixed-point integer value to be converted + * \return The corresponding floating-point value + * + * The conversion sign-extends the integer value if required and divides by the + * scaling factor defined by the number of fractional bits F. + */ + +/** + * \typedef Q1_7 + * \brief 1.7 signed fixed-point quantizer + * + * A Quantized type using 1 bit for the integer part and 7 bits for the + * fractional part, stored in a signed 8-bit integer (\c int8_t). Represents + * values approximately in the range [-1.0, 0.992] with a resolution of 1/128. + */ + +/** + * \typedef UQ1_7 + * \brief 1.7 unsigned fixed-point quantizer + * + * A Quantized type using 1 bit for the integer part and 7 bits for the + * fractional part, stored in an unsigned 8-bit integer (\c uint8_t). Represents + * values in the range [0.0, 1.992] with a resolution of 1/128. + */ + +/** + * \typedef Q12_4 + * \brief 12.4 signed fixed-point quantizer + * + * A Quantized type using 12 bits for the integer part and 4 bits for the + * fractional part, stored in a signed 16-bit integer (\c int16_t). Represents + * values in the range approximately [-2048.0, 2047.9375] with a resolution of + * 1/16. + */ + +/** + * \typedef UQ12_4 + * \brief 12.4 unsigned fixed-point quantizer + * + * A Quantized type using 12 bits for the integer part and 4 bits for the + * fractional part, stored in an unsigned 16-bit integer (\c uint16_t). + * Represents values in the range [0.0, 4095.9375] with a resolution of 1/16. + */ + } /* namespace ipa */ } /* namespace libcamera */ diff --git a/src/ipa/libipa/fixedpoint.h b/src/ipa/libipa/fixedpoint.h index 709cf50f0fcd..baf5dbfa6bf8 100644 --- a/src/ipa/libipa/fixedpoint.h +++ b/src/ipa/libipa/fixedpoint.h @@ -10,6 +10,8 @@ #include #include +#include "quantized.h" + namespace libcamera { namespace ipa { @@ -60,6 +62,47 @@ constexpr R fixedToFloatingPoint(T number) return static_cast(t) / static_cast(1 << F); } +template +struct FixedPointQTraits { + static_assert(std::is_integral_v, "FixedPointQTraits: T must be integral"); + using QuantizedType = T; + + static constexpr unsigned int Bits = I + F; + + static constexpr T BitMask = (Bits < sizeof(T) * 8) + ? (T{1} << Bits) - 1 + : T{-1}; + + static constexpr T qmin = std::is_signed_v + ? -(T{1} << (Bits - 1)) + : T{0}; + + static constexpr T qmax = std::is_signed_v + ? ((T{1} << (Bits - 1)) - 1) + : ((T{1} << Bits) - 1); + + static constexpr float min = fixedToFloatingPoint(qmin); + static constexpr float max = fixedToFloatingPoint(qmax); + + /* Conversion functions required by Quantized */ + static QuantizedType fromFloat(float v) + { + v = std::clamp(v, min, max); + return floatingToFixedPoint(v); + } + + static float toFloat(QuantizedType q) + { + return fixedToFloatingPoint(q); + } +}; + +using Q1_7 = Quantized>; +using UQ1_7 = Quantized>; + +using Q12_4 = Quantized>; +using UQ12_4 = Quantized>; + } /* namespace ipa */ } /* namespace libcamera */