diff --git a/3rdparty/ippicv/downloader.cmake b/3rdparty/ippicv/downloader.cmake index e20804d7b4..0b186c0946 100644 --- a/3rdparty/ippicv/downloader.cmake +++ b/3rdparty/ippicv/downloader.cmake @@ -31,7 +31,7 @@ function(_icv_downloader) return() # Not supported endif() - set(OPENCV_ICV_UNPACK_PATH "${CMAKE_CURRENT_LIST_DIR}/unpack") + set(OPENCV_ICV_UNPACK_PATH "${CMAKE_BINARY_DIR}/3rdparty/ippicv") set(OPENCV_ICV_PATH "${OPENCV_ICV_UNPACK_PATH}${OPENCV_ICV_PACKAGE_SUBDIR}") if(DEFINED OPENCV_ICV_PACKAGE_DOWNLOADED diff --git a/3rdparty/openvx/CMakeLists.txt b/3rdparty/openvx/CMakeLists.txt index 4c71ecfe6b..41fd377d70 100644 --- a/3rdparty/openvx/CMakeLists.txt +++ b/3rdparty/openvx/CMakeLists.txt @@ -1,18 +1,7 @@ -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 - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/modules/core/include - ${CMAKE_SOURCE_DIR}/modules/imgproc/include - ${OPENVX_INCLUDE_DIR}) -target_link_libraries(openvx_hal LINK_PUBLIC ${OPENVX_LIBRARIES}) -set_target_properties(openvx_hal PROPERTIES POSITION_INDEPENDENT_CODE TRUE) -set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}) -if(NOT BUILD_SHARED_LIBS) - ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) +if(NOT HAVE_OPENVX) + message(STATUS "OpenVX is not available, disabling openvx-related HAL and stuff") + return() endif() -set(OPENVX_HAL_FOUND TRUE PARENT_SCOPE) -set(OPENVX_HAL_VERSION 0.0.1 PARENT_SCOPE) -set(OPENVX_HAL_LIBRARIES "openvx_hal" PARENT_SCOPE) -set(OPENVX_HAL_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/openvx_hal.hpp" PARENT_SCOPE) -set(OPENVX_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" "${OPENVX_INCLUDE_DIR}" PARENT_SCOPE) +set(OPENCV_3P_OPENVX_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +add_subdirectory(hal) \ No newline at end of file diff --git a/3rdparty/openvx/hal/CMakeLists.txt b/3rdparty/openvx/hal/CMakeLists.txt new file mode 100644 index 0000000000..519d8d731f --- /dev/null +++ b/3rdparty/openvx/hal/CMakeLists.txt @@ -0,0 +1,19 @@ +add_library(openvx_hal STATIC openvx_hal.cpp openvx_hal.hpp ${OPENCV_3P_OPENVX_DIR}/include/ivx.hpp ${OPENCV_3P_OPENVX_DIR}/include/ivx_lib_debug.hpp) +target_include_directories(openvx_hal PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${OPENCV_3P_OPENVX_DIR}/include + ${CMAKE_SOURCE_DIR}/modules/core/include + ${CMAKE_SOURCE_DIR}/modules/imgproc/include + ${OPENVX_INCLUDE_DIR}) +target_link_libraries(openvx_hal LINK_PUBLIC ${OPENVX_LIBRARIES}) +set_target_properties(openvx_hal PROPERTIES POSITION_INDEPENDENT_CODE TRUE) +set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}) +if(NOT BUILD_SHARED_LIBS) + ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) +endif() + +set(OPENVX_HAL_FOUND TRUE CACHE INTERNAL "") +set(OPENVX_HAL_VERSION 0.0.1 CACHE INTERNAL "") +set(OPENVX_HAL_LIBRARIES "openvx_hal" CACHE INTERNAL "") +set(OPENVX_HAL_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/openvx_hal.hpp" CACHE INTERNAL "") +set(OPENVX_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" "${OPENCV_3P_OPENVX_DIR}/include" "${OPENVX_INCLUDE_DIR}" CACHE INTERNAL "") diff --git a/3rdparty/openvx/hal/README.md b/3rdparty/openvx/hal/README.md new file mode 100644 index 0000000000..a4266015a7 --- /dev/null +++ b/3rdparty/openvx/hal/README.md @@ -0,0 +1,4 @@ +#OpenVX-based HAL implementation. +It's built when OpenVX is available (`HAVE_OPENVX`). +To build OpenCV with OpenVX support add the following **cmake** options: +`-DOPENVX_ROOT=/path/to/prebuilt/openvx -DWITH_OPENVX=YES` \ No newline at end of file diff --git a/3rdparty/openvx/hal/openvx_hal.cpp b/3rdparty/openvx/hal/openvx_hal.cpp new file mode 100644 index 0000000000..f7962d1eb5 --- /dev/null +++ b/3rdparty/openvx/hal/openvx_hal.cpp @@ -0,0 +1,1088 @@ +#include "openvx_hal.hpp" + +#define IVX_HIDE_INFO_WARNINGS +#include "ivx.hpp" + +#include +#include + +#include +#include +#include +#include + +//================================================================================================== +// utility +// ... + +#if 0 +#include +#define PRINT(...) printf(__VA_ARGS__) +#define PRINT_HALERR_MSG(type) PRINT("OpenVX HAL impl "#type" error: %s\n", e.what()) +#else +#define PRINT(...) +#define PRINT_HALERR_MSG(type) (void)e +#endif + + +#if __cplusplus >= 201103L +#include +struct Tick +{ + typedef std::chrono::time_point point_t; + point_t start; + point_t point; + Tick() + { + start = std::chrono::steady_clock::now(); + point = std::chrono::steady_clock::now(); + } + inline int one() + { + point_t old = point; + point = std::chrono::steady_clock::now(); + return std::chrono::duration_cast(point - old).count(); + } + inline int total() + { + return std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count(); + } +}; +#endif + +inline ivx::Context& getOpenVXHALContext() +{ + // not thread safe + static ivx::Context instance = ivx::Context::create(); + return instance; +} + +inline bool dimTooBig(int size) +{ + static vx_uint16 current_vendor = getOpenVXHALContext().vendorID(); + + if (current_vendor == VX_ID_KHRONOS || current_vendor == VX_ID_DEFAULT) + { + //OpenVX use uint32_t for image addressing + return ((unsigned)size > (UINT_MAX / VX_SCALE_UNITY)); + } + else + return false; +} + +inline void setConstantBorder(ivx::border_t &border, vx_uint8 val) +{ + border.mode = VX_BORDER_CONSTANT; +#if VX_VERSION > VX_VERSION_1_0 + border.constant_value.U8 = val; +#else + border.constant_value = val; +#endif +} + +inline void refineStep(int w, int h, int imgType, size_t& step) +{ + if (h == 1) + step = w * ((imgType == VX_DF_IMAGE_RGBX || + imgType == VX_DF_IMAGE_U32 || imgType == VX_DF_IMAGE_S32) ? 4 : + imgType == VX_DF_IMAGE_RGB ? 3 : + (imgType == VX_DF_IMAGE_U16 || imgType == VX_DF_IMAGE_S16 || + imgType == VX_DF_IMAGE_UYVY || imgType == VX_DF_IMAGE_YUYV) ? 2 : 1); +} + +//================================================================================================== +// ivx::Image wrapped to simplify call to swapHandle prior to release +// TODO update ivx::Image to handle swapHandle prior to release on the own + +class vxImage: public ivx::Image +{ +public: + vxImage(const ivx::Image &_img) : ivx::Image(_img) {} + + ~vxImage() + { +#if VX_VERSION > VX_VERSION_1_0 + swapHandle(); +#endif + } +}; + +//================================================================================================== +// real code starts here +// ... + +#define OVX_BINARY_OP(hal_func, ovx_call) \ +template \ +int ovx_hal_##hal_func(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h) \ +{ \ + if(dimTooBig(w) || dimTooBig(h)) \ + return CV_HAL_ERROR_NOT_IMPLEMENTED; \ + refineStep(w, h, ivx::TypeToEnum::imgType, astep); \ + refineStep(w, h, ivx::TypeToEnum::imgType, bstep); \ + refineStep(w, h, ivx::TypeToEnum::imgType, cstep); \ + try \ + { \ + ivx::Context ctx = getOpenVXHALContext(); \ + vxImage \ + ia = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum::imgType, \ + ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(astep)), (void*)a), \ + ib = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum::imgType, \ + ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(bstep)), (void*)b), \ + ic = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum::imgType, \ + ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(cstep)), (void*)c); \ + ovx_call \ + } \ + catch (ivx::RuntimeError & e) \ + { \ + PRINT_HALERR_MSG(runtime); \ + return CV_HAL_ERROR_UNKNOWN; \ + } \ + catch (ivx::WrapperError & e) \ + { \ + PRINT_HALERR_MSG(wrapper); \ + return CV_HAL_ERROR_UNKNOWN; \ + } \ + return CV_HAL_ERROR_OK; \ +} + +OVX_BINARY_OP(add, { ivx::IVX_CHECK_STATUS(vxuAdd(ctx, ia, ib, VX_CONVERT_POLICY_SATURATE, ic)); }) +OVX_BINARY_OP(sub, { ivx::IVX_CHECK_STATUS(vxuSubtract(ctx, ia, ib, VX_CONVERT_POLICY_SATURATE, ic)); }) + +OVX_BINARY_OP(absdiff, { ivx::IVX_CHECK_STATUS(vxuAbsDiff(ctx, ia, ib, ic)); }) + +OVX_BINARY_OP(and, { ivx::IVX_CHECK_STATUS(vxuAnd(ctx, ia, ib, ic)); }) +OVX_BINARY_OP(or , { ivx::IVX_CHECK_STATUS(vxuOr(ctx, ia, ib, ic)); }) +OVX_BINARY_OP(xor, { ivx::IVX_CHECK_STATUS(vxuXor(ctx, ia, ib, ic)); }) + +template +int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h, double scale) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, ivx::TypeToEnum::imgType, astep); + refineStep(w, h, ivx::TypeToEnum::imgType, bstep); + refineStep(w, h, ivx::TypeToEnum::imgType, cstep); +#ifdef _MSC_VER + const float MAGIC_SCALE = 0x0.01010102; +#else + const float MAGIC_SCALE = 0x1.010102p-8; +#endif + try + { + int rounding_policy = VX_ROUND_POLICY_TO_ZERO; + float fscale = (float)scale; + if (fabs(fscale - MAGIC_SCALE) > FLT_EPSILON) + { + int exp = 0; + double significand = frexp(fscale, &exp); + if ((significand != 0.5) || (exp > 1) || (exp < -14)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + else + { + fscale = MAGIC_SCALE; + rounding_policy = VX_ROUND_POLICY_TO_NEAREST_EVEN;// That's the only rounding that MUST be supported for 1/255 scale + } + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum::imgType, + ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(astep)), (void*)a), + ib = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum::imgType, + ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(bstep)), (void*)b), + ic = ivx::Image::createFromHandle(ctx, ivx::TypeToEnum::imgType, + ivx::Image::createAddressing(w, h, sizeof(T), (vx_int32)(cstep)), (void*)c); + ivx::IVX_CHECK_STATUS(vxuMultiply(ctx, ia, ib, fscale, VX_CONVERT_POLICY_SATURATE, rounding_policy, ic)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +template int ovx_hal_add(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h); +template int ovx_hal_add(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h); +template int ovx_hal_sub(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h); +template int ovx_hal_sub(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h); + +template int ovx_hal_absdiff(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h); +template int ovx_hal_absdiff(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h); + +template int ovx_hal_and(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h); +template int ovx_hal_or(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h); +template int ovx_hal_xor(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h); + +template int ovx_hal_mul(const uchar *a, size_t astep, const uchar *b, size_t bstep, uchar *c, size_t cstep, int w, int h, double scale); +template int ovx_hal_mul(const short *a, size_t astep, const short *b, size_t bstep, short *c, size_t cstep, int w, int h, double scale); + +int ovx_hal_not(const uchar *a, size_t astep, uchar *c, size_t cstep, int w, int h) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, VX_DF_IMAGE_U8, astep); + refineStep(w, h, VX_DF_IMAGE_U8, cstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, 1, (vx_int32)(astep)), (void*)a), + ic = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, 1, (vx_int32)(cstep)), (void*)c); + ivx::IVX_CHECK_STATUS(vxuNot(ctx, ia, ic)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_merge8u(const uchar **src_data, uchar *dst_data, int len, int cn) +{ + if (dimTooBig(len)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (cn != 3 && cn != 4) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[0]), + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[1]), + ic = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[2]), + id = ivx::Image::createFromHandle(ctx, cn == 4 ? VX_DF_IMAGE_RGBX : VX_DF_IMAGE_RGB, + ivx::Image::createAddressing(len, 1, cn, (vx_int32)(len*cn)), (void*)dst_data); + ivx::IVX_CHECK_STATUS(vxuChannelCombine(ctx, ia, ib, ic, + cn == 4 ? (vx_image)(ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(len, 1, 1, (vx_int32)(len)), (void*)src_data[3])) : NULL, + id)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, double inv_scale_x, double inv_scale_y, int interpolation) +{ + if (dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(aw, ah, VX_DF_IMAGE_U8, astep); + refineStep(bw, bh, VX_DF_IMAGE_U8, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(aw, ah, 1, (vx_int32)(astep)), (void*)a), + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(bw, bh, 1, (vx_int32)(bstep)), (void*)b); + + if (!((atype == CV_8UC1 || atype == CV_8SC1) && + inv_scale_x > 0 && inv_scale_y > 0 && + (bw - 0.5) / inv_scale_x - 0.5 < aw && (bh - 0.5) / inv_scale_y - 0.5 < ah && + (bw + 0.5) / inv_scale_x + 0.5 >= aw && (bh + 0.5) / inv_scale_y + 0.5 >= ah && + std::abs(bw / inv_scale_x - aw) < 0.1 && std::abs(bh / inv_scale_y - ah) < 0.1)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + int mode; + if (interpolation == CV_HAL_INTER_LINEAR) + { + mode = VX_INTERPOLATION_BILINEAR; + if (inv_scale_x > 1 || inv_scale_y > 1) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + else if (interpolation == CV_HAL_INTER_AREA) + return CV_HAL_ERROR_NOT_IMPLEMENTED; //mode = VX_INTERPOLATION_AREA; + else if (interpolation == CV_HAL_INTER_NEAREST) + return CV_HAL_ERROR_NOT_IMPLEMENTED; //mode = VX_INTERPOLATION_NEAREST_NEIGHBOR; + else + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + ivx::IVX_CHECK_STATUS(vxuScaleImage(ctx, ia, ib, mode)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_warpAffine(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[6], int interpolation, int borderType, const double borderValue[4]) +{ + if (dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(aw, ah, VX_DF_IMAGE_U8, astep); + refineStep(bw, bh, VX_DF_IMAGE_U8, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(aw, ah, 1, (vx_int32)(astep)), (void*)a), + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(bw, bh, 1, (vx_int32)(bstep)), (void*)b); + + if (!(atype == CV_8UC1 || atype == CV_8SC1)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + if(borderType != CV_HAL_BORDER_CONSTANT) // Neither 1.0 nor 1.1 OpenVX support BORDER_REPLICATE for warpings + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + int mode; + if (interpolation == CV_HAL_INTER_LINEAR) + mode = VX_INTERPOLATION_BILINEAR; + //AREA interpolation is unsupported + //else if (interpolation == CV_HAL_INTER_AREA) + // mode = VX_INTERPOLATION_AREA; + else if (interpolation == CV_HAL_INTER_NEAREST) + mode = VX_INTERPOLATION_NEAREST_NEIGHBOR; + else + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + std::vector data; + data.reserve(6); + for (int j = 0; j < 3; ++j) + for (int i = 0; i < 2; ++i) + data.push_back((float)(M[i * 3 + j])); + + ivx::Matrix mtx = ivx::Matrix::create(ctx, VX_TYPE_FLOAT32, 2, 3); + mtx.copyFrom(data); + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standart says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(VX_BORDER_CONSTANT, (vx_uint8)borderValue[0]); + ivx::IVX_CHECK_STATUS(vxuWarpAffine(ctx, ia, mtx, mode, ib)); + ctx.setImmediateBorder(prevBorder); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_warpPerspectve(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[9], int interpolation, int borderType, const double borderValue[4]) +{ + if (dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(aw, ah, VX_DF_IMAGE_U8, astep); + refineStep(bw, bh, VX_DF_IMAGE_U8, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(aw, ah, 1, (vx_int32)(astep)), (void*)a), + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(bw, bh, 1, (vx_int32)(bstep)), (void*)b); + + if (!(atype == CV_8UC1 || atype == CV_8SC1)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + if (borderType != CV_HAL_BORDER_CONSTANT) // Neither 1.0 nor 1.1 OpenVX support BORDER_REPLICATE for warpings + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + int mode; + if (interpolation == CV_HAL_INTER_LINEAR) + mode = VX_INTERPOLATION_BILINEAR; + //AREA interpolation is unsupported + //else if (interpolation == CV_HAL_INTER_AREA) + // mode = VX_INTERPOLATION_AREA; + else if (interpolation == CV_HAL_INTER_NEAREST) + mode = VX_INTERPOLATION_NEAREST_NEIGHBOR; + else + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + std::vector data; + data.reserve(9); + for (int j = 0; j < 3; ++j) + for (int i = 0; i < 3; ++i) + data.push_back((float)(M[i * 3 + j])); + + ivx::Matrix mtx = ivx::Matrix::create(ctx, VX_TYPE_FLOAT32, 3, 3); + mtx.copyFrom(data); + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standart says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(VX_BORDER_CONSTANT, (vx_uint8)borderValue[0]); + ivx::IVX_CHECK_STATUS(vxuWarpPerspective(ctx, ia, mtx, mode, ib)); + ctx.setImmediateBorder(prevBorder); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +struct cvhalFilter2D; + +struct FilterCtx +{ + ivx::Convolution cnv; + int dst_type; + ivx::border_t border; + FilterCtx(ivx::Context &ctx, const std::vector data, int w, int h, int _dst_type, ivx::border_t & _border) : + cnv(ivx::Convolution::create(ctx, w, h)), dst_type(_dst_type), border(_border) { + cnv.copyFrom(data); + } +}; + +int ovx_hal_filterInit(cvhalFilter2D **filter_context, uchar *kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height, + int, int, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool allowSubmatrix, bool allowInplace) +{ + if (!filter_context || !kernel_data || allowSubmatrix || allowInplace || delta != 0 || + src_type != CV_8UC1 || (dst_type != CV_8UC1 && dst_type != CV_16SC1) || + kernel_width % 2 == 0 || kernel_height % 2 == 0 || anchor_x != kernel_width / 2 || anchor_y != kernel_height / 2) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + ivx::border_t border; + switch (borderType) + { + case CV_HAL_BORDER_CONSTANT: + setConstantBorder(border, 0); + break; + case CV_HAL_BORDER_REPLICATE: + border.mode = VX_BORDER_REPLICATE; + break; + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + ivx::Context ctx = getOpenVXHALContext(); + + std::vector data; + data.reserve(kernel_width*kernel_height); + switch (kernel_type) + { + case CV_8UC1: + for (int j = 0; j < kernel_height; ++j) + { + uchar * row = (uchar*)(kernel_data + kernel_step*j); + for (int i = 0; i < kernel_width; ++i) + data.push_back(row[i]); + } + break; + case CV_8SC1: + for (int j = 0; j < kernel_height; ++j) + { + schar * row = (schar*)(kernel_data + kernel_step*j); + for (int i = 0; i < kernel_width; ++i) + data.push_back(row[i]); + } + break; + case CV_16SC1: + for (int j = 0; j < kernel_height; ++j) + { + short * row = (short*)(kernel_data + kernel_step*j); + for (int i = 0; i < kernel_width; ++i) + data.push_back(row[i]); + } + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + FilterCtx* cnv = new FilterCtx(ctx, data, kernel_width, kernel_height, dst_type, border); + if (!cnv) + return CV_HAL_ERROR_UNKNOWN; + + *filter_context = (cvhalFilter2D*)(cnv); + return CV_HAL_ERROR_OK; +} + +int ovx_hal_filterFree(cvhalFilter2D *filter_context) +{ + if (filter_context) + { + delete (FilterCtx*)filter_context; + return CV_HAL_ERROR_OK; + } + else + { + return CV_HAL_ERROR_UNKNOWN; + } +} + +int ovx_hal_filter(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int, int, int, int) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + try + { + FilterCtx* cnv = (FilterCtx*)filter_context; + if (!cnv) + throw ivx::WrapperError("Bad HAL context"); + refineStep(w, h, VX_DF_IMAGE_U8, astep); + refineStep(w, h, cnv->dst_type == CV_16SC1 ? VX_DF_IMAGE_S16 : VX_DF_IMAGE_U8, bstep); + + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, 1, (vx_int32)(astep)), (void*)a), + ib = ivx::Image::createFromHandle(ctx, cnv->dst_type == CV_16SC1 ? VX_DF_IMAGE_S16 : VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, cnv->dst_type == CV_16SC1 ? 2 : 1, (vx_int32)(bstep)), (void*)b); + + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standart says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(cnv->border); + ivx::IVX_CHECK_STATUS(vxuConvolve(ctx, ia, cnv->cnv, ib)); + ctx.setImmediateBorder(prevBorder); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_sepFilterInit(cvhalFilter2D **filter_context, int src_type, int dst_type, + int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length, + int anchor_x, int anchor_y, double delta, int borderType) +{ + if (!filter_context || !kernelx_data || !kernely_data || delta != 0 || + src_type != CV_8UC1 || (dst_type != CV_8UC1 && dst_type != CV_16SC1) || + kernelx_length % 2 == 0 || kernely_length % 2 == 0 || anchor_x != kernelx_length / 2 || anchor_y != kernely_length / 2) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + ivx::border_t border; + switch (borderType) + { + case CV_HAL_BORDER_CONSTANT: + setConstantBorder(border, 0); + break; + case CV_HAL_BORDER_REPLICATE: + border.mode = VX_BORDER_REPLICATE; + break; + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + ivx::Context ctx = getOpenVXHALContext(); + + //At the moment OpenVX doesn't support separable filters natively so combine kernels to generic convolution + std::vector data; + data.reserve(kernelx_length*kernely_length); + switch (kernel_type) + { + case CV_8UC1: + for (int j = 0; j < kernely_length; ++j) + for (int i = 0; i < kernelx_length; ++i) + data.push_back((short)(kernely_data[j]) * kernelx_data[i]); + break; + case CV_8SC1: + for (int j = 0; j < kernely_length; ++j) + for (int i = 0; i < kernelx_length; ++i) + data.push_back((short)(((schar*)kernely_data)[j]) * ((schar*)kernelx_data)[i]); + break; + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + FilterCtx* cnv = new FilterCtx(ctx, data, kernelx_length, kernely_length, dst_type, border); + if (!cnv) + return CV_HAL_ERROR_UNKNOWN; + + *filter_context = (cvhalFilter2D*)(cnv); + return CV_HAL_ERROR_OK; +} + +#if VX_VERSION > VX_VERSION_1_0 + +struct MorphCtx +{ + ivx::Matrix mask; + int operation; + ivx::border_t border; + MorphCtx(ivx::Context &ctx, const std::vector data, int w, int h, int _operation, ivx::border_t & _border) : + mask(ivx::Matrix::create(ctx, ivx::TypeToEnum::value, w, h)), operation(_operation), border(_border) { + mask.copyFrom(data); + } +}; + +int ovx_hal_morphInit(cvhalFilter2D **filter_context, int operation, int src_type, int dst_type, int, int, + int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, + int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace) +{ + if (!filter_context || !kernel_data || allowSubmatrix || allowInplace || iterations != 1 || + src_type != CV_8UC1 || dst_type != CV_8UC1 || + kernel_width % 2 == 0 || kernel_height % 2 == 0 || anchor_x != kernel_width / 2 || anchor_y != kernel_height / 2) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + ivx::border_t border; + switch (borderType) + { + case CV_HAL_BORDER_CONSTANT: + if (borderValue[0] == DBL_MAX && borderValue[1] == DBL_MAX && borderValue[2] == DBL_MAX && borderValue[3] == DBL_MAX) + { + if (operation == MORPH_ERODE) + setConstantBorder(border, UCHAR_MAX); + else + setConstantBorder(border, 0); + } + else + { + int rounded = (int)round(borderValue[0]); + setConstantBorder(border, (vx_uint8)((unsigned)rounded <= UCHAR_MAX ? rounded : rounded > 0 ? UCHAR_MAX : 0)); + } + break; + case CV_HAL_BORDER_REPLICATE: + border.mode = VX_BORDER_REPLICATE; + break; + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + ivx::Context ctx = getOpenVXHALContext(); + + vx_size maxKernelDim = ctx.nonlinearMaxDimension(); + if ((vx_size)kernel_width > maxKernelDim || (vx_size)kernel_height > maxKernelDim) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + std::vector kernel_mat; + kernel_mat.reserve(kernel_width * kernel_height); + switch (CV_MAT_DEPTH(kernel_type)) + { + case CV_8U: + case CV_8S: + for (int j = 0; j < kernel_height; ++j) + { + uchar * kernel_row = kernel_data + j * kernel_step; + for (int i = 0; i < kernel_width; ++i) + kernel_mat.push_back(kernel_row[i] ? 255 : 0); + } + break; + case CV_16U: + case CV_16S: + for (int j = 0; j < kernel_height; ++j) + { + short * kernel_row = (short*)(kernel_data + j * kernel_step); + for (int i = 0; i < kernel_width; ++i) + kernel_mat.push_back(kernel_row[i] ? 255 : 0); + } + break; + case CV_32S: + for (int j = 0; j < kernel_height; ++j) + { + int * kernel_row = (int*)(kernel_data + j * kernel_step); + for (int i = 0; i < kernel_width; ++i) + kernel_mat.push_back(kernel_row[i] ? 255 : 0); + } + break; + case CV_32F: + for (int j = 0; j < kernel_height; ++j) + { + float * kernel_row = (float*)(kernel_data + j * kernel_step); + for (int i = 0; i < kernel_width; ++i) + kernel_mat.push_back(kernel_row[i] ? 255 : 0); + } + break; + case CV_64F: + for (int j = 0; j < kernel_height; ++j) + { + double * kernel_row = (double*)(kernel_data + j * kernel_step); + for (int i = 0; i < kernel_width; ++i) + kernel_mat.push_back(kernel_row[i] ? 255 : 0); + } + break; + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + MorphCtx* mat; + switch (operation) + { + case MORPH_ERODE: + mat = new MorphCtx(ctx, kernel_mat, kernel_width, kernel_height, VX_NONLINEAR_FILTER_MIN, border); + break; + case MORPH_DILATE: + mat = new MorphCtx(ctx, kernel_mat, kernel_width, kernel_height, VX_NONLINEAR_FILTER_MAX, border); + break; + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + if (!mat) + return CV_HAL_ERROR_UNKNOWN; + + *filter_context = (cvhalFilter2D*)(mat); + return CV_HAL_ERROR_OK; +} + +int ovx_hal_morphFree(cvhalFilter2D *filter_context) +{ + if (filter_context) + { + delete (MorphCtx*)filter_context; + return CV_HAL_ERROR_OK; + } + else + { + return CV_HAL_ERROR_UNKNOWN; + } +} + +int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int, int, int, int, int, int, int, int) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, VX_DF_IMAGE_U8, astep); + refineStep(w, h, VX_DF_IMAGE_U8, bstep); + try + { + MorphCtx* mat = (MorphCtx*)filter_context; + if (!mat) + throw ivx::WrapperError("Bad HAL context"); + + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, 1, (vx_int32)(astep)), (void*)a), + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, 1, (vx_int32)(bstep)), (void*)b); + + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standart says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(mat->border); + ivx::IVX_CHECK_STATUS(vxuNonLinearFilter(ctx, mat->operation, ia, mat->mask, ib)); + ctx.setImmediateBorder(prevBorder); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +#endif // 1.0 guard + +int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (depth != CV_8U || swapBlue || acn == bcn || (acn != 3 && acn != 4) || (bcn != 3 && bcn != 4)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + if (w & 1 || h & 1) // It's strange but sample implementation unable to convert odd sized images + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, astep); + refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, + ivx::Image::createAddressing(w, h, acn, (vx_int32)astep), (void*)a), + ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, + ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b); + ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (depth != CV_8U || (bcn != 3 && bcn != 4)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, VX_DF_IMAGE_U8, astep); + refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + ivx::Image + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, 1, (vx_int32)astep), const_cast(a)), + ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, + ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b); + ivx::IVX_CHECK_STATUS(vxuChannelCombine(ctx, ia, ia, ia, + bcn == 4 ? (vx_image)(ivx::Image::createUniform(ctx, w, h, VX_DF_IMAGE_U8, vx_uint8(255))) : NULL, + ib)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (!swapBlue || (bcn != 3 && bcn != 4)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, astep); + refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + + std::vector addr; + std::vector ptrs; + addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)astep)); + ptrs.push_back((void*)a); + addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 2, (vx_int32)astep)); + ptrs.push_back((void*)(a + h * astep)); + + vxImage + ia = ivx::Image::createFromHandle(ctx, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, addr, ptrs); + if (ia.range() == VX_CHANNEL_RANGE_FULL) + return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL + vxImage + ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, + ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b); + ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (!swapBlue || (bcn != 3 && bcn != 4) || uIdx || (size_t)w / 2 != astep - (size_t)w / 2) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, VX_DF_IMAGE_IYUV, astep); + refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + + std::vector addr; + std::vector ptrs; + addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)astep)); + ptrs.push_back((void*)a); + addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2)); + ptrs.push_back((void*)(a + h * astep)); + if (addr[1].dim_x != (astep - addr[1].dim_x)) + throw ivx::WrapperError("UV planes use variable stride"); + addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2)); + ptrs.push_back((void*)(a + h * astep + addr[1].dim_y * addr[1].stride_y)); + + vxImage + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_IYUV, addr, ptrs); + if (ia.range() == VX_CHANNEL_RANGE_FULL) + return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL + vxImage + ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, + ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b); + ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (!swapBlue || (acn != 3 && acn != 4) || uIdx || (size_t)w / 2 != bstep - (size_t)w / 2) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, astep); + refineStep(w, h, VX_DF_IMAGE_IYUV, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, + ivx::Image::createAddressing(w, h, acn, (vx_int32)astep), (void*)a); + + std::vector addr; + std::vector ptrs; + addr.push_back(ivx::Image::createAddressing(w, h, 1, (vx_int32)bstep)); + ptrs.push_back((void*)b); + addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2)); + ptrs.push_back((void*)(b + h * bstep)); + if (addr[1].dim_x != (bstep - addr[1].dim_x)) + throw ivx::WrapperError("UV planes use variable stride"); + addr.push_back(ivx::Image::createAddressing(w / 2, h / 2, 1, w / 2)); + ptrs.push_back((void*)(b + h * bstep + addr[1].dim_y * addr[1].stride_y)); + + vxImage + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_IYUV, addr, ptrs); + ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn) +{ + if (dimTooBig(w) || dimTooBig(h)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + if (!swapBlue || (bcn != 3 && bcn != 4) || uIdx) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + + if (w & 1) // It's not described in spec but sample implementation unable to convert odd sized images + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, ycn ? VX_DF_IMAGE_UYVY : VX_DF_IMAGE_YUYV, astep); + refineStep(w, h, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, bstep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + vxImage + ia = ivx::Image::createFromHandle(ctx, ycn ? VX_DF_IMAGE_UYVY : VX_DF_IMAGE_YUYV, + ivx::Image::createAddressing(w, h, 2, (vx_int32)astep), (void*)a); + if (ia.range() == VX_CHANNEL_RANGE_FULL) + return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL + vxImage + ib = ivx::Image::createFromHandle(ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, + ivx::Image::createAddressing(w, h, bcn, (vx_int32)bstep), b); + ivx::IVX_CHECK_STATUS(vxuColorConvert(ctx, ia, ib)); + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep, uchar * b, size_t bstep, uchar * c, size_t, uchar * d, size_t, int w, int h, int cn) +{ + if (depth != CV_8U || sdepth != CV_32S || c != NULL || d != NULL || cn != 1) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + refineStep(w, h, VX_DF_IMAGE_U8, astep); + try + { + ivx::Context ctx = getOpenVXHALContext(); + ivx::Image + ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(w, h, 1, (vx_int32)astep), const_cast(a)), + ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U32, + ivx::Image::createAddressing(w, h, 1, (vx_int32)bstep), (unsigned int *)(b + bstep + sizeof(unsigned int))); + ivx::IVX_CHECK_STATUS(vxuIntegralImage(ctx, ia, ib)); + memset(b, 0, (w + 1) * sizeof(unsigned int)); + b += bstep; + for (int i = 0; i < h; i++, b += bstep) + { + *((unsigned int*)b) = 0; + } + } + catch (ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} diff --git a/3rdparty/openvx/hal/openvx_hal.hpp b/3rdparty/openvx/hal/openvx_hal.hpp new file mode 100644 index 0000000000..63da1fa5b3 --- /dev/null +++ b/3rdparty/openvx/hal/openvx_hal.hpp @@ -0,0 +1,143 @@ +#ifndef OPENCV_OPENVX_HAL_HPP_INCLUDED +#define OPENCV_OPENVX_HAL_HPP_INCLUDED + +#include "opencv2/core/hal/interface.h" +#include "opencv2/imgproc/hal/interface.h" + +#include "VX/vx.h" + +template +int ovx_hal_add(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h); +template +int ovx_hal_sub(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h); + +template +int ovx_hal_absdiff(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h); + +template +int ovx_hal_and(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h); +template +int ovx_hal_or(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h); +template +int ovx_hal_xor(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h); +int ovx_hal_not(const uchar *a, size_t astep, uchar *c, size_t cstep, int w, int h); + +template +int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h, double scale); + +int ovx_hal_merge8u(const uchar **src_data, uchar *dst_data, int len, int cn); +int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, double inv_scale_x, double inv_scale_y, int interpolation); +int ovx_hal_warpAffine(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[6], int interpolation, int borderType, const double borderValue[4]); +int ovx_hal_warpPerspectve(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[9], int interpolation, int borderType, const double borderValue[4]); + +struct cvhalFilter2D; +int ovx_hal_filterInit(cvhalFilter2D **filter_context, uchar *kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height, + int, int, int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool allowSubmatrix, bool allowInplace); +int ovx_hal_filterFree(cvhalFilter2D *filter_context); +int ovx_hal_filter(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int, int, int, int); +int ovx_hal_sepFilterInit(cvhalFilter2D **filter_context, int src_type, int dst_type, + int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length, + int anchor_x, int anchor_y, double delta, int borderType); + +#if VX_VERSION > VX_VERSION_1_0 +int ovx_hal_morphInit(cvhalFilter2D **filter_context, int operation, int src_type, int dst_type, int , int , + int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, + int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace); +int ovx_hal_morphFree(cvhalFilter2D *filter_context); +int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int , int , int , int , int , int , int , int ); +#endif // 1.0 guard + +int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue); +int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn); +int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx); +int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx); +int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx); +int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn); +int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep, uchar * b, size_t bstep, uchar * c, size_t, uchar * d, size_t, int w, int h, int cn); + +//================================================================================================== +// functions redefinition +// ... + +#undef cv_hal_add8u +#define cv_hal_add8u ovx_hal_add +#undef cv_hal_add16s +#define cv_hal_add16s ovx_hal_add +#undef cv_hal_sub8u +#define cv_hal_sub8u ovx_hal_sub +#undef cv_hal_sub16s +#define cv_hal_sub16s ovx_hal_sub + +#undef cv_hal_absdiff8u +#define cv_hal_absdiff8u ovx_hal_absdiff +#undef cv_hal_absdiff16s +#define cv_hal_absdiff16s ovx_hal_absdiff + +#undef cv_hal_and8u +#define cv_hal_and8u ovx_hal_and +#undef cv_hal_or8u +#define cv_hal_or8u ovx_hal_or +#undef cv_hal_xor8u +#define cv_hal_xor8u ovx_hal_xor +#undef cv_hal_not8u +#define cv_hal_not8u ovx_hal_not + +#undef cv_hal_mul8u +#define cv_hal_mul8u ovx_hal_mul +#undef cv_hal_mul16s +#define cv_hal_mul16s ovx_hal_mul + +#undef cv_hal_merge8u +#define cv_hal_merge8u ovx_hal_merge8u + +//#undef cv_hal_resize +//#define cv_hal_resize ovx_hal_resize + +//OpenVX warps use round to zero policy at least in sample implementation +//while OpenCV require round to nearest +//#undef cv_hal_warpAffine +//#define cv_hal_warpAffine ovx_hal_warpAffine +//#undef cv_hal_warpPerspective +//#define cv_hal_warpPerspective ovx_hal_warpPerspectve + +#undef cv_hal_filterInit +#define cv_hal_filterInit ovx_hal_filterInit +#undef cv_hal_filter +#define cv_hal_filter ovx_hal_filter +#undef cv_hal_filterFree +#define cv_hal_filterFree ovx_hal_filterFree + +#undef cv_hal_sepFilterInit +#define cv_hal_sepFilterInit ovx_hal_sepFilterInit +#undef cv_hal_sepFilter +#define cv_hal_sepFilter ovx_hal_filter +#undef cv_hal_sepFilterFree +#define cv_hal_sepFilterFree ovx_hal_filterFree + +#if VX_VERSION > VX_VERSION_1_0 + +#undef cv_hal_morphInit +#define cv_hal_morphInit ovx_hal_morphInit +#undef cv_hal_morph +#define cv_hal_morph ovx_hal_morph +#undef cv_hal_morphFree +#define cv_hal_morphFree ovx_hal_morphFree + +#endif // 1.0 guard + +#undef cv_hal_cvtBGRtoBGR +#define cv_hal_cvtBGRtoBGR ovx_hal_cvtBGRtoBGR +#undef cv_hal_cvtGraytoBGR +#define cv_hal_cvtGraytoBGR ovx_hal_cvtGraytoBGR +#undef cv_hal_cvtTwoPlaneYUVtoBGR +#define cv_hal_cvtTwoPlaneYUVtoBGR ovx_hal_cvtTwoPlaneYUVtoBGR +#undef cv_hal_cvtThreePlaneYUVtoBGR +#define cv_hal_cvtThreePlaneYUVtoBGR ovx_hal_cvtThreePlaneYUVtoBGR +#undef cv_hal_cvtBGRtoThreePlaneYUV +#define cv_hal_cvtBGRtoThreePlaneYUV ovx_hal_cvtBGRtoThreePlaneYUV +#undef cv_hal_cvtOnePlaneYUVtoBGR +#define cv_hal_cvtOnePlaneYUVtoBGR ovx_hal_cvtOnePlaneYUVtoBGR +#undef cv_hal_integral +#define cv_hal_integral ovx_hal_integral + +#endif diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index c18723b278..47213e6d5c 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -22,6 +22,18 @@ Details: TBD #include #include +#ifndef VX_VERSION_1_1 +// 1.1 to 1.0 backward compatibility defines + +static const vx_enum VX_INTERPOLATION_BILINEAR = VX_INTERPOLATION_TYPE_BILINEAR; +static const vx_enum VX_INTERPOLATION_AREA = VX_INTERPOLATION_TYPE_AREA; +static const vx_enum VX_INTERPOLATION_NEAREST_NEIGHBOR = VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR; + +static const vx_enum VX_BORDER_CONSTANT = VX_BORDER_MODE_CONSTANT; +static const vx_enum VX_BORDER_REPLICATE = VX_BORDER_MODE_REPLICATE; + +#endif + #ifndef IVX_USE_CXX98 // checking compiler #if __cplusplus < 201103L && (!defined(_MSC_VER) || _MSC_VER < 1800) @@ -56,6 +68,7 @@ Details: TBD #include #include #include +#include #ifndef IVX_USE_CXX98 #include @@ -190,14 +203,14 @@ inline vx_size enumToTypeSize(vx_enum type) template struct TypeToEnum {}; template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_CHAR; }; template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_INT8; }; -template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_UINT8; }; -template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_INT16; }; -template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_UINT16; }; -template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_INT32; }; -template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_UINT32; }; +template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_UINT8, imgType = VX_DF_IMAGE_U8; }; +template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_INT16, imgType = VX_DF_IMAGE_S16; }; +template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_UINT16, imgType = VX_DF_IMAGE_U16; }; +template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_INT32, imgType = VX_DF_IMAGE_S32; }; +template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_UINT32, imgType = VX_DF_IMAGE_U32; }; template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_INT64; }; template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_UINT64; }; -template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_FLOAT32; }; +template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_FLOAT32, imgType = VX_DF_IMAGE('F', '0', '3', '2'); }; template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_FLOAT64; }; template<> struct TypeToEnum { static const vx_enum value = VX_TYPE_BOOL; }; template<> struct TypeToEnum {static const vx_enum value = VX_TYPE_KEYPOINT; }; @@ -343,6 +356,15 @@ template <> struct RefTypeTraits static vx_status release(vxType& ref) { return vxReleaseLUT(&ref); } }; +class Pyramid; +template <> struct RefTypeTraits +{ + typedef vx_pyramid vxType; + typedef Pyramid wrapperType; + static const vx_enum vxTypeEnum = VX_TYPE_PYRAMID; + static vx_status release(vxType& ref) { return vxReleasePyramid(&ref); } +}; + class Distribution; template <> struct RefTypeTraits { @@ -352,6 +374,15 @@ template <> struct RefTypeTraits static vx_status release(vxType& ref) { return vxReleaseDistribution(&ref); } }; +class Remap; +template <> struct RefTypeTraits +{ + typedef vx_remap vxType; + typedef Remap wrapperType; + static const vx_enum vxTypeEnum = VX_TYPE_REMAP; + static vx_status release(vxType& ref) { return vxReleaseRemap(&ref); } +}; + #ifdef IVX_USE_CXX98 /// Casting to vx_reference with compile-time check @@ -909,6 +940,34 @@ public: void setImmediateBorder(vx_enum mode, const vx_pixel_value_t& val) { border_t bm = {mode, val}; setImmediateBorder(bm); } + /// vxSetContextAttribute(BORDER) wrapper + template + void setImmediateBorder(vx_enum mode, const T& _val) + { + vx_pixel_value_t val; + switch (TypeToEnum::value) + { + case VX_TYPE_UINT8: + val.U8 = _val; + break; + case VX_TYPE_INT16: + val.S16 = _val; + break; + case VX_TYPE_UINT16: + val.U16 = _val; + break; + case VX_TYPE_INT32: + val.S32 = _val; + break; + case VX_TYPE_UINT32: + val.U32 = _val; + break; + default: + throw WrapperError("Unsupported constant border value type"); + } + setImmediateBorder(mode, val); + } + /// vxSetContextAttribute(BORDER) wrapper void setImmediateBorder(vx_enum mode) { vx_pixel_value_t val = {}; setImmediateBorder(mode, val); } @@ -1264,6 +1323,34 @@ static const vx_enum void setBorder(vx_enum mode, const vx_pixel_value_t& val) { vx_border_t bm = {mode, val}; setBorder(bm); } + /// vxSetNodeAttribute(BORDER) wrapper + template + void setBorder(vx_enum mode, const T& _val) + { + vx_pixel_value_t val; + switch (TypeToEnum::value) + { + case VX_TYPE_UINT8: + val.U8 = _val; + break; + case VX_TYPE_INT16: + val.S16 = _val; + break; + case VX_TYPE_UINT16: + val.U16 = _val; + break; + case VX_TYPE_INT32: + val.S32 = _val; + break; + case VX_TYPE_UINT32: + val.U32 = _val; + break; + default: + throw WrapperError("Unsupported constant border value type"); + } + setBorder(mode, val); + } + /// vxSetNodeAttribute(BORDER) wrapper void setBorder(vx_enum mode) { vx_pixel_value_t val = {}; setBorder(mode, val); } @@ -1302,6 +1389,25 @@ public: static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const void* value) { return Image(vxCreateUniformImage(context, width, height, format, value)); } #endif + template + static Image createUniform(vx_context context, vx_uint32 width, vx_uint32 height, vx_df_image format, const T value) + { +#if VX_VERSION > VX_VERSION_1_0 + vx_pixel_value_t pixel; + switch (format) + { + case VX_DF_IMAGE_U8:pixel.U8 = (vx_uint8)value; break; + case VX_DF_IMAGE_S16:pixel.S16 = (vx_int16)value; break; + case VX_DF_IMAGE_U16:pixel.U16 = (vx_uint16)value; break; + case VX_DF_IMAGE_S32:pixel.S32 = (vx_int32)value; break; + case VX_DF_IMAGE_U32:pixel.U32 = (vx_uint32)value; break; + default:throw ivx::WrapperError("uniform image type unsupported by this call"); + } + return Image(vxCreateUniformImage(context, width, height, format, &pixel)); +#else + return Image(vxCreateUniformImage(context, width, height, format, &value)); +#endif + } /// Planes number for the specified image format (fourcc) /// \return 0 for unknown formats @@ -1514,6 +1620,15 @@ static const vx_enum } #endif // VX_VERSION_1_1 + /// vxSetImageAttribute() wrapper + template + void setAttribute(vx_enum att, T& value) const + { IVX_CHECK_STATUS(vxSetImageAttribute(ref, att, &value, sizeof(value))); } + + /// vxSetImageAttribute(SPACE) wrapper + void setColorSpace(const vx_enum& sp) + { setAttribute(VX_IMAGE_SPACE, sp); } + /// vxGetValidRegionImage() wrapper vx_rectangle_t getValidRegion() const { @@ -1804,7 +1919,9 @@ public: swap(_planeIdx, p._planeIdx); #endif swap(_img, p._img); +#ifdef IVX_USE_OPENCV swap(_m, p._m); +#endif } #endif @@ -2755,6 +2872,74 @@ public: #endif //IVX_USE_OPENCV }; +/* + * Pyramid + */ +class Pyramid : public RefWrapper +{ +public: + IVX_REF_STD_CTORS_AND_ASSIGNMENT(Pyramid) + + static Pyramid create(vx_context context, vx_size levels, vx_float32 scale, + vx_uint32 width, vx_uint32 height, vx_df_image format) + {return Pyramid(vxCreatePyramid(context, levels, scale, width, height, format));} + + static Pyramid createVirtual(vx_graph graph, vx_size levels, vx_float32 scale, + vx_uint32 width, vx_uint32 height, vx_df_image format) + {return Pyramid(vxCreateVirtualPyramid(graph, levels, scale, width, height, format));} + +#ifndef VX_VERSION_1_1 + static const vx_enum + VX_PYRAMID_LEVELS = VX_PYRAMID_ATTRIBUTE_LEVELS, + VX_PYRAMID_SCALE = VX_PYRAMID_ATTRIBUTE_SCALE, + VX_PYRAMID_WIDTH = VX_PYRAMID_ATTRIBUTE_WIDTH, + VX_PYRAMID_HEIGHT = VX_PYRAMID_ATTRIBUTE_HEIGHT, + VX_PYRAMID_FORMAT = VX_PYRAMID_ATTRIBUTE_FORMAT; +#endif + + template + void query(vx_enum att, T& value) const + { IVX_CHECK_STATUS( vxQueryPyramid(ref, att, &value, sizeof(value)) ); } + + vx_size levels() const + { + vx_size l; + query(VX_PYRAMID_LEVELS, l); + return l; + } + + vx_float32 scale() const + { + vx_float32 s; + query(VX_PYRAMID_SCALE, s); + return s; + } + + vx_uint32 width() const + { + vx_uint32 v; + query(VX_PYRAMID_WIDTH, v); + return v; + } + + vx_uint32 height() const + { + vx_uint32 v; + query(VX_PYRAMID_HEIGHT, v); + return v; + } + + vx_df_image format() const + { + vx_df_image f; + query(VX_PYRAMID_FORMAT, f); + return f; + } + + Image getLevel(vx_uint32 index) + { return Image(vxGetPyramidLevel(ref, index)); } +}; + /* * Distribution */ @@ -2922,6 +3107,148 @@ public: #endif //IVX_USE_OPENCV }; +/* +* Remap +*/ +class Remap : public RefWrapper +{ +public: + IVX_REF_STD_CTORS_AND_ASSIGNMENT(Remap); + + static Remap create(vx_context context, vx_uint32 src_width, vx_uint32 src_height, vx_uint32 dst_width, vx_uint32 dst_height) + { + return Remap(vxCreateRemap(context, src_width, src_height, dst_width, dst_height)); + } + +#ifndef VX_VERSION_1_1 + static const vx_enum + VX_REMAP_SOURCE_WIDTH = VX_REMAP_ATTRIBUTE_SOURCE_WIDTH, + VX_REMAP_SOURCE_HEIGHT = VX_REMAP_ATTRIBUTE_SOURCE_HEIGHT, + VX_REMAP_DESTINATION_WIDTH = VX_REMAP_ATTRIBUTE_DESTINATION_WIDTH, + VX_REMAP_DESTINATION_HEIGHT = VX_REMAP_ATTRIBUTE_DESTINATION_HEIGHT; +#endif + + template + void query(vx_enum att, T& value) const + { IVX_CHECK_STATUS(vxQueryRemap(ref, att, &value, sizeof(value))); } + + vx_uint32 srcWidth() const + { + vx_uint32 v; + query(VX_REMAP_SOURCE_WIDTH, v); + return v; + } + + vx_uint32 srcHeight() const + { + vx_uint32 v; + query(VX_REMAP_SOURCE_HEIGHT, v); + return v; + } + + vx_uint32 dstWidth() const + { + vx_uint32 v; + query(VX_REMAP_DESTINATION_WIDTH, v); + return v; + } + + vx_uint32 dstHeight() const + { + vx_uint32 v; + query(VX_REMAP_DESTINATION_HEIGHT, v); + return v; + } + + vx_uint32 srcCoordType() const + { return VX_TYPE_FLOAT32; } + + vx_uint32 dstCoordType() const + { return VX_TYPE_UINT32; } + + void setMapping(vx_uint32 dst_x, vx_uint32 dst_y, vx_float32 src_x, vx_float32 src_y) + { IVX_CHECK_STATUS(vxSetRemapPoint(ref, dst_x, dst_y, src_x, src_y)); } + + void getMapping(vx_uint32 dst_x, vx_uint32 dst_y, vx_float32 &src_x, vx_float32 &src_y) const + { IVX_CHECK_STATUS(vxGetRemapPoint(ref, dst_x, dst_y, &src_x, &src_y)); } + +#ifdef IVX_USE_OPENCV + void setMappings(const cv::Mat& map_x, const cv::Mat& map_y) + { + if (map_x.type() != enumToCVType(srcCoordType()) || map_y.type() != enumToCVType(srcCoordType())) + throw WrapperError(std::string(__func__) + "(): mapping type is wrong"); + if ((vx_uint32)(map_x.rows) != dstHeight() || (vx_uint32)(map_x.cols) != dstWidth()) + throw WrapperError(std::string(__func__) + "(): x mapping size is wrong"); + if ((vx_uint32)(map_y.rows) != dstHeight() || (vx_uint32)(map_y.cols) != dstWidth()) + throw WrapperError(std::string(__func__) + "(): y mapping size is wrong"); + + for (vx_uint32 y = 0; y < dstHeight(); y++) + { + const vx_float32* map_x_line = map_x.ptr(y); + const vx_float32* map_y_line = map_y.ptr(y); + for (vx_uint32 x = 0; x < dstWidth(); x++) + setMapping(x, y, map_x_line[x], map_y_line[x]); + } + } + + void setMappings(const cv::Mat& map) + { + if (map.depth() != CV_MAT_DEPTH(enumToCVType(srcCoordType())) || map.channels() != 2) + throw WrapperError(std::string(__func__) + "(): mapping type is wrong"); + if ((vx_uint32)(map.rows) != dstHeight() || (vx_uint32)(map.cols) != dstWidth()) + throw WrapperError(std::string(__func__) + "(): x mapping size is wrong"); + + for (vx_uint32 y = 0; y < dstHeight(); y++) + { + const vx_float32* map_line = map.ptr(y); + for (vx_uint32 x = 0; x < 2*dstWidth(); x+=2) + setMapping(x, y, map_line[x], map_line[x+1]); + } + } + + void getMappings(cv::Mat& map_x, cv::Mat& map_y) const + { + if (map_x.type() != enumToCVType(srcCoordType()) || map_y.type() != enumToCVType(srcCoordType())) + throw WrapperError(std::string(__func__) + "(): mapping type is wrong"); + if (((vx_uint32)(map_x.rows) != dstHeight() || (vx_uint32)(map_x.cols) != dstWidth()) && !map_x.empty()) + throw WrapperError(std::string(__func__) + "(): x mapping size is wrong"); + if (((vx_uint32)(map_y.rows) != dstHeight() || (vx_uint32)(map_y.cols) != dstWidth()) && !map_y.empty()) + throw WrapperError(std::string(__func__) + "(): y mapping size is wrong"); + + if (map_x.empty()) + map_x = cv::Mat((int)dstHeight(), (int)dstWidth(), enumToCVType(srcCoordType())); + if (map_y.empty()) + map_y = cv::Mat((int)dstHeight(), (int)dstWidth(), enumToCVType(srcCoordType())); + + for (vx_uint32 y = 0; y < dstHeight(); y++) + { + vx_float32* map_x_line = map_x.ptr(y); + vx_float32* map_y_line = map_y.ptr(y); + for (vx_uint32 x = 0; x < dstWidth(); x++) + getMapping(x, y, map_x_line[x], map_y_line[x]); + } + } + + void getMappings(cv::Mat& map) const + { + if (map.depth() != CV_MAT_DEPTH(enumToCVType(srcCoordType())) || map.channels() != 2) + throw WrapperError(std::string(__func__) + "(): mapping type is wrong"); + if (((vx_uint32)(map.rows) != dstHeight() || (vx_uint32)(map.cols) != dstWidth()) && !map.empty()) + throw WrapperError(std::string(__func__) + "(): x mapping size is wrong"); + + if (map.empty()) + map = cv::Mat((int)dstHeight(), (int)dstWidth(), CV_MAKETYPE(CV_MAT_DEPTH(enumToCVType(srcCoordType())),2)); + + for (vx_uint32 y = 0; y < dstHeight(); y++) + { + vx_float32* map_line = map.ptr(y); + for (vx_uint32 x = 0; x < 2*dstWidth(); x+=2) + getMapping(x, y, map_line[x], map_line[x+1]); + } + } +#endif //IVX_USE_OPENCV +}; + /// Standard nodes namespace nodes { diff --git a/3rdparty/openvx/include/openvx_hal.hpp b/3rdparty/openvx/include/openvx_hal.hpp deleted file mode 100644 index 7dd89addb2..0000000000 --- a/3rdparty/openvx/include/openvx_hal.hpp +++ /dev/null @@ -1,1273 +0,0 @@ -#ifndef OPENCV_OPENVX_HAL_HPP_INCLUDED -#define OPENCV_OPENVX_HAL_HPP_INCLUDED - -#include "opencv2/core/hal/interface.h" -#include "opencv2/imgproc/hal/interface.h" - -#include "VX/vx.h" -#include "VX/vxu.h" - -#include -#include - -#include -#include -#include -#include - -#ifndef VX_VENDOR_ID -#define VX_VENDOR_ID VX_ID_DEFAULT -#endif - -#if VX_VERSION == VX_VERSION_1_0 - -static const vx_enum VX_MEMORY_TYPE_HOST = VX_IMPORT_TYPE_HOST; -static const vx_enum VX_INTERPOLATION_BILINEAR = VX_INTERPOLATION_TYPE_BILINEAR; -static const vx_enum VX_INTERPOLATION_AREA = VX_INTERPOLATION_TYPE_AREA; -static const vx_enum VX_INTERPOLATION_NEAREST_NEIGHBOR = VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR; -static const vx_enum VX_IMAGE_RANGE = VX_IMAGE_ATTRIBUTE_RANGE; -static const vx_enum VX_IMAGE_SPACE = VX_IMAGE_ATTRIBUTE_SPACE; -typedef vx_border_mode_t vx_border_t; -static const vx_enum VX_BORDER_CONSTANT = VX_BORDER_MODE_CONSTANT; -static const vx_enum VX_BORDER_REPLICATE = VX_BORDER_MODE_REPLICATE; -static const vx_enum VX_CONTEXT_IMMEDIATE_BORDER = VX_CONTEXT_ATTRIBUTE_IMMEDIATE_BORDER_MODE; - -#endif - -//================================================================================================== -// utility -// ... - -#if 0 -#include -#define PRINT(...) printf(__VA_ARGS__) -#else -#define PRINT(...) -#endif - -#if __cplusplus >= 201103L -#include -struct Tick -{ - typedef std::chrono::time_point point_t; - point_t start; - point_t point; - Tick() - { - start = std::chrono::steady_clock::now(); - point = std::chrono::steady_clock::now(); - } - inline int one() - { - point_t old = point; - point = std::chrono::steady_clock::now(); - return std::chrono::duration_cast(point - old).count(); - } - inline int total() - { - return std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count(); - } -}; -#endif - -inline bool dimTooBig(int size) -{ - if (VX_VENDOR_ID == VX_ID_KHRONOS || VX_VENDOR_ID == VX_ID_DEFAULT) - { - //OpenVX use uint32_t for image addressing - return ((unsigned)size > (UINT_MAX / VX_SCALE_UNITY)); - } - else - return false; -} - -//================================================================================================== -// One more OpenVX C++ binding :-) -// ... - -template -struct VX_Traits -{ - enum { - ImgType = 0, - DataType = 0 - }; -}; - -template <> -struct VX_Traits -{ - enum { - ImgType = VX_DF_IMAGE_U8, - DataType = VX_TYPE_UINT8 - }; -}; - -template <> -struct VX_Traits -{ - enum { - ImgType = VX_DF_IMAGE_U16, - DataType = VX_TYPE_UINT16 - }; -}; - -template <> -struct VX_Traits -{ - enum { - ImgType = VX_DF_IMAGE_S16, - DataType = VX_TYPE_INT16 - }; -}; - -template <> -struct VX_Traits -{ - enum { - ImgType = VX_DF_IMAGE_U32, - DataType = VX_TYPE_UINT32 - }; -}; - -template <> -struct VX_Traits -{ - enum { - ImgType = VX_DF_IMAGE_S32, - DataType = VX_TYPE_INT32 - }; -}; - -template <> -struct VX_Traits -{ - enum { - ImgType = 0, - DataType = VX_TYPE_FLOAT32 - }; -}; - - -struct vxContext; -struct vxImage; -struct vxErr; - - -struct vxErr -{ - vx_status status; - std::string msg; - vxErr(vx_status status_, const std::string & msg_) : status(status_), msg(msg_) {} - void check() - { - if (status != VX_SUCCESS) - throw *this; - } - void print() - { - PRINT("OpenVX HAL impl error: %d (%s)\n", status, msg.c_str()); - } - static void check(vx_context ctx) - { - vxErr(vxGetStatus((vx_reference)ctx), "context check").check(); - } - static void check(vx_image img) - { - vxErr(vxGetStatus((vx_reference)img), "image check").check(); - } - static void check(vx_matrix mtx) - { - vxErr(vxGetStatus((vx_reference)mtx), "matrix check").check(); - } - static void check(vx_convolution cnv) - { - vxErr(vxGetStatus((vx_reference)cnv), "convolution check").check(); - } - static void check(vx_status s) - { - vxErr(s, "status check").check(); - } -}; - - -struct vxContext -{ - vx_context ctx; - static vxContext * getContext(); -private: - vxContext() - { - ctx = vxCreateContext(); - vxErr::check(ctx); - } - ~vxContext() - { - vxReleaseContext(&ctx); - } -}; - - -struct vxImage -{ - vx_image img; - - template - vxImage(vxContext &ctx, const T *data, size_t step, int w, int h) - { - if (h == 1) - step = w * sizeof(T); - vx_imagepatch_addressing_t addr; - addr.dim_x = w; - addr.dim_y = h; - addr.stride_x = sizeof(T); - addr.stride_y = (vx_int32)step; - void *ptrs[] = { (void*)data }; - img = vxCreateImageFromHandle(ctx.ctx, VX_Traits::ImgType, &addr, ptrs, VX_MEMORY_TYPE_HOST); - vxErr::check(img); - swapMemory = true; - } - template - vxImage(vxContext &ctx, T value, int w, int h) - { -#if VX_VERSION > VX_VERSION_1_0 - vx_pixel_value_t pixel; - switch ((int)(VX_Traits::DataType)) - { - case VX_TYPE_UINT8:pixel.U8 = value; break; - case VX_TYPE_UINT16:pixel.U16 = value; break; - case VX_TYPE_INT16:pixel.S16 = value; break; - default:vxErr(VX_ERROR_INVALID_PARAMETERS, "uniform image creation").check(); - } - img = vxCreateUniformImage(ctx.ctx, w, h, VX_Traits::ImgType, &pixel); -#else - img = vxCreateUniformImage(ctx.ctx, w, h, VX_Traits::ImgType, &value); -#endif - vxErr::check(img); - swapMemory = false; - } - vxImage(vxContext &ctx, int imgType, const uchar *data, size_t step, int w, int h) - { - if (h == 1) - step = w * ((imgType == VX_DF_IMAGE_RGBX || - imgType == VX_DF_IMAGE_U32 || imgType == VX_DF_IMAGE_S32) ? 4 : - imgType == VX_DF_IMAGE_RGB ? 3 : - (imgType == VX_DF_IMAGE_U16 || imgType == VX_DF_IMAGE_S16 || - imgType == VX_DF_IMAGE_UYVY || imgType == VX_DF_IMAGE_YUYV) ? 2 : 1); - - vx_imagepatch_addressing_t addr[4]; - void *ptrs[4]; - switch (imgType) - { - case VX_DF_IMAGE_U8: - case VX_DF_IMAGE_U16: - case VX_DF_IMAGE_S16: - case VX_DF_IMAGE_U32: - case VX_DF_IMAGE_S32: - case VX_DF_IMAGE_RGB: - case VX_DF_IMAGE_RGBX: - case VX_DF_IMAGE_UYVY: - case VX_DF_IMAGE_YUYV: - addr[0].dim_x = w; - addr[0].dim_y = h; - addr[0].stride_x = imgType == VX_DF_IMAGE_U8 ? 1 : - imgType == VX_DF_IMAGE_RGB ? 3 : - (imgType == VX_DF_IMAGE_U16 || imgType == VX_DF_IMAGE_S16 || - imgType == VX_DF_IMAGE_UYVY || imgType == VX_DF_IMAGE_YUYV) ? 2 : 4; - addr[0].stride_y = (vx_int32)step; - ptrs[0] = (void*)data; - break; - case VX_DF_IMAGE_NV12: - case VX_DF_IMAGE_NV21: - addr[0].dim_x = w; - addr[0].dim_y = h; - addr[0].stride_x = 1; - addr[0].stride_y = (vx_int32)step; - ptrs[0] = (void*)data; - addr[1].dim_x = w / 2; - addr[1].dim_y = h / 2; - addr[1].stride_x = 2; - addr[1].stride_y = (vx_int32)step; - ptrs[1] = (void*)(data + h * step); - break; - case VX_DF_IMAGE_IYUV: - case VX_DF_IMAGE_YUV4: - addr[0].dim_x = w; - addr[0].dim_y = h; - addr[0].stride_x = 1; - addr[0].stride_y = (vx_int32)step; - ptrs[0] = (void*)data; - addr[1].dim_x = imgType == VX_DF_IMAGE_YUV4 ? w : w / 2; - addr[1].dim_y = imgType == VX_DF_IMAGE_YUV4 ? h : h / 2; - if (addr[1].dim_x != (step - addr[1].dim_x)) - vxErr(VX_ERROR_INVALID_PARAMETERS, "UV planes use variable stride").check(); - addr[1].stride_x = 1; - addr[1].stride_y = (vx_int32)addr[1].dim_x; - ptrs[1] = (void*)(data + h * step); - addr[2].dim_x = addr[1].dim_x; - addr[2].dim_y = addr[1].dim_y; - addr[2].stride_x = 1; - addr[2].stride_y = addr[1].stride_y; - ptrs[2] = (void*)(data + h * step + addr[1].dim_y * addr[1].stride_y); - break; - default: - vxErr(VX_ERROR_INVALID_PARAMETERS, "Bad image format").check(); - } - img = vxCreateImageFromHandle(ctx.ctx, imgType, addr, ptrs, VX_MEMORY_TYPE_HOST); - vxErr::check(img); - swapMemory = true; - } - ~vxImage() - { -#if VX_VERSION > VX_VERSION_1_0 - if (swapMemory) - vxErr::check(vxSwapImageHandle(img, NULL, NULL, 1)); -#endif - vxReleaseImage(&img); - } -private: - bool swapMemory; -}; - -struct vxMatrix -{ - vx_matrix mtx; - - template - vxMatrix(vxContext &ctx, const T *data, int w, int h) - { - mtx = vxCreateMatrix(ctx.ctx, VX_Traits::DataType, w, h); - vxErr::check(mtx); -#if VX_VERSION > VX_VERSION_1_0 - vxErr::check(vxCopyMatrix(mtx, const_cast(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST)); -#else - vxErr::check(vxWriteMatrix(mtx, const_cast(data))); -#endif - } - ~vxMatrix() - { - vxReleaseMatrix(&mtx); - } -}; - -struct vxConvolution -{ - vx_convolution cnv; - - vxConvolution(vxContext &ctx, const short *data, int w, int h) - { - cnv = vxCreateConvolution(ctx.ctx, w, h); - vxErr::check(cnv); -#if VX_VERSION > VX_VERSION_1_0 - vxErr::check(vxCopyConvolutionCoefficients(cnv, const_cast(data), VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST)); -#else - vxErr::check(vxWriteConvolutionCoefficients(cnv, const_cast(data))); -#endif - } - ~vxConvolution() - { - vxReleaseConvolution(&cnv); - } -}; - -inline void setConstantBorder(vx_border_t &border, vx_uint8 val) -{ - border.mode = VX_BORDER_CONSTANT; -#if VX_VERSION > VX_VERSION_1_0 - border.constant_value.U8 = val; -#else - border.constant_value = val; -#endif -} - -//================================================================================================== -// real code starts here -// ... - -#define OVX_BINARY_OP(hal_func, ovx_call) \ -template \ -inline int ovx_hal_##hal_func(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h) \ -{ \ - if(dimTooBig(w) || dimTooBig(h)) \ - return CV_HAL_ERROR_NOT_IMPLEMENTED; \ - try \ - { \ - vxContext * ctx = vxContext::getContext(); \ - vxImage ia(*ctx, a, astep, w, h); \ - vxImage ib(*ctx, b, bstep, w, h); \ - vxImage ic(*ctx, c, cstep, w, h); \ - ovx_call \ - } \ - catch (vxErr & e) \ - { \ - e.print(); \ - return CV_HAL_ERROR_UNKNOWN; \ - } \ - return CV_HAL_ERROR_OK; \ -} - -OVX_BINARY_OP(add, {vxErr::check(vxuAdd(ctx->ctx, ia.img, ib.img, VX_CONVERT_POLICY_SATURATE, ic.img));}) -OVX_BINARY_OP(sub, {vxErr::check(vxuSubtract(ctx->ctx, ia.img, ib.img, VX_CONVERT_POLICY_SATURATE, ic.img));}) - -OVX_BINARY_OP(absdiff, {vxErr::check(vxuAbsDiff(ctx->ctx, ia.img, ib.img, ic.img));}) - -OVX_BINARY_OP(and, {vxErr::check(vxuAnd(ctx->ctx, ia.img, ib.img, ic.img));}) -OVX_BINARY_OP(or, {vxErr::check(vxuOr(ctx->ctx, ia.img, ib.img, ic.img));}) -OVX_BINARY_OP(xor, {vxErr::check(vxuXor(ctx->ctx, ia.img, ib.img, ic.img));}) - -template -inline int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h, double scale) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; -#ifdef _MSC_VER - const float MAGIC_SCALE = 0x0.01010102; -#else - const float MAGIC_SCALE = 0x1.010102p-8; -#endif - try - { - int rounding_policy = VX_ROUND_POLICY_TO_ZERO; - float fscale = (float)scale; - if (fabs(fscale - MAGIC_SCALE) > FLT_EPSILON) - { - int exp = 0; - double significand = frexp(fscale, &exp); - if((significand != 0.5) || (exp > 1) || (exp < -14)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - else - { - fscale = MAGIC_SCALE; - rounding_policy = VX_ROUND_POLICY_TO_NEAREST_EVEN;// That's the only rounding that MUST be supported for 1/255 scale - } - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, w, h); - vxImage ib(*ctx, b, bstep, w, h); - vxImage ic(*ctx, c, cstep, w, h); - vxErr::check(vxuMultiply(ctx->ctx, ia.img, ib.img, fscale, VX_CONVERT_POLICY_SATURATE, rounding_policy, ic.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_not(const uchar *a, size_t astep, uchar *c, size_t cstep, int w, int h) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, w, h); - vxImage ic(*ctx, c, cstep, w, h); - vxErr::check(vxuNot(ctx->ctx, ia.img, ic.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_merge8u(const uchar **src_data, uchar *dst_data, int len, int cn) -{ - if(dimTooBig(len)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - if (cn != 3 && cn != 4) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, src_data[0], len, len, 1); - vxImage ib(*ctx, src_data[1], len, len, 1); - vxImage ic(*ctx, src_data[2], len, len, 1); - vxImage id(*ctx, cn == 4 ? VX_DF_IMAGE_RGBX : VX_DF_IMAGE_RGB, dst_data, len, len, 1); - vxErr::check(vxuChannelCombine(ctx->ctx, ia.img, ib.img, ic.img, - cn == 4 ? vxImage(*ctx, src_data[3], len, len, 1).img : NULL, - id.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, double inv_scale_x, double inv_scale_y, int interpolation) -{ - if(dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, aw, ah); - vxImage ib(*ctx, b, bstep, bw, bh); - - if(!((atype == CV_8UC1 || atype == CV_8SC1) && - inv_scale_x > 0 && inv_scale_y > 0 && - (bw - 0.5) / inv_scale_x - 0.5 < aw && (bh - 0.5) / inv_scale_y - 0.5 < ah && - (bw + 0.5) / inv_scale_x + 0.5 >= aw && (bh + 0.5) / inv_scale_y + 0.5 >= ah && - std::abs(bw / inv_scale_x - aw) < 0.1 && std::abs(bh / inv_scale_y - ah) < 0.1 )) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - int mode; - if (interpolation == CV_HAL_INTER_LINEAR) - { - mode = VX_INTERPOLATION_BILINEAR; - if (inv_scale_x > 1 || inv_scale_y > 1) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - else if (interpolation == CV_HAL_INTER_AREA) - return CV_HAL_ERROR_NOT_IMPLEMENTED; //mode = VX_INTERPOLATION_AREA; - else if (interpolation == CV_HAL_INTER_NEAREST) - return CV_HAL_ERROR_NOT_IMPLEMENTED; //mode = VX_INTERPOLATION_NEAREST_NEIGHBOR; - else - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - vxErr::check( vxuScaleImage(ctx->ctx, ia.img, ib.img, mode)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_warpAffine(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[6], int interpolation, int borderType, const double borderValue[4]) -{ - if(dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, aw, ah); - vxImage ib(*ctx, b, bstep, bw, bh); - - if (!(atype == CV_8UC1 || atype == CV_8SC1)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - vx_border_t border; - switch (borderType) - { - case CV_HAL_BORDER_CONSTANT: - setConstantBorder(border, (vx_uint8)borderValue[0]); - break; - case CV_HAL_BORDER_REPLICATE: - // Neither 1.0 nor 1.1 OpenVX support BORDER_REPLICATE for warpings - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - int mode; - if (interpolation == CV_HAL_INTER_LINEAR) - mode = VX_INTERPOLATION_BILINEAR; - //AREA interpolation is unsupported - //else if (interpolation == CV_HAL_INTER_AREA) - // mode = VX_INTERPOLATION_AREA; - else if (interpolation == CV_HAL_INTER_NEAREST) - mode = VX_INTERPOLATION_NEAREST_NEIGHBOR; - else - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - std::vector data; - data.reserve(6); - for (int j = 0; j < 3; ++j) - for (int i = 0; i < 2; ++i) - data.push_back((float)(M[i*3+j])); - - vxMatrix mtx(*ctx, data.data(), 2, 3); - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standart says nothing about thread-safety for now - vx_border_t prevBorder; - vxErr::check(vxQueryContext(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &border, sizeof(border))); - vxErr::check(vxuWarpAffine(ctx->ctx, ia.img, mtx.mtx, mode, ib.img)); - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_warpPerspectve(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[9], int interpolation, int borderType, const double borderValue[4]) -{ - if(dimTooBig(aw) || dimTooBig(ah) || dimTooBig(bw) || dimTooBig(bh)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, aw, ah); - vxImage ib(*ctx, b, bstep, bw, bh); - - if (!(atype == CV_8UC1 || atype == CV_8SC1)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - vx_border_t border; - switch (borderType) - { - case CV_HAL_BORDER_CONSTANT: - setConstantBorder(border, (vx_uint8)borderValue[0]); - break; - case CV_HAL_BORDER_REPLICATE: - // Neither 1.0 nor 1.1 OpenVX support BORDER_REPLICATE for warpings - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - int mode; - if (interpolation == CV_HAL_INTER_LINEAR) - mode = VX_INTERPOLATION_BILINEAR; - //AREA interpolation is unsupported - //else if (interpolation == CV_HAL_INTER_AREA) - // mode = VX_INTERPOLATION_AREA; - else if (interpolation == CV_HAL_INTER_NEAREST) - mode = VX_INTERPOLATION_NEAREST_NEIGHBOR; - else - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - std::vector data; - data.reserve(9); - for (int j = 0; j < 3; ++j) - for (int i = 0; i < 3; ++i) - data.push_back((float)(M[i * 3 + j])); - - vxMatrix mtx(*ctx, data.data(), 3, 3); - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standart says nothing about thread-safety for now - vx_border_t prevBorder; - vxErr::check(vxQueryContext(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &border, sizeof(border))); - vxErr::check(vxuWarpPerspective(ctx->ctx, ia.img, mtx.mtx, mode, ib.img)); - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -struct cvhalFilter2D; - -struct FilterCtx -{ - vxConvolution cnv; - int dst_type; - vx_border_t border; - FilterCtx(vxContext &ctx, const short *data, int w, int h, int _dst_type, vx_border_t & _border) : - cnv(ctx, data, w, h), dst_type(_dst_type), border(_border) {} -}; - -inline int ovx_hal_filterInit(cvhalFilter2D **filter_context, uchar *kernel_data, size_t kernel_step, int kernel_type, int kernel_width, int kernel_height, - int , int , int src_type, int dst_type, int borderType, double delta, int anchor_x, int anchor_y, bool allowSubmatrix, bool allowInplace) -{ - if (!filter_context || !kernel_data || allowSubmatrix || allowInplace || delta != 0 || - src_type != CV_8UC1 || (dst_type != CV_8UC1 && dst_type != CV_16SC1) || - kernel_width % 2 == 0 || kernel_height % 2 == 0 || anchor_x != kernel_width / 2 || anchor_y != kernel_height / 2) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - vx_border_t border; - switch (borderType) - { - case CV_HAL_BORDER_CONSTANT: - setConstantBorder(border, 0); - break; - case CV_HAL_BORDER_REPLICATE: - border.mode = VX_BORDER_REPLICATE; - break; - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - vxContext * ctx = vxContext::getContext(); - - std::vector data; - data.reserve(kernel_width*kernel_height); - switch (kernel_type) - { - case CV_8UC1: - for (int j = 0; j < kernel_height; ++j) - { - uchar * row = (uchar*)(kernel_data + kernel_step*j); - for (int i = 0; i < kernel_width; ++i) - data.push_back(row[i]); - } - break; - case CV_8SC1: - for (int j = 0; j < kernel_height; ++j) - { - schar * row = (schar*)(kernel_data + kernel_step*j); - for (int i = 0; i < kernel_width; ++i) - data.push_back(row[i]); - } - break; - case CV_16SC1: - for (int j = 0; j < kernel_height; ++j) - { - short * row = (short*)(kernel_data + kernel_step*j); - for (int i = 0; i < kernel_width; ++i) - data.push_back(row[i]); - } - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - FilterCtx* cnv = new FilterCtx(*ctx, data.data(), kernel_width, kernel_height, dst_type, border); - if (!cnv) - return CV_HAL_ERROR_UNKNOWN; - - *filter_context = (cvhalFilter2D*)(cnv); - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_filterFree(cvhalFilter2D *filter_context) -{ - if (filter_context) - { - delete (FilterCtx*)filter_context; - return CV_HAL_ERROR_OK; - } - else - { - return CV_HAL_ERROR_UNKNOWN; - } -} - -inline int ovx_hal_filter(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int , int , int , int ) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - try - { - FilterCtx* cnv = (FilterCtx*)filter_context; - if(!cnv) - vxErr(VX_ERROR_INVALID_PARAMETERS, "Bad HAL context").check(); - - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, w, h); - - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standart says nothing about thread-safety for now - vx_border_t prevBorder; - vxErr::check(vxQueryContext(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &(cnv->border), sizeof(cnv->border))); - if (cnv->dst_type == CV_16SC1) - { - vxImage ib(*ctx, (short*)b, bstep, w, h); - vxErr::check(vxuConvolve(ctx->ctx, ia.img, cnv->cnv.cnv, ib.img)); - } - else - { - vxImage ib(*ctx, b, bstep, w, h); - vxErr::check(vxuConvolve(ctx->ctx, ia.img, cnv->cnv.cnv, ib.img)); - } - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_sepFilterInit(cvhalFilter2D **filter_context, int src_type, int dst_type, - int kernel_type, uchar *kernelx_data, int kernelx_length, uchar *kernely_data, int kernely_length, - int anchor_x, int anchor_y, double delta, int borderType) -{ - if (!filter_context || !kernelx_data || !kernely_data || delta != 0 || - src_type != CV_8UC1 || (dst_type != CV_8UC1 && dst_type != CV_16SC1) || - kernelx_length % 2 == 0 || kernely_length % 2 == 0 || anchor_x != kernelx_length / 2 || anchor_y != kernely_length / 2) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - vx_border_t border; - switch (borderType) - { - case CV_HAL_BORDER_CONSTANT: - setConstantBorder(border, 0); - break; - case CV_HAL_BORDER_REPLICATE: - border.mode = VX_BORDER_REPLICATE; - break; - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - vxContext * ctx = vxContext::getContext(); - - //At the moment OpenVX doesn't support separable filters natively so combine kernels to generic convolution - std::vector data; - data.reserve(kernelx_length*kernely_length); - switch (kernel_type) - { - case CV_8UC1: - for (int j = 0; j < kernely_length; ++j) - for (int i = 0; i < kernelx_length; ++i) - data.push_back((short)(kernely_data[j]) * kernelx_data[i]); - break; - case CV_8SC1: - for (int j = 0; j < kernely_length; ++j) - for (int i = 0; i < kernelx_length; ++i) - data.push_back((short)(((schar*)kernely_data)[j]) * ((schar*)kernelx_data)[i]); - break; - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - FilterCtx* cnv = new FilterCtx(*ctx, data.data(), kernelx_length, kernely_length, dst_type, border); - if (!cnv) - return CV_HAL_ERROR_UNKNOWN; - - *filter_context = (cvhalFilter2D*)(cnv); - return CV_HAL_ERROR_OK; -} - -#if VX_VERSION > VX_VERSION_1_0 - -struct MorphCtx -{ - vxMatrix mask; - int operation; - vx_border_t border; - MorphCtx(vxContext &ctx, const uchar *data, int w, int h, int _operation, vx_border_t & _border) : - mask(ctx, data, w, h), operation(_operation), border(_border) {} -}; - -inline int ovx_hal_morphInit(cvhalFilter2D **filter_context, int operation, int src_type, int dst_type, int , int , - int kernel_type, uchar *kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, - int borderType, const double borderValue[4], int iterations, bool allowSubmatrix, bool allowInplace) -{ - if (!filter_context || !kernel_data || allowSubmatrix || allowInplace || iterations != 1 || - src_type != CV_8UC1 || dst_type != CV_8UC1 || - kernel_width % 2 == 0 || kernel_height % 2 == 0 || anchor_x != kernel_width / 2 || anchor_y != kernel_height / 2) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - vx_border_t border; - switch (borderType) - { - case CV_HAL_BORDER_CONSTANT: - if (borderValue[0] == DBL_MAX && borderValue[1] == DBL_MAX && borderValue[2] == DBL_MAX && borderValue[3] == DBL_MAX) - { - if (operation == MORPH_ERODE) - setConstantBorder(border, UCHAR_MAX); - else - setConstantBorder(border, 0); - } - else - { - int rounded = (int)round(borderValue[0]); - setConstantBorder(border, (vx_uint8)((unsigned)rounded <= UCHAR_MAX ? rounded : rounded > 0 ? UCHAR_MAX : 0)); - } - break; - case CV_HAL_BORDER_REPLICATE: - border.mode = VX_BORDER_REPLICATE; - break; - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - vxContext * ctx = vxContext::getContext(); - - vx_size maxKernelDim; - vxErr::check(vxQueryContext(ctx->ctx, VX_CONTEXT_NONLINEAR_MAX_DIMENSION, &maxKernelDim, sizeof(maxKernelDim))); - if ((vx_size)kernel_width > maxKernelDim || (vx_size)kernel_height > maxKernelDim) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - std::vector kernel_mat; - kernel_mat.reserve(kernel_width * kernel_height); - switch (CV_MAT_DEPTH(kernel_type)) - { - case CV_8U: - case CV_8S: - for (int j = 0; j < kernel_height; ++j) - { - uchar * kernel_row = kernel_data + j * kernel_step; - for (int i = 0; i < kernel_width; ++i) - kernel_mat.push_back(kernel_row[i] ? 255 : 0); - } - break; - case CV_16U: - case CV_16S: - for (int j = 0; j < kernel_height; ++j) - { - short * kernel_row = (short*)(kernel_data + j * kernel_step); - for (int i = 0; i < kernel_width; ++i) - kernel_mat.push_back(kernel_row[i] ? 255 : 0); - } - break; - case CV_32S: - for (int j = 0; j < kernel_height; ++j) - { - int * kernel_row = (int*)(kernel_data + j * kernel_step); - for (int i = 0; i < kernel_width; ++i) - kernel_mat.push_back(kernel_row[i] ? 255 : 0); - } - break; - case CV_32F: - for (int j = 0; j < kernel_height; ++j) - { - float * kernel_row = (float*)(kernel_data + j * kernel_step); - for (int i = 0; i < kernel_width; ++i) - kernel_mat.push_back(kernel_row[i] ? 255 : 0); - } - break; - case CV_64F: - for (int j = 0; j < kernel_height; ++j) - { - double * kernel_row = (double*)(kernel_data + j * kernel_step); - for (int i = 0; i < kernel_width; ++i) - kernel_mat.push_back(kernel_row[i] ? 255 : 0); - } - break; - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - - MorphCtx* mat; - switch (operation) - { - case MORPH_ERODE: - mat = new MorphCtx(*ctx, kernel_mat.data(), kernel_width, kernel_height, VX_NONLINEAR_FILTER_MIN, border); - break; - case MORPH_DILATE: - mat = new MorphCtx(*ctx, kernel_mat.data(), kernel_width, kernel_height, VX_NONLINEAR_FILTER_MAX, border); - break; - default: - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } - if (!mat) - return CV_HAL_ERROR_UNKNOWN; - - *filter_context = (cvhalFilter2D*)(mat); - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_morphFree(cvhalFilter2D *filter_context) -{ - if (filter_context) - { - delete (MorphCtx*)filter_context; - return CV_HAL_ERROR_OK; - } - else - { - return CV_HAL_ERROR_UNKNOWN; - } -} - -inline int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, uchar *b, size_t bstep, int w, int h, int , int , int , int , int , int , int , int ) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - try - { - MorphCtx* mat = (MorphCtx*)filter_context; - if (!mat) - vxErr(VX_ERROR_INVALID_PARAMETERS, "Bad HAL context").check(); - - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, w, h); - vxImage ib(*ctx, b, bstep, w, h); - - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standart says nothing about thread-safety for now - vx_border_t prevBorder; - vxErr::check(vxQueryContext(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &(mat->border), sizeof(mat->border))); - vxErr::check(vxuNonLinearFilter(ctx->ctx, mat->operation, ia.img, mat->mask.mtx, ib.img)); - vxErr::check(vxSetContextAttribute(ctx->ctx, VX_CONTEXT_IMMEDIATE_BORDER, &prevBorder, sizeof(prevBorder))); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -#endif // 1.0 guard - -inline int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - if (depth != CV_8U || swapBlue || acn == bcn || (acn != 3 && acn != 4) || (bcn != 3 && bcn != 4)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - if (w & 1 || h & 1) // It's strange but sample implementation unable to convert odd sized images - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, a, astep, w, h); - vxImage ib(*ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, b, bstep, w, h); - vxErr::check(vxuColorConvert(ctx->ctx, ia.img, ib.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_cvtGraytoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int bcn) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - if (depth != CV_8U || (bcn != 3 && bcn != 4)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, w, h); - vxImage ib(*ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, b, bstep, w, h); - vxErr::check(vxuChannelCombine(ctx->ctx, ia.img, ia.img, ia.img, - bcn == 4 ? vxImage(*ctx, uchar(255), w, h).img : NULL, - ib.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_cvtTwoPlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - if (!swapBlue || (bcn != 3 && bcn != 4)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, uIdx ? VX_DF_IMAGE_NV21 : VX_DF_IMAGE_NV12, a, astep, w, h); - vx_channel_range_e cRange; - vxErr::check(vxQueryImage(ia.img, VX_IMAGE_RANGE, &cRange, sizeof(cRange))); - if (cRange == VX_CHANNEL_RANGE_FULL) - return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL - vxImage ib(*ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, b, bstep, w, h); - vxErr::check(vxuColorConvert(ctx->ctx, ia.img, ib.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - if (!swapBlue || (bcn != 3 && bcn != 4) || uIdx || (size_t)w / 2 != astep - (size_t)w / 2) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, VX_DF_IMAGE_IYUV, a, astep, w, h); - vx_channel_range_e cRange; - vxErr::check(vxQueryImage(ia.img, VX_IMAGE_RANGE, &cRange, sizeof(cRange))); - if (cRange == VX_CHANNEL_RANGE_FULL) - return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL - vxImage ib(*ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, b, bstep, w, h); - vxErr::check(vxuColorConvert(ctx->ctx, ia.img, ib.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - if (!swapBlue || (acn != 3 && acn != 4) || uIdx || (size_t)w / 2 != bstep - (size_t)w / 2) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - if (w & 1 || h & 1) // It's not described in spec but sample implementation unable to convert odd sized images - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, acn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, a, astep, w, h); - vxImage ib(*ctx, VX_DF_IMAGE_IYUV, b, bstep, w, h); - vxErr::check(vxuColorConvert(ctx->ctx, ia.img, ib.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn) -{ - if(dimTooBig(w) || dimTooBig(h)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - if (!swapBlue || (bcn != 3 && bcn != 4) || uIdx) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - if (w & 1) // It's not described in spec but sample implementation unable to convert odd sized images - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, ycn ? VX_DF_IMAGE_UYVY : VX_DF_IMAGE_YUYV, a, astep, w, h); - vx_channel_range_e cRange; - vxErr::check(vxQueryImage(ia.img, VX_IMAGE_RANGE, &cRange, sizeof(cRange))); - if (cRange == VX_CHANNEL_RANGE_FULL) - return CV_HAL_ERROR_NOT_IMPLEMENTED; // OpenCV store NV12/NV21 as RANGE_RESTRICTED while OpenVX expect RANGE_FULL - vxImage ib(*ctx, bcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX, b, bstep, w, h); - vxErr::check(vxuColorConvert(ctx->ctx, ia.img, ib.img)); - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -inline int ovx_hal_integral(int depth, int sdepth, int , const uchar * a, size_t astep, uchar * b, size_t bstep, uchar * c, size_t , uchar * d, size_t , int w, int h, int cn) -{ - if (depth != CV_8U || sdepth != CV_32S || c != NULL || d != NULL || cn != 1) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - - try - { - vxContext * ctx = vxContext::getContext(); - vxImage ia(*ctx, a, astep, w, h); - vxImage ib(*ctx, (unsigned int *)(b+bstep+sizeof(unsigned int)), bstep, w, h); - vxErr::check(vxuIntegralImage(ctx->ctx, ia.img, ib.img)); - memset(b, 0, (w+1)*sizeof(unsigned int)); - b += bstep; - for (int i = 0; i < h; i++, b += bstep) - { - *((unsigned int*)b) = 0; - } - } - catch (vxErr & e) - { - e.print(); - return CV_HAL_ERROR_UNKNOWN; - } - return CV_HAL_ERROR_OK; -} - -//================================================================================================== -// functions redefinition -// ... - -#undef cv_hal_add8u -#define cv_hal_add8u ovx_hal_add -#undef cv_hal_add16s -#define cv_hal_add16s ovx_hal_add -#undef cv_hal_sub8u -#define cv_hal_sub8u ovx_hal_sub -#undef cv_hal_sub16s -#define cv_hal_sub16s ovx_hal_sub - -#undef cv_hal_absdiff8u -#define cv_hal_absdiff8u ovx_hal_absdiff -#undef cv_hal_absdiff16s -#define cv_hal_absdiff16s ovx_hal_absdiff - -#undef cv_hal_and8u -#define cv_hal_and8u ovx_hal_and -#undef cv_hal_or8u -#define cv_hal_or8u ovx_hal_or -#undef cv_hal_xor8u -#define cv_hal_xor8u ovx_hal_xor -#undef cv_hal_not8u -#define cv_hal_not8u ovx_hal_not - -#undef cv_hal_mul8u -#define cv_hal_mul8u ovx_hal_mul -#undef cv_hal_mul16s -#define cv_hal_mul16s ovx_hal_mul - -#undef cv_hal_merge8u -#define cv_hal_merge8u ovx_hal_merge8u - -//#undef cv_hal_resize -//#define cv_hal_resize ovx_hal_resize - -//OpenVX warps use round to zero policy at least in sample implementation -//while OpenCV require round to nearest -//#undef cv_hal_warpAffine -//#define cv_hal_warpAffine ovx_hal_warpAffine -//#undef cv_hal_warpPerspective -//#define cv_hal_warpPerspective ovx_hal_warpPerspectve - -#undef cv_hal_filterInit -#define cv_hal_filterInit ovx_hal_filterInit -#undef cv_hal_filter -#define cv_hal_filter ovx_hal_filter -#undef cv_hal_filterFree -#define cv_hal_filterFree ovx_hal_filterFree - -#undef cv_hal_sepFilterInit -#define cv_hal_sepFilterInit ovx_hal_sepFilterInit -#undef cv_hal_sepFilter -#define cv_hal_sepFilter ovx_hal_filter -#undef cv_hal_sepFilterFree -#define cv_hal_sepFilterFree ovx_hal_filterFree - -#if VX_VERSION > VX_VERSION_1_0 - -#undef cv_hal_morphInit -#define cv_hal_morphInit ovx_hal_morphInit -#undef cv_hal_morph -#define cv_hal_morph ovx_hal_morph -#undef cv_hal_morphFree -#define cv_hal_morphFree ovx_hal_morphFree - -#endif // 1.0 guard - -#undef cv_hal_cvtBGRtoBGR -#define cv_hal_cvtBGRtoBGR ovx_hal_cvtBGRtoBGR -#undef cv_hal_cvtGraytoBGR -#define cv_hal_cvtGraytoBGR ovx_hal_cvtGraytoBGR -#undef cv_hal_cvtTwoPlaneYUVtoBGR -#define cv_hal_cvtTwoPlaneYUVtoBGR ovx_hal_cvtTwoPlaneYUVtoBGR -#undef cv_hal_cvtThreePlaneYUVtoBGR -#define cv_hal_cvtThreePlaneYUVtoBGR ovx_hal_cvtThreePlaneYUVtoBGR -#undef cv_hal_cvtBGRtoThreePlaneYUV -#define cv_hal_cvtBGRtoThreePlaneYUV ovx_hal_cvtBGRtoThreePlaneYUV -#undef cv_hal_cvtOnePlaneYUVtoBGR -#define cv_hal_cvtOnePlaneYUVtoBGR ovx_hal_cvtOnePlaneYUVtoBGR -#undef cv_hal_integral -#define cv_hal_integral ovx_hal_integral - -#endif diff --git a/3rdparty/openvx/src/openvx_hal.cpp b/3rdparty/openvx/src/openvx_hal.cpp deleted file mode 100644 index e95bbb2b58..0000000000 --- a/3rdparty/openvx/src/openvx_hal.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "openvx_hal.hpp" - -vxContext * vxContext::getContext() -{ - // not thread safe - static vxContext instance; - return &instance; -} diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a746764f7..cc45f6f394 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,7 +227,7 @@ OCV_OPTION(WITH_VA "Include VA support" OFF OCV_OPTION(WITH_VA_INTEL "Include Intel VA-API/OpenCL support" OFF IF (UNIX AND NOT ANDROID) ) OCV_OPTION(WITH_GDAL "Include GDAL Support" OFF IF (NOT ANDROID AND NOT IOS AND NOT WINRT) ) OCV_OPTION(WITH_GPHOTO2 "Include gPhoto2 library support" ON IF (UNIX AND NOT ANDROID) ) -OCV_OPTION(WITH_LAPACK "Include Lapack library support" ON IF (NOT ANDROID) ) +OCV_OPTION(WITH_LAPACK "Include Lapack library support" ON IF (NOT ANDROID AND NOT IOS) ) # OpenCV build components # =================================================== @@ -556,6 +556,7 @@ include(cmake/OpenCVFindLibsGrfmt.cmake) include(cmake/OpenCVFindLibsGUI.cmake) include(cmake/OpenCVFindLibsVideo.cmake) include(cmake/OpenCVFindLibsPerf.cmake) +include(cmake/OpenCVFindLAPACK.cmake) # ---------------------------------------------------------------------------- # Detect other 3rd-party libraries/tools @@ -1222,7 +1223,7 @@ status(" Use Intel VA-API/OpenCL:" HAVE_VA_INTEL THEN "YES (MSDK: ${VA endif(DEFINED WITH_VA_INTEL) if(DEFINED WITH_LAPACK) -status(" Use Lapack:" HAVE_LAPACK THEN "YES" ELSE NO) +status(" Use Lapack:" HAVE_LAPACK THEN "YES (${LAPACK_LIBRARIES})" ELSE NO) endif(DEFINED WITH_LAPACK) status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO) diff --git a/apps/createsamples/utility.cpp b/apps/createsamples/utility.cpp index cf2bdebbf9..2226cd8c92 100644 --- a/apps/createsamples/utility.cpp +++ b/apps/createsamples/utility.cpp @@ -1270,7 +1270,7 @@ void cvCreateTrainingSamples( const char* filename, if( showsamples ) { cvShowImage( "Sample", &sample ); - if( cvWaitKey( 0 ) == 27 ) + if( (cvWaitKey( 0 ) & 0xFF) == 27 ) { showsamples = 0; } @@ -1402,7 +1402,7 @@ void cvCreateTestSamples( const char* infoname, if( showsamples ) { cvShowImage( "Image", &cvbgreader->src ); - if( cvWaitKey( 0 ) == 27 ) + if( (cvWaitKey( 0 ) & 0xFF) == 27 ) { showsamples = 0; } @@ -1525,7 +1525,7 @@ int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilena if( showsamples ) { cvShowImage( "Sample", sample ); - if( cvWaitKey( 0 ) == 27 ) + if( (cvWaitKey( 0 ) & 0xFF) == 27 ) { showsamples = 0; } @@ -1672,7 +1672,7 @@ void cvShowVecSamples( const char* filename, int winwidth, int winheight, icvGetTraininDataFromVec( sample, &file ); if( scale != 1.0 ) cvResize( sample, scaled_sample, CV_INTER_LINEAR); cvShowImage( "Sample", scaled_sample ); - if( cvWaitKey( 0 ) == 27 ) break; + if( (cvWaitKey( 0 ) & 0xFF) == 27 ) break; } if( scaled_sample && scaled_sample != sample ) cvReleaseMat( &scaled_sample ); cvReleaseMat( &sample ); @@ -1680,4 +1680,4 @@ void cvShowVecSamples( const char* filename, int winwidth, int winheight, } fclose( file.input ); } -} \ No newline at end of file +} diff --git a/apps/interactive-calibration/calibPipeline.cpp b/apps/interactive-calibration/calibPipeline.cpp index 1047bfce5f..a92dbffc2f 100644 --- a/apps/interactive-calibration/calibPipeline.cpp +++ b/apps/interactive-calibration/calibPipeline.cpp @@ -68,7 +68,7 @@ PipelineExitStatus CalibPipeline::start(std::vector > pr for (std::vector >::iterator it = processors.begin(); it != processors.end(); ++it) processedFrame = (*it)->processFrame(processedFrame); cv::imshow(mainWindowName, processedFrame); - int key = cv::waitKey(CAP_DELAY); + char key = (char)cv::waitKey(CAP_DELAY); if(key == 27) // esc return Finished; diff --git a/apps/traincascade/cascadeclassifier.cpp b/apps/traincascade/cascadeclassifier.cpp index 9c24feb49a..ebfb43e6c3 100644 --- a/apps/traincascade/cascadeclassifier.cpp +++ b/apps/traincascade/cascadeclassifier.cpp @@ -412,6 +412,7 @@ bool CvCascadeClassifier::readStages( const FileNode &node) } // For old Haar Classifier file saving +#define ICV_HAAR_TYPE_ID "opencv-haar-classifier" #define ICV_HAAR_SIZE_NAME "size" #define ICV_HAAR_STAGES_NAME "stages" #define ICV_HAAR_TREES_NAME "trees" @@ -434,11 +435,12 @@ void CvCascadeClassifier::save( const string filename, bool baseFormat ) if ( !fs.isOpened() ) return; - fs << FileStorage::getDefaultObjectName(filename) << "{"; + fs << FileStorage::getDefaultObjectName(filename); if ( !baseFormat ) { Mat featureMap; getUsedFeaturesIdxMap( featureMap ); + fs << "{"; writeParams( fs ); fs << CC_STAGE_NUM << (int)stageClassifiers.size(); writeStages( fs, featureMap ); @@ -450,6 +452,7 @@ void CvCascadeClassifier::save( const string filename, bool baseFormat ) CvSeq* weak; if ( cascadeParams.featureType != CvFeatureParams::HAAR ) CV_Error( CV_StsBadFunc, "old file format is used for Haar-like features only"); + fs << "{:" ICV_HAAR_TYPE_ID; fs << ICV_HAAR_SIZE_NAME << "[:" << cascadeParams.winSize.width << cascadeParams.winSize.height << "]"; fs << ICV_HAAR_STAGES_NAME << "["; diff --git a/cmake/OpenCVCompilerOptions.cmake b/cmake/OpenCVCompilerOptions.cmake index c433d988fd..5bb0479113 100644 --- a/cmake/OpenCVCompilerOptions.cmake +++ b/cmake/OpenCVCompilerOptions.cmake @@ -101,6 +101,10 @@ if(MINGW) endif() endif() +if(CV_ICC AND NOT ENABLE_FAST_MATH) + add_extra_compiler_option("-fp-model precise") +endif() + if(CMAKE_COMPILER_IS_GNUCXX) # High level of warnings. add_extra_compiler_option(-W) @@ -414,8 +418,13 @@ if(MSVC) string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - if(NOT ENABLE_NOISY_WARNINGS AND MSVC_VERSION EQUAL 1400) - ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4510 /wd4610 /wd4312 /wd4201 /wd4244 /wd4328 /wd4267) + if(NOT ENABLE_NOISY_WARNINGS) + if(MSVC_VERSION EQUAL 1400) + ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4510 /wd4610 /wd4312 /wd4201 /wd4244 /wd4328 /wd4267) + endif() + if(MSVC_VERSION LESS 1900) # MSVS2015 + ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127) # warning C4127: conditional expression is constant + endif() endif() # allow extern "C" functions throw exceptions @@ -432,6 +441,13 @@ if(MSVC) ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4275) # non dll-interface class 'std::exception' used as base for dll-interface class 'cv::Exception' ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4589) # Constructor of abstract class 'cv::ORB' ignores initializer for virtual base class 'cv::Algorithm' endif() + + if(CV_ICC AND NOT ENABLE_NOISY_WARNINGS) + foreach(flags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG) + string(REGEX REPLACE "( |^)/W[0-9]+( |$)" "\\1\\2" ${flags} "${${flags}}") + endforeach() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qwd673") # PCH warning + endif() endif() if(APPLE AND NOT CMAKE_CROSSCOMPILING AND NOT DEFINED ENV{LDFLAGS} AND EXISTS "/usr/local/lib") diff --git a/cmake/OpenCVFindAtlas.cmake b/cmake/OpenCVFindAtlas.cmake new file mode 100644 index 0000000000..4fc7317749 --- /dev/null +++ b/cmake/OpenCVFindAtlas.cmake @@ -0,0 +1,97 @@ +#COPYRIGHT +# +#All contributions by the University of California: +#Copyright (c) 2014, 2015, The Regents of the University of California (Regents) +#All rights reserved. +# +#All other contributions: +#Copyright (c) 2014, 2015, the respective contributors +#All rights reserved. +# +#Caffe uses a shared copyright model: each contributor holds copyright over +#their contributions to Caffe. The project versioning records all such +#contribution and copyright details. If a contributor wants to further mark +#their specific copyright on a particular contribution, they should indicate +#their copyright solely in the commit message of the change when it is +#committed. +# +#LICENSE +# +#Redistribution and use in source and binary forms, with or without +#modification, are permitted provided that the following conditions are met: +# +#1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +#2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#CONTRIBUTION AGREEMENT +# +#By contributing to the BVLC/caffe repository through pull-request, comment, +#or otherwise, the contributor releases their content to the +#license and copyright terms herein. + + +# Find the Atlas (and Lapack) libraries +# +# The following variables are optionally searched for defaults +# Atlas_ROOT_DIR: Base directory where all Atlas components are found +# +# The following are set after configuration is done: +# Atlas_FOUND +# Atlas_INCLUDE_DIRS +# Atlas_LIBRARIES +# Atlas_LIBRARYRARY_DIRS + +set(Atlas_INCLUDE_SEARCH_PATHS + /usr/include/atlas + /usr/include/atlas-base + $ENV{Atlas_ROOT_DIR} + $ENV{Atlas_ROOT_DIR}/include +) + +set(Atlas_LIB_SEARCH_PATHS + /usr/lib/atlas + /usr/lib/atlas-base + $ENV{Atlas_ROOT_DIR} + $ENV{Atlas_ROOT_DIR}/lib +) + +find_path(Atlas_CBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${Atlas_INCLUDE_SEARCH_PATHS}) +find_path(Atlas_CLAPACK_INCLUDE_DIR NAMES lapacke.h PATHS ${Atlas_INCLUDE_SEARCH_PATHS}) + +find_library(Atlas_CBLAS_LIBRARY NAMES ptcblas_r ptcblas cblas_r cblas PATHS ${Atlas_LIB_SEARCH_PATHS}) +find_library(Atlas_BLAS_LIBRARY NAMES atlas_r atlas PATHS ${Atlas_LIB_SEARCH_PATHS}) +find_library(Atlas_LAPACK_LIBRARY NAMES lapack alapack_r alapack lapack_atlas PATHS ${Atlas_LIB_SEARCH_PATHS}) + +set(LOOKED_FOR + Atlas_CBLAS_INCLUDE_DIR + Atlas_CLAPACK_INCLUDE_DIR + + Atlas_CBLAS_LIBRARY + Atlas_BLAS_LIBRARY + Atlas_LAPACK_LIBRARY +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Atlas DEFAULT_MSG ${LOOKED_FOR}) + +if(ATLAS_FOUND) + set(Atlas_INCLUDE_DIR ${Atlas_CBLAS_INCLUDE_DIR} ${Atlas_CLAPACK_INCLUDE_DIR}) + set(Atlas_LIBRARIES ${Atlas_LAPACK_LIBRARY} ${Atlas_CBLAS_LIBRARY} ${Atlas_BLAS_LIBRARY}) + mark_as_advanced(${LOOKED_FOR}) + + message(STATUS "Found Atlas (include: ${Atlas_CBLAS_INCLUDE_DIR}, library: ${Atlas_BLAS_LIBRARY})") +endif(ATLAS_FOUND) \ No newline at end of file diff --git a/cmake/OpenCVFindLAPACK.cmake b/cmake/OpenCVFindLAPACK.cmake new file mode 100644 index 0000000000..dfacf24328 --- /dev/null +++ b/cmake/OpenCVFindLAPACK.cmake @@ -0,0 +1,78 @@ +macro(_find_file_in_dirs VAR NAME DIRS) + find_path(${VAR} ${NAME} ${DIRS} NO_DEFAULT_PATH) + set(${VAR} ${${VAR}}/${NAME}) + unset(${VAR} CACHE) +endmacro() + +if(WITH_LAPACK) + ocv_update(LAPACK_IMPL "Unknown") + if(NOT LAPACK_LIBRARIES) + include(cmake/OpenCVFindMKL.cmake) + if(HAVE_MKL) + set(LAPACK_INCLUDE_DIR ${MKL_INCLUDE_DIRS}) + set(LAPACK_LIBRARIES ${MKL_LIBRARIES} ) + set(LAPACK_CBLAS_H "mkl_cblas.h" ) + set(LAPACK_LAPACKE_H "mkl_lapack.h" ) + set(LAPACK_IMPL "MKL") + endif() + endif() + if(NOT LAPACK_LIBRARIES) + include(cmake/OpenCVFindOpenBLAS.cmake) + if(OpenBLAS_FOUND) + set(LAPACK_INCLUDE_DIR ${OpenBLAS_INCLUDE_DIR} ) + set(LAPACK_LIBRARIES ${OpenBLAS_LIB} ) + set(LAPACK_CBLAS_H "cblas.h" ) + set(LAPACK_LAPACKE_H "lapacke.h" ) + set(LAPACK_IMPL "OpenBLAS") + endif() + endif() + if(NOT LAPACK_LIBRARIES AND UNIX) + include(cmake/OpenCVFindAtlas.cmake) + if(ATLAS_FOUND) + set(LAPACK_INCLUDE_DIR ${Atlas_INCLUDE_DIR}) + set(LAPACK_LIBRARIES ${Atlas_LIBRARIES} ) + set(LAPACK_CBLAS_H "cblas.h" ) + set(LAPACK_LAPACKE_H "lapacke.h" ) + set(LAPACK_IMPL "Atlas") + endif() + endif() + + if(NOT LAPACK_LIBRARIES AND APPLE) + set(LAPACK_INCLUDE_DIR "Accelerate") + set(LAPACK_LIBRARIES "-framework Accelerate") + set(LAPACK_CBLAS_H "cblas.h" ) + set(LAPACK_LAPACKE_H "lapacke.h" ) + set(LAPACK_IMPL "Apple") + endif() + + set(LAPACK_INCLUDE_DIR ${LAPACK_INCLUDE_DIR} CACHE PATH "Path to BLAS include dir" FORCE) + set(LAPACK_CBLAS_H ${LAPACK_CBLAS_H} CACHE STRING "Alternative name of cblas.h" FORCE) + set(LAPACK_LAPACKE_H ${LAPACK_LAPACKE_H} CACHE STRING "Alternative name of lapacke.h" FORCE) + set(LAPACK_LIBRARIES ${LAPACK_LIBRARIES} CACHE STRING "Names of BLAS & LAPACK binaries (.so, .dll, .a, .lib)" FORCE) + set(LAPACK_IMPL ${LAPACK_IMPL} CACHE STRING "Lapack implementation id" FORCE) + + if(LAPACK_LIBRARIES) #adding proxy cblas.h header + message(STATUS "LAPACK_IMPL: ${LAPACK_IMPL}, LAPACK_LIBRARIES: ${LAPACK_LIBRARIES}") + if("${LAPACK_IMPL}" STREQUAL "Apple") + set(CBLAS_H_PATH "Accelerate/Accelerate.h") + set(LAPACKE_H_PATH "Accelerate/Accelerate.h") + else() + _find_file_in_dirs(CBLAS_H_PATH "${LAPACK_CBLAS_H}" "${LAPACK_INCLUDE_DIR}") + _find_file_in_dirs(LAPACKE_H_PATH "${LAPACK_LAPACKE_H}" "${LAPACK_INCLUDE_DIR}") + endif() + if(NOT CBLAS_H_PATH OR NOT LAPACKE_H_PATH) + message(WARNING "CBLAS/LAPACK headers are not found in '${LAPACK_INCLUDE_DIR}'") + endif() + ocv_include_directories(${LAPACK_INCLUDE_DIR}) + list(APPEND OPENCV_LINKER_LIBS ${LAPACK_LIBRARIES}) + set(HAVE_LAPACK 1) + + set(CBLAS_H_PROXY_PATH ${CMAKE_BINARY_DIR}/opencv_lapack.h) + set(_include_str "\#include \"${CBLAS_H_PATH}\"") + if("${CBLAS_H_PATH}" STREQUAL "${LAPACKE_H_PATH}") + else() + set(_include_str "${_include_str}\n\#include \"${LAPACKE_H_PATH}\"") + endif() + file(WRITE ${CBLAS_H_PROXY_PATH} ${_include_str}) + endif() +endif() diff --git a/cmake/OpenCVFindLibsPerf.cmake b/cmake/OpenCVFindLibsPerf.cmake index 82afd390ae..70b6cf543e 100644 --- a/cmake/OpenCVFindLibsPerf.cmake +++ b/cmake/OpenCVFindLibsPerf.cmake @@ -3,33 +3,29 @@ # ---------------------------------------------------------------------------- # --- Lapack --- -if(WITH_LAPACK) - if(WIN32) - set(BLA_STATIC 1) - endif() - find_package(LAPACK) - if(LAPACK_FOUND) - find_path(LAPACKE_INCLUDE_DIR "lapacke.h") - find_path(MKL_LAPACKE_INCLUDE_DIR "mkl_lapack.h") - if(LAPACKE_INCLUDE_DIR OR MKL_LAPACKE_INCLUDE_DIR) - find_path(CBLAS_INCLUDE_DIR "cblas.h") - find_path(MKL_CBLAS_INCLUDE_DIR "mkl_cblas.h") - - if(CBLAS_INCLUDE_DIR OR MKL_CBLAS_INCLUDE_DIR) - set(HAVE_LAPACK 1) - - if(CBLAS_INCLUDE_DIR) - ocv_include_directories(${LAPACKE_INCLUDE_DIR} ${CBLAS_INCLUDE_DIR}) - set(HAVE_LAPACK_GENERIC 1) - elseif(MKL_CBLAS_INCLUDE_DIR) - ocv_include_directories(${MKL_LAPACKE_INCLUDE_DIR} ${MKL_CBLAS_INCLUDE_DIR}) - set(HAVE_LAPACK_MKL 1) - endif() - list(APPEND OPENCV_LINKER_LIBS ${LAPACK_LIBRARIES}) - endif() - endif() - endif() -endif() +# if(WITH_LAPACK) +# if(WIN32) +# set(BLA_STATIC 1) +# endif() +# find_package(LAPACK) +# if(LAPACK_FOUND) +# find_path(LAPACKE_INCLUDE_DIR "lapacke.h") +# find_path(MKL_LAPACKE_INCLUDE_DIR "mkl_lapack.h") +# if(LAPACKE_INCLUDE_DIR) +# ocv_include_directories(${LAPACKE_INCLUDE_DIR}) +# set(HAVE_LAPACK 1) +# set(HAVE_LAPACK_GENERIC 1) +# elseif(MKL_LAPACKE_INCLUDE_DIR) +# ocv_include_directories(${MKL_LAPACKE_INCLUDE_DIR}) +# set(HAVE_LAPACK 1) +# set(HAVE_LAPACK_MKL 1) +# elseif(APPLE) +# set(HAVE_LAPACK 1) +# set(HAVE_LAPACK_APPLE 1) +# endif() +# list(APPEND OPENCV_LINKER_LIBS ${LAPACK_LIBRARIES}) +# endif() +# endif() # --- TBB --- if(WITH_TBB) diff --git a/cmake/OpenCVFindLibsVideo.cmake b/cmake/OpenCVFindLibsVideo.cmake index b2b74b7a3b..1eff03b581 100644 --- a/cmake/OpenCVFindLibsVideo.cmake +++ b/cmake/OpenCVFindLibsVideo.cmake @@ -236,6 +236,7 @@ if(WITH_FFMPEG) if(NOT __VALID_FFMPEG) #message(FATAL_ERROR "FFMPEG: test check build log:\n${TRY_OUT}") message(STATUS "WARNING: Can't build ffmpeg test code") + set(HAVE_FFMPEG FALSE) else() ocv_append_build_options(VIDEOIO FFMPEG) endif() diff --git a/cmake/OpenCVFindMKL.cmake b/cmake/OpenCVFindMKL.cmake new file mode 100644 index 0000000000..f43ce9c286 --- /dev/null +++ b/cmake/OpenCVFindMKL.cmake @@ -0,0 +1,136 @@ +# +# The script to detect Intel(R) Math Kernel Library (MKL) +# installation/package +# +# Parameters: +# MKL_WITH_TBB +# +# On return this will define: +# +# HAVE_MKL - True if Intel IPP found +# MKL_ROOT_DIR - root of IPP installation +# MKL_INCLUDE_DIRS - IPP include folder +# MKL_LIBRARIES - IPP libraries that are used by OpenCV +# + +macro (mkl_find_lib VAR NAME DIRS) + find_path(${VAR} ${NAME} ${DIRS} NO_DEFAULT_PATH) + set(${VAR} ${${VAR}}/${NAME}) + unset(${VAR} CACHE) +endmacro() + +macro(mkl_fail) + set(HAVE_MKL OFF CACHE BOOL "True if MKL found") + set(MKL_ROOT_DIR ${MKL_ROOT_DIR} CACHE PATH "Path to MKL directory") + unset(MKL_INCLUDE_DIRS CACHE) + unset(MKL_LIBRARIES CACHE) + return() +endmacro() + +macro(get_mkl_version VERSION_FILE) + # read MKL version info from file + file(STRINGS ${VERSION_FILE} STR1 REGEX "__INTEL_MKL__") + file(STRINGS ${VERSION_FILE} STR2 REGEX "__INTEL_MKL_MINOR__") + file(STRINGS ${VERSION_FILE} STR3 REGEX "__INTEL_MKL_UPDATE__") + #file(STRINGS ${VERSION_FILE} STR4 REGEX "INTEL_MKL_VERSION") + + # extract info and assign to variables + string(REGEX MATCHALL "[0-9]+" MKL_VERSION_MAJOR ${STR1}) + string(REGEX MATCHALL "[0-9]+" MKL_VERSION_MINOR ${STR2}) + string(REGEX MATCHALL "[0-9]+" MKL_VERSION_UPDATE ${STR3}) + set(MKL_VERSION_STR "${MKL_VERSION_MAJOR}.${MKL_VERSION_MINOR}.${MKL_VERSION_UPDATE}" CACHE STRING "MKL version" FORCE) +endmacro() + + +if(NOT DEFINED MKL_USE_MULTITHREAD) + OCV_OPTION(MKL_WITH_TBB "Use MKL with TBB multithreading" OFF)#ON IF WITH_TBB) + OCV_OPTION(MKL_WITH_OPENMP "Use MKL with OpenMP multithreading" OFF)#ON IF WITH_OPENMP) +endif() + +#check current MKL_ROOT_DIR +if(NOT MKL_ROOT_DIR OR NOT EXISTS ${MKL_ROOT_DIR}/include/mkl.h) + set(mkl_root_paths ${MKL_ROOT_DIR}) + if(DEFINED $ENV{MKLROOT}) + list(APPEND mkl_root_paths $ENV{MKLROOT}) + endif() + if(WIN32) + set(ProgramFilesx86 "ProgramFiles(x86)") + list(APPEND mkl_root_paths $ENV{${ProgramFilesx86}}/IntelSWTools/compilers_and_libraries/windows/mkl) + endif() + if(UNIX) + list(APPEND mkl_root_paths "/opt/intel/mkl") + endif() + + find_path(MKL_ROOT_DIR include/mkl.h PATHS ${mkl_root_paths}) +endif() + +if(NOT MKL_ROOT_DIR) + mkl_fail() +endif() + +set(MKL_INCLUDE_DIRS ${MKL_ROOT_DIR}/include) +get_mkl_version(${MKL_INCLUDE_DIRS}/mkl_version.h) + +#determine arch +if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) + set(MKL_X64 1) + set(MKL_ARCH "intel64") + + include(CheckTypeSize) + CHECK_TYPE_SIZE(int _sizeof_int) + if (_sizeof_int EQUAL 4) + set(MKL_LP64 "lp64") + else() + set(MKL_LP64 "ilp64") + endif() +else() + set(MKL_ARCH "ia32") +endif() + +if(${MKL_VERSION_STR} VERSION_GREATER "11.3.0" OR ${MKL_VERSION_STR} VERSION_EQUAL "11.3.0") + set(mkl_lib_find_paths + ${MKL_ROOT_DIR}/lib + ${MKL_ROOT_DIR}/lib/${MKL_ARCH} ${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH}) + + set(mkl_lib_list + mkl_core + mkl_intel_${MKL_LP64}) + + if(MKL_WITH_TBB) + list(APPEND mkl_lib_list mkl_tbb_thread tbb) + elseif(MKL_WITH_OPENMP) + if(MSVC) + list(APPEND mkl_lib_list mkl_intel_thread libiomp5md) + else() + list(APPEND mkl_lib_list libmkl_gnu_thread) + endif() + else() + list(APPEND mkl_lib_list mkl_sequential) + endif() +else() + message(STATUS "MKL version ${MKL_VERSION_STR} is not supported") + mkl_fail() +endif() + + +set(MKL_LIBRARIES "") +foreach(lib ${mkl_lib_list}) + find_library(${lib} ${lib} ${mkl_lib_find_paths}) + mark_as_advanced(${lib}) + if(NOT ${lib}) + mkl_fail() + endif() + list(APPEND MKL_LIBRARIES ${${lib}}) +endforeach() + +message(STATUS "Found MKL ${MKL_VERSION_STR} at: ${MKL_ROOT_DIR}") +set(HAVE_MKL ON CACHE BOOL "True if MKL found") +set(MKL_ROOT_DIR ${MKL_ROOT_DIR} CACHE PATH "Path to MKL directory") +set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIRS} CACHE PATH "Path to MKL include directory") +if(NOT UNIX) + set(MKL_LIBRARIES ${MKL_LIBRARIES} CACHE FILEPATH "MKL libarries") +else() + #it's ugly but helps to avoid cyclic lib problem + set(MKL_LIBRARIES ${MKL_LIBRARIES} ${MKL_LIBRARIES} ${MKL_LIBRARIES} "-lpthread" "-lm" "-ldl") + set(MKL_LIBRARIES ${MKL_LIBRARIES} CACHE STRING "MKL libarries") +endif() \ No newline at end of file diff --git a/cmake/OpenCVFindOpenBLAS.cmake b/cmake/OpenCVFindOpenBLAS.cmake new file mode 100644 index 0000000000..60594dee46 --- /dev/null +++ b/cmake/OpenCVFindOpenBLAS.cmake @@ -0,0 +1,106 @@ +#COPYRIGHT +# +#All contributions by the University of California: +#Copyright (c) 2014, 2015, The Regents of the University of California (Regents) +#All rights reserved. +# +#All other contributions: +#Copyright (c) 2014, 2015, the respective contributors +#All rights reserved. +# +#Caffe uses a shared copyright model: each contributor holds copyright over +#their contributions to Caffe. The project versioning records all such +#contribution and copyright details. If a contributor wants to further mark +#their specific copyright on a particular contribution, they should indicate +#their copyright solely in the commit message of the change when it is +#committed. +# +#LICENSE +# +#Redistribution and use in source and binary forms, with or without +#modification, are permitted provided that the following conditions are met: +# +#1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +#2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#CONTRIBUTION AGREEMENT +# +#By contributing to the BVLC/caffe repository through pull-request, comment, +#or otherwise, the contributor releases their content to the +#license and copyright terms herein. + +SET(Open_BLAS_INCLUDE_SEARCH_PATHS + /usr/include + /usr/include/openblas + /usr/include/openblas-base + /usr/local/include + /usr/local/include/openblas + /usr/local/include/openblas-base + /opt/OpenBLAS/include + $ENV{OpenBLAS_HOME} + $ENV{OpenBLAS_HOME}/include +) + +SET(Open_BLAS_LIB_SEARCH_PATHS + /lib/ + /lib/openblas-base + /lib64/ + /usr/lib + /usr/lib/openblas-base + /usr/lib64 + /usr/local/lib + /usr/local/lib64 + /opt/OpenBLAS/lib + $ENV{OpenBLAS}cd + $ENV{OpenBLAS}/lib + $ENV{OpenBLAS_HOME} + $ENV{OpenBLAS_HOME}/lib + ) + +FIND_PATH(OpenBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${Open_BLAS_INCLUDE_SEARCH_PATHS}) +FIND_LIBRARY(OpenBLAS_LIB NAMES openblas PATHS ${Open_BLAS_LIB_SEARCH_PATHS}) + +SET(OpenBLAS_FOUND ON) + +# Check include files +IF(NOT OpenBLAS_INCLUDE_DIR) + SET(OpenBLAS_FOUND OFF) + MESSAGE(STATUS "Could not find OpenBLAS include. Turning OpenBLAS_FOUND off") +ENDIF() + +# Check libraries +IF(NOT OpenBLAS_LIB) + SET(OpenBLAS_FOUND OFF) + MESSAGE(STATUS "Could not find OpenBLAS lib. Turning OpenBLAS_FOUND off") +ENDIF() + +IF (OpenBLAS_FOUND) + IF (NOT OpenBLAS_FIND_QUIETLY) + MESSAGE(STATUS "Found OpenBLAS libraries: ${OpenBLAS_LIB}") + MESSAGE(STATUS "Found OpenBLAS include: ${OpenBLAS_INCLUDE_DIR}") + ENDIF (NOT OpenBLAS_FIND_QUIETLY) +ELSE (OpenBLAS_FOUND) + IF (OpenBLAS_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find OpenBLAS") + ENDIF (OpenBLAS_FIND_REQUIRED) +ENDIF (OpenBLAS_FOUND) + +MARK_AS_ADVANCED( + OpenBLAS_INCLUDE_DIR + OpenBLAS_LIB + OpenBLAS +) \ No newline at end of file diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 1d779d6775..cdf257d5fe 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -302,6 +302,7 @@ macro(ocv_warnings_disable) set(_flag_vars "") set(_msvc_warnings "") set(_gxx_warnings "") + set(_icc_warnings "") foreach(arg ${ARGN}) if(arg MATCHES "^CMAKE_") list(APPEND _flag_vars ${arg}) @@ -309,6 +310,8 @@ macro(ocv_warnings_disable) list(APPEND _msvc_warnings ${arg}) elseif(arg MATCHES "^-W") list(APPEND _gxx_warnings ${arg}) + elseif(arg MATCHES "^-wd" OR arg MATCHES "^-Qwd" OR arg MATCHES "^/Qwd") + list(APPEND _icc_warnings ${arg}) endif() endforeach() if(MSVC AND _msvc_warnings AND _flag_vars) @@ -331,9 +334,25 @@ macro(ocv_warnings_disable) endforeach() endforeach() endif() + if(CV_ICC AND _icc_warnings AND _flag_vars) + foreach(var ${_flag_vars}) + foreach(warning ${_icc_warnings}) + if(UNIX) + string(REPLACE "-Qwd" "-wd" warning "${warning}") + else() + string(REPLACE "-wd" "-Qwd" warning "${warning}") + endif() + ocv_check_flag_support(${var} "${warning}" _varname) + if(${_varname}) + set(${var} "${${var}} ${warning}") + endif() + endforeach() + endforeach() + endif() unset(_flag_vars) unset(_msvc_warnings) unset(_gxx_warnings) + unset(_icc_warnings) endif(NOT ENABLE_NOISY_WARNINGS) endmacro() @@ -672,8 +691,11 @@ function(ocv_install_target) set(${__package}_TARGETS "${${__package}_TARGETS}" CACHE INTERNAL "List of ${__package} targets") endif() - if(INSTALL_CREATE_DISTRIB) - if(MSVC AND NOT BUILD_SHARED_LIBS) + if(MSVS) + if(NOT INSTALL_IGNORE_PDB AND + (INSTALL_PDB OR + (INSTALL_CREATE_DISTRIB AND NOT BUILD_SHARED_LIBS) + )) set(__target "${ARGV0}") set(isArchive 0) @@ -701,13 +723,13 @@ function(ocv_install_target) get_target_property(fname ${__target} LOCATION_DEBUG) if(fname MATCHES "\\.lib$") string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}") - install(FILES "${fname}" DESTINATION "${__dst}" CONFIGURATIONS Debug) + install(FILES "${fname}" DESTINATION "${__dst}" CONFIGURATIONS Debug OPTIONAL) endif() get_target_property(fname ${__target} LOCATION_RELEASE) if(fname MATCHES "\\.lib$") string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}") - install(FILES "${fname}" DESTINATION "${__dst}" CONFIGURATIONS Release) + install(FILES "${fname}" DESTINATION "${__dst}" CONFIGURATIONS Release OPTIONAL) endif() else() # CMake 2.8.12 broke PDB support for STATIC libraries from MSVS, fix was introduced in CMake 3.1.0. @@ -1076,16 +1098,16 @@ endfunction() macro(ocv_add_testdata basedir dest_subdir) if(BUILD_TESTS) - cmake_parse_arguments(__TESTDATA "" "COMPONENT" "" ${ARGN}) if(NOT CMAKE_CROSSCOMPILING AND NOT INSTALL_TESTS) file(COPY ${basedir}/ DESTINATION ${CMAKE_BINARY_DIR}/${OPENCV_TEST_DATA_INSTALL_PATH}/${dest_subdir} - ${__TESTDATA_UNPARSED_ARGUMENTS} + ${ARGN} ) endif() if(INSTALL_TESTS) install(DIRECTORY ${basedir}/ DESTINATION ${OPENCV_TEST_DATA_INSTALL_PATH}/contrib/text + COMPONENT "tests" ${ARGN} ) endif() diff --git a/cmake/templates/OpenCVConfig.cmake.in b/cmake/templates/OpenCVConfig.cmake.in index dfe9aeafe1..47751f55cf 100644 --- a/cmake/templates/OpenCVConfig.cmake.in +++ b/cmake/templates/OpenCVConfig.cmake.in @@ -14,6 +14,10 @@ # # find_package(OpenCV REQUIRED core videoio) # +# You can also mark OpenCV components as optional: + +# find_package(OpenCV REQUIRED core OPTIONAL_COMPONENTS viz) +# # If the module is found then OPENCV__FOUND is set to TRUE. # # This file will define the following variables: @@ -48,6 +52,21 @@ SET(OpenCV_VERSION_PATCH @OPENCV_VERSION_PATCH@) SET(OpenCV_VERSION_TWEAK 0) SET(OpenCV_VERSION_STATUS "@OPENCV_VERSION_STATUS@") +include(FindPackageHandleStandardArgs) + +if(NOT CMAKE_VERSION VERSION_LESS 2.8.8 + AND OpenCV_FIND_COMPONENTS # prevent excessive output +) + # HANDLE_COMPONENTS was introduced in CMake 2.8.8 + list(APPEND _OpenCV_FPHSA_ARGS HANDLE_COMPONENTS) + # The missing components will be handled by the FindPackageHandleStandardArgs + # module. + set(_OpenCV_HANDLE_COMPONENTS_MANUALLY FALSE) +else() + # The missing components will be handled by this config. + set(_OpenCV_HANDLE_COMPONENTS_MANUALLY TRUE) +endif() + # Extract directory name from full path of the file currently being processed. # Note that CMake 2.8.3 introduced CMAKE_CURRENT_LIST_DIR. We reimplement it # for older versions of CMake to support these as well. @@ -120,24 +139,33 @@ endif() set(OpenCV_WORLD_COMPONENTS @OPENCV_WORLD_MODULES@) # expand short module names and see if requested components exist -set(OpenCV_FIND_COMPONENTS_ "") foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) + # Store the name of the original component so we can set the + # OpenCV__FOUND variable which can be checked by the user. + set (__original_cvcomponent ${__cvcomponent}) if(NOT __cvcomponent MATCHES "^opencv_") set(__cvcomponent opencv_${__cvcomponent}) endif() list(FIND OpenCV_LIB_COMPONENTS ${__cvcomponent} __cvcomponentIdx) if(__cvcomponentIdx LESS 0) - #requested component is not found... - if(OpenCV_FIND_REQUIRED) - message(FATAL_ERROR "${__cvcomponent} is required but was not found") - elseif(NOT OpenCV_FIND_QUIETLY) - message(WARNING "${__cvcomponent} is required but was not found") - endif() + if(_OpenCV_HANDLE_COMPONENTS_MANUALLY) + # Either the component is required or the user did not set any components at + # all. In the latter case, the OpenCV_FIND_REQUIRED_ variable + # will not be defined since it is not set by this config. So let's assume + # the implicitly set components are always required. + if(NOT DEFINED OpenCV_FIND_REQUIRED_${__original_cvcomponent} OR + OpenCV_FIND_REQUIRED_${__original_cvcomponent}) + message(FATAL_ERROR "${__cvcomponent} is required but was not found") + elseif(NOT OpenCV_FIND_QUIETLY) + # The component was marked as optional using OPTIONAL_COMPONENTS + message(WARNING "Optional component ${__cvcomponent} was not found") + endif() + endif(_OpenCV_HANDLE_COMPONENTS_MANUALLY) #indicate that module is NOT found string(TOUPPER "${__cvcomponent}" __cvcomponentUP) set(${__cvcomponentUP}_FOUND "${__cvcomponentUP}_FOUND-NOTFOUND") + set(OpenCV_${__original_cvcomponent}_FOUND FALSE) else() - list(APPEND OpenCV_FIND_COMPONENTS_ ${__cvcomponent}) # Not using list(APPEND) here, because OpenCV_LIBS may not exist yet. # Also not clearing OpenCV_LIBS anywhere, so that multiple calls # to find_package(OpenCV) with different component lists add up. @@ -145,6 +173,7 @@ foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) #indicate that module is found string(TOUPPER "${__cvcomponent}" __cvcomponentUP) set(${__cvcomponentUP}_FOUND 1) + set(OpenCV_${__original_cvcomponent}_FOUND TRUE) endif() if(OpenCV_SHARED AND ";${OpenCV_WORLD_COMPONENTS};" MATCHES ";${__cvcomponent};" AND NOT TARGET ${__cvcomponent}) get_target_property(__implib_dbg opencv_world IMPORTED_IMPLIB_DEBUG) @@ -170,7 +199,6 @@ foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) endif() endif() endforeach() -set(OpenCV_FIND_COMPONENTS ${OpenCV_FIND_COMPONENTS_}) # ============================================================== # Compatibility stuff @@ -226,3 +254,8 @@ macro(ocv_list_filterout lst regex) endif() endforeach() endmacro() + +# We do not actually need REQUIRED_VARS to be checked for. Just use the +# installation directory for the status. +find_package_handle_standard_args(OpenCV REQUIRED_VARS OpenCV_INSTALL_PATH + VERSION_VAR OpenCV_VERSION ${_OpenCV_FPHSA_ARGS}) diff --git a/cmake/templates/cvconfig.h.in b/cmake/templates/cvconfig.h.in index 514d1f5c70..05add9e2c5 100644 --- a/cmake/templates/cvconfig.h.in +++ b/cmake/templates/cvconfig.h.in @@ -198,12 +198,6 @@ /* Lapack */ #cmakedefine HAVE_LAPACK -/* Lapack Generic */ -#cmakedefine HAVE_LAPACK_GENERIC - -/* Lapack MKL */ -#cmakedefine HAVE_LAPACK_MKL - /* FP16 */ #cmakedefine HAVE_FP16 diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index f0c15e01b0..2e4ac7066a 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -31,10 +31,17 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 -ALIASES = +ALIASES += add_toggle{1}="@htmlonly[block]
\1
@endhtmlonly" +ALIASES += add_toggle_cpp="@htmlonly[block]