libcamera  v0.5.1
Supporting cameras in Linux since 2019
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 namespace libcamera {
14 
15 namespace ipa {
16 
17 #ifndef __DOXYGEN__
18 template<unsigned int I, unsigned int F, typename R, typename T,
19  std::enable_if_t<std::is_integral_v<R> &&
20  std::is_floating_point_v<T>> * = nullptr>
21 #else
22 template<unsigned int I, unsigned int F, typename R, typename T>
23 #endif
24 constexpr R floatingToFixedPoint(T number)
25 {
26  static_assert(sizeof(int) >= sizeof(R));
27  static_assert(I + F <= sizeof(R) * 8);
28 
29  /*
30  * The intermediate cast to int is needed on arm platforms to properly
31  * cast negative values. See
32  * https://embeddeduse.com/2013/08/25/casting-a-negative-float-to-an-unsigned-int/
33  */
34  R mask = (1 << (F + I)) - 1;
35  R frac = static_cast<R>(static_cast<int>(std::round(number * (1 << F)))) & mask;
36 
37  return frac;
38 }
39 
40 #ifndef __DOXYGEN__
41 template<unsigned int I, unsigned int F, typename R, typename T,
42  std::enable_if_t<std::is_floating_point_v<R> &&
43  std::is_integral_v<T>> * = nullptr>
44 #else
45 template<unsigned int I, unsigned int F, typename R, typename T>
46 #endif
47 constexpr R fixedToFloatingPoint(T number)
48 {
49  static_assert(sizeof(int) >= sizeof(T));
50  static_assert(I + F <= sizeof(T) * 8);
51 
52  /*
53  * Recreate the upper bits in case of a negative number by shifting the sign
54  * bit from the fixed point to the first bit of the unsigned and then right shifting
55  * by the same amount which keeps the sign bit in place.
56  * This can be optimized by the compiler quite well.
57  */
58  int remaining_bits = sizeof(int) * 8 - (I + F);
59  int t = static_cast<int>(static_cast<unsigned>(number) << remaining_bits) >> remaining_bits;
60  return static_cast<R>(t) / static_cast<R>(1 << F);
61 }
62 
63 } /* namespace ipa */
64 
65 } /* namespace libcamera */
Top-level libcamera namespace.
Definition: backtrace.h:17
constexpr R fixedToFloatingPoint(T number)
Convert a fixed-point number to a floating point representation.
Definition: fixedpoint.h:47
constexpr R floatingToFixedPoint(T number)
Convert a floating point number to a fixed-point representation.
Definition: fixedpoint.h:24