[v5,01/16] ipa: libipa: Provide a Quantized data type support
diff mbox series

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

Commit Message

Kieran Bingham Jan. 14, 2026, 5:39 p.m. UTC
Frequently when handling data in IPA components we must convert and
store user interface values which may be floating point values, and
perform a specific operation or conversion to quantize this to a
hardware value.

This value may be to a fixed point type, or more custom code mappings,
but in either case it is important to contain both the required hardware
value, with its effective quantized value.

Provide a new storage type 'Quantized' which can be defined based on a
set of type specific Traits to perform the conversions between floats
and the underlying hardware type.

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

---
v3:
 - adapt string format to [0xff:1.99] style instead of Q:0xff V:1.99
 - Clean up comments and copyright
 - Remove private initialisers - already handled by constructors
 - Change quantized_type to QuantizedType

v5:
- introduce operator<<(std::ostream &out, const Quantized<Traits> &q)
- Remove unused iomanip and stdint.h from includes

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/ipa/libipa/meson.build   |   2 +
 src/ipa/libipa/quantized.cpp | 142 +++++++++++++++++++++++++++++++++++
 src/ipa/libipa/quantized.h   |  83 ++++++++++++++++++++
 3 files changed, 227 insertions(+)
 create mode 100644 src/ipa/libipa/quantized.cpp
 create mode 100644 src/ipa/libipa/quantized.h

Patch
diff mbox series

diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build
index 7202df869c2f..963c5ee73063 100644
--- a/src/ipa/libipa/meson.build
+++ b/src/ipa/libipa/meson.build
@@ -17,6 +17,7 @@  libipa_headers = files([
     'lux.h',
     'module.h',
     'pwl.h',
+    'quantized.h',
     'v4l2_params.h',
 ])
 
@@ -37,6 +38,7 @@  libipa_sources = files([
     'lux.cpp',
     'module.cpp',
     'pwl.cpp',
+    'quantized.cpp',
     'v4l2_params.cpp',
 ])
 
