Commit 1f1dc425 authored by Andrey Pavlenko's avatar Andrey Pavlenko Committed by Alexander Alekhin

Merge pull request #7681 from apavlenko:ivx-docs

OpenVX C++ wrappers docs (#7681)

* adding wrapper headers to the project to see them in IDE project explorer

* readme

* doxygen: toplevel brief-s

* more doxygen

* more doxygen
parent 876c2c0e
add_library(openvx_hal STATIC include/openvx_hal.hpp src/openvx_hal.cpp) add_library(openvx_hal STATIC src/openvx_hal.cpp include/openvx_hal.hpp include/ivx.hpp include/ivx_lib_debug.hpp)
target_include_directories(openvx_hal PUBLIC target_include_directories(openvx_hal PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/modules/core/include ${CMAKE_SOURCE_DIR}/modules/core/include
......
# C++ wrappers for OpenVX-1.x C API
## Core ideas:
* lightweight - minimal overhead vs standard C API
* automatic references counting
* exceptions instead of return codes
* object-oriented design
* (NYI) helpers for user-defined kernels & nodes
* C++ 11 friendly
## Quick start sample
The following short sample gives basic knowledges on the wrappers usage:
```cpp
#include "ivx.hpp"
#include "ivx_lib_debug.hpp" // ivx::debug::*
int main()
{
vx_uint32 width = 640, height = 480;
try
{
ivx::Context context = ivx::Context::create();
ivx::Graph graph = ivx::Graph::create(context);
ivx::Image
gray = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8),
gb = ivx::Image::createVirtual(graph),
res = ivx::Image::create(context, width, height, VX_DF_IMAGE_U8);
context.loadKernels("openvx-debug"); // ivx::debug::*
ivx::debug::fReadImage(context, inputPath, gray);
ivx::Node::create(graph, VX_KERNEL_GAUSSIAN_3x3, gray, gb);
ivx::Node::create(
graph,
VX_KERNEL_THRESHOLD,
gb,
ivx::Threshold::createBinary(context, VX_TYPE_UINT8, 50),
res
);
graph.verify();
graph.process();
ivx::debug::fWriteImage(context, res, "ovx-res-cpp.pgm");
}
catch (const ivx::RuntimeError& e)
{
printf("ErrorRuntime: code = %d(%x), message = %s\n", e.status(), e.status(), e.what());
return e.status();
}
catch (const ivx::WrapperError& e)
{
printf("ErrorWrapper: message = %s\n", e.what());
return -1;
}
catch(const std::exception& e)
{
printf("runtime_error: message = %s\n", e.what());
return -1;
}
return 0;
}
```
## C++ API overview
The wrappers have **header-only** implementation that simplifies their integration to projects.
All the API is inside `ivx` namespace (E.g. `class ivx::Graph`).
While the C++ API is pretty much the same for underlying OpenVX version **1.0** and **1.1**, there are alternative code branches for some features implementation that are selected at **compile time** via `#ifdef` preprocessor directives.
E.g. external ref-counting is implemented for 1.0 version and native OpenVX one is used (via `vxRetainReference()` and `vxReleaseXYZ()`) for version 1.1.
Also there are some **C++ 11** features are used (e.g. rvalue ref-s) when their availability is detected at ***compile time***.
C++ exceptions are used for errors indication instead of return codes. There are two types of exceptions are defined: `RuntimeError` is thrown when OpenVX C call returned unsuccessful result and `WrapperError` is thrown when a problem is occured in the wrappers code. Both exception calsses are derived from `std::exception` (actually from its inheritants).
The so called **OpenVX objects** (e.g. `vx_image`) are represented as C++ classes in wrappers.
All these classes use automatic ref-counting that allows development of exception-safe code.
All these classes have `create()` or `createXYZ()` `static` methods for instances creation. (E.g. `Image::create()`, `Image::createVirtual()` and `Image::createFromHandle()`)
Most of the wrapped OpenVX functions are represented as methods of the corresponding C++ classes, but in most cases they still accept C "object" types (e.g. `vx_image` or `vx_context`) that allows mixing of C and C++ OpenVX API use.
E.g.:
```cpp
class Image
{
static Image create(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format);
static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT);
// ...
}
```
All the classes instances can automatically be converted to the corresponding C "object" types.
For more details please refer to C++ wrappers reference manual or directly to their source code.
...@@ -61,8 +61,14 @@ Details: TBD ...@@ -61,8 +61,14 @@ Details: TBD
#else #else
namespace ivx namespace ivx
{ {
// helpers for compile-time type checking
template<typename, typename> struct is_same { static const bool value = false; }; template<typename, typename> struct is_same { static const bool value = false; };
template<typename T> struct is_same<T, T> { static const bool value = true; }; template<typename T> struct is_same<T, T> { static const bool value = true; };
template<typename T> struct is_pointer { static const bool value = false; };
template<typename T> struct is_pointer<T*> { static const bool value = true; };
template<typename T> struct is_pointer<const T*> { static const bool value = true; };
} }
#endif #endif
...@@ -73,16 +79,16 @@ Details: TBD ...@@ -73,16 +79,16 @@ Details: TBD
namespace ivx namespace ivx
{ {
/* /// Exception class for OpenVX runtime errors
* RuntimeError - OpenVX runtime errors exception class
*/
class RuntimeError : public std::runtime_error class RuntimeError : public std::runtime_error
{ {
public: public:
/// Constructor
explicit RuntimeError(vx_status status, const std::string& msg = "") explicit RuntimeError(vx_status status, const std::string& msg = "")
: runtime_error(msg), _status(status) : runtime_error(msg), _status(status)
{} {}
/// OpenVX error code
vx_status status() const vx_status status() const
{ return _status; } { return _status; }
...@@ -90,12 +96,11 @@ private: ...@@ -90,12 +96,11 @@ private:
vx_status _status; vx_status _status;
}; };
/* /// Exception class for wrappers logic errors
* WrapperError - wrappers logic errors exception class
*/
class WrapperError : public std::logic_error class WrapperError : public std::logic_error
{ {
public: public:
/// Constructor
explicit WrapperError(const std::string& msg) : logic_error(msg) explicit WrapperError(const std::string& msg) : logic_error(msg)
{} {}
}; };
...@@ -106,12 +111,11 @@ inline void checkVxStatus(vx_status status, const std::string& func, const std:: ...@@ -106,12 +111,11 @@ inline void checkVxStatus(vx_status status, const std::string& func, const std::
} }
/// Helper macro for turning a runtime error in the provided code into a \RuntimeError
#define IVX_CHECK_STATUS(code) checkVxStatus(code, __func__, #code) #define IVX_CHECK_STATUS(code) checkVxStatus(code, __func__, #code)
/* /// OpenVX enum to type compile-time converter (TODO: add more types)
* EnumToType - enum to type compile-time converter (TODO: add more types)
*/
template<vx_enum E> struct EnumToType {}; template<vx_enum E> struct EnumToType {};
template<> struct EnumToType<VX_TYPE_CHAR> { typedef vx_char type; static const vx_size bytes = sizeof(type); }; template<> struct EnumToType<VX_TYPE_CHAR> { typedef vx_char type; static const vx_size bytes = sizeof(type); };
template<> struct EnumToType<VX_TYPE_INT8> { typedef vx_int8 type; static const vx_size bytes = sizeof(type); }; template<> struct EnumToType<VX_TYPE_INT8> { typedef vx_int8 type; static const vx_size bytes = sizeof(type); };
...@@ -132,6 +136,7 @@ template<> struct EnumToType<VX_TYPE_BOOL> { typedef vx_bool type; stat ...@@ -132,6 +136,7 @@ template<> struct EnumToType<VX_TYPE_BOOL> { typedef vx_bool type; stat
template <vx_enum E> using EnumToType_t = typename EnumToType<E>::type; template <vx_enum E> using EnumToType_t = typename EnumToType<E>::type;
#endif #endif
/// Gets size in bytes for the provided OpenVX type enum
vx_size enumToTypeSize(vx_enum type) vx_size enumToTypeSize(vx_enum type)
{ {
switch (type) switch (type)
...@@ -155,9 +160,7 @@ vx_size enumToTypeSize(vx_enum type) ...@@ -155,9 +160,7 @@ vx_size enumToTypeSize(vx_enum type)
} }
} }
/* /// type to enum compile-time converter (TODO: add more types)
* TypeToEnum - type to enum compile-time converter (TODO: add more types)
*/
template<typename T> struct TypeToEnum {}; template<typename T> struct TypeToEnum {};
template<> struct TypeToEnum<vx_char> { static const vx_enum value = VX_TYPE_CHAR; }; template<> struct TypeToEnum<vx_char> { static const vx_enum value = VX_TYPE_CHAR; };
template<> struct TypeToEnum<vx_int8> { static const vx_enum value = VX_TYPE_INT8; }; template<> struct TypeToEnum<vx_int8> { static const vx_enum value = VX_TYPE_INT8; };
...@@ -176,9 +179,7 @@ template<> struct TypeToEnum<vx_bool> { static const vx_enum value = VX_TYPE ...@@ -176,9 +179,7 @@ template<> struct TypeToEnum<vx_bool> { static const vx_enum value = VX_TYPE
//template<> struct TypeToEnum<vx_size> { static const vx_enum val = VX_TYPE_SIZE; }; //template<> struct TypeToEnum<vx_size> { static const vx_enum val = VX_TYPE_SIZE; };
//template<> struct TypeToEnum<vx_df_image> { static const vx_enum val = VX_TYPE_DF_IMAGE; }; //template<> struct TypeToEnum<vx_df_image> { static const vx_enum val = VX_TYPE_DF_IMAGE; };
/* /// Helper type, provides info for OpenVX 'objects' (vx_reference extending) types
* RefTypeTraits - provides info for vx_reference extending types
*/
template <typename T> struct RefTypeTraits {}; template <typename T> struct RefTypeTraits {};
class Context; class Context;
...@@ -262,11 +263,10 @@ template <> struct RefTypeTraits <vx_threshold> ...@@ -262,11 +263,10 @@ template <> struct RefTypeTraits <vx_threshold>
static vx_status release(vxType& ref) { return vxReleaseThreshold(&ref); } static vx_status release(vxType& ref) { return vxReleaseThreshold(&ref); }
}; };
/*
* Casting to vx_reference with compile-time check
*/
#ifdef IVX_USE_CXX98 #ifdef IVX_USE_CXX98
/// Casting to vx_reference with compile-time check
// takes 'vx_reference' itself and RefWrapper<T> via 'operator vx_reference()' // takes 'vx_reference' itself and RefWrapper<T> via 'operator vx_reference()'
vx_reference castToReference(vx_reference ref) vx_reference castToReference(vx_reference ref)
{ return ref; } { return ref; }
...@@ -294,6 +294,8 @@ struct is_ref<T, decltype(T::vxType(), void())> : std::true_type {}; ...@@ -294,6 +294,8 @@ struct is_ref<T, decltype(T::vxType(), void())> : std::true_type {};
template<typename T> template<typename T>
struct is_ref<T, decltype(RefTypeTraits<T>::vxTypeEnum, void())> : std::true_type {}; struct is_ref<T, decltype(RefTypeTraits<T>::vxTypeEnum, void())> : std::true_type {};
/// Casting to vx_reference with compile-time check
template<typename T> template<typename T>
vx_reference castToReference(const T& obj) vx_reference castToReference(const T& obj)
{ {
...@@ -309,30 +311,35 @@ inline void checkVxRef(vx_reference ref, const std::string& func, const std::str ...@@ -309,30 +311,35 @@ inline void checkVxRef(vx_reference ref, const std::string& func, const std::str
if(status != VX_SUCCESS) throw RuntimeError( status, func + "() : " + msg ); if(status != VX_SUCCESS) throw RuntimeError( status, func + "() : " + msg );
} }
/// Helper macro for checking the provided OpenVX 'object' and throwing a \RuntimeError in case of error
#define IVX_CHECK_REF(code) checkVxRef(castToReference(code), __func__, #code) #define IVX_CHECK_REF(code) checkVxRef(castToReference(code), __func__, #code)
/*
* RefWrapper - base class for referenced objects wrappers
*/
#ifdef IVX_USE_EXTERNAL_REFCOUNT #ifdef IVX_USE_EXTERNAL_REFCOUNT
/// Base class for OpenVX 'objects' wrappers
template <typename T> class RefWrapper template <typename T> class RefWrapper
{ {
public: public:
typedef T vxType; typedef T vxType;
static const vx_enum vxTypeEnum = RefTypeTraits <T>::vxTypeEnum; static const vx_enum vxTypeEnum = RefTypeTraits <T>::vxTypeEnum;
/// Default constructor
RefWrapper() : ref(0), refcount(0) RefWrapper() : ref(0), refcount(0)
{} {}
/// Constructor
/// \param r OpenVX 'object' (e.g. vx_image)
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
explicit RefWrapper(T r, bool retainRef = false) : ref(0), refcount(0) explicit RefWrapper(T r, bool retainRef = false) : ref(0), refcount(0)
{ reset(r, retainRef); } { reset(r, retainRef); }
/// Copy constructor
RefWrapper(const RefWrapper& r) : ref(r.ref), refcount(r.refcount) RefWrapper(const RefWrapper& r) : ref(r.ref), refcount(r.refcount)
{ addRef(); } { addRef(); }
#ifndef IVX_USE_CXX98 #ifndef IVX_USE_CXX98
/// Move constructor
RefWrapper(RefWrapper&& rw) noexcept : RefWrapper() RefWrapper(RefWrapper&& rw) noexcept : RefWrapper()
{ {
using std::swap; using std::swap;
...@@ -341,12 +348,17 @@ public: ...@@ -341,12 +348,17 @@ public:
} }
#endif #endif
/// Casting to the wrapped OpenVX 'object'
operator T() const operator T() const
{ return ref; } { return ref; }
/// Casting to vx_reference since every OpenVX 'object' extends it
operator vx_reference() const operator vx_reference() const
{ return castToReference(ref); } { return castToReference(ref); }
/// Assigning a new value (decreasing ref counter for the old one)
/// \param r OpenVX 'object' (e.g. vx_image)
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
void reset(T r, bool retainRef = false) void reset(T r, bool retainRef = false)
{ {
release(); release();
...@@ -360,9 +372,12 @@ public: ...@@ -360,9 +372,12 @@ public:
checkRef(); checkRef();
} }
/// Assigning an empty value (decreasing ref counter for the old one)
void reset() void reset()
{ release(); } { release(); }
/// Dropping kept value without releas decreasing ref counter
/// \return the value being dropped
T detach() T detach()
{ {
T tmp = ref; T tmp = ref;
...@@ -371,6 +386,7 @@ public: ...@@ -371,6 +386,7 @@ public:
return tmp; return tmp;
} }
/// Unified assignment operator (covers both copy and move cases)
RefWrapper& operator=(RefWrapper r) RefWrapper& operator=(RefWrapper r)
{ {
using std::swap; using std::swap;
...@@ -379,15 +395,18 @@ public: ...@@ -379,15 +395,18 @@ public:
return *this; return *this;
} }
/// Checking for non-empty
bool operator !() const bool operator !() const
{ return ref == 0; } { return ref == 0; }
#ifndef IVX_USE_CXX98 #ifndef IVX_USE_CXX98
/// Explicit boolean evaluation (called automatically inside conditional operators only)
explicit operator bool() const explicit operator bool() const
{ return ref != 0; } { return ref != 0; }
#endif #endif
#ifdef IVX_USE_CXX98 #ifdef IVX_USE_CXX98
/// Getting a context that is kept in each OpenVX 'object' (call get<Context>())
template<typename C> template<typename C>
C get() const C get() const
{ {
...@@ -397,6 +416,7 @@ public: ...@@ -397,6 +416,7 @@ public:
return C(c, true); return C(c, true);
} }
#else #else
/// Getting a context that is kept in each OpenVX 'object'
template<typename C = Context, typename = typename std::enable_if<std::is_same<C, Context>::value>::type> template<typename C = Context, typename = typename std::enable_if<std::is_same<C, Context>::value>::type>
C getContext() const C getContext() const
{ {
...@@ -469,22 +489,29 @@ protected: ...@@ -469,22 +489,29 @@ protected:
#else // not IVX_USE_EXTERNAL_REFCOUNT #else // not IVX_USE_EXTERNAL_REFCOUNT
/// Base class for OpenVX 'objects' wrappers
template <typename T> class RefWrapper template <typename T> class RefWrapper
{ {
public: public:
typedef T vxType; typedef T vxType;
static const vx_enum vxTypeEnum = RefTypeTraits <T>::vxTypeEnum; static const vx_enum vxTypeEnum = RefTypeTraits <T>::vxTypeEnum;
/// Default constructor
RefWrapper() : ref(0) RefWrapper() : ref(0)
{} {}
/// Constructor
/// \param r OpenVX 'object' (e.g. vx_image)
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
explicit RefWrapper(T r, bool retainRef = false) : ref(0) explicit RefWrapper(T r, bool retainRef = false) : ref(0)
{ reset(r, retainRef); } { reset(r, retainRef); }
/// Copy constructor
RefWrapper(const RefWrapper& r) : ref(r.ref) RefWrapper(const RefWrapper& r) : ref(r.ref)
{ addRef(); } { addRef(); }
#ifndef IVX_USE_CXX98 #ifndef IVX_USE_CXX98
/// Move constructor
RefWrapper(RefWrapper&& rw) noexcept : RefWrapper() RefWrapper(RefWrapper&& rw) noexcept : RefWrapper()
{ {
using std::swap; using std::swap;
...@@ -492,13 +519,16 @@ public: ...@@ -492,13 +519,16 @@ public:
} }
#endif #endif
/// Casting to the wrapped OpenVX 'object'
operator T() const operator T() const
{ return ref; } { return ref; }
/// Casting to vx_reference since every OpenVX 'object' extends it
operator vx_reference() const operator vx_reference() const
{ return castToReference(ref); } { return castToReference(ref); }
#ifdef IVX_USE_CXX98 #ifdef IVX_USE_CXX98
/// Getting a context that is kept in each OpenVX 'object' (call get<Context>())
template<typename C> template<typename C>
C get() const C get() const
{ {
...@@ -508,6 +538,7 @@ public: ...@@ -508,6 +538,7 @@ public:
return C(c, true); return C(c, true);
} }
#else #else
/// Getting a context that is kept in each OpenVX 'object'
template<typename C = Context, typename = typename std::enable_if<std::is_same<C, Context>::value>::type> template<typename C = Context, typename = typename std::enable_if<std::is_same<C, Context>::value>::type>
C getContext() const C getContext() const
{ {
...@@ -517,6 +548,9 @@ public: ...@@ -517,6 +548,9 @@ public:
} }
#endif // IVX_USE_CXX98 #endif // IVX_USE_CXX98
/// Assigning a new value (decreasing ref counter for the old one)
/// \param r OpenVX 'object' (e.g. vx_image)
/// \param retainRef flag indicating whether to increase ref counter in constructor (false by default)
void reset(T r, bool retainRef = false) void reset(T r, bool retainRef = false)
{ {
release(); release();
...@@ -525,9 +559,12 @@ public: ...@@ -525,9 +559,12 @@ public:
checkRef(); checkRef();
} }
/// Assigning an empty value (decreasing ref counter for the old one)
void reset() void reset()
{ release(); } { release(); }
/// Dropping kept value without releas decreasing ref counter
/// \return the value being dropped
T detach() T detach()
{ {
T tmp = ref; T tmp = ref;
...@@ -535,6 +572,7 @@ public: ...@@ -535,6 +572,7 @@ public:
return tmp; return tmp;
} }
/// Unified assignment operator (covers both copy and move cases)
RefWrapper& operator=(RefWrapper r) RefWrapper& operator=(RefWrapper r)
{ {
using std::swap; using std::swap;
...@@ -542,10 +580,12 @@ public: ...@@ -542,10 +580,12 @@ public:
return *this; return *this;
} }
/// Checking for non-empty
bool operator !() const bool operator !() const
{ return ref == 0; } { return ref == 0; }
#ifndef IVX_USE_CXX98 #ifndef IVX_USE_CXX98
/// Explicit boolean evaluation (called automatically inside conditional operators only)
explicit operator bool() const explicit operator bool() const
{ return ref != 0; } { return ref != 0; }
#endif #endif
...@@ -597,18 +637,18 @@ protected: ...@@ -597,18 +637,18 @@ protected:
#endif // IVX_USE_EXTERNAL_REFCOUNT #endif // IVX_USE_EXTERNAL_REFCOUNT
/* /// vx_context wrapper
* Context
*/
class Context : public RefWrapper<vx_context> class Context : public RefWrapper<vx_context>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Context) IVX_REF_STD_CTORS_AND_ASSIGNMENT(Context)
/// vxCreateContext() wrapper
static Context create() static Context create()
{ return Context(vxCreateContext()); } { return Context(vxCreateContext()); }
/// vxGetContext() wrapper
template <typename T> template <typename T>
static Context getFrom(const T& ref) static Context getFrom(const T& ref)
{ {
...@@ -617,62 +657,66 @@ public: ...@@ -617,62 +657,66 @@ public:
return Context(c, true); return Context(c, true);
} }
/// vxLoadKernels() wrapper
void loadKernels(const std::string& module) void loadKernels(const std::string& module)
{ IVX_CHECK_STATUS( vxLoadKernels(ref, module.c_str()) ); } { IVX_CHECK_STATUS( vxLoadKernels(ref, module.c_str()) ); }
}; };
/* /// vx_graph wrapper
* Graph
*/
class Graph : public RefWrapper<vx_graph> class Graph : public RefWrapper<vx_graph>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Graph); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Graph);
/// vxCreateGraph() wrapper
static Graph create(vx_context c) static Graph create(vx_context c)
{ return Graph(vxCreateGraph(c)); } { return Graph(vxCreateGraph(c)); }
/// vxVerifyGraph() wrapper
void verify() void verify()
{ IVX_CHECK_STATUS( vxVerifyGraph(ref) ); } { IVX_CHECK_STATUS( vxVerifyGraph(ref) ); }
/// vxProcessGraph() wrapper
void process() void process()
{ IVX_CHECK_STATUS( vxProcessGraph(ref) ); } { IVX_CHECK_STATUS( vxProcessGraph(ref) ); }
/// vxScheduleGraph() wrapper
void schedule() void schedule()
{ IVX_CHECK_STATUS(vxScheduleGraph(ref) ); } { IVX_CHECK_STATUS(vxScheduleGraph(ref) ); }
/// vxWaitGraph() wrapper
void wait() void wait()
{ IVX_CHECK_STATUS(vxWaitGraph(ref)); } { IVX_CHECK_STATUS(vxWaitGraph(ref)); }
}; };
/* /// vx_kernel wrapper
* Kernel
*/
class Kernel : public RefWrapper<vx_kernel> class Kernel : public RefWrapper<vx_kernel>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Kernel); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Kernel);
/// vxGetKernelByEnum() wrapper
static Kernel getByEnum(vx_context c, vx_enum kernelID) static Kernel getByEnum(vx_context c, vx_enum kernelID)
{ return Kernel(vxGetKernelByEnum(c, kernelID)); } { return Kernel(vxGetKernelByEnum(c, kernelID)); }
/// vxGetKernelByName() wrapper
static Kernel getByName(vx_context c, const std::string& name) static Kernel getByName(vx_context c, const std::string& name)
{ return Kernel(vxGetKernelByName(c, name.c_str())); } { return Kernel(vxGetKernelByName(c, name.c_str())); }
}; };
/*
* Node
*/
#ifdef IVX_USE_CXX98 #ifdef IVX_USE_CXX98
/// vx_node wrapper
class Node : public RefWrapper<vx_node> class Node : public RefWrapper<vx_node>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Node); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Node);
/// vxCreateGenericNode() wrapper
static Node create(vx_graph g, vx_kernel k) static Node create(vx_graph g, vx_kernel k)
{ return Node(vxCreateGenericNode(g, k)); } { return Node(vxCreateGenericNode(g, k)); }
/// Create node for the kernel and set the parameters
static Node create(vx_graph graph, vx_kernel kernel, const std::vector<vx_reference>& params) static Node create(vx_graph graph, vx_kernel kernel, const std::vector<vx_reference>& params)
{ {
Node node = Node::create(graph, kernel); Node node = Node::create(graph, kernel);
...@@ -682,9 +726,11 @@ public: ...@@ -682,9 +726,11 @@ public:
return node; return node;
} }
/// Create node for the kernel ID and set the parameters
static Node create(vx_graph graph, vx_enum kernelID, const std::vector<vx_reference>& params) static Node create(vx_graph graph, vx_enum kernelID, const std::vector<vx_reference>& params)
{ return Node::create(graph, Kernel::getByEnum(Context::getFrom(graph), kernelID), params); } { return Node::create(graph, Kernel::getByEnum(Context::getFrom(graph), kernelID), params); }
/// Create node for the kernel ID and set one parameter
template<typename T0> template<typename T0>
static Node create(vx_graph g, vx_enum kernelID, static Node create(vx_graph g, vx_enum kernelID,
const T0& arg0) const T0& arg0)
...@@ -694,6 +740,7 @@ public: ...@@ -694,6 +740,7 @@ public:
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params); return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
} }
/// Create node for the kernel ID and set two parameters
template<typename T0, typename T1> template<typename T0, typename T1>
static Node create(vx_graph g, vx_enum kernelID, static Node create(vx_graph g, vx_enum kernelID,
const T0& arg0, const T1& arg1) const T0& arg0, const T1& arg1)
...@@ -704,6 +751,7 @@ public: ...@@ -704,6 +751,7 @@ public:
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params); return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
} }
/// Create node for the kernel ID and set three parameters
template<typename T0, typename T1, typename T2> template<typename T0, typename T1, typename T2>
static Node create(vx_graph g, vx_enum kernelID, static Node create(vx_graph g, vx_enum kernelID,
const T0& arg0, const T1& arg1, const T2& arg2) const T0& arg0, const T1& arg1, const T2& arg2)
...@@ -715,6 +763,7 @@ public: ...@@ -715,6 +763,7 @@ public:
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params); return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
} }
/// Create node for the kernel ID and set four parameters
template<typename T0, typename T1, typename T2, typename T3> template<typename T0, typename T1, typename T2, typename T3>
static Node create(vx_graph g, vx_enum kernelID, static Node create(vx_graph g, vx_enum kernelID,
const T0& arg0, const T1& arg1, const T2& arg2, const T0& arg0, const T1& arg1, const T2& arg2,
...@@ -728,6 +777,7 @@ public: ...@@ -728,6 +777,7 @@ public:
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params); return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
} }
/// Create node for the kernel ID and set five parameters
template<typename T0, typename T1, typename T2, typename T3, typename T4> template<typename T0, typename T1, typename T2, typename T3, typename T4>
static Node create(vx_graph g, vx_enum kernelID, static Node create(vx_graph g, vx_enum kernelID,
const T0& arg0, const T1& arg1, const T2& arg2, const T0& arg0, const T1& arg1, const T2& arg2,
...@@ -742,6 +792,7 @@ public: ...@@ -742,6 +792,7 @@ public:
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params); return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
} }
/// Create node for the kernel ID and set six parameters
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5> template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
static Node create(vx_graph g, vx_enum kernelID, static Node create(vx_graph g, vx_enum kernelID,
const T0& arg0, const T1& arg1, const T2& arg2, const T0& arg0, const T1& arg1, const T2& arg2,
...@@ -757,20 +808,24 @@ public: ...@@ -757,20 +808,24 @@ public:
return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params); return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), params);
} }
/// vxSetParameterByIndex() wrapper
void setParameterByIndex(vx_uint32 index, vx_reference value) void setParameterByIndex(vx_uint32 index, vx_reference value)
{ IVX_CHECK_STATUS(vxSetParameterByIndex(ref, index, value)); } { IVX_CHECK_STATUS(vxSetParameterByIndex(ref, index, value)); }
}; };
#else // not IVX_USE_CXX98 #else // not IVX_USE_CXX98
/// vx_node wrapper
class Node : public RefWrapper<vx_node> class Node : public RefWrapper<vx_node>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Node); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Node);
/// vxCreateGenericNode() wrapper
static Node create(vx_graph g, vx_kernel k) static Node create(vx_graph g, vx_kernel k)
{ return Node(vxCreateGenericNode(g, k)); } { return Node(vxCreateGenericNode(g, k)); }
/// Create node for the kernel and set the parameters
static Node create(vx_graph graph, vx_kernel kernel, const std::vector<vx_reference>& params) static Node create(vx_graph graph, vx_kernel kernel, const std::vector<vx_reference>& params)
{ {
Node node = Node::create(graph, kernel); Node node = Node::create(graph, kernel);
...@@ -780,34 +835,39 @@ public: ...@@ -780,34 +835,39 @@ public:
return node; return node;
} }
/// Create node for the kernel ID and set the parameters
static Node create(vx_graph graph, vx_enum kernelID, const std::vector<vx_reference>& params) static Node create(vx_graph graph, vx_enum kernelID, const std::vector<vx_reference>& params)
{ return Node::create(graph, Kernel::getByEnum(Context::getFrom(graph), kernelID), params); } { return Node::create(graph, Kernel::getByEnum(Context::getFrom(graph), kernelID), params); }
/// Create node for the kernel ID and set the specified parameters
template<typename...Ts> template<typename...Ts>
static Node create(vx_graph g, vx_enum kernelID, const Ts&...args) static Node create(vx_graph g, vx_enum kernelID, const Ts&...args)
{ return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), { castToReference(args)... }); } { return create(g, Kernel::getByEnum(Context::getFrom(g), kernelID), { castToReference(args)... }); }
/// vxSetParameterByIndex() wrapper
void setParameterByIndex(vx_uint32 index, vx_reference value) void setParameterByIndex(vx_uint32 index, vx_reference value)
{ IVX_CHECK_STATUS(vxSetParameterByIndex(ref, index, value)); } { IVX_CHECK_STATUS(vxSetParameterByIndex(ref, index, value)); }
}; };
#endif // IVX_USE_CXX98 #endif // IVX_USE_CXX98
/* /// vx_image wrapper
* Image
*/
class Image : public RefWrapper<vx_image> class Image : public RefWrapper<vx_image>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Image); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Image);
/// vxCreateImage() wrapper
static Image create(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format) static Image create(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format)
{ return Image(vxCreateImage(context, width, height, format)); } { return Image(vxCreateImage(context, width, height, format)); }
/// vxCreateVirtualImage() wrapper
static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT) static Image createVirtual(vx_graph graph, vx_uint32 width = 0, vx_uint32 height = 0, vx_df_image format = VX_DF_IMAGE_VIRT)
{ return Image(vxCreateVirtualImage(graph, width, height, format)); } { return Image(vxCreateVirtualImage(graph, width, height, format)); }
/// Planes number for the specified image format (fourcc)
/// \return 0 for unknown formats
static vx_size planes(vx_df_image format) static vx_size planes(vx_df_image format)
{ {
switch (format) switch (format)
...@@ -831,9 +891,11 @@ public: ...@@ -831,9 +891,11 @@ public:
} }
} }
/// Create vx_imagepatch_addressing_t structure with default values
static vx_imagepatch_addressing_t createAddressing() static vx_imagepatch_addressing_t createAddressing()
{ vx_imagepatch_addressing_t ipa = VX_IMAGEPATCH_ADDR_INIT; return ipa; } { vx_imagepatch_addressing_t ipa = VX_IMAGEPATCH_ADDR_INIT; return ipa; }
/// Create vx_imagepatch_addressing_t structure with the provided values
static vx_imagepatch_addressing_t createAddressing( static vx_imagepatch_addressing_t createAddressing(
vx_uint32 dimX, vx_uint32 dimY, vx_uint32 dimX, vx_uint32 dimY,
vx_int32 strideX, vx_int32 strideY, vx_int32 strideX, vx_int32 strideY,
...@@ -851,9 +913,11 @@ public: ...@@ -851,9 +913,11 @@ public:
return ipa; return ipa;
} }
/// Create vx_imagepatch_addressing_t structure for the specified image plane and its valid region
vx_imagepatch_addressing_t createAddressing(vx_uint32 planeIdx) vx_imagepatch_addressing_t createAddressing(vx_uint32 planeIdx)
{ return createAddressing(planeIdx, getValidRegion()); } { return createAddressing(planeIdx, getValidRegion()); }
/// Create vx_imagepatch_addressing_t structure for the specified image plane and the provided region
vx_imagepatch_addressing_t createAddressing(vx_uint32 planeIdx, const vx_rectangle_t& rect) vx_imagepatch_addressing_t createAddressing(vx_uint32 planeIdx, const vx_rectangle_t& rect)
{ {
vx_uint32 w = rect.end_x-rect.start_x, h = rect.end_y-rect.start_y; vx_uint32 w = rect.end_x-rect.start_x, h = rect.end_y-rect.start_y;
...@@ -865,6 +929,7 @@ public: ...@@ -865,6 +929,7 @@ public:
#ifndef VX_VERSION_1_1 #ifndef VX_VERSION_1_1
static const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST; static const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST;
#endif #endif
/// vxCreateImageFromHandle() wrapper
static Image createFromHandle( static Image createFromHandle(
vx_context context, vx_df_image format, vx_context context, vx_df_image format,
const std::vector<vx_imagepatch_addressing_t>& addrs, const std::vector<vx_imagepatch_addressing_t>& addrs,
...@@ -885,36 +950,34 @@ public: ...@@ -885,36 +950,34 @@ public:
} }
#ifdef VX_VERSION_1_1 #ifdef VX_VERSION_1_1
/// vxSwapImageHandle() wrapper
/// \param newPtrs keeps addresses of new image planes data, can be of image planes size or empty when new pointers are not provided
/// \param prevPtrs storage for the previous addresses of image planes data, can be of image planes size or empty when previous pointers are not needed
void swapHandle(const std::vector<void*>& newPtrs, std::vector<void*>& prevPtrs) void swapHandle(const std::vector<void*>& newPtrs, std::vector<void*>& prevPtrs)
{ {
vx_size num = planes(); vx_size num = planes();
if(num == 0) if(num == 0)
throw WrapperError(std::string(__func__)+"(): unexpected planes number"); throw WrapperError(std::string(__func__)+"(): unexpected planes number");
if (newPtrs.size() < num) if (!newPtrs.empty() && newPtrs.size() != num)
throw WrapperError(std::string(__func__)+"(): too few input pointers"); throw WrapperError(std::string(__func__)+"(): unexpected number of input pointers");
if (prevPtrs.empty()) prevPtrs.resize(num, 0); if (!prevPtrs.empty() && prevPtrs.size() != num)
else if (prevPtrs.size() < num) throw WrapperError(std::string(__func__)+"(): unexpected number of output pointers");
throw WrapperError(std::string(__func__)+"(): too few output pointers"); IVX_CHECK_STATUS( vxSwapImageHandle( ref,
IVX_CHECK_STATUS( vxSwapImageHandle(ref, &newPtrs[0], &prevPtrs[0], num) ); newPtrs.empty() ? 0 : &newPtrs[0],
} prevPtrs.empty() ? 0 : &prevPtrs[0],
num ) );
void swapHandle(const std::vector<void*>& newPtrs)
{
vx_size num = planes();
if(num == 0)
throw WrapperError(std::string(__func__)+"(): unexpected planes number");
if (newPtrs.size() < num)
throw WrapperError(std::string(__func__)+"(): too few input pointers");
IVX_CHECK_STATUS( vxSwapImageHandle(ref, &newPtrs[0], 0, num) );
} }
/// vxSwapImageHandle() wrapper for the case when no new pointers provided and previous ones are not needed (retrive memory back)
void swapHandle() void swapHandle()
{ IVX_CHECK_STATUS( vxSwapImageHandle(ref, 0, 0, 0) ); } { IVX_CHECK_STATUS( vxSwapImageHandle(ref, 0, 0, 0) ); }
/// vxCreateImageFromChannel() wrapper
Image createFromChannel(vx_enum channel) Image createFromChannel(vx_enum channel)
{ return Image(vxCreateImageFromChannel(ref, channel)); } { return Image(vxCreateImageFromChannel(ref, channel)); }
#endif // VX_VERSION_1_1 #endif // VX_VERSION_1_1
/// vxQueryImage() wrapper
template<typename T> template<typename T>
void query(vx_enum att, T& value) const void query(vx_enum att, T& value) const
{ IVX_CHECK_STATUS( vxQueryImage(ref, att, &value, sizeof(value)) ); } { IVX_CHECK_STATUS( vxQueryImage(ref, att, &value, sizeof(value)) ); }
...@@ -930,6 +993,7 @@ static const vx_enum ...@@ -930,6 +993,7 @@ static const vx_enum
VX_IMAGE_SIZE = VX_IMAGE_ATTRIBUTE_SIZE; VX_IMAGE_SIZE = VX_IMAGE_ATTRIBUTE_SIZE;
#endif #endif
/// vxQueryImage(VX_IMAGE_WIDTH) wrapper
vx_uint32 width() const vx_uint32 width() const
{ {
vx_uint32 v; vx_uint32 v;
...@@ -937,6 +1001,7 @@ static const vx_enum ...@@ -937,6 +1001,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryImage(VX_IMAGE_HEIGHT) wrapper
vx_uint32 height() const vx_uint32 height() const
{ {
vx_uint32 v; vx_uint32 v;
...@@ -944,6 +1009,7 @@ static const vx_enum ...@@ -944,6 +1009,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryImage(VX_IMAGE_FORMAT) wrapper
vx_df_image format() const vx_df_image format() const
{ {
vx_df_image v; vx_df_image v;
...@@ -951,6 +1017,7 @@ static const vx_enum ...@@ -951,6 +1017,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryImage(VX_IMAGE_PLANES) wrapper
vx_size planes() const vx_size planes() const
{ {
vx_size v; vx_size v;
...@@ -958,6 +1025,7 @@ static const vx_enum ...@@ -958,6 +1025,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryImage(VX_IMAGE_SPACE) wrapper
vx_enum space() const vx_enum space() const
{ {
vx_enum v; vx_enum v;
...@@ -965,6 +1033,7 @@ static const vx_enum ...@@ -965,6 +1033,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryImage(VX_IMAGE_RANGE) wrapper
vx_enum range() const vx_enum range() const
{ {
vx_enum v; vx_enum v;
...@@ -972,6 +1041,7 @@ static const vx_enum ...@@ -972,6 +1041,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryImage(VX_IMAGE_SIZE) wrapper
vx_size size() const vx_size size() const
{ {
vx_size v; vx_size v;
...@@ -980,6 +1050,7 @@ static const vx_enum ...@@ -980,6 +1050,7 @@ static const vx_enum
} }
#ifdef VX_VERSION_1_1 #ifdef VX_VERSION_1_1
/// vxQueryImage(VX_IMAGE_MEMORY_TYPE) wrapper
vx_memory_type_e memType() const vx_memory_type_e memType() const
{ {
vx_memory_type_e v; vx_memory_type_e v;
...@@ -988,6 +1059,7 @@ static const vx_enum ...@@ -988,6 +1059,7 @@ static const vx_enum
} }
#endif // VX_VERSION_1_1 #endif // VX_VERSION_1_1
/// vxGetValidRegionImage() wrapper
vx_rectangle_t getValidRegion() const vx_rectangle_t getValidRegion() const
{ {
vx_rectangle_t rect; vx_rectangle_t rect;
...@@ -995,9 +1067,11 @@ static const vx_enum ...@@ -995,9 +1067,11 @@ static const vx_enum
return rect; return rect;
} }
/// vxComputeImagePatchSize(valid region) wrapper
vx_size computePatchSize(vx_uint32 planeIdx) vx_size computePatchSize(vx_uint32 planeIdx)
{ return computePatchSize(planeIdx, getValidRegion()); } { return computePatchSize(planeIdx, getValidRegion()); }
/// vxComputeImagePatchSize() wrapper
vx_size computePatchSize(vx_uint32 planeIdx, const vx_rectangle_t& rect) vx_size computePatchSize(vx_uint32 planeIdx, const vx_rectangle_t& rect)
{ {
vx_size bytes = vxComputeImagePatchSize(ref, &rect, planeIdx); vx_size bytes = vxComputeImagePatchSize(ref, &rect, planeIdx);
...@@ -1006,10 +1080,12 @@ static const vx_enum ...@@ -1006,10 +1080,12 @@ static const vx_enum
} }
#ifdef VX_VERSION_1_1 #ifdef VX_VERSION_1_1
/// vxSetImageValidRectangle() wrapper
void setValidRectangle(const vx_rectangle_t& rect) void setValidRectangle(const vx_rectangle_t& rect)
{ IVX_CHECK_STATUS( vxSetImageValidRectangle(ref, &rect) ); } { IVX_CHECK_STATUS( vxSetImageValidRectangle(ref, &rect) ); }
#endif // VX_VERSION_1_1 #endif // VX_VERSION_1_1
/// Copy image plane content to the provided memory
void copyTo(vx_uint32 planeIdx, const vx_imagepatch_addressing_t& addr, void* data) void copyTo(vx_uint32 planeIdx, const vx_imagepatch_addressing_t& addr, void* data)
{ {
if(!data) throw WrapperError(std::string(__func__)+"(): output pointer is 0"); if(!data) throw WrapperError(std::string(__func__)+"(): output pointer is 0");
...@@ -1029,6 +1105,7 @@ static const vx_enum ...@@ -1029,6 +1105,7 @@ static const vx_enum
#endif #endif
} }
/// Copy the provided memory data to the specified image plane
void copyFrom(vx_uint32 planeIdx, const vx_imagepatch_addressing_t& addr, const void* data) void copyFrom(vx_uint32 planeIdx, const vx_imagepatch_addressing_t& addr, const void* data)
{ {
if (!data) throw WrapperError(std::string(__func__)+"(): input pointer is 0"); if (!data) throw WrapperError(std::string(__func__)+"(): input pointer is 0");
...@@ -1049,6 +1126,7 @@ static const vx_enum ...@@ -1049,6 +1126,7 @@ static const vx_enum
#endif #endif
} }
/// vxCopyImagePatch() wrapper (or vxAccessImagePatch() + vxCommitImagePatch() for OpenVX 1.0)
void copy( vx_uint32 planeIdx, vx_rectangle_t rect, void copy( vx_uint32 planeIdx, vx_rectangle_t rect,
const vx_imagepatch_addressing_t& addr, void* data, const vx_imagepatch_addressing_t& addr, void* data,
vx_enum usage, vx_enum memType = VX_MEMORY_TYPE_HOST ) vx_enum usage, vx_enum memType = VX_MEMORY_TYPE_HOST )
...@@ -1064,6 +1142,8 @@ static const vx_enum ...@@ -1064,6 +1142,8 @@ static const vx_enum
} }
#ifdef IVX_USE_OPENCV #ifdef IVX_USE_OPENCV
/// Convert image format (fourcc) to cv::Mat type
/// \return CV_USRTYPE1 for unknown image formats
static int formatToMatType(vx_df_image format, vx_uint32 planeIdx = 0) static int formatToMatType(vx_df_image format, vx_uint32 planeIdx = 0)
{ {
switch (format) switch (format)
...@@ -1087,6 +1167,7 @@ static const vx_enum ...@@ -1087,6 +1167,7 @@ static const vx_enum
} }
} }
/// Convert cv::Mat type to standard image format (fourcc), throws WrapperError if not possible
static vx_df_image matTypeToFormat(int matType) static vx_df_image matTypeToFormat(int matType)
{ {
switch (matType) switch (matType)
...@@ -1102,6 +1183,7 @@ static const vx_enum ...@@ -1102,6 +1183,7 @@ static const vx_enum
} }
} }
/// Initialize cv::Mat shape to fit the specified image plane data
void createMatForPlane(cv::Mat& m, vx_uint32 planeIdx) void createMatForPlane(cv::Mat& m, vx_uint32 planeIdx)
{ {
vx_df_image f = format(); vx_df_image f = format();
...@@ -1142,14 +1224,24 @@ static const vx_enum ...@@ -1142,14 +1224,24 @@ static const vx_enum
} }
} }
/// Create vx_imagepatch_addressing_t corresponding to the provided cv::Mat
static vx_imagepatch_addressing_t createAddressing(const cv::Mat& m)
{
if(m.empty()) throw WrapperError(std::string(__func__)+"(): empty input Mat");
return createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step);
}
/// Copy image plane content to the provided cv::Mat (reallocate if needed)
void copyTo(vx_uint32 planeIdx, cv::Mat& m) void copyTo(vx_uint32 planeIdx, cv::Mat& m)
{ {
createMatForPlane(m, planeIdx); createMatForPlane(m, planeIdx);
copyTo(planeIdx, createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step), m.ptr()); copyTo(planeIdx, createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step), m.ptr());
} }
/// Copy the provided cv::Mat data to the specified image plane
void copyFrom(vx_uint32 planeIdx, const cv::Mat& m) void copyFrom(vx_uint32 planeIdx, const cv::Mat& m)
{ {
if(m.empty()) throw WrapperError(std::string(__func__)+"(): empty input Mat");
// TODO: add sizes consistency checks // TODO: add sizes consistency checks
//vx_rectangle_t r = getValidRegion(); //vx_rectangle_t r = getValidRegion();
copyFrom(planeIdx, createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step), m.ptr()); copyFrom(planeIdx, createAddressing((vx_uint32)m.cols, (vx_uint32)m.rows, (vx_int32)m.elemSize(), (vx_int32)m.step), m.ptr());
...@@ -1159,36 +1251,46 @@ static const vx_enum ...@@ -1159,36 +1251,46 @@ static const vx_enum
struct Patch; struct Patch;
}; };
/// Helper class for a mapping vx_image patch
struct Image::Patch struct Image::Patch
{ {
public: public:
/// reference to the current vx_imagepatch_addressing_t
const vx_imagepatch_addressing_t& addr() const const vx_imagepatch_addressing_t& addr() const
{ return _addr;} { return _addr;}
/// current pixels data pointer
void* data() const void* data() const
{ return _data; } { return _data; }
#ifdef VX_VERSION_1_1 #ifdef VX_VERSION_1_1
/// vx_memory_type_e for the current data pointer
vx_memory_type_e memType() const vx_memory_type_e memType() const
{ return _memType; } { return _memType; }
/// vx_map_id for the current mapping
vx_map_id mapId() const vx_map_id mapId() const
{ return _mapId; } { return _mapId; }
#else #else
/// reference to vx_rectangle_t for the current mapping
const vx_rectangle_t& rect() const const vx_rectangle_t& rect() const
{ return _rect; } { return _rect; }
/// Image plane index for the current mapping
vx_uint32 planeIdx() const vx_uint32 planeIdx() const
{ return _planeIdx; } { return _planeIdx; }
#endif // VX_VERSION_1_1 #endif // VX_VERSION_1_1
/// vx_image for the current mapping
vx_image img() const vx_image img() const
{ return _img; } { return _img; }
/// where this patch is mapped
bool isMapped() const bool isMapped() const
{ return _img != 0; } { return _img != 0; }
#ifdef IVX_USE_OPENCV #ifdef IVX_USE_OPENCV
/// Reference to cv::Mat instance wrapping the mapped image data, becomes invalid after unmap()
cv::Mat& getMat() cv::Mat& getMat()
{ return _m; } { return _m; }
#endif //IVX_USE_OPENCV #endif //IVX_USE_OPENCV
...@@ -1209,9 +1311,10 @@ protected: ...@@ -1209,9 +1311,10 @@ protected:
#endif #endif
public: public:
/// Default constructor
Patch() : _addr(createAddressing()), _data(0), _img(0) Patch() : _addr(createAddressing()), _data(0), _img(0)
#ifdef VX_VERSION_1_1 #ifdef VX_VERSION_1_1
, _memType(VX_MEMORY_TYPE_HOST) , _memType(VX_MEMORY_TYPE_HOST), _mapId(0)
{} {}
#else #else
, _planeIdx(-1) , _planeIdx(-1)
...@@ -1219,6 +1322,7 @@ public: ...@@ -1219,6 +1322,7 @@ public:
#endif #endif
#ifndef IVX_USE_CXX98 #ifndef IVX_USE_CXX98
/// Move constructor
Patch(Patch&& p) : Patch() Patch(Patch&& p) : Patch()
{ {
using std::swap; using std::swap;
...@@ -1236,9 +1340,11 @@ public: ...@@ -1236,9 +1340,11 @@ public:
} }
#endif #endif
/// vxMapImagePatch(VX_READ_ONLY, planeIdx valid region)
void map(vx_image img, vx_uint32 planeIdx) void map(vx_image img, vx_uint32 planeIdx)
{ map(img, planeIdx, Image(img, true).getValidRegion()); } { map(img, planeIdx, Image(img, true).getValidRegion()); }
/// vxMapImagePatch() wrapper (or vxAccessImagePatch() for 1.0)
void map(vx_image img, vx_uint32 planeIdx, const vx_rectangle_t& rect, vx_enum usage = VX_READ_ONLY, vx_uint32 flags = 0) void map(vx_image img, vx_uint32 planeIdx, const vx_rectangle_t& rect, vx_enum usage = VX_READ_ONLY, vx_uint32 flags = 0)
{ {
if (isMapped()) throw WrapperError(std::string(__func__)+"(): already mapped"); if (isMapped()) throw WrapperError(std::string(__func__)+"(): already mapped");
...@@ -1261,10 +1367,12 @@ public: ...@@ -1261,10 +1367,12 @@ public:
#endif #endif
} }
/// vxUnmapImagePatch() wrapper (or vxCommitImagePatch() for 1.0)
void unmap() void unmap()
{ {
#ifdef VX_VERSION_1_1 #ifdef VX_VERSION_1_1
IVX_CHECK_STATUS(vxUnmapImagePatch(_img, _mapId)); IVX_CHECK_STATUS(vxUnmapImagePatch(_img, _mapId));
_mapId = 0;
#else #else
IVX_CHECK_STATUS(vxCommitImagePatch(_img, &_rect, _planeIdx, &_addr, _data)); IVX_CHECK_STATUS(vxCommitImagePatch(_img, &_rect, _planeIdx, &_addr, _data));
_rect.start_x = _rect.end_x = _rect.start_y = _rect.end_y = 0u; _rect.start_x = _rect.end_x = _rect.start_y = _rect.end_y = 0u;
...@@ -1273,14 +1381,17 @@ public: ...@@ -1273,14 +1381,17 @@ public:
#endif #endif
_img = 0; _img = 0;
_data = 0; _data = 0;
_addr = createAddressing();
#ifdef IVX_USE_OPENCV #ifdef IVX_USE_OPENCV
_m.release(); _m.release();
#endif #endif
} }
/// Destructor
~Patch() ~Patch()
{ try { if (_img) unmap(); } catch(...) {; /*ignore*/} } { try { if (_img) unmap(); } catch(...) {; /*ignore*/} }
/// Pointer to the specified pixel data (vxFormatImagePatchAddress2d)
void* pixelPtr(vx_uint32 x, vx_uint32 y) void* pixelPtr(vx_uint32 x, vx_uint32 y)
{ {
if (!_data) throw WrapperError(std::string(__func__)+"(): base pointer is NULL"); if (!_data) throw WrapperError(std::string(__func__)+"(): base pointer is NULL");
...@@ -1297,9 +1408,7 @@ private: ...@@ -1297,9 +1408,7 @@ private:
#endif #endif
}; };
/* /// vx_parameter wrapper
* Param
*/
class Param : public RefWrapper<vx_parameter> class Param : public RefWrapper<vx_parameter>
{ {
public: public:
...@@ -1307,26 +1416,31 @@ public: ...@@ -1307,26 +1416,31 @@ public:
// NYI // NYI
}; };
/* /// vx_scalar wrapper
* Scalar
*/
class Scalar : public RefWrapper<vx_scalar> class Scalar : public RefWrapper<vx_scalar>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Scalar); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Scalar);
/// vxCreateScalar() wrapper
static Scalar create(vx_context c, vx_enum dataType, const void *ptr) static Scalar create(vx_context c, vx_enum dataType, const void *ptr)
{ return Scalar( vxCreateScalar(c, dataType, ptr) ); } { return Scalar( vxCreateScalar(c, dataType, ptr) ); }
/// vxCreateScalar() wrapper, value is passed as a value not as a pointer
template<typename T> static Scalar create(vx_context c, vx_enum dataType, T value) template<typename T> static Scalar create(vx_context c, vx_enum dataType, T value)
{ return Scalar( vxCreateScalar(c, dataType, &value) ); } {
typedef int static_assert_not_pointer[is_pointer<T>::value ? -1 : 1];
return Scalar( vxCreateScalar(c, dataType, &value) );
}
/// vxCreateScalar() wrapper, data type is guessed based on the passed value
template<vx_enum E> static Scalar create(vx_context c, typename EnumToType<E>::type value) template<vx_enum E> static Scalar create(vx_context c, typename EnumToType<E>::type value)
{ return Scalar( vxCreateScalar(c, E, &value) ); } { return Scalar( vxCreateScalar(c, E, &value) ); }
#ifndef VX_VERSION_1_1 #ifndef VX_VERSION_1_1
static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE; static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE;
#endif #endif
/// Get scalar data type
vx_enum type() vx_enum type()
{ {
vx_enum val; vx_enum val;
...@@ -1334,6 +1448,7 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE; ...@@ -1334,6 +1448,7 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE;
return val; return val;
} }
/// Get scalar value
template<typename T> template<typename T>
void getValue(T& val) void getValue(T& val)
{ {
...@@ -1345,6 +1460,7 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE; ...@@ -1345,6 +1460,7 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE;
#endif #endif
} }
/// Get scalar value
template<typename T> template<typename T>
T getValue() T getValue()
{ {
...@@ -1354,6 +1470,7 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE; ...@@ -1354,6 +1470,7 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE;
} }
/// Set scalar value
template<typename T> template<typename T>
void setValue(T val) void setValue(T val)
{ {
...@@ -1366,14 +1483,13 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE; ...@@ -1366,14 +1483,13 @@ static const vx_enum VX_SCALAR_TYPE = VX_SCALAR_ATTRIBUTE_TYPE;
} }
}; };
/* /// vx_threshold wrapper
* Threshold
*/
class Threshold : public RefWrapper<vx_threshold> class Threshold : public RefWrapper<vx_threshold>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Threshold); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Threshold);
/// vxCreateThreshold() wrapper
static Threshold create(vx_context c, vx_enum threshType, vx_enum dataType) static Threshold create(vx_context c, vx_enum threshType, vx_enum dataType)
{ return Threshold(vxCreateThreshold(c, threshType, dataType)); } { return Threshold(vxCreateThreshold(c, threshType, dataType)); }
...@@ -1389,6 +1505,7 @@ static const vx_enum ...@@ -1389,6 +1505,7 @@ static const vx_enum
#endif #endif
/// Create binary threshold with the provided value
static Threshold createBinary(vx_context c, vx_enum dataType, vx_int32 val) static Threshold createBinary(vx_context c, vx_enum dataType, vx_int32 val)
{ {
Threshold thr = create(c, VX_THRESHOLD_TYPE_BINARY, dataType); Threshold thr = create(c, VX_THRESHOLD_TYPE_BINARY, dataType);
...@@ -1396,7 +1513,8 @@ static const vx_enum ...@@ -1396,7 +1513,8 @@ static const vx_enum
return thr; return thr;
} }
static Threshold createRange(vx_context c, vx_enum dataType, vx_int32 val1, vx_int32 val2) /// Create range threshold with the provided low and high values
static Threshold createRange(vx_context c, vx_enum dataType, vx_int32 valLower, vx_int32 valUpper)
{ {
Threshold thr = create(c, VX_THRESHOLD_TYPE_RANGE, dataType); Threshold thr = create(c, VX_THRESHOLD_TYPE_RANGE, dataType);
IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_LOWER, &val1, sizeof(val1)) ); IVX_CHECK_STATUS( vxSetThresholdAttribute(thr.ref, VX_THRESHOLD_THRESHOLD_LOWER, &val1, sizeof(val1)) );
...@@ -1404,10 +1522,12 @@ static const vx_enum ...@@ -1404,10 +1522,12 @@ static const vx_enum
return thr; return thr;
} }
/// vxQueryThreshold() wrapper
template<typename T> template<typename T>
void query(vx_enum att, T& value) const void query(vx_enum att, T& value) const
{ IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &value, sizeof(value)) ); } { IVX_CHECK_STATUS( vxQueryThreshold(ref, att, &value, sizeof(value)) ); }
/// vxQueryThreshold(VX_THRESHOLD_TYPE) wrapper
vx_enum type() const vx_enum type() const
{ {
vx_enum v; vx_enum v;
...@@ -1415,6 +1535,7 @@ static const vx_enum ...@@ -1415,6 +1535,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryThreshold(DATA_TYPE) wrapper
vx_enum dataType() const vx_enum dataType() const
{ {
vx_enum v; vx_enum v;
...@@ -1422,6 +1543,7 @@ static const vx_enum ...@@ -1422,6 +1543,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryThreshold(THRESHOLD_VALUE) wrapper
vx_int32 value() const vx_int32 value() const
{ {
vx_int32 v; vx_int32 v;
...@@ -1429,6 +1551,7 @@ static const vx_enum ...@@ -1429,6 +1551,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryThreshold(THRESHOLD_LOWER) wrapper
vx_int32 valueLower() const vx_int32 valueLower() const
{ {
vx_int32 v; vx_int32 v;
...@@ -1436,6 +1559,7 @@ static const vx_enum ...@@ -1436,6 +1559,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryThreshold(THRESHOLD_UPPER) wrapper
vx_int32 valueUpper() const vx_int32 valueUpper() const
{ {
vx_int32 v; vx_int32 v;
...@@ -1443,6 +1567,7 @@ static const vx_enum ...@@ -1443,6 +1567,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryThreshold(TRUE_VALUE) wrapper
vx_int32 valueTrue() const vx_int32 valueTrue() const
{ {
vx_int32 v; vx_int32 v;
...@@ -1450,6 +1575,7 @@ static const vx_enum ...@@ -1450,6 +1575,7 @@ static const vx_enum
return v; return v;
} }
/// vxQueryThreshold(FALSE_VALUE) wrapper
vx_int32 valueFalse() const vx_int32 valueFalse() const
{ {
vx_int32 v; vx_int32 v;
...@@ -1458,31 +1584,28 @@ static const vx_enum ...@@ -1458,31 +1584,28 @@ static const vx_enum
} }
}; };
/* /// vx_array wrapper
* Array
*/
class Array : public RefWrapper<vx_array> class Array : public RefWrapper<vx_array>
{ {
public: public:
IVX_REF_STD_CTORS_AND_ASSIGNMENT(Array); IVX_REF_STD_CTORS_AND_ASSIGNMENT(Array);
/// vxCreateArray() wrapper
static Array create(vx_context c, vx_enum type, vx_size capacity) static Array create(vx_context c, vx_enum type, vx_size capacity)
{ return Array(vxCreateArray(c, type, capacity)); } { return Array(vxCreateArray(c, type, capacity)); }
/// vxCreateVirtualArray() wrapper
static Array createVirtual(vx_graph g, vx_enum type, vx_size capacity) static Array createVirtual(vx_graph g, vx_enum type, vx_size capacity)
{ return Array(vxCreateVirtualArray(g, type, capacity)); } { return Array(vxCreateVirtualArray(g, type, capacity)); }
}; };
/* /// Standard nodes
* standard nodes
*/
namespace nodes { namespace nodes {
/// Creates a Gaussian Filter 3x3 Node (vxGaussian3x3Node)
Node gaussian3x3(vx_graph graph, vx_image inImg, vx_image outImg) Node gaussian3x3(vx_graph graph, vx_image inImg, vx_image outImg)
{ { return Node(vxGaussian3x3Node(graph, inImg, outImg)); }
return Node(vxGaussian3x3Node(graph, inImg, outImg));
}
} // namespace nodes } // namespace nodes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment