@@ -17,6 +17,7 @@ libipa_headers = files([
'lux.h',
'module.h',
'pwl.h',
+ 'quantized.h',
])
libipa_sources = files([
@@ -36,6 +37,7 @@ libipa_sources = files([
'lux.cpp',
'module.cpp',
'pwl.cpp',
+ 'quantized.cpp',
])
libipa_includes = include_directories('..')
new file mode 100644
@@ -0,0 +1,134 @@
+/* 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
+ */
+
+} /* namespace ipa */
+
+} /* namespace libcamera */
new file mode 100644
@@ -0,0 +1,78 @@
+/* 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 <iomanip>
+#include <sstream>
+#include <stdint.h>
+#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::ostringstream oss;
+
+ oss << "[" << utils::hex(quantized_)
+ << ":" << value_ << "]";
+
+ return oss.str();
+ }
+
+ bool operator==(const Quantized &other) const noexcept
+ {
+ return quantized_ == other.quantized_;
+ }
+
+ bool operator!=(const Quantized &other) const noexcept
+ {
+ return !(*this == other);
+ }
+
+private:
+ QuantizedType quantized_;
+ float value_;
+};
+
+} /* namespace ipa */
+
+} /* namespace libcamera */
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. 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 src/ipa/libipa/meson.build | 2 + src/ipa/libipa/quantized.cpp | 134 +++++++++++++++++++++++++++++++++++ src/ipa/libipa/quantized.h | 78 ++++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 src/ipa/libipa/quantized.cpp create mode 100644 src/ipa/libipa/quantized.h