diff --git a/3rdparty/libjpeg/CMakeLists.txt b/3rdparty/libjpeg/CMakeLists.txt index 4d06bbffd6..b50fc09840 100644 --- a/3rdparty/libjpeg/CMakeLists.txt +++ b/3rdparty/libjpeg/CMakeLists.txt @@ -15,13 +15,6 @@ else() ocv_list_filterout(lib_srcs jmemnobs.c) endif() -if(WINRT) - add_definitions(-DNO_GETENV) - get_directory_property( DirDefs COMPILE_DEFINITIONS ) - message(STATUS "Adding NO_GETENV to compiler definitions for WINRT:") - message(STATUS " COMPILE_DEFINITIONS = ${DirDefs}") -endif() - # ---------------------------------------------------------------------------------- # Define the library target: # ---------------------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index 718a04c38b..81a659b8e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,40 +29,19 @@ else() cmake_minimum_required(VERSION "${MIN_VER_CMAKE}" FATAL_ERROR) endif() -option(ENABLE_PIC "Generate position independent code (necessary for shared libraries)" TRUE) -set(CMAKE_POSITION_INDEPENDENT_CODE ${ENABLE_PIC}) - -set(OPENCV_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0" CACHE STRING "URI to a MathJax installation") - -# Following block can break build in case of cross-compiling -# but CMAKE_CROSSCOMPILING variable will be set only on project(OpenCV) command -# so we will try to detect cross-compiling by the presence of CMAKE_TOOLCHAIN_FILE -if(NOT DEFINED CMAKE_INSTALL_PREFIX) - if(NOT CMAKE_TOOLCHAIN_FILE) - # it _must_ go before project(OpenCV) in order to work - if(WIN32) - set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory") - else() - set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation Directory") - endif() - else() - #Android: set output folder to ${CMAKE_BINARY_DIR} - set(LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to" ) - # any cross-compiling - set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory") - endif() -endif() - +# +# Configure CMake policies +# if(POLICY CMP0026) cmake_policy(SET CMP0026 NEW) endif() if(POLICY CMP0042) - cmake_policy(SET CMP0042 NEW) + cmake_policy(SET CMP0042 NEW) # CMake 3.0+ (2.8.12): MacOS "@rpath" in target's install name endif() if(POLICY CMP0046) - cmake_policy(SET CMP0046 NEW) + cmake_policy(SET CMP0046 NEW) # warn about non-existed dependencies endif() if(POLICY CMP0051) @@ -74,17 +53,21 @@ if(POLICY CMP0054) # CMake 3.1: Only interpret if() arguments as variables or k endif() if(POLICY CMP0056) - cmake_policy(SET CMP0056 NEW) + cmake_policy(SET CMP0056 NEW) # try_compile(): link flags endif() if(POLICY CMP0067) - cmake_policy(SET CMP0067 NEW) + cmake_policy(SET CMP0067 NEW) # CMake 3.8: try_compile(): honor language standard variables (like C++11) endif() if(POLICY CMP0068) cmake_policy(SET CMP0068 NEW) # CMake 3.9+: `RPATH` settings on macOS do not affect `install_name`. endif() + +# +# Configure OpenCV CMake hooks +# include(cmake/OpenCVUtils.cmake) ocv_cmake_reset_hooks() ocv_check_environment_variables(OPENCV_CMAKE_HOOKS_DIR) @@ -97,49 +80,46 @@ endif() ocv_cmake_hook(CMAKE_INIT) -# must go before the project command +# must go before the project()/enable_language() commands ocv_update(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) if(DEFINED CMAKE_BUILD_TYPE) - set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} ) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${CMAKE_CONFIGURATION_TYPES}") +endif() + +option(ENABLE_PIC "Generate position independent code (necessary for shared libraries)" TRUE) +set(CMAKE_POSITION_INDEPENDENT_CODE ${ENABLE_PIC}) + +ocv_cmake_hook(PRE_CMAKE_BOOTSTRAP) + +# Bootstap CMake system: setup CMAKE_SYSTEM_NAME and other vars +enable_language(CXX C) + +ocv_cmake_hook(POST_CMAKE_BOOTSTRAP) + +if(NOT OPENCV_SKIP_CMAKE_SYSTEM_FILE) + include("cmake/platforms/OpenCV-${CMAKE_SYSTEM_NAME}.cmake" OPTIONAL RESULT_VARIABLE "OPENCV_CMAKE_SYSTEM_FILE") + if(NOT OPENCV_CMAKE_SYSTEM_FILE) + message(STATUS "OpenCV: system-specific configuration file is not found: '${CMAKE_SYSTEM_NAME}'") + endif() +endif() + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) # https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html + if(NOT CMAKE_TOOLCHAIN_FILE) + if(WIN32) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory" FORCE) + else() + set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation Directory" FORCE) + endif() + else() + # any cross-compiling + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory" FORCE) + endif() endif() enable_testing() project(OpenCV CXX C) -if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) - set(WINRT TRUE) -endif() - -if(WINRT OR WINCE) - add_definitions(-DNO_GETENV) -endif() - -if(WINRT) - add_definitions(-DWINRT) - - # Making definitions available to other configurations and - # to filter dependency restrictions at compile time. - if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone) - set(WINRT_PHONE TRUE) - add_definitions(-DWINRT_PHONE) - elseif(CMAKE_SYSTEM_NAME MATCHES WindowsStore) - set(WINRT_STORE TRUE) - add_definitions(-DWINRT_STORE) - endif() - - if(CMAKE_SYSTEM_VERSION MATCHES 10) - set(WINRT_10 TRUE) - add_definitions(-DWINRT_10) - elseif(CMAKE_SYSTEM_VERSION MATCHES 8.1) - set(WINRT_8_1 TRUE) - add_definitions(-DWINRT_8_1) - elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0) - set(WINRT_8_0 TRUE) - add_definitions(-DWINRT_8_0) - endif() -endif() - if(MSVC) set(CMAKE_USE_RELATIVE_PATHS ON CACHE INTERNAL "" FORCE) endif() @@ -501,6 +481,7 @@ if(ENABLE_IMPL_COLLECTION) add_definitions(-DCV_COLLECT_IMPL_DATA) endif() +set(OPENCV_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0" CACHE STRING "URI to a MathJax installation") # ---------------------------------------------------------------------------- # Get actual OpenCV version number from sources @@ -647,12 +628,12 @@ endif() if(WIN32) # Postfix of DLLs: - set(OPENCV_DLLVERSION "${OPENCV_VERSION_MAJOR}${OPENCV_VERSION_MINOR}${OPENCV_VERSION_PATCH}") - set(OPENCV_DEBUG_POSTFIX d) + ocv_update(OPENCV_DLLVERSION "${OPENCV_VERSION_MAJOR}${OPENCV_VERSION_MINOR}${OPENCV_VERSION_PATCH}") + ocv_update(OPENCV_DEBUG_POSTFIX d) else() # Postfix of so's: - set(OPENCV_DLLVERSION "") - set(OPENCV_DEBUG_POSTFIX "") + ocv_update(OPENCV_DLLVERSION "") + ocv_update(OPENCV_DEBUG_POSTFIX "") endif() if(DEFINED CMAKE_DEBUG_POSTFIX) diff --git a/cmake/OpenCVCRTLinkage.cmake b/cmake/OpenCVCRTLinkage.cmake index 4916800211..b87dfd3a7c 100644 --- a/cmake/OpenCVCRTLinkage.cmake +++ b/cmake/OpenCVCRTLinkage.cmake @@ -4,16 +4,6 @@ if(NOT MSVC) message(FATAL_ERROR "CRT options are available only for MSVC") endif() -if (WINRT) - if (CMAKE_SYSTEM_VERSION MATCHES 10) - add_definitions(/DWINVER=_WIN32_WINNT_WIN10 /DNTDDI_VERSION=NTDDI_WIN10 /D_WIN32_WINNT=_WIN32_WINNT_WIN10) - elseif(CMAKE_SYSTEM_VERSION MATCHES 8.1) - add_definitions(/DWINVER=_WIN32_WINNT_WINBLUE /DNTDDI_VERSION=NTDDI_WINBLUE /D_WIN32_WINNT=_WIN32_WINNT_WINBLUE) - else() - add_definitions(/DWINVER=_WIN32_WINNT_WIN8 /DNTDDI_VERSION=NTDDI_WIN8 /D_WIN32_WINNT=_WIN32_WINNT_WIN8) - endif() -endif() - # Removing LNK4075 warnings for debug WinRT builds # "LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification" # "LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification" diff --git a/cmake/OpenCVCompilerOptions.cmake b/cmake/OpenCVCompilerOptions.cmake index 2202cdff3b..d2738b0b7f 100644 --- a/cmake/OpenCVCompilerOptions.cmake +++ b/cmake/OpenCVCompilerOptions.cmake @@ -285,11 +285,6 @@ if(MSVC) endif() endif() -# Adding additional using directory for WindowsPhone 8.0 to get Windows.winmd properly -if(WINRT_PHONE AND WINRT_8_0) - set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} /AI\$(WindowsSDK_MetadataPath)") -endif() - include(cmake/OpenCVCompilerOptimizations.cmake) if(COMMAND ocv_compiler_optimization_options) ocv_compiler_optimization_options() diff --git a/cmake/OpenCVMinDepVersions.cmake b/cmake/OpenCVMinDepVersions.cmake index f4afdf7b53..a57f2a4984 100644 --- a/cmake/OpenCVMinDepVersions.cmake +++ b/cmake/OpenCVMinDepVersions.cmake @@ -1,4 +1,6 @@ -set(MIN_VER_CMAKE 3.5.1) +if(NOT DEFINED MIN_VER_CMAKE) + set(MIN_VER_CMAKE 3.5.1) +endif() set(MIN_VER_CUDA 6.5) set(MIN_VER_CUDNN 6) set(MIN_VER_PYTHON2 2.7) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index b6109615b2..2e3180afbb 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -1206,10 +1206,6 @@ endfunction() function(ocv_add_accuracy_tests) ocv_debug_message("ocv_add_accuracy_tests(" ${ARGN} ")") - if(WINRT) - set(OPENCV_DEBUG_POSTFIX "") - endif() - set(test_path "${CMAKE_CURRENT_LIST_DIR}/test") if(BUILD_TESTS AND EXISTS "${test_path}") __ocv_parse_test_sources(TEST ${ARGN}) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 092deed811..c1058c536e 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -16,7 +16,8 @@ function(ocv_cmake_dump_vars) string(TOLOWER "${__variableName}" __variableName_lower) if((__variableName MATCHES "${regex}" OR __variableName_lower MATCHES "${regex_lower}") AND NOT __variableName_lower MATCHES "^__") - set(__VARS "${__VARS}${__variableName}=${${__variableName}}\n") + get_property(__value VARIABLE PROPERTY "${__variableName}") + set(__VARS "${__VARS}${__variableName}=${__value}\n") endif() endforeach() if(DUMP_TOFILE) diff --git a/cmake/platforms/OpenCV-Android.cmake b/cmake/platforms/OpenCV-Android.cmake new file mode 100644 index 0000000000..1bb8bf6d7f --- /dev/null +++ b/cmake/platforms/OpenCV-Android.cmake @@ -0,0 +1 @@ +# empty diff --git a/cmake/platforms/OpenCV-Darwin.cmake b/cmake/platforms/OpenCV-Darwin.cmake new file mode 100644 index 0000000000..1bb8bf6d7f --- /dev/null +++ b/cmake/platforms/OpenCV-Darwin.cmake @@ -0,0 +1 @@ +# empty diff --git a/cmake/platforms/OpenCV-Linux.cmake b/cmake/platforms/OpenCV-Linux.cmake new file mode 100644 index 0000000000..1bb8bf6d7f --- /dev/null +++ b/cmake/platforms/OpenCV-Linux.cmake @@ -0,0 +1 @@ +# empty diff --git a/cmake/platforms/OpenCV-WinRT.cmake b/cmake/platforms/OpenCV-WinRT.cmake new file mode 100644 index 0000000000..0a5e9f3c7d --- /dev/null +++ b/cmake/platforms/OpenCV-WinRT.cmake @@ -0,0 +1,31 @@ +set(WINRT TRUE) + +add_definitions(-DWINRT -DNO_GETENV) + +# Making definitions available to other configurations and +# to filter dependency restrictions at compile time. +if(WINDOWS_PHONE) + set(WINRT_PHONE TRUE) + add_definitions(-DWINRT_PHONE) +elseif(WINDOWS_STORE) + set(WINRT_STORE TRUE) + add_definitions(-DWINRT_STORE) +endif() + +if(CMAKE_SYSTEM_VERSION MATCHES 10) + set(WINRT_10 TRUE) + add_definitions(-DWINRT_10) + add_definitions(/DWINVER=_WIN32_WINNT_WIN10 /DNTDDI_VERSION=NTDDI_WIN10 /D_WIN32_WINNT=_WIN32_WINNT_WIN10) +elseif(CMAKE_SYSTEM_VERSION MATCHES 8.1) + set(WINRT_8_1 TRUE) + add_definitions(-DWINRT_8_1) + add_definitions(/DWINVER=_WIN32_WINNT_WINBLUE /DNTDDI_VERSION=NTDDI_WINBLUE /D_WIN32_WINNT=_WIN32_WINNT_WINBLUE) +elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0) + set(WINRT_8_0 TRUE) + add_definitions(-DWINRT_8_0) + add_definitions(/DWINVER=_WIN32_WINNT_WIN8 /DNTDDI_VERSION=NTDDI_WIN8 /D_WIN32_WINNT=_WIN32_WINNT_WIN8) +else() + message(STATUS "Unsupported WINRT version (consider upgrading OpenCV): ${CMAKE_SYSTEM_VERSION}") +endif() + +set(OPENCV_DEBUG_POSTFIX "") diff --git a/cmake/platforms/OpenCV-Windows.cmake b/cmake/platforms/OpenCV-Windows.cmake new file mode 100644 index 0000000000..1bb8bf6d7f --- /dev/null +++ b/cmake/platforms/OpenCV-Windows.cmake @@ -0,0 +1 @@ +# empty diff --git a/cmake/platforms/OpenCV-WindowsCE.cmake b/cmake/platforms/OpenCV-WindowsCE.cmake new file mode 100644 index 0000000000..f5ac590754 --- /dev/null +++ b/cmake/platforms/OpenCV-WindowsCE.cmake @@ -0,0 +1 @@ +add_definitions(-DNO_GETENV) diff --git a/cmake/platforms/OpenCV-WindowsPhone.cmake b/cmake/platforms/OpenCV-WindowsPhone.cmake new file mode 100644 index 0000000000..8a496d3a7b --- /dev/null +++ b/cmake/platforms/OpenCV-WindowsPhone.cmake @@ -0,0 +1,6 @@ +include("${CMAKE_CURRENT_LIST_DIR}/OpenCV_WinRT.cmake") + +# Adding additional using directory for WindowsPhone 8.0 to get Windows.winmd properly +if(WINRT_8_0) + set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} /AI\$(WindowsSDK_MetadataPath)") +endif() diff --git a/cmake/platforms/OpenCV-WindowsStore.cmake b/cmake/platforms/OpenCV-WindowsStore.cmake new file mode 100644 index 0000000000..8b5dfa5556 --- /dev/null +++ b/cmake/platforms/OpenCV-WindowsStore.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/OpenCV_WinRT.cmake") diff --git a/cmake/platforms/OpenCV-iOS.cmake b/cmake/platforms/OpenCV-iOS.cmake new file mode 100644 index 0000000000..1bb8bf6d7f --- /dev/null +++ b/cmake/platforms/OpenCV-iOS.cmake @@ -0,0 +1 @@ +# empty diff --git a/modules/calib3d/perf/perf_undistort.cpp b/modules/calib3d/perf/perf_undistort.cpp index 6381a15c92..5372aaea92 100644 --- a/modules/calib3d/perf/perf_undistort.cpp +++ b/modules/calib3d/perf/perf_undistort.cpp @@ -16,4 +16,4 @@ PERF_TEST(Undistort, InitUndistortMap) SANITY_CHECK_NOTHING(); } -} +} // namespace diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 246f23b0b8..3e510fad4e 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -23,7 +23,7 @@ ocv_add_module(core set(extra_libs "") -if(WINRT AND CMAKE_SYSTEM_NAME MATCHES WindowsStore AND CMAKE_SYSTEM_VERSION MATCHES "8.0") +if(WINRT AND WINDOWS_STORE AND CMAKE_SYSTEM_VERSION MATCHES "8.0") list(APPEND extra_libs ole32.lib) endif() diff --git a/modules/core/include/opencv2/core/fast_math.hpp b/modules/core/include/opencv2/core/fast_math.hpp index 065879b5f1..13b70e1061 100644 --- a/modules/core/include/opencv2/core/fast_math.hpp +++ b/modules/core/include/opencv2/core/fast_math.hpp @@ -70,7 +70,14 @@ # endif #endif -#if defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__ || defined __ARM_NEON__) && !defined __SOFTFP__ && !defined(__CUDACC__) +#if defined __PPC64__ && defined __GNUC__ && defined _ARCH_PWR8 && !defined (__CUDACC__) +# include +#endif + +#if defined(CV_INLINE_ROUND_FLT) + // user-specified version + // CV_INLINE_ROUND_DBL should be defined too +#elif defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__ || defined __ARM_NEON__) && !defined __SOFTFP__ && !defined(__CUDACC__) // 1. general scheme #define ARM_ROUND(_value, _asm_string) \ int res; \ @@ -80,12 +87,55 @@ return res // 2. version for double #ifdef __clang__ - #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]") + #define CV_INLINE_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]") #else - #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]") + #define CV_INLINE_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]") #endif // 3. version for float - #define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]") + #define CV_INLINE_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]") +#elif defined __PPC64__ && defined __GNUC__ && defined _ARCH_PWR8 && !defined (__CUDACC__) + // P8 and newer machines can convert fp32/64 to int quickly. + #define CV_INLINE_ROUND_DBL(value) \ + int out; \ + double temp; \ + __asm__( "fctiw %[temp],%[in]\n\tmffprwz %[out],%[temp]\n\t" : [out] "=r" (out), [temp] "=d" (temp) : [in] "d" ((double)(value)) : ); \ + return out; + + // FP32 also works with FP64 routine above + #define CV_INLINE_ROUND_FLT(value) CV_INLINE_ROUND_DBL(value) + + #ifdef _ARCH_PWR9 + #define CV_INLINE_ISINF_DBL(value) return scalar_test_data_class(value, 0x30); + #define CV_INLINE_ISNAN_DBL(value) return scalar_test_data_class(value, 0x40); + #define CV_INLINE_ISINF_FLT(value) CV_INLINE_ISINF_DBL(value) + #define CV_INLINE_ISNAN_FLT(value) CV_INLINE_ISNAN_DBL(value) + #endif +#elif defined CV_ICC || defined __GNUC__ + #define CV_INLINE_ROUND_DBL(value) return (int)(lrint(value)); + #define CV_INLINE_ROUND_FLT(value) return (int)(lrintf(value)); +#endif + +#if defined __PPC64__ && !defined OPENCV_USE_FASTMATH_GCC_BUILTINS + /* Let GCC inline C math functions when available. Dedicated hardware is available to + round and covert FP values. */ + #define OPENCV_USE_FASTMATH_GCC_BUILTINS +#endif + +/* Enable GCC builtin math functions if possible, desired, and available. + Note, not all math functions inline equally. E.g lrint will not inline + without the -fno-math-errno option. */ +#if defined OPENCV_USE_FASTMATH_GCC_BUILTINS && defined __GNUC__ && !defined __clang__ && !defined (__CUDACC__) + #define _OPENCV_FASTMATH_ENABLE_GCC_MATH_BUILTINS +#endif + +/* Allow overrides for some functions which may benefit from tuning. Likewise, + note that isinf is not used as the return value is signed. */ +#if defined _OPENCV_FASTMATH_ENABLE_GCC_MATH_BUILTINS && !defined CV_INLINE_ISNAN_DBL + #define CV_INLINE_ISNAN_DBL(value) return __builtin_isnan(value); +#endif + +#if defined _OPENCV_FASTMATH_ENABLE_GCC_MATH_BUILTINS && !defined CV_INLINE_ISNAN_FLT + #define CV_INLINE_ISNAN_FLT(value) return __builtin_isnanf(value); #endif /** @brief Rounds floating-point number to the nearest integer @@ -108,12 +158,10 @@ cvRound( double value ) fistp t; } return t; +#elif defined CV_INLINE_ROUND_DBL + CV_INLINE_ROUND_DBL(value); #elif defined CV_ICC || defined __GNUC__ -# if defined ARM_ROUND_DBL - ARM_ROUND_DBL(value); -# else return (int)lrint(value); -# endif #else /* it's ok if round does not comply with IEEE754 standard; the tests should allow +/-1 difference when the tested functions use round */ @@ -131,8 +179,12 @@ cvRound( double value ) */ CV_INLINE int cvFloor( double value ) { +#if defined _OPENCV_FASTMATH_ENABLE_GCC_MATH_BUILTINS + return __builtin_floor(value); +#else int i = (int)value; return i - (i > value); +#endif } /** @brief Rounds floating-point number to the nearest integer not smaller than the original. @@ -144,8 +196,12 @@ CV_INLINE int cvFloor( double value ) */ CV_INLINE int cvCeil( double value ) { +#if defined _OPENCV_FASTMATH_ENABLE_GCC_MATH_BUILTINS + return __builtin_ceil(value); +#else int i = (int)value; return i + (i < value); +#endif } /** @brief Determines if the argument is Not A Number. @@ -156,10 +212,14 @@ CV_INLINE int cvCeil( double value ) otherwise. */ CV_INLINE int cvIsNaN( double value ) { +#if defined CV_INLINE_ISNAN_DBL + CV_INLINE_ISNAN_DBL(value); +#else Cv64suf ieee754; ieee754.f = value; return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + ((unsigned)ieee754.u != 0) > 0x7ff00000; +#endif } /** @brief Determines if the argument is Infinity. @@ -170,10 +230,14 @@ CV_INLINE int cvIsNaN( double value ) and 0 otherwise. */ CV_INLINE int cvIsInf( double value ) { +#if defined CV_INLINE_ISINF_DBL + CV_INLINE_ISINF_DBL(value); +#else Cv64suf ieee754; ieee754.f = value; return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && (unsigned)ieee754.u == 0; +#endif } #ifdef __cplusplus @@ -193,12 +257,10 @@ CV_INLINE int cvRound(float value) fistp t; } return t; +#elif defined CV_INLINE_ROUND_FLT + CV_INLINE_ROUND_FLT(value); #elif defined CV_ICC || defined __GNUC__ -# if defined ARM_ROUND_FLT - ARM_ROUND_FLT(value); -# else return (int)lrintf(value); -# endif #else /* it's ok if round does not comply with IEEE754 standard; the tests should allow +/-1 difference when the tested functions use round */ @@ -215,8 +277,12 @@ CV_INLINE int cvRound( int value ) /** @overload */ CV_INLINE int cvFloor( float value ) { +#if defined _OPENCV_FASTMATH_ENABLE_GCC_MATH_BUILTINS + return __builtin_floorf(value); +#else int i = (int)value; return i - (i > value); +#endif } /** @overload */ @@ -228,8 +294,12 @@ CV_INLINE int cvFloor( int value ) /** @overload */ CV_INLINE int cvCeil( float value ) { +#if defined _OPENCV_FASTMATH_ENABLE_GCC_MATH_BUILTINS + return __builtin_ceilf(value); +#else int i = (int)value; return i + (i < value); +#endif } /** @overload */ @@ -241,17 +311,25 @@ CV_INLINE int cvCeil( int value ) /** @overload */ CV_INLINE int cvIsNaN( float value ) { +#if defined CV_INLINE_ISNAN_FLT + CV_INLINE_ISNAN_FLT(value); +#else Cv32suf ieee754; ieee754.f = value; return (ieee754.u & 0x7fffffff) > 0x7f800000; +#endif } /** @overload */ CV_INLINE int cvIsInf( float value ) { +#if defined CV_INLINE_ISINF_FLT + CV_INLINE_ISINF_FLT(value); +#else Cv32suf ieee754; ieee754.f = value; return (ieee754.u & 0x7fffffff) == 0x7f800000; +#endif } #endif // __cplusplus diff --git a/modules/core/perf/perf_cvround.cpp b/modules/core/perf/perf_cvround.cpp index 933792dcaa..0e3ceb0597 100644 --- a/modules/core/perf/perf_cvround.cpp +++ b/modules/core/perf/perf_cvround.cpp @@ -4,42 +4,52 @@ namespace opencv_test { using namespace perf; -template -static void CvRoundMat(const cv::Mat & src, cv::Mat & dst) -{ - for (int y = 0; y < dst.rows; ++y) - { - const T * sptr = src.ptr(y); - int * dptr = dst.ptr(y); - - for (int x = 0; x < dst.cols; ++x) - dptr[x] = cvRound(sptr[x]); - } -} - -PERF_TEST_P(Size_MatType, CvRound_Float, - testing::Combine(testing::Values(TYPICAL_MAT_SIZES), - testing::Values(CV_32FC1, CV_64FC1))) -{ - Size size = get<0>(GetParam()); - int type = get<1>(GetParam()), depth = CV_MAT_DEPTH(type); - - cv::Mat src(size, type), dst(size, CV_32SC1); - - declare.in(src, WARMUP_RNG).out(dst); - - if (depth == CV_32F) - { - TEST_CYCLE() - CvRoundMat(src, dst); - } - else if (depth == CV_64F) - { - TEST_CYCLE() - CvRoundMat(src, dst); +#define DECL_ROUND_TEST(NAME, OP, EXTRA) \ + template \ + static void OP ## Mat(const cv::Mat & src, cv::Mat & dst) \ + { \ + for (int y = 0; y < dst.rows; ++y) \ + { \ + const T * sptr = src.ptr(y); \ + int * dptr = dst.ptr(y); \ + \ + for (int x = 0; x < dst.cols; ++x) \ + dptr[x] = OP(sptr[x]) EXTRA; \ + } \ + } \ + \ + PERF_TEST_P(Size_MatType, CvRound_Float ## NAME, \ + testing::Combine(testing::Values(TYPICAL_MAT_SIZES), \ + testing::Values(CV_32FC1, CV_64FC1))) \ + { \ + Size size = get<0>(GetParam()); \ + int type = get<1>(GetParam()), depth = CV_MAT_DEPTH(type); \ + \ + cv::Mat src(size, type), dst(size, CV_32SC1); \ + \ + declare.in(src, WARMUP_RNG).out(dst); \ + \ + if (depth == CV_32F) \ + { \ + TEST_CYCLE() \ + OP ## Mat(src, dst); \ + } \ + else if (depth == CV_64F) \ + { \ + TEST_CYCLE() \ + OP ## Mat(src, dst); \ + } \ + \ + SANITY_CHECK_NOTHING(); \ } - SANITY_CHECK_NOTHING(); -} +DECL_ROUND_TEST(,cvRound,) +DECL_ROUND_TEST(_Ceil,cvCeil,) +DECL_ROUND_TEST(_Floor,cvFloor,) + +/* For FP classification tests, try to test them in way which uses + branching logic and avoids extra FP logic. */ +DECL_ROUND_TEST(_NaN,cvIsNaN, ? 1 : 2) +DECL_ROUND_TEST(_Inf,cvIsInf, ? 1 : 2) } // namespace diff --git a/modules/core/test/test_math.cpp b/modules/core/test/test_math.cpp index d65b3fa39e..8b13a391cb 100644 --- a/modules/core/test/test_math.cpp +++ b/modules/core/test/test_math.cpp @@ -3923,5 +3923,59 @@ TEST(Core_SoftFloat, CvRound) } } +template +static void checkRounding(T in, int outCeil, int outFloor) +{ + EXPECT_EQ(outCeil,cvCeil(in)); + EXPECT_EQ(outFloor,cvFloor(in)); + + /* cvRound is not expected to be IEEE compliant. The implementation + should round to one of the above. */ + EXPECT_TRUE((cvRound(in) == outCeil) || (cvRound(in) == outFloor)); +} + +TEST(Core_FastMath, InlineRoundingOps) +{ + struct + { + double in; + int outCeil; + int outFloor; + } values[] = + { + // Values are chosen to convert to binary float 32/64 exactly + { 1.0, 1, 1 }, + { 1.5, 2, 1 }, + { -1.5, -1, -2} + }; + + for (int i = 0, maxi = sizeof(values) / sizeof(values[0]); i < maxi; i++) + { + checkRounding(values[i].in, values[i].outCeil, values[i].outFloor); + checkRounding((float)values[i].in, values[i].outCeil, values[i].outFloor); + } +} + +TEST(Core_FastMath, InlineNaN) +{ + EXPECT_EQ( cvIsNaN((float) NAN), 1); + EXPECT_EQ( cvIsNaN((float) -NAN), 1); + EXPECT_EQ( cvIsNaN(0.0f), 0); + EXPECT_EQ( cvIsNaN((double) NAN), 1); + EXPECT_EQ( cvIsNaN((double) -NAN), 1); + EXPECT_EQ( cvIsNaN(0.0), 0); +} + +TEST(Core_FastMath, InlineIsInf) +{ + // Assume HUGE_VAL is infinity. Strictly speaking, may not always be true. + EXPECT_EQ( cvIsInf((float) HUGE_VAL), 1); + EXPECT_EQ( cvIsInf((float) -HUGE_VAL), 1); + EXPECT_EQ( cvIsInf(0.0f), 0); + EXPECT_EQ( cvIsInf((double) HUGE_VAL), 1); + EXPECT_EQ( cvIsInf((double) -HUGE_VAL), 1); + EXPECT_EQ( cvIsInf(0.0), 0); +} + }} // namespace /* End of file. */ diff --git a/platforms/android/android.toolchain.cmake b/platforms/android/android.toolchain.cmake index b37dea01ae..50b342c7a6 100644 --- a/platforms/android/android.toolchain.cmake +++ b/platforms/android/android.toolchain.cmake @@ -1554,6 +1554,9 @@ if( ANDROID_EXPLICIT_CRT_LINK ) endif() # setup output directories +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 1) +endif() set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) if( DEFINED LIBRARY_OUTPUT_PATH_ROOT