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