@@ -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<Traits> 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::quantized_type
+ * \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(quantized_type 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 */
@@ -10,6 +10,8 @@
#include <cmath>
#include <type_traits>
+#include "quantized.h"
+
namespace libcamera {
namespace ipa {
@@ -60,6 +62,47 @@ constexpr R fixedToFloatingPoint(T number)
return static_cast<R>(t) / static_cast<R>(1 << F);
}
+template<unsigned int I, unsigned int F, typename T>
+struct FixedPointQTraits {
+ static_assert(std::is_integral_v<T>, "FixedPointQTraits: T must be integral");
+ using quantized_type = 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>
+ ? -(T{1} << (Bits - 1))
+ : T{0};
+
+ static constexpr T qmax = std::is_signed_v<T>
+ ? ((T{1} << (Bits - 1)) - 1)
+ : ((T{1} << Bits) - 1);
+
+ static constexpr float min = fixedToFloatingPoint<I, F, float>(qmin);
+ static constexpr float max = fixedToFloatingPoint<I, F, float>(qmax);
+
+ /* Conversion functions required by Quantized<Traits> */
+ static quantized_type fromFloat(float v)
+ {
+ v = std::clamp(v, min, max);
+ return floatingToFixedPoint<I, F, quantized_type, float>(v);
+ }
+
+ static float toFloat(quantized_type q)
+ {
+ return fixedToFloatingPoint<I, F, float, quantized_type>(q);
+ }
+};
+
+using Q1_7 = Quantized<FixedPointQTraits<1, 7, int8_t>>;
+using UQ1_7 = Quantized<FixedPointQTraits<1, 7, uint8_t>>;
+
+using Q12_4 = Quantized<FixedPointQTraits<12, 4, int16_t>>;
+using UQ12_4 = Quantized<FixedPointQTraits<12, 4, uint16_t>>;
+
} /* namespace ipa */
} /* namespace libcamera */
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 <kieran.bingham@ideasonboard.com> --- src/ipa/libipa/fixedpoint.cpp | 114 ++++++++++++++++++++++++++++++++++ src/ipa/libipa/fixedpoint.h | 43 +++++++++++++ 2 files changed, 157 insertions(+)