ipa: libipa: Provide a Quantized data type support

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: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Kieran Bingham
2026-02-19 15:05:02 +00:00
parent da12b1854f
commit be64005a8e
3 changed files with 212 additions and 0 deletions
+2
View File
@@ -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',
])
+135
View File
@@ -0,0 +1,135 @@
/* 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::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 */
+75
View File
@@ -0,0 +1,75 @@
/* 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 { return value_; }
QuantizedType quantized() const { return quantized_; }
bool operator==(const Quantized &other) const
{
return quantized_ == other.quantized_;
}
bool operator!=(const Quantized &other) const
{
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 */