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 #ifdef NDEBUG
15 # ifndef ASSERT
16 # define ASSERT(t) { }
17 # endif
18 #else
19 #include <cassert>
20 #define ASSERT(t) assert(t)
21 #endif
22
23 #if defined(_WIN32)
24 #ifdef _MSC_VER
25 #pragma warning (disable:4512) // assignment operator could not be generated [VS2013]
26 #endif
27 #endif
28
29 #undef NEAR
30
31 #ifndef inlinehint
32 # ifdef _MSC_VER
33 # ifdef NDEBUG
34 # define inlinehint __forceinline
35 # else
36 # define inlinehint inline
37 # endif
38 # else
39 # define inlinehint inline
40 # endif
41 #endif
42
43
44 #ifndef MAX
45 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
46 #endif
47
48 #ifndef MIN
49 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
50 #endif
51
52 enum constants
53 {
54 INT32_BITCOUNT = sizeof(int32_t) * 8
55 };
56
57
push_back(std::vector<uint8_t> & values,uint16_t value)58 inline void push_back(std::vector<uint8_t>& values, uint16_t value)
59 {
60 values.push_back(uint8_t(value / 0x100));
61 values.push_back(uint8_t(value % 0x100));
62 }
63
64
log_2(int32_t n)65 inline int32_t log_2(int32_t n)
66 {
67 int32_t x = 0;
68 while (n > (int32_t(1) << x))
69 {
70 ++x;
71 }
72 return x;
73 }
74
75
Sign(int32_t n)76 inline int32_t Sign(int32_t n)
77 {
78 return (n >> (INT32_BITCOUNT - 1)) | 1;
79 }
80
81
BitWiseSign(int32_t i)82 inline int32_t BitWiseSign(int32_t i)
83 {
84 return i >> (INT32_BITCOUNT - 1);
85 }
86
87
88 struct Size
89 {
SizeSize90 Size(int32_t width, int32_t height) :
91 cx(width),
92 cy(height)
93 {}
94 int32_t cx;
95 int32_t cy;
96 };
97
98
99 template<typename SAMPLE>
100 struct Triplet
101 {
TripletTriplet102 Triplet() :
103 v1(0),
104 v2(0),
105 v3(0)
106 {}
107
TripletTriplet108 Triplet(int32_t x1, int32_t x2, int32_t x3) :
109 v1(static_cast<SAMPLE>(x1)),
110 v2(static_cast<SAMPLE>(x2)),
111 v3(static_cast<SAMPLE>(x3))
112 {}
113
114 union
115 {
116 SAMPLE v1;
117 SAMPLE R;
118 };
119 union
120 {
121 SAMPLE v2;
122 SAMPLE G;
123 };
124 union
125 {
126 SAMPLE v3;
127 SAMPLE B;
128 };
129 };
130
131
132 inline bool operator==(const Triplet<uint8_t>& lhs, const Triplet<uint8_t>& rhs)
133 {
134 return lhs.v1 == rhs.v1 && lhs.v2 == rhs.v2 && lhs.v3 == rhs.v3;
135 }
136
137
138 inline bool operator!=(const Triplet<uint8_t>& lhs, const Triplet<uint8_t>& rhs)
139 {
140 return !(lhs == rhs);
141 }
142
143
144 template<typename sample>
145 struct Quad : Triplet<sample>
146 {
QuadQuad147 Quad() :
148 v4(0)
149 {}
150
QuadQuad151 Quad(Triplet<sample> triplet, int32_t alpha) : Triplet<sample>(triplet), A(static_cast<sample>(alpha))
152 {}
153
154 union
155 {
156 sample v4;
157 sample A;
158 };
159 };
160
161
162 template<int size>
163 struct FromBigEndian
164 {
165 };
166
167
168 template<>
169 struct FromBigEndian<4>
170 {
171 inlinehint static unsigned int Read(uint8_t* pbyte)
172 {
173 return (pbyte[0] << 24) + (pbyte[1] << 16) + (pbyte[2] << 8) + (pbyte[3] << 0);
174 }
175 };
176
177
178 template<>
179 struct FromBigEndian<8>
180 {
181 inlinehint static uint64_t Read(uint8_t* pbyte)
182 {
183 return (uint64_t(pbyte[0]) << 56) + (uint64_t(pbyte[1]) << 48) + (uint64_t(pbyte[2]) << 40) + (uint64_t(pbyte[3]) << 32) +
184 (uint64_t(pbyte[4]) << 24) + (uint64_t(pbyte[5]) << 16) + (uint64_t(pbyte[6]) << 8) + (uint64_t(pbyte[7]) << 0);
185 }
186 };
187
188
189 const std::error_category& CharLSCategoryInstance();
190
191
192 inline ByteStreamInfo FromStream(std::basic_streambuf<char>* stream)
193 {
194 ByteStreamInfo info = ByteStreamInfo();
195 info.rawStream = stream;
196 return info;
197 }
198
199
200 inline void SkipBytes(ByteStreamInfo& streamInfo, std::size_t count)
201 {
202 if (!streamInfo.rawData)
203 return;
204
205 streamInfo.rawData += count;
206 streamInfo.count -= count;
207 }
208
209
210 template<typename T>
211 std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
212 {
213 return stream << static_cast<typename std::underlying_type<T>::type>(e);
214 }
215
216
217 inline std::system_error CreateSystemError(charls::ApiResult errorCode, const std::string& message)
218 {
219 return std::system_error(static_cast<int>(errorCode), CharLSCategoryInstance(), message);
220 }
221
222 #if __cplusplus == 201103L
223 template<typename T, typename... Args>
224 std::unique_ptr<T> make_unique(Args&&... args)
225 {
226 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
227 }
228 #endif
229 #endif
230