[v2,07/13] ipa: libipa: fixedpoint: Provide a ScaledFixedPoint type
diff mbox series

Message ID 20251029172439.1513907-8-kieran.bingham@ideasonboard.com
State New
Headers show
Series
  • libipa: Introduce a Quantized type
Related show

Commit Message

Kieran Bingham Oct. 29, 2025, 5:24 p.m. UTC
Extend the new Quantized FixedPoint capabilities with a ScaledFixedPointQTraits
which takes an existing Quantized type and scales the conversion by the
given Scale template parameter.

This can be useful to represent fixed point values which represent
a linear range with a different scale to the underlying float
or integral type.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/ipa/libipa/fixedpoint.cpp | 59 +++++++++++++++++++++++++++++++++++
 src/ipa/libipa/fixedpoint.h   | 24 ++++++++++++++
 2 files changed, 83 insertions(+)

Patch
diff mbox series

diff --git a/src/ipa/libipa/fixedpoint.cpp b/src/ipa/libipa/fixedpoint.cpp
index 2568c7921348..e6e1408ccff6 100644
--- a/src/ipa/libipa/fixedpoint.cpp
+++ b/src/ipa/libipa/fixedpoint.cpp
@@ -151,6 +151,65 @@  namespace ipa {
  * Represents values in the range [0.0, 4095.9375] with a resolution of 1/16.
  */
 
+/**
+ * \struct ScaledFixedPointQTraits
+ * \brief Wrap a FixedPointQTraits with a linear scaling factor
+ *
+ * This trait extends an existing fixed-point quantisation policy
+ * by applying an additional multiplicative scale between the
+ * floating-point and quantised domains.
+ *
+ * \tparam Q The base fixed-point traits type
+ * \tparam Scale The scale factor applied to the floating-point domain
+ */
+
+/**
+ * \typedef ScaledFixedPointQTraits::quantized_type
+ * \copydoc FixedPointQTraits::quantized_type
+ */
+
+/**
+ * \var ScaledFixedPointQTraits::scale
+ * \brief The constant scaling factor applied to the floating-point domain.
+ *
+ * Floating-point inputs are divided by this factor before quantisation,
+ * and multiplied by it after dequantisation.
+ */
+
+/**
+ * \var ScaledFixedPointQTraits::qmin
+ * \copydoc FixedPointQTraits::qmin
+ */
+
+/**
+ * \var ScaledFixedPointQTraits::qmax
+ * \copydoc FixedPointQTraits::qmax
+ */
+
+/**
+ * \var ScaledFixedPointQTraits::min
+ * \copydoc FixedPointQTraits::min
+ */
+
+/**
+ * \var ScaledFixedPointQTraits::max
+ * \copydoc FixedPointQTraits::max
+ */
+
+/**
+ * \fn ScaledFixedPointQTraits::fromFloat(float v)
+ * \copydoc FixedPointQTraits::fromFloat(float v)
+ *
+ * The input value \a v is divided by the scaling factor before conversion.
+ */
+
+/**
+ * \fn ScaledFixedPointQTraits::toFloat(quantized_type q)
+ * \copydoc FixedPointQTraits::toFloat(quantized_type q)
+ *
+ * The output value is multiplied by the scaling factor after conversion.
+ */
+
 } /* namespace ipa */
 
 } /* namespace libcamera */
diff --git a/src/ipa/libipa/fixedpoint.h b/src/ipa/libipa/fixedpoint.h
index 557f7f5b3382..7a9103ed3a77 100644
--- a/src/ipa/libipa/fixedpoint.h
+++ b/src/ipa/libipa/fixedpoint.h
@@ -106,6 +106,30 @@  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>>;
 
+template<typename Q, int Scale>
+struct ScaledFixedPointQTraits {
+	using quantized_type = typename Q::quantized_type;
+
+	static constexpr float scale = static_cast<float>(Scale);
+
+	/* Re-expose base limits, adjusted by the scaling factor */
+	static constexpr quantized_type qmin = Q::qmin;
+	static constexpr quantized_type qmax = Q::qmax;
+	static constexpr float min = Q::min * scale;
+	static constexpr float max = Q::max * scale;
+
+	static quantized_type fromFloat(float v)
+	{
+		v = std::clamp(v, min, max);
+		return Q::fromFloat(v / scale);
+	}
+
+	static float toFloat(quantized_type q)
+	{
+		return Q::toFloat(q) * scale;
+	}
+};
+
 } /* namespace ipa */
 
 } /* namespace libcamera */