1 //
2 // (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use.
3 //
4
5
6 #ifndef CHARLS_UTIL
7 #define CHARLS_UTIL
8
9 #include "publictypes.h"
10 #include <vector>
11 #include <system_error>
12 #include <memory>
13
14 // ReSharper disable once CppUnusedIncludeDirective
15 #include <cassert>
16
17 // Use an uppercase alias for assert to make it clear that it is a pre-processor macro.
18 #define ASSERT(t) assert(t)
19
20 //https://github.com/team-charls/charls/issues/38
21 #if __cplusplus == 201103L
22 template<typename T, typename... Args>
make_unique(Args &&...args)23 std::unique_ptr<T> make_unique(Args&&... args)
24 {
25 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
26 }
27 #endif
28
29 // Only use __forceinline for the Microsoft C++ compiler in release mode (verified scenario)
30 // Use the build-in optimizer for all other C++ compilers.
31 // Note: usage of FORCE_INLINE may be reduced in the future as the latest generation of C++ compilers
32 // can handle optimization by themselves.
33 #ifndef FORCE_INLINE
34 # ifdef _MSC_VER
35 # ifdef NDEBUG
36 # define FORCE_INLINE __forceinline
37 # else
38 # define FORCE_INLINE
39 # endif
40 # else
41 # define FORCE_INLINE
42 # endif
43 #endif
44
45 #ifdef _MSC_VER
46 #define WARNING_SUPPRESS(x) __pragma(warning(push)) __pragma(warning(disable : x))
47 #define WARNING_UNSUPPRESS() __pragma(warning(pop))
48 #else
49 #define WARNING_SUPPRESS(x)
50 #define WARNING_UNSUPPRESS()
51 #endif
52
53
54 constexpr size_t int32_t_bit_count = sizeof(int32_t) * 8;
55
56
push_back(std::vector<uint8_t> & values,uint16_t value)57 inline void push_back(std::vector<uint8_t>& values, uint16_t value)
58 {
59 values.push_back(uint8_t(value / 0x100));
60 values.push_back(uint8_t(value % 0x100));
61 }
62
63
log_2(int32_t n)64 inline int32_t log_2(int32_t n) noexcept
65 {
66 int32_t x = 0;
67 while (n > (static_cast<int32_t>(1) << x))
68 {
69 ++x;
70 }
71 return x;
72 }
73
74
Sign(int32_t n)75 inline int32_t Sign(int32_t n) noexcept
76 {
77 return (n >> (int32_t_bit_count - 1)) | 1;
78 }
79
80
BitWiseSign(int32_t i)81 inline int32_t BitWiseSign(int32_t i) noexcept
82 {
83 return i >> (int32_t_bit_count - 1);
84 }
85
86
87 template<typename T>
88 struct Triplet
89 {
TripletTriplet90 Triplet() noexcept :
91 v1(0),
92 v2(0),
93 v3(0)
94 {}
95
TripletTriplet96 Triplet(int32_t x1, int32_t x2, int32_t x3) noexcept :
97 v1(static_cast<T>(x1)),
98 v2(static_cast<T>(x2)),
99 v3(static_cast<T>(x3))
100 {}
101
102 union
103 {
104 T v1;
105 T R;
106 };
107 union
108 {
109 T v2;
110 T G;
111 };
112 union
113 {
114 T v3;
115 T B;
116 };
117 };
118
119
120 inline bool operator==(const Triplet<uint8_t>& lhs, const Triplet<uint8_t>& rhs) noexcept
121 {
122 return lhs.v1 == rhs.v1 && lhs.v2 == rhs.v2 && lhs.v3 == rhs.v3;
123 }
124
125
126 inline bool operator!=(const Triplet<uint8_t>& lhs, const Triplet<uint8_t>& rhs) noexcept
127 {
128 return !(lhs == rhs);
129 }
130
131
132 template<typename sample>
133 struct Quad : Triplet<sample>
134 {
QuadQuad135 Quad() :
136 v4(0)
137 {}
138
139 WARNING_SUPPRESS(26495) // false warning that v4 is unintialized
QuadQuad140 Quad(Triplet<sample> triplet, int32_t alpha) noexcept
141 :
142 Triplet<sample>(triplet),
143 A(static_cast<sample>(alpha))
144 {}
145 WARNING_UNSUPPRESS()
146
147 union
148 {
149 sample v4;
150 sample A;
151 };
152 };
153
154
155 template<int size>
156 struct FromBigEndian
157 {
158 };
159
160
161 template<>
162 struct FromBigEndian<4>
163 {
164 FORCE_INLINE static unsigned int Read(const uint8_t* pbyte) noexcept
165 {
166 return (pbyte[0] << 24u) + (pbyte[1] << 16u) + (pbyte[2] << 8u) + (pbyte[3] << 0u);
167 }
168 };
169
170
171 template<>
172 struct FromBigEndian<8>
173 {
174 FORCE_INLINE static uint64_t Read(const uint8_t* pbyte) noexcept
175 {
176 return (static_cast<uint64_t>(pbyte[0]) << 56u) + (static_cast<uint64_t>(pbyte[1]) << 48u) +
177 (static_cast<uint64_t>(pbyte[2]) << 40u) + (static_cast<uint64_t>(pbyte[3]) << 32u) +
178 (static_cast<uint64_t>(pbyte[4]) << 24u) + (static_cast<uint64_t>(pbyte[5]) << 16u) +
179 (static_cast<uint64_t>(pbyte[6]) << 8u) + (static_cast<uint64_t>(pbyte[7]) << 0u);
180 }
181 };
182
183
184 class charls_error : public std::system_error
185 {
186 public:
187 explicit charls_error(charls::ApiResult errorCode)
188 : system_error(static_cast<int>(errorCode), CharLSCategoryInstance())
189 {
190 }
191
192
193 charls_error(charls::ApiResult errorCode, const std::string& message)
194 : system_error(static_cast<int>(errorCode), CharLSCategoryInstance(), message)
195 {
196 }
197
198 private:
199 static const std::error_category& CharLSCategoryInstance() noexcept;
200 };
201
202
203 inline void SkipBytes(ByteStreamInfo& streamInfo, std::size_t count) noexcept
204 {
205 if (!streamInfo.rawData)
206 return;
207
208 streamInfo.rawData += count;
209 streamInfo.count -= count;
210 }
211
212
213 template<typename T>
214 std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
215 {
216 return stream << static_cast<typename std::underlying_type<T>::type>(e);
217 }
218
219 #endif
220