diff --git a/src/ipa/libipa/quantized.cpp b/src/ipa/libipa/quantized.cpp
new file mode 100644
index 000000000000..115739e71654
--- /dev/null
+++ b/src/ipa/libipa/quantized.cpp
@@ -0,0 +1,142 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2025, Ideas On Board Oy
+ *
+ * Helper class to manage conversions between floating point types and quantized
+ * storage and representation of those values.
+ */
+
+#include "quantized.h"
+
+/**
+ * \file quantized.h
+ * \brief Quantized storage and Quantizer representations
+ */
+
+namespace libcamera {
+
+namespace ipa {
+
+/**
+ * \struct libcamera::ipa::Quantized
+ * \brief Wrapper that stores a value in both quantized and floating-point form
+ * \tparam Traits The traits class defining the quantization behaviour
+ *
+ * The Quantized struct template provides a thin wrapper around a quantized
+ * representation of a floating-point value. It uses a traits type \a Traits
+ * to define the conversion policy between the floating-point domain and the
+ * quantized integer domain.
+ *
+ * Each Quantized instance maintains two synchronized members:
+ *  - the quantized integer representation, and
+ *  - the corresponding floating-point value.
+ *
+ * The traits type defines:
+ *  - the integer storage type used for quantization,
+ *  - the static conversion functions \c fromFloat() and \c toFloat(), and
+ *  - optional metadata such as value ranges.
+ *
+ * Quantized provides convenient constructors and assignment operators from
+ * either representation, as well as comparison and string formatting utilities.
+ */
+
+/**
+ * \typedef Quantized::TraitsType
+ * \brief The traits policy type defining the quantization behaviour
+ *
+ * Exposes the associated traits type used by this Quantized instance.
+ * This allows external code to refer to constants or metadata defined in
+ * the traits, such as \c TraitsType::min or \c TraitsType::max.
+ */
+
+/**
+ * \typedef Quantized::QuantizedType
+ * \brief The integer type used for the quantized representation
+ *
+ * This alias corresponds to \c TraitsType::QuantizedType, as defined by
+ * the traits class.
+ */
+
+/**
+ * \fn Quantized::Quantized(float x)
+ * \brief Construct a Quantized value from a floating-point number
+ * \param[in] x The floating-point value to be quantized
+ *
+ * Converts the floating-point input \a x to its quantized integer
+ * representation using the associated traits policy, and initializes
+ * both the quantized and floating-point members.
+ */
+
+/**
+ * \fn Quantized::Quantized(QuantizedType x)
+ * \brief Construct a Quantized value from an existing quantized integer
+ * \param[in] x The quantized integer value
+ *
+ * Converts the quantized integer \a x to its corresponding floating-point
+ * value using the traits policy, and initializes both internal members.
+ */
+
+/**
+ * \fn Quantized::operator=(float x)
+ * \brief Assign a floating-point value to the Quantized object
+ * \param[in] x The floating-point value to assign
+ * \return A reference to the updated Quantized object
+ *
+ * Converts the floating-point value \a x to its quantized integer
+ * representation using the traits policy and updates both members.
+ */
+
+/**
+ * \fn Quantized::operator=(QuantizedType x)
+ * \brief Assign a quantized integer value to the Quantized object
+ * \param[in] x The quantized integer value to assign
+ * \return A reference to the updated Quantized object
+ *
+ * Converts the quantized integer \a x to its corresponding floating-point
+ * value using the traits policy and updates both members.
+ */
+
+/**
+ * \fn Quantized::value() const noexcept
+ * \brief Retrieve the floating-point representation
+ * \return The floating-point value corresponding to the quantized value
+ */
+
+/**
+ * \fn Quantized::quantized() const noexcept
+ * \brief Retrieve the quantized integer representation
+ * \return The quantized integer value
+ */
+
+/**
+ * \fn Quantized::toString() const
+ * \brief Format the quantized and floating-point values as a string
+ * \return A string containing the hexadecimal quantized value and its
+ *         floating-point equivalent.
+ */
+
+/**
+ * \fn Quantized::operator==(const Quantized &other) const noexcept
+ * \brief Compare two Quantized objects for equality
+ * \param[in] other The other Quantized object to compare against
+ * \return True if both objects have the same quantized integer value
+ */
+
+/**
+ * \fn Quantized::operator!=(const Quantized &other) const noexcept
+ * \brief Compare two Quantized objects for inequality
+ * \param[in] other The other Quantized object to compare against
+ * \return True if the quantized integer values differ
+ */
+
+/**
+ * \fn std::ostream &Quantized::operator<<(std::ostream &out, const Quantized<Traits> &q)
+ * \brief Insert a text representation of a Quantized into an output stream
+ * \param[in] out The output stream
+ * \param[in] q The Quantized
+ * \return The output stream \a out
+ */
+
+} /* namespace ipa */
+
+} /* namespace libcamera */
diff --git a/src/ipa/libipa/quantized.h b/src/ipa/libipa/quantized.h
new file mode 100644
index 000000000000..045ccb755a85
--- /dev/null
+++ b/src/ipa/libipa/quantized.h
@@ -0,0 +1,83 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2025, Ideas On Board Oy
+ *
+ * Helper class to manage conversions between floating point types and quantized
+ * storage and representation of those values.
+ */
+
+#pragma once
+
+#include <sstream>
+#include <type_traits>
+
+#include <libcamera/base/utils.h>
+
+namespace libcamera {
+
+namespace ipa {
+
+template<typename Traits>
+struct Quantized {
+	using TraitsType = Traits;
+	using QuantizedType = typename Traits::QuantizedType;
+	static_assert(std::is_arithmetic_v<QuantizedType>,
+		      "Quantized: QuantizedType must be arithmetic");
+
+	Quantized()
+		: Quantized(0.0f) {}
+	Quantized(float x) { *this = x; }
+	Quantized(QuantizedType x) { *this = x; }
+
+	Quantized &operator=(float x)
+	{
+		quantized_ = Traits::fromFloat(x);
+		value_ = Traits::toFloat(quantized_);
+		return *this;
+	}
+
+	Quantized &operator=(QuantizedType x)
+	{
+		value_ = Traits::toFloat(x);
+		quantized_ = x;
+		return *this;
+	}
+
+	float value() const noexcept { return value_; }
+	QuantizedType quantized() const noexcept { return quantized_; }
+
+	std::string toString() const
+	{
+		std::stringstream ss;
+		ss << *this;
+
+		return ss.str();
+	}
+
+	bool operator==(const Quantized &other) const noexcept
+	{
+		return quantized_ == other.quantized_;
+	}
+
+	bool operator!=(const Quantized &other) const noexcept
+	{
+		return !(*this == other);
+	}
+
+	friend std::ostream &operator<<(std::ostream &out,
+					const Quantized<Traits> &q)
+	{
+		out << "[" << utils::hex(q.quantized())
+		    << ":" << q.value() << "]";
+
+		return out;
+	}
+
+private:
+	QuantizedType quantized_;
+	float value_;
+};
+
+} /* namespace ipa */
+
+} /* namespace libcamera */