libcamera: src/ipa/libipa/fixedpoint.h Source File

libcamera v0.7.1 Supporting cameras in Linux since 2019

Loading...
Searching...
No Matches
fixedpoint.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2024, Paul Elder <paul.elder@ideasonboard.com>
4 *
5 * Fixed / floating point conversions
6 */
7
8#pragma once
9
10#include <cmath>
11#include <type_traits>
12
13#include "quantized.h"
14
15namespace libcamera {
16
17namespace ipa {
18
19template<unsigned int I, unsigned int F, typename T>
20 struct FixedPointQTraits {
21private:
22 static_assert(std::is_integral_v<T>, "FixedPointQTraits: T must be integral");
23 using UT = std::make_unsigned_t<T>;
24
25 static constexpr unsigned int bits = I + F;
26 static_assert(bits <= sizeof(UT) * 8, "FixedPointQTraits: too many bits for type UT");
27
28 /*
29 * If fixed point storage is required with more than 24 bits, consider
30 * updating this implementation to use double-precision floating point.
31 */
32 static_assert(bits <= 24, "Floating point precision may be insufficient for more than 24 bits");
33
34 static constexpr UT bitMask = bits < sizeof(UT) * 8
35 ? (UT{ 1 } << bits) - 1
36 : ~UT{ 0 };
37
38public:
39 using QuantizedType = UT;
40
41 static constexpr UT qMin = std::is_signed_v<T>
42 ? -(UT{ 1 } << (bits - 1))
43 : 0;
44
45 static constexpr UT qMax = std::is_signed_v<T>
46 ? (UT{ 1 } << (bits - 1)) - 1
47 : bitMask;
48
49 static constexpr float toFloat(QuantizedType q)
50 {
51 if constexpr (std::is_unsigned_v<T>)
52 return static_cast<float>(q) / static_cast<float>(UT{ 1 } << F);
53
54 /*
55 * Recreate the upper bits in case of a negative number by
56 * shifting the sign bit from the fixed point to the first bit
57 * of the unsigned and then right shifting by the same amount
58 * which keeps the sign bit in place. This can be optimized by
59 * the compiler quite well.
60 */
61 unsigned int remaining_bits = sizeof(UT) * 8 - (I + F);
62 T t = static_cast<T>(static_cast<UT>(q) << remaining_bits) >> remaining_bits;
63 return static_cast<float>(t) / static_cast<float>(UT{ 1 } << F);
64 }
65
66 static constexpr float min = toFloat(qMin);
67 static constexpr float max = toFloat(qMax);
68
69 static_assert(min < max, "FixedPointQTraits: Minimum must be less than maximum");
70
71 /* Conversion functions required by Quantized<Traits> */
72 static QuantizedType fromFloat(float v)
73 {
74 v = std::clamp(v, min, max);
75
76 /*
77 * The intermediate cast to int is needed on arm platforms to
78 * properly cast negative values. See
79 * https://embeddeduse.com/2013/08/25/casting-a-negative-float-to-an-unsigned-int/
80 */
81 return static_cast<UT>(static_cast<T>(std::round(v * (1 << F)))) & bitMask;
82 }
83};
84
85namespace details {
86
87template<unsigned int Bits>
88constexpr auto qtype()
89{
90 static_assert(Bits <= 32,
91 "Unsupported number of bits for quantized type");
92
93 if constexpr (Bits <= 8)
94 return int8_t();
95 else if constexpr (Bits <= 16)
96 return int16_t();
97 else if constexpr (Bits <= 32)
98 return int32_t();
99}
100
101} /* namespace details */
102
103template<unsigned int I, unsigned int F>
104 using Q = Quantized<FixedPointQTraits<I, F, decltype(details::qtype<I + F>())>>;
105
106template<unsigned int I, unsigned int F>
107 using UQ = Quantized<FixedPointQTraits<I, F, std::make_unsigned_t<decltype(details::qtype<I + F>())>>>;
108
109} /* namespace ipa */
110
111} /* namespace libcamera */
libcamera::ipa
The IPA (Image Processing Algorithm) namespace.
Definition af.cpp:58
libcamera::ipa::UQ
Quantized< FixedPointQTraits< I, F, std::make_unsigned_t< decltype(details::qtype< I+F >())> > > UQ
Define an unsigned fixed-point quantized type with automatic storage width.
Definition fixedpoint.h:107
libcamera::ipa::Q
Quantized< FixedPointQTraits< I, F, decltype(details::qtype< I+F >())> > Q
Define a signed fixed-point quantized type with automatic storage width.
Definition fixedpoint.h:104
libcamera
Top-level libcamera namespace.
Definition backtrace.h:17
quantized.h
Quantized storage and Quantizer representations.
libcamera::ipa::FixedPointQTraits
Traits type implementing fixed-point quantization conversions.
Definition fixedpoint.h:20
libcamera::ipa::FixedPointQTraits::fromFloat
static QuantizedType fromFloat(float v)
Convert a floating-point value to a fixed-point integer.
Definition fixedpoint.h:72
libcamera::ipa::FixedPointQTraits::QuantizedType
UT QuantizedType
The integral storage type used for the fixed-point representation.
Definition fixedpoint.h:39
libcamera::ipa::FixedPointQTraits::qMin
static constexpr UT qMin
Minimum representable quantized integer value.
Definition fixedpoint.h:41
libcamera::ipa::FixedPointQTraits::max
static constexpr float max
Maximum representable floating-point value corresponding to qMax.
Definition fixedpoint.h:67
libcamera::ipa::FixedPointQTraits::min
static constexpr float min
Minimum representable floating-point value corresponding to qMin.
Definition fixedpoint.h:66
libcamera::ipa::FixedPointQTraits::qMax
static constexpr UT qMax
Maximum representable quantized integer value.
Definition fixedpoint.h:45
libcamera::ipa::FixedPointQTraits::toFloat
static constexpr float toFloat(QuantizedType q)
Convert a fixed-point integer to a floating-point value.
Definition fixedpoint.h:49
libcamera::ipa::Quantized
Wrapper that stores a value in both quantized and floating-point form.
Definition quantized.h:21