/src/libjxl/lib/jxl/base/common.h
Line | Count | Source |
1 | | // Copyright (c) the JPEG XL Project Authors. All rights reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style |
4 | | // license that can be found in the LICENSE file. |
5 | | |
6 | | #ifndef LIB_JXL_BASE_COMMON_H_ |
7 | | #define LIB_JXL_BASE_COMMON_H_ |
8 | | |
9 | | // Shared constants and helper functions. |
10 | | |
11 | | #include <array> |
12 | | #include <cstddef> |
13 | | #include <cstdint> |
14 | | #include <cstdio> |
15 | | #include <limits> |
16 | | #include <memory> |
17 | | #include <string> |
18 | | #include <type_traits> |
19 | | #include <vector> |
20 | | |
21 | | #include "lib/jxl/base/compiler_specific.h" |
22 | | |
23 | | namespace jxl { |
24 | | // Some enums and typedefs used by more than one header file. |
25 | | |
26 | | constexpr size_t kBitsPerByte = 8; // more clear than CHAR_BIT |
27 | | |
28 | 24.0k | constexpr inline size_t RoundUpBitsToByteMultiple(size_t bits) { |
29 | 24.0k | return (bits + 7) & ~static_cast<size_t>(7); |
30 | 24.0k | } |
31 | | |
32 | 13.8k | constexpr inline size_t RoundUpToBlockDim(size_t dim) { |
33 | 13.8k | return (dim + 7) & ~static_cast<size_t>(7); |
34 | 13.8k | } |
35 | | |
36 | | template <typename U, |
37 | | class = typename std::enable_if<std::is_unsigned<U>::value>::type> |
38 | 55.0M | static inline bool SafeAdd(const U a, const U b, U& sum) { |
39 | 55.0M | sum = a + b; |
40 | 55.0M | return sum >= a; // no need to check b - either sum >= both or < both. |
41 | 55.0M | } fields.cc:bool jxl::SafeAdd<unsigned long, void>(unsigned long, unsigned long, unsigned long&) Line | Count | Source | 38 | 177k | static inline bool SafeAdd(const U a, const U b, U& sum) { | 39 | 177k | sum = a + b; | 40 | 177k | return sum >= a; // no need to check b - either sum >= both or < both. | 41 | 177k | } |
memory_manager_internal.cc:bool jxl::SafeAdd<unsigned long, void>(unsigned long, unsigned long, unsigned long&) Line | Count | Source | 38 | 54.8M | static inline bool SafeAdd(const U a, const U b, U& sum) { | 39 | 54.8M | sum = a + b; | 40 | 54.8M | return sum >= a; // no need to check b - either sum >= both or < both. | 41 | 54.8M | } |
|
42 | | |
43 | | template <typename U, |
44 | | class = typename std::enable_if<std::is_unsigned<U>::value>::type> |
45 | 26.7M | static inline bool SafeMul(const U a, const U b, U& product) { |
46 | 26.7M | product = 0; |
47 | 26.7M | if (a == 0 || b == 0) return true; |
48 | 26.7M | if (b > (std::numeric_limits<U>::max() / a)) return false; |
49 | 26.7M | product = a * b; |
50 | 26.7M | return true; |
51 | 26.7M | } |
52 | | |
53 | | template <typename T1, typename T2> |
54 | 68.7M | constexpr inline T1 DivCeil(T1 a, T2 b) { |
55 | 68.7M | return (a + b - 1) / b; |
56 | 68.7M | } unsigned long jxl::DivCeil<unsigned long, unsigned long>(unsigned long, unsigned long) Line | Count | Source | 54 | 61.4M | constexpr inline T1 DivCeil(T1 a, T2 b) { | 55 | 61.4M | return (a + b - 1) / b; | 56 | 61.4M | } |
unsigned long jxl::DivCeil<unsigned long, int>(unsigned long, int) Line | Count | Source | 54 | 6.45M | constexpr inline T1 DivCeil(T1 a, T2 b) { | 55 | 6.45M | return (a + b - 1) / b; | 56 | 6.45M | } |
int jxl::DivCeil<int, int>(int, int) Line | Count | Source | 54 | 490k | constexpr inline T1 DivCeil(T1 a, T2 b) { | 55 | 490k | return (a + b - 1) / b; | 56 | 490k | } |
unsigned long jxl::DivCeil<unsigned long, long>(unsigned long, long) Line | Count | Source | 54 | 353k | constexpr inline T1 DivCeil(T1 a, T2 b) { | 55 | 353k | return (a + b - 1) / b; | 56 | 353k | } |
|
57 | | |
58 | | // Works for any `align`; if a power of two, compiler emits ADD+AND. |
59 | 52.8M | constexpr inline size_t RoundUpTo(size_t what, size_t align) { |
60 | 52.8M | return DivCeil(what, align) * align; |
61 | 52.8M | } |
62 | | |
63 | | constexpr double kPi = 3.14159265358979323846264338327950288; |
64 | | |
65 | | // Multiplier for conversion of log2(x) result to ln(x). |
66 | | // print(1.0 / math.log2(math.e)) |
67 | | constexpr float kInvLog2e = 0.6931471805599453; |
68 | | |
69 | | // Reasonable default for sRGB, matches common monitors. We map white to this |
70 | | // many nits (cd/m^2) by default. Butteraugli was tuned for 250 nits, which is |
71 | | // very close. |
72 | | // NB: This constant is not very "base", but it is shared between modules. |
73 | | static constexpr float kDefaultIntensityTarget = 255; |
74 | | |
75 | | template <typename T> |
76 | | constexpr T Pi(T multiplier) { |
77 | | return static_cast<T>(multiplier * kPi); |
78 | | } |
79 | | |
80 | | // Prior to C++14 (i.e. C++11): provide our own make_unique |
81 | | #if __cplusplus < 201402L |
82 | | template <typename T, typename... Args> |
83 | | std::unique_ptr<T> make_unique(Args&&... args) { |
84 | | return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); |
85 | | } |
86 | | #else |
87 | | using std::make_unique; |
88 | | #endif |
89 | | |
90 | | template <typename T> |
91 | | struct UninitializedAllocator : std::allocator<T> { |
92 | | static_assert(std::is_trivially_copyable<T>::value, |
93 | | "Uninitialized values have to be trivially destructible"); |
94 | | using value_type = T; |
95 | | |
96 | 12.5k | UninitializedAllocator() noexcept = default; |
97 | | UninitializedAllocator(const UninitializedAllocator& other) noexcept = |
98 | | default; |
99 | | |
100 | | template <typename U> |
101 | | explicit UninitializedAllocator( |
102 | | const UninitializedAllocator<U>& other) noexcept {} |
103 | | |
104 | | template <typename U> |
105 | | struct rebind { |
106 | | using other = UninitializedAllocator<U>; |
107 | | }; |
108 | | |
109 | | template <typename U, typename... Args> |
110 | 332k | void construct(U* place, Args&&... args) {} |
111 | | |
112 | | template <typename U> |
113 | 332k | void destroy(U* place) {} |
114 | | }; |
115 | | |
116 | | template <typename T> |
117 | | using uninitialized_vector = std::vector<T, UninitializedAllocator<T>>; |
118 | | |
119 | | template <typename T> |
120 | 12.5k | uninitialized_vector<T> make_uninitialized_vector(size_t n) { |
121 | 12.5k | return uninitialized_vector<T>(n, UninitializedAllocator<T>()); |
122 | 12.5k | } |
123 | | |
124 | | typedef std::array<float, 3> Color; |
125 | | |
126 | | // Backported std::experimental::to_array |
127 | | |
128 | | template <typename T> |
129 | | using remove_cv_t = typename std::remove_cv<T>::type; |
130 | | |
131 | | template <size_t... I> |
132 | | struct index_sequence {}; |
133 | | |
134 | | template <size_t N, size_t... I> |
135 | | struct make_index_sequence : make_index_sequence<N - 1, N - 1, I...> {}; |
136 | | |
137 | | template <size_t... I> |
138 | | struct make_index_sequence<0, I...> : index_sequence<I...> {}; |
139 | | |
140 | | namespace detail { |
141 | | |
142 | | template <typename T, size_t N, size_t... I> |
143 | | constexpr auto to_array(T (&&arr)[N], index_sequence<I...> _) |
144 | 0 | -> std::array<remove_cv_t<T>, N> { |
145 | 0 | return {{std::move(arr[I])...}}; |
146 | 0 | } |
147 | | |
148 | | } // namespace detail |
149 | | |
150 | | template <typename T, size_t N> |
151 | 0 | constexpr auto to_array(T (&&arr)[N]) -> std::array<remove_cv_t<T>, N> { |
152 | 0 | return detail::to_array(std::move(arr), make_index_sequence<N>()); |
153 | 0 | } |
154 | | |
155 | | template <typename T> |
156 | 499M | JXL_INLINE T Clamp1(T val, T low, T hi) { |
157 | 499M | return val < low ? low : val > hi ? hi : val; |
158 | 499M | } float jxl::Clamp1<float>(float, float, float) Line | Count | Source | 156 | 155M | JXL_INLINE T Clamp1(T val, T low, T hi) { | 157 | 155M | return val < low ? low : val > hi ? hi : val; | 158 | 155M | } |
double jxl::Clamp1<double>(double, double, double) Line | Count | Source | 156 | 140k | JXL_INLINE T Clamp1(T val, T low, T hi) { | 157 | 140k | return val < low ? low : val > hi ? hi : val; | 158 | 140k | } |
int jxl::Clamp1<int>(int, int, int) Line | Count | Source | 156 | 343M | JXL_INLINE T Clamp1(T val, T low, T hi) { | 157 | 343M | return val < low ? low : val > hi ? hi : val; | 158 | 343M | } |
Unexecuted instantiation: unsigned char jxl::Clamp1<unsigned char>(unsigned char, unsigned char, unsigned char) Unexecuted instantiation: long jxl::Clamp1<long>(long, long, long) |
159 | | |
160 | | // conversion from integer to string. |
161 | | template <typename T> |
162 | 15.5k | std::string ToString(T n) { |
163 | 15.5k | char data[32] = {}; |
164 | 15.5k | if (std::is_floating_point<T>::value) { |
165 | | // float |
166 | 15.5k | snprintf(data, sizeof(data), "%g", static_cast<double>(n)); |
167 | 15.5k | } else if (std::is_unsigned<T>::value) { |
168 | | // unsigned |
169 | 0 | snprintf(data, sizeof(data), "%llu", static_cast<unsigned long long>(n)); |
170 | 0 | } else { |
171 | | // signed |
172 | 0 | snprintf(data, sizeof(data), "%lld", static_cast<long long>(n)); |
173 | 0 | } |
174 | 15.5k | return data; |
175 | 15.5k | } std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > jxl::ToString<double>(double) Line | Count | Source | 162 | 15.5k | std::string ToString(T n) { | 163 | 15.5k | char data[32] = {}; | 164 | 15.5k | if (std::is_floating_point<T>::value) { | 165 | | // float | 166 | 15.5k | snprintf(data, sizeof(data), "%g", static_cast<double>(n)); | 167 | 15.5k | } else if (std::is_unsigned<T>::value) { | 168 | | // unsigned | 169 | 0 | snprintf(data, sizeof(data), "%llu", static_cast<unsigned long long>(n)); | 170 | 0 | } else { | 171 | | // signed | 172 | 0 | snprintf(data, sizeof(data), "%lld", static_cast<long long>(n)); | 173 | 0 | } | 174 | 15.5k | return data; | 175 | 15.5k | } |
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > jxl::ToString<int>(int) |
176 | | |
177 | | #define JXL_JOIN(x, y) JXL_DO_JOIN(x, y) |
178 | | #define JXL_DO_JOIN(x, y) x##y |
179 | | |
180 | | } // namespace jxl |
181 | | |
182 | | #endif // LIB_JXL_BASE_COMMON_H_ |