1 /*******************************************************************************
2 * Copyright 2016-2019 Intel Corporation.
3 *
4 * This software and the related documents are Intel copyrighted materials, and
5 * your use of them is governed by the express license under which they were
6 * provided to you (License). Unless the License provides otherwise, you may not
7 * use, modify, copy, publish, distribute, disclose or transmit this software or
8 * the related documents without Intel's prior written permission.
9 *
10 * This software and the related documents are provided as is, with no express
11 * or implied warranties, other than those that are expressly stated in the
12 * License.
13 *******************************************************************************/
14
15 #if !defined( __IPP_IWPP_CORE__ )
16 #define __IPP_IWPP_CORE__
17
18 #include "iw/iw_core.h"
19
20 #include <string>
21
22 // IW++ interface configuration switches
23 #ifndef IW_ENABLE_EXCEPTIONS
24 #define IW_ENABLE_EXCEPTIONS 1 // IW++ can return all errors by exceptions or by classic return codes.
25 // Note that some errors cannot be returned without exceptions and may be lost.
26 #endif
27
28
29 #if IW_ENABLE_EXCEPTIONS == 0
30 #define OWN_ERROR_THROW(IPP_STATUS) return (IPP_STATUS);
31 #define OWN_ERROR_THROW_ONLY(IPP_STATUS) (void)(IPP_STATUS);
32 #else
33 #define OWN_ERROR_THROW(IPP_STATUS) throw IwException(IPP_STATUS);
34 #define OWN_ERROR_THROW_ONLY(IPP_STATUS) OWN_ERROR_THROW(IPP_STATUS);
35 #endif
36 #define OWN_ERROR_CHECK_THROW_ONLY(IPP_STATUS)\
37 {\
38 if((IPP_STATUS) < 0)\
39 {\
40 OWN_ERROR_THROW_ONLY(IPP_STATUS)\
41 }\
42 }
43 #define OWN_ERROR_CHECK(IPP_STATUS)\
44 {\
45 if((IPP_STATUS) < 0)\
46 {\
47 OWN_ERROR_THROW(IPP_STATUS)\
48 }\
49 }
50
51 // Common IW++ API declaration macro
52 #define IW_DECL_CPP(RET_TYPE) IW_INLINE RET_TYPE IPP_STDCALL
53
54 // Base constructors set for auxiliary parameters
55 #define IW_BASE_PARAMS_CONSTRUCTORS(NAME, FUN)\
56 NAME(const ::NAME *pParams)\
57 {\
58 if(pParams)\
59 *((::NAME*)this) = *pParams;\
60 else\
61 FUN(this);\
62 }\
63 NAME(const ::NAME ¶ms)\
64 {\
65 *((::NAME*)this) = params;\
66 }\
67 NAME(const ipp::IwDefault &)\
68 {\
69 FUN(this);\
70 }
71
72 namespace ipp
73 {
74
75 /* /////////////////////////////////////////////////////////////////////////////
76 // Base IW++ definitions
77 ///////////////////////////////////////////////////////////////////////////// */
78
79 using ::IppStatus;
80 using ::IwSize;
81
82 using ::Ipp8u;
83 using ::Ipp16u;
84 using ::Ipp32u;
85 using ::Ipp8s;
86 using ::Ipp16s;
87 using ::Ipp32s;
88 using ::Ipp32f;
89 using ::Ipp64s;
90 using ::Ipp64u;
91 using ::Ipp64f;
92 using ::Ipp16f;
93
94 using ::IppDataType;
95 using ::ipp1u;
96 using ::ipp8u;
97 using ::ipp8uc;
98 using ::ipp8s;
99 using ::ipp8sc;
100 using ::ipp16u;
101 using ::ipp16uc;
102 using ::ipp16s;
103 using ::ipp16sc;
104 using ::ipp32u;
105 using ::ipp32uc;
106 using ::ipp32s;
107 using ::ipp32sc;
108 using ::ipp32f;
109 using ::ipp32fc;
110 using ::ipp64u;
111 using ::ipp64uc;
112 using ::ipp64s;
113 using ::ipp64sc;
114 using ::ipp64f;
115 using ::ipp64fc;
116
117 // Class to initialize default objects
118 class IwDefault
119 {
120 public:
IwDefault()121 IwDefault() {}
122 };
123
124 #if IW_ENABLE_EXCEPTIONS
125 // Stores an error code value for an exception thrown by the function
126 class IwException
127 {
128 public:
129 // Constructor with status assignment
IwException(IppStatus status)130 IwException(
131 IppStatus status // IppStatus value
132 )
133 {
134 m_status = status;
135 m_string = iwGetStatusString(m_status);
136 }
137
138 // Default destructor
~IwException()139 ~IwException() {}
140
141 // IwException to IppStatus cast operator
operator IppStatus() const142 inline operator IppStatus() const { return m_status;}
143
144 IppStatus m_status; // Stored IppStatus value
145 const char *m_string; // Stored status string
146 };
147 #endif
148
149 // This class sets Intel IPP optimizations for the current region and restores previous optimizations at the region end
150 class IwSetCpuFeaturesRegion
151 {
152 public:
153 // Default constructor. Saves current enabled CPU features.
IwSetCpuFeaturesRegion()154 IwSetCpuFeaturesRegion()
155 {
156 m_stored = ::ippGetEnabledCpuFeatures();
157 }
158
159 // Saves current enabled CPU features and sets new features mask.
IwSetCpuFeaturesRegion(Ipp64u featuresMask)160 IwSetCpuFeaturesRegion(Ipp64u featuresMask)
161 {
162 m_stored = ::ippGetEnabledCpuFeatures();
163 Set(featuresMask);
164 }
165
166 // Sets new features mask for the region.
Set(Ipp64u featuresMask)167 IppStatus Set(Ipp64u featuresMask)
168 {
169 return ::ippSetCpuFeatures(featuresMask);
170 }
171
172 // Default destructor. Restores saved features mask.
~IwSetCpuFeaturesRegion()173 ~IwSetCpuFeaturesRegion()
174 {
175 ::ippSetCpuFeatures(m_stored);
176 }
177
178 private:
179 Ipp64u m_stored;
180 };
181
182 // Stores values for an array for array type casting
183 template<typename DST>
184 class IwValue
185 {
186 public:
187 // Default constructor. Sets array to zero
IwValue()188 IwValue()
189 {
190 SetValue<Ipp8u>(0);
191 }
192
193 // Uniform template-based constructor. Sets channels to one value
194 template<typename SRC>
IwValue(SRC valUniform)195 IwValue(SRC valUniform)
196 {
197 SetValue<SRC>(valUniform);
198 }
199
200 // 3 channels template-based constructor. Sets channels to individual values
201 template<typename SRC>
IwValue(SRC valC1,SRC valC2,SRC valC3)202 IwValue(SRC valC1, SRC valC2, SRC valC3)
203 {
204 SetValue<SRC>(valC1, valC2, valC3);
205 }
206
207 // 4 channels template-based constructor. Sets channels to individual values
208 template<typename SRC>
IwValue(SRC valC1,SRC valC2,SRC valC3,SRC valC4)209 IwValue(SRC valC1, SRC valC2, SRC valC3, SRC valC4)
210 {
211 SetValue<SRC>(valC1, valC2, valC3, valC4);
212 }
213
214 // Buffer template-based constructor. Sets values from a buffer of specific type
215 template<typename SRC>
IwValue(SRC * pBuffer,int channels)216 IwValue(SRC *pBuffer, int channels)
217 {
218 SetValue(pBuffer, channels);
219 }
220
221 // Buffer parameter-based constructor. Sets values from a buffer of specific type
IwValue(void * pBuffer,IppDataType type,int channels)222 IwValue(void *pBuffer, IppDataType type, int channels)
223 {
224 SetValue(pBuffer, type, channels);
225 }
226
227 // Uniform template setter. Sets channels to one value
228 template<typename SRC>
SetValue(SRC valUniform)229 void SetValue(SRC valUniform)
230 {
231 m_values = 1;
232 m_val[0] = m_val[1] = m_val[2] = m_val[3] = (DST)valUniform;
233 }
234
235 // 3 channels template setter. Sets channels to individual values
236 template<typename SRC>
SetValue(SRC valC1,SRC valC2,SRC valC3)237 void SetValue(SRC valC1, SRC valC2, SRC valC3)
238 {
239 m_values = 3;
240 m_val[0] = (DST)valC1, m_val[1] = (DST)valC2, m_val[2] = (DST)valC3;
241 }
242
243 // 4 channels template setter. Sets channels to individual values
244 template<typename SRC>
SetValue(SRC valC1,SRC valC2,SRC valC3,SRC valC4)245 void SetValue(SRC valC1, SRC valC2, SRC valC3, SRC valC4)
246 {
247 m_values = 4;
248 m_val[0] = (DST)valC1, m_val[1] = (DST)valC2, m_val[2] = (DST)valC3, m_val[3] = (DST)valC4;
249 }
250
251 // Buffer template-based setter. Sets values from a buffer of specific type
252 template<typename SRC>
SetValue(SRC * pBuffer,int channels)253 void SetValue(SRC *pBuffer, int channels)
254 {
255 if(!pBuffer)
256 OWN_ERROR_THROW_ONLY(ippStsNullPtrErr);
257 if(channels > 4 || channels < 1)
258 OWN_ERROR_THROW_ONLY(ippStsNumChannelsErr);
259 m_values = channels;
260
261 for(int i = 0; i < channels; i++)
262 m_val[i] = (DST)(pBuffer[i]);
263 }
264
265 // Buffer parameter-based setter. Sets values from a buffer of specific type
SetValue(void * pBuffer,IppDataType type,int channels)266 void SetValue(void *pBuffer, IppDataType type, int channels)
267 {
268 switch(type)
269 {
270 case ipp8u:
271 SetValue((Ipp8u*)pBuffer, channels); break;
272 case ipp8s:
273 SetValue((Ipp8s*)pBuffer, channels); break;
274 case ipp16u:
275 SetValue((Ipp16u*)pBuffer, channels); break;
276 case ipp16s:
277 SetValue((Ipp16s*)pBuffer, channels); break;
278 case ipp32u:
279 SetValue((Ipp32u*)pBuffer, channels); break;
280 case ipp32s:
281 SetValue((Ipp32s*)pBuffer, channels); break;
282 case ipp32f:
283 SetValue((Ipp32f*)pBuffer, channels); break;
284 case ipp64u:
285 SetValue((Ipp64u*)pBuffer, channels); break;
286 case ipp64s:
287 SetValue((Ipp64s*)pBuffer, channels); break;
288 case ipp64f:
289 SetValue((Ipp64f*)pBuffer, channels); break;
290 default:
291 OWN_ERROR_THROW_ONLY(ippStsDataTypeErr);
292 }
293 }
294
295 // Returns number of initialized values
ValuesNum() const296 int ValuesNum() const { return m_values; }
297
298 // IwValue to Ipp64f cast operator
operator DST() const299 inline operator DST () const { return ((DST*)m_val)[0];}
300
301 // IwValue to Ipp64f* cast operator
operator DST*() const302 inline operator DST* () const { return (DST*)m_val;}
303
304 // IwValue to const Ipp64f* cast operator
operator const DST*() const305 inline operator const DST* () const { return (const DST*)m_val;}
306
307 // Array subscript operator
operator [](int channel)308 inline DST& operator[](int channel) { return (channel>=m_values)?m_val[m_values-1]:m_val[channel]; }
operator [](int channel) const309 inline const DST& operator[](int channel) const { return (channel>=m_values)?m_val[m_values-1]:m_val[channel]; }
310
311 // Compares values
operator ==(const IwValue & rhs) const312 bool operator==(const IwValue& rhs) const
313 {
314 if((*this)[0] == rhs[0] && (*this)[1] == rhs[1] && (*this)[2] == rhs[2] && (*this)[3] == rhs[3])
315 return true;
316 else
317 return false;
318 }
operator !=(const IwValue & rhs) const319 bool operator!=(const IwValue& rhs) const
320 {
321 return !(*this==rhs);
322 }
323
324 private:
325 int m_values; // Number of initialized values
326 DST m_val[4]; // reserve 4 channels
327 };
328
329 typedef IwValue<Ipp64f> IwValueFloat;
330 typedef IwValue<Ipp32s> IwValueInt;
331
332 // Convert IppDataType to actual size in bytes
333 // Returns:
334 // Size of IppDataType in bytes
iwTypeToSize(IppDataType type)335 IW_DECL_CPP(int) iwTypeToSize(
336 IppDataType type // Data type
337 )
338 {
339 return ::iwTypeToSize(type);
340 }
341
342 // Returns 1 if data type is of float type and 0 otherwise
343 // Returns:
344 // Absolute value
iwTypeIsFloat(IppDataType type)345 IW_DECL_CPP(int) iwTypeIsFloat(
346 IppDataType type // Data type
347 )
348 {
349 return ::iwTypeIsFloat(type);
350 }
351
352 // Returns minimum possible value for specified data type
353 // Returns:
354 // Minimum value
iwTypeGetMin(IppDataType type)355 IW_DECL_CPP(double) iwTypeGetMin(
356 IppDataType type // Data type for min value
357 )
358 {
359 return ::iwTypeGetMin(type);
360 }
361
362 // Returns maximum possible value for specified data type
363 // Returns:
364 // Maximum value
iwTypeGetMax(IppDataType type)365 IW_DECL_CPP(double) iwTypeGetMax(
366 IppDataType type // Data type for max value
367 )
368 {
369 return ::iwTypeGetMax(type);
370 }
371
372 // Returns values range for specified data type
373 // Returns:
374 // Range value
iwTypeGetRange(IppDataType type)375 IW_DECL_CPP(double) iwTypeGetRange(
376 IppDataType type // Data type for range value
377 )
378 {
379 return ::iwTypeGetRange(type);
380 }
381
382 // Cast double value to input type with rounding and saturation
383 // Returns:
384 // Rounded and saturated value
iwValueSaturate(double val,IppDataType dstType)385 IW_DECL_CPP(double) iwValueSaturate(
386 double val, // Input value
387 IppDataType dstType // Data type for saturation range
388 )
389 {
390 return ::iwValueSaturate(val, dstType);
391 }
392
393 // Converts relative value in range of [0,1] to the absolute value according to specified type
394 // Returns:
395 // Absolute value
iwValueRelToAbs(double val,IppDataType type)396 IW_DECL_CPP(double) iwValueRelToAbs(
397 double val, // Relative value. From 0 to 1
398 IppDataType type // Data type for the absolute range
399 )
400 {
401 return ::iwValueRelToAbs(val, type);
402 }
403
404 /* /////////////////////////////////////////////////////////////////////////////
405 // IW with Threading Layer control
406 ///////////////////////////////////////////////////////////////////////////// */
407
408 // This function sets number of threads for IW functions with parallel execution support
iwSetThreadsNum(int threads)409 IW_DECL_CPP(void) iwSetThreadsNum(
410 int threads // Number of threads to use
411 )
412 {
413 ::iwSetThreadsNum(threads);
414 }
415
416 // This function returns number of threads used by IW functions with parallel execution support
417 // Returns:
418 // Number of threads or 0 if compiled without internal threading support
iwGetThreadsNum()419 IW_DECL_CPP(int) iwGetThreadsNum()
420 {
421 return ::iwGetThreadsNum();
422 }
423
424 // This function returns initial number of threads used by IW functions with parallel execution support
425 // Returns:
426 // Default number of threads or 0 if compiled without internal threading support
iwGetThreadsNumDefault()427 IW_DECL_CPP(int) iwGetThreadsNumDefault()
428 {
429 return ::iwGetThreadsNumDefault();
430 }
431
432
433 /* /////////////////////////////////////////////////////////////////////////////
434 // IwTls - TLS data storage interface
435 ///////////////////////////////////////////////////////////////////////////// */
436
437 // Template-based TLS abstraction layer class.
438 // This is an extension of C IwTls structure with automatic objects destruction
439 template<class TYPE>
440 class IwTls: private ::IwTls
441 {
442 public:
443 // Default constructor
IwTls()444 IwTls()
445 {
446 IppStatus status = ::iwTls_Init(this, (IwTlsDestructor)(IwTls::TypeDestructor));
447 OWN_ERROR_CHECK_THROW_ONLY(status);
448 }
449
450 // Default destructor
~IwTls()451 ~IwTls()
452 {
453 ::iwTls_Release(this);
454 }
455
456 // Allocates object for current thread and returns pointer to it
Create()457 TYPE* Create()
458 {
459 TYPE *pData = new TYPE;
460 if(!pData)
461 return NULL;
462 IppStatus status = ::iwTls_Set(this, pData);
463 if(status < 0)
464 {
465 delete pData;
466 OWN_ERROR_CHECK_THROW_ONLY(status);
467 return NULL;
468 }
469 return pData;
470 }
471
472 // Releases object for current thread
Release()473 void Release()
474 {
475 IppStatus status = ::iwTls_Set(this, NULL);
476 if(status < 0)
477 OWN_ERROR_CHECK_THROW_ONLY(status);
478 }
479
480 // Releases objects for all threads
ReleaseAll()481 void ReleaseAll()
482 {
483 IppStatus status = ::iwTls_ReleaseData(this);
484 if(status < 0)
485 OWN_ERROR_CHECK_THROW_ONLY(status);
486 }
487
488 // Returns pointer to object for current thread
Get() const489 TYPE* Get() const
490 {
491 return (TYPE*)::iwTls_Get(this);
492 }
493
494 private:
495 // Object destructor
TypeDestructor(void * pData)496 static void IPP_STDCALL TypeDestructor(void *pData)
497 {
498 if(pData)
499 delete ((TYPE*)pData);
500 }
501 };
502
503 /* /////////////////////////////////////////////////////////////////////////////
504 // IW version info
505 ///////////////////////////////////////////////////////////////////////////// */
506
507 class IppVersion: private ::IwVersion
508 {
509 public:
IppVersion()510 IppVersion()
511 {
512 ::iwGetLibVersion(this);
513 if(!this->m_pIppVersion)
514 OWN_ERROR_THROW_ONLY(ippStsNullPtrErr);
515 }
516
getMajor()517 int getMajor()
518 {
519 return this->m_pIppVersion->major;
520 }
521
getMinor()522 int getMinor()
523 {
524 return this->m_pIppVersion->minor;
525 }
526
getUpdate()527 int getUpdate()
528 {
529 return this->m_pIppVersion->majorBuild;
530 }
531
getRevision()532 int getRevision()
533 {
534 return this->m_pIppVersion->build;
535 }
536
getString()537 std::string getString()
538 {
539 return this->m_pIppVersion->Version;
540 }
541
getLibraryName()542 std::string getLibraryName()
543 {
544 return this->m_pIppVersion->Name;
545 }
546
getTargetCpu()547 std::string getTargetCpu()
548 {
549 return this->m_pIppVersion->targetCpu;
550 }
551
getBuildDate()552 std::string getBuildDate()
553 {
554 return this->m_pIppVersion->BuildDate;
555 }
556
getInfoString()557 std::string getInfoString()
558 {
559 return getLibraryName() + " " + getString() + ", " + getBuildDate();
560 }
561 };
562
563 class IwVersion: private ::IwVersion
564 {
565 public:
IwVersion()566 IwVersion()
567 {
568 ::iwGetLibVersion(this);
569 if(!this->m_pIppVersion)
570 OWN_ERROR_THROW_ONLY(ippStsNullPtrErr);
571 }
572
getMajor()573 int getMajor()
574 {
575 return this->m_major;
576 }
577
getMinor()578 int getMinor()
579 {
580 return this->m_minor;
581 }
582
getUpdate()583 int getUpdate()
584 {
585 return this->m_update;
586 }
587
getString()588 std::string getString()
589 {
590 return this->m_versionStr;
591 }
592
getInfoString()593 std::string getInfoString()
594 {
595 if(isReleaseBuild())
596 return getString() + ", release build";
597 else
598 return getString() + ", user build";
599 }
600
isReleaseBuild()601 bool isReleaseBuild()
602 {
603 return !this->m_bUserBuild;
604 }
605 };
606
607 }
608
609 #endif
610