Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/imgproc/src/fixedpoint.inl.hpp
16354 views
1
// This file is part of OpenCV project.
2
// It is subject to the license terms in the LICENSE file found in the top-level directory
3
// of this distribution and at http://opencv.org/license.html.
4
//
5
// Copyright (C) 2017, Intel Corporation, all rights reserved.
6
// Third party copyrights are property of their respective owners.
7
8
9
#ifndef _CV_FIXEDPOINT_HPP_
10
#define _CV_FIXEDPOINT_HPP_
11
12
#include "opencv2/core/softfloat.hpp"
13
14
#ifndef CV_ALWAYS_INLINE
15
#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
16
#define CV_ALWAYS_INLINE inline __attribute__((always_inline))
17
#elif defined(_MSC_VER)
18
#define CV_ALWAYS_INLINE __forceinline
19
#else
20
#define CV_ALWAYS_INLINE inline
21
#endif
22
#endif
23
24
namespace
25
{
26
27
class fixedpoint64
28
{
29
private:
30
static const int fixedShift = 32;
31
32
int64_t val;
33
fixedpoint64(int64_t _val) : val(_val) {}
34
static CV_ALWAYS_INLINE uint64_t fixedround(const uint64_t& _val) { return (_val + ((1LL << fixedShift) >> 1)); }
35
public:
36
typedef fixedpoint64 WT;
37
CV_ALWAYS_INLINE fixedpoint64() { val = 0; }
38
CV_ALWAYS_INLINE fixedpoint64(const int8_t& _val) { val = ((int64_t)_val) << fixedShift; }
39
CV_ALWAYS_INLINE fixedpoint64(const uint8_t& _val) { val = ((int64_t)_val) << fixedShift; }
40
CV_ALWAYS_INLINE fixedpoint64(const int16_t& _val) { val = ((int64_t)_val) << fixedShift; }
41
CV_ALWAYS_INLINE fixedpoint64(const uint16_t& _val) { val = ((int64_t)_val) << fixedShift; }
42
CV_ALWAYS_INLINE fixedpoint64(const int32_t& _val) { val = ((int64_t)_val) << fixedShift; }
43
CV_ALWAYS_INLINE fixedpoint64(const cv::softdouble& _val) { val = cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); }
44
CV_ALWAYS_INLINE fixedpoint64& operator = (const int8_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
45
CV_ALWAYS_INLINE fixedpoint64& operator = (const uint8_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
46
CV_ALWAYS_INLINE fixedpoint64& operator = (const int16_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
47
CV_ALWAYS_INLINE fixedpoint64& operator = (const uint16_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
48
CV_ALWAYS_INLINE fixedpoint64& operator = (const int32_t& _val) { val = ((int64_t)_val) << fixedShift; return *this; }
49
CV_ALWAYS_INLINE fixedpoint64& operator = (const cv::softdouble& _val) { val = cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); return *this; }
50
CV_ALWAYS_INLINE fixedpoint64& operator = (const fixedpoint64& _val) { val = _val.val; return *this; }
51
CV_ALWAYS_INLINE fixedpoint64 operator * (const int8_t& val2) const { return operator *(fixedpoint64(val2)); }
52
CV_ALWAYS_INLINE fixedpoint64 operator * (const uint8_t& val2) const { return operator *(fixedpoint64(val2)); }
53
CV_ALWAYS_INLINE fixedpoint64 operator * (const int16_t& val2) const { return operator *(fixedpoint64(val2)); }
54
CV_ALWAYS_INLINE fixedpoint64 operator * (const uint16_t& val2) const { return operator *(fixedpoint64(val2)); }
55
CV_ALWAYS_INLINE fixedpoint64 operator * (const int32_t& val2) const { return operator *(fixedpoint64(val2)); }
56
CV_ALWAYS_INLINE fixedpoint64 operator * (const fixedpoint64& val2) const
57
{
58
bool sign_val = val < 0;
59
bool sign_mul = val2.val < 0;
60
uint64_t uval = sign_val ? (uint64_t)(-val) : (uint64_t)val;
61
uint64_t umul = sign_mul ? (uint64_t)(-val2.val) : (uint64_t)val2.val;
62
bool ressign = sign_val ^ sign_mul;
63
64
uint64_t sh0 = fixedround((uval & 0xFFFFFFFF) * (umul & 0xFFFFFFFF));
65
uint64_t sh1_0 = (uval >> 32) * (umul & 0xFFFFFFFF);
66
uint64_t sh1_1 = (uval & 0xFFFFFFFF) * (umul >> 32);
67
uint64_t sh2 = (uval >> 32) * (umul >> 32);
68
uint64_t val0_l = (sh1_0 & 0xFFFFFFFF) + (sh1_1 & 0xFFFFFFFF) + (sh0 >> 32);
69
uint64_t val0_h = (sh2 & 0xFFFFFFFF) + (sh1_0 >> 32) + (sh1_1 >> 32) + (val0_l >> 32);
70
val0_l &= 0xFFFFFFFF;
71
72
if (sh2 > CV_BIG_INT(0x7FFFFFFF) || val0_h > CV_BIG_INT(0x7FFFFFFF))
73
return (int64_t)(ressign ? CV_BIG_UINT(0x8000000000000000) : CV_BIG_INT(0x7FFFFFFFFFFFFFFF));
74
75
if (ressign)
76
{
77
return -(int64_t)(val0_h << 32 | val0_l);
78
}
79
return (int64_t)(val0_h << 32 | val0_l);
80
}
81
CV_ALWAYS_INLINE fixedpoint64 operator + (const fixedpoint64& val2) const
82
{
83
int64_t res = val + val2.val;
84
return (int64_t)(((val ^ res) & (val2.val ^ res)) < 0 ? ~(res & CV_BIG_UINT(0x8000000000000000)) : res);
85
}
86
CV_ALWAYS_INLINE fixedpoint64 operator - (const fixedpoint64& val2) const
87
{
88
int64_t res = val - val2.val;
89
return (int64_t)(((val ^ val2.val) & (val ^ res)) < 0 ? ~(res & CV_BIG_UINT(0x8000000000000000)) : res);
90
}
91
CV_ALWAYS_INLINE fixedpoint64 operator >> (int n) const { return fixedpoint64(val >> n); }
92
CV_ALWAYS_INLINE fixedpoint64 operator << (int n) const { return fixedpoint64(val << n); }
93
CV_ALWAYS_INLINE bool operator == (const fixedpoint64& val2) const { return val == val2.val; }
94
template <typename ET>
95
CV_ALWAYS_INLINE ET saturate_cast() const { return cv::saturate_cast<ET>((int64_t)fixedround((uint64_t)val) >> fixedShift); }
96
CV_ALWAYS_INLINE operator double() const { return (double)val / (1LL << fixedShift); }
97
CV_ALWAYS_INLINE operator float() const { return (float)val / (1LL << fixedShift); }
98
CV_ALWAYS_INLINE operator uint8_t() const { return saturate_cast<uint8_t>(); }
99
CV_ALWAYS_INLINE operator int8_t() const { return saturate_cast<int8_t>(); }
100
CV_ALWAYS_INLINE operator uint16_t() const { return saturate_cast<uint16_t>(); }
101
CV_ALWAYS_INLINE operator int16_t() const { return saturate_cast<int16_t>(); }
102
CV_ALWAYS_INLINE operator int32_t() const { return saturate_cast<int32_t>(); }
103
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
104
static CV_ALWAYS_INLINE fixedpoint64 zero() { return fixedpoint64(); }
105
static CV_ALWAYS_INLINE fixedpoint64 one() { return fixedpoint64((int64_t)(1LL << fixedShift)); }
106
friend class fixedpoint32;
107
};
108
109
class ufixedpoint64
110
{
111
private:
112
static const int fixedShift = 32;
113
114
uint64_t val;
115
ufixedpoint64(uint64_t _val) : val(_val) {}
116
static CV_ALWAYS_INLINE uint64_t fixedround(const uint64_t& _val) { return (_val + ((1LL << fixedShift) >> 1)); }
117
public:
118
typedef ufixedpoint64 WT;
119
CV_ALWAYS_INLINE ufixedpoint64() { val = 0; }
120
CV_ALWAYS_INLINE ufixedpoint64(const uint8_t& _val) { val = ((uint64_t)_val) << fixedShift; }
121
CV_ALWAYS_INLINE ufixedpoint64(const uint16_t& _val) { val = ((uint64_t)_val) << fixedShift; }
122
CV_ALWAYS_INLINE ufixedpoint64(const uint32_t& _val) { val = ((uint64_t)_val) << fixedShift; }
123
CV_ALWAYS_INLINE ufixedpoint64(const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint64_t)cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); }
124
CV_ALWAYS_INLINE ufixedpoint64& operator = (const uint8_t& _val) { val = ((uint64_t)_val) << fixedShift; return *this; }
125
CV_ALWAYS_INLINE ufixedpoint64& operator = (const uint16_t& _val) { val = ((uint64_t)_val) << fixedShift; return *this; }
126
CV_ALWAYS_INLINE ufixedpoint64& operator = (const uint32_t& _val) { val = ((uint64_t)_val) << fixedShift; return *this; }
127
CV_ALWAYS_INLINE ufixedpoint64& operator = (const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint64_t)cvRound64(_val * cv::softdouble((int64_t)(1LL << fixedShift))); return *this; }
128
CV_ALWAYS_INLINE ufixedpoint64& operator = (const ufixedpoint64& _val) { val = _val.val; return *this; }
129
CV_ALWAYS_INLINE ufixedpoint64 operator * (const uint8_t& val2) const { return operator *(ufixedpoint64(val2)); }
130
CV_ALWAYS_INLINE ufixedpoint64 operator * (const uint16_t& val2) const { return operator *(ufixedpoint64(val2)); }
131
CV_ALWAYS_INLINE ufixedpoint64 operator * (const uint32_t& val2) const { return operator *(ufixedpoint64(val2)); }
132
CV_ALWAYS_INLINE ufixedpoint64 operator * (const ufixedpoint64& val2) const
133
{
134
uint64_t sh0 = fixedround((val & 0xFFFFFFFF) * (val2.val & 0xFFFFFFFF));
135
uint64_t sh1_0 = (val >> 32) * (val2.val & 0xFFFFFFFF);
136
uint64_t sh1_1 = (val & 0xFFFFFFFF) * (val2.val >> 32);
137
uint64_t sh2 = (val >> 32) * (val2.val >> 32);
138
uint64_t val0_l = (sh1_0 & 0xFFFFFFFF) + (sh1_1 & 0xFFFFFFFF) + (sh0 >> 32);
139
uint64_t val0_h = (sh2 & 0xFFFFFFFF) + (sh1_0 >> 32) + (sh1_1 >> 32) + (val0_l >> 32);
140
val0_l &= 0xFFFFFFFF;
141
142
if (sh2 > CV_BIG_INT(0xFFFFFFFF) || val0_h > CV_BIG_INT(0xFFFFFFFF))
143
return (uint64_t)CV_BIG_UINT(0xFFFFFFFFFFFFFFFF);
144
145
return (val0_h << 32 | val0_l);
146
}
147
CV_ALWAYS_INLINE ufixedpoint64 operator + (const ufixedpoint64& val2) const
148
{
149
uint64_t res = val + val2.val;
150
return (uint64_t)((val > res) ? CV_BIG_UINT(0xFFFFFFFFFFFFFFFF) : res);
151
}
152
CV_ALWAYS_INLINE ufixedpoint64 operator - (const ufixedpoint64& val2) const
153
{
154
return val > val2.val ? (val - val2.val) : 0;
155
}
156
CV_ALWAYS_INLINE ufixedpoint64 operator >> (int n) const { return ufixedpoint64(val >> n); }
157
CV_ALWAYS_INLINE ufixedpoint64 operator << (int n) const { return ufixedpoint64(val << n); }
158
CV_ALWAYS_INLINE bool operator == (const ufixedpoint64& val2) const { return val == val2.val; }
159
template <typename ET>
160
CV_ALWAYS_INLINE ET saturate_cast() const { return cv::saturate_cast<ET>(fixedround(val) >> fixedShift); }
161
CV_ALWAYS_INLINE operator double() const { return (double)val / (1LL << fixedShift); }
162
CV_ALWAYS_INLINE operator float() const { return (float)val / (1LL << fixedShift); }
163
CV_ALWAYS_INLINE operator uint8_t() const { return saturate_cast<uint8_t>(); }
164
CV_ALWAYS_INLINE operator int8_t() const { return saturate_cast<int8_t>(); }
165
CV_ALWAYS_INLINE operator uint16_t() const { return saturate_cast<uint16_t>(); }
166
CV_ALWAYS_INLINE operator int16_t() const { return saturate_cast<int16_t>(); }
167
CV_ALWAYS_INLINE operator int32_t() const { return saturate_cast<int32_t>(); }
168
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
169
static CV_ALWAYS_INLINE ufixedpoint64 zero() { return ufixedpoint64(); }
170
static CV_ALWAYS_INLINE ufixedpoint64 one() { return ufixedpoint64((uint64_t)(1ULL << fixedShift)); }
171
friend class ufixedpoint32;
172
};
173
174
class fixedpoint32
175
{
176
private:
177
static const int fixedShift = 16;
178
179
int32_t val;
180
fixedpoint32(int32_t _val) : val(_val) {}
181
static CV_ALWAYS_INLINE uint32_t fixedround(const uint32_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
182
public:
183
typedef fixedpoint64 WT;
184
CV_ALWAYS_INLINE fixedpoint32() { val = 0; }
185
CV_ALWAYS_INLINE fixedpoint32(const int8_t& _val) { val = ((int32_t)_val) << fixedShift; }
186
CV_ALWAYS_INLINE fixedpoint32(const uint8_t& _val) { val = ((int32_t)_val) << fixedShift; }
187
CV_ALWAYS_INLINE fixedpoint32(const int16_t& _val) { val = ((int32_t)_val) << fixedShift; }
188
CV_ALWAYS_INLINE fixedpoint32(const cv::softdouble& _val) { val = (int32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); }
189
CV_ALWAYS_INLINE fixedpoint32& operator = (const int8_t& _val) { val = ((int32_t)_val) << fixedShift; return *this; }
190
CV_ALWAYS_INLINE fixedpoint32& operator = (const uint8_t& _val) { val = ((int32_t)_val) << fixedShift; return *this; }
191
CV_ALWAYS_INLINE fixedpoint32& operator = (const int16_t& _val) { val = ((int32_t)_val) << fixedShift; return *this; }
192
CV_ALWAYS_INLINE fixedpoint32& operator = (const cv::softdouble& _val) { val = (int32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); return *this; }
193
CV_ALWAYS_INLINE fixedpoint32& operator = (const fixedpoint32& _val) { val = _val.val; return *this; }
194
CV_ALWAYS_INLINE fixedpoint32 operator * (const int8_t& val2) const { return cv::saturate_cast<int32_t>((int64_t)val * val2); }
195
CV_ALWAYS_INLINE fixedpoint32 operator * (const uint8_t& val2) const { return cv::saturate_cast<int32_t>((int64_t)val * val2); }
196
CV_ALWAYS_INLINE fixedpoint32 operator * (const int16_t& val2) const { return cv::saturate_cast<int32_t>((int64_t)val * val2); }
197
CV_ALWAYS_INLINE fixedpoint64 operator * (const fixedpoint32& val2) const { return (int64_t)val * (int64_t)(val2.val); }
198
CV_ALWAYS_INLINE fixedpoint32 operator + (const fixedpoint32& val2) const
199
{
200
int32_t res = val + val2.val;
201
return (int64_t)((val ^ res) & (val2.val ^ res)) >> 31 ? ~(res & ~0x7FFFFFFF) : res;
202
}
203
CV_ALWAYS_INLINE fixedpoint32 operator - (const fixedpoint32& val2) const
204
{
205
int32_t res = val - val2.val;
206
return (int64_t)((val ^ val2.val) & (val ^ res)) >> 31 ? ~(res & ~0x7FFFFFFF) : res;
207
}
208
CV_ALWAYS_INLINE fixedpoint32 operator >> (int n) const { return fixedpoint32(val >> n); }
209
CV_ALWAYS_INLINE fixedpoint32 operator << (int n) const { return fixedpoint32(val << n); }
210
CV_ALWAYS_INLINE bool operator == (const fixedpoint32& val2) const { return val == val2.val; }
211
template <typename ET>
212
CV_ALWAYS_INLINE ET saturate_cast() const { return cv::saturate_cast<ET>((int32_t)fixedround((uint32_t)val) >> fixedShift); }
213
CV_ALWAYS_INLINE operator fixedpoint64() const { return (int64_t)val << (fixedpoint64::fixedShift - fixedShift); }
214
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
215
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
216
CV_ALWAYS_INLINE operator uint8_t() const { return saturate_cast<uint8_t>(); }
217
CV_ALWAYS_INLINE operator int8_t() const { return saturate_cast<int8_t>(); }
218
CV_ALWAYS_INLINE operator uint16_t() const { return saturate_cast<uint16_t>(); }
219
CV_ALWAYS_INLINE operator int16_t() const { return saturate_cast<int16_t>(); }
220
CV_ALWAYS_INLINE operator int32_t() const { return saturate_cast<int32_t>(); }
221
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
222
static CV_ALWAYS_INLINE fixedpoint32 zero() { return fixedpoint32(); }
223
static CV_ALWAYS_INLINE fixedpoint32 one() { return fixedpoint32((1 << fixedShift)); }
224
friend class fixedpoint16;
225
};
226
227
class ufixedpoint32
228
{
229
private:
230
static const int fixedShift = 16;
231
232
uint32_t val;
233
ufixedpoint32(uint32_t _val) : val(_val) {}
234
static CV_ALWAYS_INLINE uint32_t fixedround(const uint32_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
235
public:
236
typedef ufixedpoint64 WT;
237
CV_ALWAYS_INLINE ufixedpoint32() { val = 0; }
238
CV_ALWAYS_INLINE ufixedpoint32(const uint8_t& _val) { val = ((uint32_t)_val) << fixedShift; }
239
CV_ALWAYS_INLINE ufixedpoint32(const uint16_t& _val) { val = ((uint32_t)_val) << fixedShift; }
240
CV_ALWAYS_INLINE ufixedpoint32(const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); }
241
CV_ALWAYS_INLINE ufixedpoint32& operator = (const uint8_t& _val) { val = ((uint32_t)_val) << fixedShift; return *this; }
242
CV_ALWAYS_INLINE ufixedpoint32& operator = (const uint16_t& _val) { val = ((uint32_t)_val) << fixedShift; return *this; }
243
CV_ALWAYS_INLINE ufixedpoint32& operator = (const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint32_t)cvRound(_val * cv::softdouble((1 << fixedShift))); return *this; }
244
CV_ALWAYS_INLINE ufixedpoint32& operator = (const ufixedpoint32& _val) { val = _val.val; return *this; }
245
CV_ALWAYS_INLINE ufixedpoint32 operator * (const uint8_t& val2) const { return cv::saturate_cast<uint32_t>((uint64_t)val * val2); }
246
CV_ALWAYS_INLINE ufixedpoint32 operator * (const uint16_t& val2) const { return cv::saturate_cast<uint32_t>((uint64_t)val * val2); }
247
CV_ALWAYS_INLINE ufixedpoint64 operator * (const ufixedpoint32& val2) const { return (uint64_t)val * (uint64_t)(val2.val); }
248
CV_ALWAYS_INLINE ufixedpoint32 operator + (const ufixedpoint32& val2) const
249
{
250
uint32_t res = val + val2.val;
251
return (val > res) ? 0xFFFFFFFF : res;
252
}
253
CV_ALWAYS_INLINE ufixedpoint32 operator - (const ufixedpoint32& val2) const
254
{
255
return val > val2.val ? (val - val2.val) : 0;
256
}
257
CV_ALWAYS_INLINE ufixedpoint32 operator >> (int n) const { return ufixedpoint32(val >> n); }
258
CV_ALWAYS_INLINE ufixedpoint32 operator << (int n) const { return ufixedpoint32(val << n); }
259
CV_ALWAYS_INLINE bool operator == (const ufixedpoint32& val2) const { return val == val2.val; }
260
template <typename ET>
261
CV_ALWAYS_INLINE ET saturate_cast() const { return cv::saturate_cast<ET>(fixedround(val) >> fixedShift); }
262
CV_ALWAYS_INLINE operator ufixedpoint64() const { return (uint64_t)val << (ufixedpoint64::fixedShift - fixedShift); }
263
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
264
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
265
CV_ALWAYS_INLINE operator uint8_t() const { return saturate_cast<uint8_t>(); }
266
CV_ALWAYS_INLINE operator int8_t() const { return saturate_cast<int8_t>(); }
267
CV_ALWAYS_INLINE operator uint16_t() const { return saturate_cast<uint16_t>(); }
268
CV_ALWAYS_INLINE operator int16_t() const { return saturate_cast<int16_t>(); }
269
CV_ALWAYS_INLINE operator int32_t() const { return saturate_cast<int32_t>(); }
270
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
271
static CV_ALWAYS_INLINE ufixedpoint32 zero() { return ufixedpoint32(); }
272
static CV_ALWAYS_INLINE ufixedpoint32 one() { return ufixedpoint32((1U << fixedShift)); }
273
friend class ufixedpoint16;
274
};
275
276
class fixedpoint16
277
{
278
private:
279
static const int fixedShift = 8;
280
281
int16_t val;
282
fixedpoint16(int16_t _val) : val(_val) {}
283
static CV_ALWAYS_INLINE uint16_t fixedround(const uint16_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
284
public:
285
typedef fixedpoint32 WT;
286
CV_ALWAYS_INLINE fixedpoint16() { val = 0; }
287
CV_ALWAYS_INLINE fixedpoint16(const int8_t& _val) { val = ((int16_t)_val) << fixedShift; }
288
CV_ALWAYS_INLINE fixedpoint16(const cv::softdouble& _val) { val = (int16_t)cvRound(_val * cv::softdouble((1 << fixedShift))); }
289
CV_ALWAYS_INLINE fixedpoint16& operator = (const int8_t& _val) { val = ((int16_t)_val) << fixedShift; return *this; }
290
CV_ALWAYS_INLINE fixedpoint16& operator = (const cv::softdouble& _val) { val = (int16_t)cvRound(_val * cv::softdouble((1 << fixedShift))); return *this; }
291
CV_ALWAYS_INLINE fixedpoint16& operator = (const fixedpoint16& _val) { val = _val.val; return *this; }
292
CV_ALWAYS_INLINE fixedpoint16 operator * (const int8_t& val2) const { return cv::saturate_cast<int16_t>((int32_t)val * val2); }
293
CV_ALWAYS_INLINE fixedpoint32 operator * (const fixedpoint16& val2) const { return (int32_t)val * (int32_t)(val2.val); }
294
CV_ALWAYS_INLINE fixedpoint16 operator + (const fixedpoint16& val2) const
295
{
296
int16_t res = val + val2.val;
297
return ((val ^ res) & (val2.val ^ res)) >> 15 ? (int16_t)(~(res & ~0x7FFF)) : res;
298
}
299
CV_ALWAYS_INLINE fixedpoint16 operator - (const fixedpoint16& val2) const
300
{
301
int16_t res = val - val2.val;
302
return ((val ^ val2.val) & (val ^ res)) >> 15 ? (int16_t)(~(res & ~(int16_t)0x7FFF)) : res;
303
}
304
CV_ALWAYS_INLINE fixedpoint16 operator >> (int n) const { return fixedpoint16((int16_t)(val >> n)); }
305
CV_ALWAYS_INLINE fixedpoint16 operator << (int n) const { return fixedpoint16((int16_t)(val << n)); }
306
CV_ALWAYS_INLINE bool operator == (const fixedpoint16& val2) const { return val == val2.val; }
307
template <typename ET>
308
CV_ALWAYS_INLINE ET saturate_cast() const { return cv::saturate_cast<ET>((int16_t)fixedround((uint16_t)val) >> fixedShift); }
309
CV_ALWAYS_INLINE operator fixedpoint32() const { return (int32_t)val << (fixedpoint32::fixedShift - fixedShift); }
310
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
311
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
312
CV_ALWAYS_INLINE operator uint8_t() const { return saturate_cast<uint8_t>(); }
313
CV_ALWAYS_INLINE operator int8_t() const { return saturate_cast<int8_t>(); }
314
CV_ALWAYS_INLINE operator uint16_t() const { return saturate_cast<uint16_t>(); }
315
CV_ALWAYS_INLINE operator int16_t() const { return saturate_cast<int16_t>(); }
316
CV_ALWAYS_INLINE operator int32_t() const { return saturate_cast<int32_t>(); }
317
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
318
static CV_ALWAYS_INLINE fixedpoint16 zero() { return fixedpoint16(); }
319
static CV_ALWAYS_INLINE fixedpoint16 one() { return fixedpoint16((int16_t)(1 << fixedShift)); }
320
};
321
322
class ufixedpoint16
323
{
324
private:
325
static const int fixedShift = 8;
326
327
uint16_t val;
328
ufixedpoint16(uint16_t _val) : val(_val) {}
329
static CV_ALWAYS_INLINE uint16_t fixedround(const uint16_t& _val) { return (_val + ((1 << fixedShift) >> 1)); }
330
public:
331
typedef ufixedpoint32 WT;
332
CV_ALWAYS_INLINE ufixedpoint16() { val = 0; }
333
CV_ALWAYS_INLINE ufixedpoint16(const uint8_t& _val) { val = ((uint16_t)_val) << fixedShift; }
334
CV_ALWAYS_INLINE ufixedpoint16(const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint16_t)cvRound(_val * cv::softdouble((int32_t)(1 << fixedShift))); }
335
CV_ALWAYS_INLINE ufixedpoint16& operator = (const uint8_t& _val) { val = ((uint16_t)_val) << fixedShift; return *this; }
336
CV_ALWAYS_INLINE ufixedpoint16& operator = (const cv::softdouble& _val) { val = _val.getSign() ? 0 : (uint16_t)cvRound(_val * cv::softdouble((int32_t)(1 << fixedShift))); return *this; }
337
CV_ALWAYS_INLINE ufixedpoint16& operator = (const ufixedpoint16& _val) { val = _val.val; return *this; }
338
CV_ALWAYS_INLINE ufixedpoint16 operator * (const uint8_t& val2) const { return cv::saturate_cast<uint16_t>((uint32_t)val * val2); }
339
CV_ALWAYS_INLINE ufixedpoint32 operator * (const ufixedpoint16& val2) const { return ((uint32_t)val * (uint32_t)(val2.val)); }
340
CV_ALWAYS_INLINE ufixedpoint16 operator + (const ufixedpoint16& val2) const
341
{
342
uint16_t res = val + val2.val;
343
return (val > res) ? (uint16_t)0xFFFF : res;
344
}
345
CV_ALWAYS_INLINE ufixedpoint16 operator - (const ufixedpoint16& val2) const
346
{
347
return val > val2.val ? (uint16_t)(val - val2.val) : (uint16_t)0;
348
}
349
CV_ALWAYS_INLINE ufixedpoint16 operator >> (int n) const { return ufixedpoint16((uint16_t)(val >> n)); }
350
CV_ALWAYS_INLINE ufixedpoint16 operator << (int n) const { return ufixedpoint16((uint16_t)(val << n)); }
351
CV_ALWAYS_INLINE bool operator == (const ufixedpoint16& val2) const { return val == val2.val; }
352
template <typename ET>
353
CV_ALWAYS_INLINE ET saturate_cast() const { return cv::saturate_cast<ET>(fixedround(val) >> fixedShift); }
354
CV_ALWAYS_INLINE operator ufixedpoint32() const { return (uint32_t)val << (ufixedpoint32::fixedShift - fixedShift); }
355
CV_ALWAYS_INLINE operator double() const { return (double)val / (1 << fixedShift); }
356
CV_ALWAYS_INLINE operator float() const { return (float)val / (1 << fixedShift); }
357
CV_ALWAYS_INLINE operator uint8_t() const { return saturate_cast<uint8_t>(); }
358
CV_ALWAYS_INLINE operator int8_t() const { return saturate_cast<int8_t>(); }
359
CV_ALWAYS_INLINE operator uint16_t() const { return saturate_cast<uint16_t>(); }
360
CV_ALWAYS_INLINE operator int16_t() const { return saturate_cast<int16_t>(); }
361
CV_ALWAYS_INLINE operator int32_t() const { return saturate_cast<int32_t>(); }
362
CV_ALWAYS_INLINE bool isZero() { return val == 0; }
363
static CV_ALWAYS_INLINE ufixedpoint16 zero() { return ufixedpoint16(); }
364
static CV_ALWAYS_INLINE ufixedpoint16 one() { return ufixedpoint16((uint16_t)(1 << fixedShift)); }
365
};
366
367
}
368
369
#endif
370
371