diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fadce559d..9cb3be0c33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,19 @@ if(UNIX AND NOT ANDROID) endif() endif() +# Add these standard paths to the search paths for FIND_PATH +# to find include files from these locations first +if(MINGW) + if(EXISTS /mingw) + list(APPEND CMAKE_INCLUDE_PATH /mingw) + endif() + if(EXISTS /mingw32) + list(APPEND CMAKE_INCLUDE_PATH /mingw32) + endif() + if(EXISTS /mingw64) + list(APPEND CMAKE_INCLUDE_PATH /mingw64) + endif() +endif() # ---------------------------------------------------------------------------- # OpenCV cmake options @@ -110,7 +123,7 @@ endif() # Optional 3rd party components # =================================================== -OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (UNIX AND NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS) OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE ) OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS) ) diff --git a/android/android.toolchain.cmake b/android/android.toolchain.cmake index df365fc2c0..9db174a138 100644 --- a/android/android.toolchain.cmake +++ b/android/android.toolchain.cmake @@ -1,6 +1,7 @@ message(STATUS "Android toolchain was moved to platfroms/android!") message(STATUS "This file is depricated and will be removed!") +# Copyright (c) 2010-2011, Ethan Rublee # Copyright (c) 2011-2013, Andrey Kamaev # All rights reserved. # @@ -291,6 +292,9 @@ message(STATUS "This file is depricated and will be removed!") # - March 2013 # [+] updated for NDK r8e (x86 version) # [+] support x86_64 version of NDK +# - April 2013 +# [+] support non-release NDK layouts (from Linaro git and Android git) +# [~] automatically detect if explicit link to crtbegin_*.o is needed # ------------------------------------------------------------------------------ cmake_minimum_required( VERSION 2.6.3 ) @@ -518,24 +522,19 @@ if( NOT ANDROID_NDK ) endif( ANDROID_NDK ) endif( NOT ANDROID_STANDALONE_TOOLCHAIN ) endif( NOT ANDROID_NDK ) + # remember found paths if( ANDROID_NDK ) get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE ) - # try to detect change - if( CMAKE_AR ) - string( LENGTH "${ANDROID_NDK}" __length ) - string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath ) - if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK ) - message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first. - " ) - endif() - unset( __androidNdkPreviousPath ) - unset( __length ) - endif() set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE ) set( BUILD_WITH_ANDROID_NDK True ) - file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? ) - string( REGEX MATCH r[0-9]+[a-z]? ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" ) + if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" ) + file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? ) + string( REGEX MATCH r[0-9]+[a-z]? ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" ) + else() + set( ANDROID_NDK_RELEASE "r1x" ) + set( ANDROID_NDK_RELEASE_FULL "unreleased" ) + endif() elseif( ANDROID_STANDALONE_TOOLCHAIN ) get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE ) # try to detect change @@ -562,6 +561,51 @@ else() sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" ) endif() +# android NDK layout +if( BUILD_WITH_ANDROID_NDK ) + if( NOT DEFINED ANDROID_NDK_LAYOUT ) + # try to automatically detect the layout + if( EXISTS "${ANDROID_NDK}/RELEASE.TXT") + set( ANDROID_NDK_LAYOUT "RELEASE" ) + elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" ) + set( ANDROID_NDK_LAYOUT "LINARO" ) + elseif( EXISTS "${ANDROID_NDK}/../../gcc/" ) + set( ANDROID_NDK_LAYOUT "ANDROID" ) + endif() + endif() + set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" ) + mark_as_advanced( ANDROID_NDK_LAYOUT ) + if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" ) + set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment + set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" ) + elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" ) + set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment + set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" ) + else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE" + set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" ) + endif() + get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE ) + + # try to detect change of NDK + if( CMAKE_AR ) + string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length ) + string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath ) + if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH ) + message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first. + " ) + endif() + unset( __androidNdkPreviousPath ) + unset( __length ) + endif() +endif() + + # get all the details about standalone toolchain if( BUILD_WITH_STANDALONE_TOOLCHAIN ) __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" ) @@ -589,17 +633,23 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN ) endif() endif() -macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __host_system_name ) +macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath ) foreach( __toolchain ${${__availableToolchainsLst}} ) - if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/" ) + if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" ) string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" ) else() set( __gcc_toolchain "${__toolchain}" ) endif() - __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__gcc_toolchain}/prebuilt/${__host_system_name}" ) + __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" ) if( __machine ) - string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__gcc_toolchain}" ) - string( REGEX MATCH "^[^-]+" __arch "${__gcc_toolchain}" ) + string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" ) + if( __machine MATCHES i686 ) + set( __arch "x86" ) + elseif( __machine MATCHES arm ) + set( __arch "arm" ) + elseif( __machine MATCHES mipsel ) + set( __arch "mipsel" ) + endif() list( APPEND __availableToolchainMachines "${__machine}" ) list( APPEND __availableToolchainArchs "${__arch}" ) list( APPEND __availableToolchainCompilerVersions "${__version}" ) @@ -617,29 +667,29 @@ if( BUILD_WITH_ANDROID_NDK ) set( __availableToolchainMachines "" ) set( __availableToolchainArchs "" ) set( __availableToolchainCompilerVersions "" ) - if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/" ) + if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" ) # do not go through all toolchains if we know the name set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME} ) - if( NOT __availableToolchains AND NOT ANDROID_NDK_HOST_SYSTEM_NAME STREQUAL ANDROID_NDK_HOST_SYSTEM_NAME2 ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) + if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" ) if( __availableToolchains ) - set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} ) endif() endif() endif() if( NOT __availableToolchains ) - file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" ) + file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" ) if( __availableToolchains ) list(SORT __availableToolchainsLst) # we need clang to go after gcc endif() __LIST_FILTER( __availableToolchainsLst "^[.]" ) __LIST_FILTER( __availableToolchainsLst "llvm" ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME} ) - if( NOT __availableToolchains AND NOT ANDROID_NDK_HOST_SYSTEM_NAME STREQUAL ANDROID_NDK_HOST_SYSTEM_NAME2 ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) + if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" ) if( __availableToolchains ) - set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} ) endif() endif() endif() @@ -770,6 +820,7 @@ else() list( GET __availableToolchainArchs ${__idx} __toolchainArch ) if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME ) list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion ) + string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}") if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion ) set( __toolchainMaxVersion "${__toolchainVersion}" ) set( __toolchainIdx ${__idx} ) @@ -973,11 +1024,11 @@ if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" ) elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" ) string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}") string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-4.6" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) - if( NOT EXISTS "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}/bin/clang${TOOL_OS_SUFFIX}" ) + if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" ) message( FATAL_ERROR "Could not find the Clang compiler driver" ) endif() set( ANDROID_COMPILER_IS_CLANG 1 ) - set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) else() set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) unset( ANDROID_COMPILER_IS_CLANG CACHE ) @@ -991,7 +1042,7 @@ endif() # setup paths and STL for NDK if( BUILD_WITH_ANDROID_NDK ) - set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" ) if( ANDROID_STL STREQUAL "none" ) @@ -1050,11 +1101,11 @@ if( BUILD_WITH_ANDROID_NDK ) endif() # find libsupc++.a - rtti & exceptions if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" ) - if( ANDROID_NDK_RELEASE STRGREATER "r8" ) # r8b - set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) - elseif( NOT ANDROID_NDK_RELEASE STRLESS "r7" AND ANDROID_NDK_RELEASE STRLESS "r8b") - set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) - else( ANDROID_NDK_RELEASE STRLESS "r7" ) + set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer + if( NOT EXISTS "${__libsupcxx}" ) + set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8 + endif() + if( NOT EXISTS "${__libsupcxx}" ) # before r7 if( ARMEABI_V7A ) if( ANDROID_FORCE_ARM_BUILD ) set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" ) @@ -1104,7 +1155,7 @@ unset( _ndk_ccache ) # setup the cross-compiler if( NOT CMAKE_C_COMPILER ) - if( NDK_CCACHE ) + if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" ) set( CMAKE_C_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" ) set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" ) if( ANDROID_COMPILER_IS_CLANG ) @@ -1176,11 +1227,25 @@ set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm ) remove_definitions( -DANDROID ) add_definitions( -DANDROID ) -if(ANDROID_SYSROOT MATCHES "[ ;\"]") - set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) +if( ANDROID_SYSROOT MATCHES "[ ;\"]" ) + if( CMAKE_HOST_WIN32 ) + # try to convert path to 8.3 form + file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" ) + execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}" + OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE __result ERROR_QUIET ) + if( __result EQUAL 0 ) + file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT ) + set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) + else() + set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) + endif() + else() + set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" ) + endif() if( NOT _CMAKE_IN_TRY_COMPILE ) - # quotes will break try_compile and compiler identification - message(WARNING "Your Android system root has non-alphanumeric symbols. It can break compiler features detection and the whole build.") + # quotes can break try_compile and compiler identification + message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n") endif() else() set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) @@ -1251,22 +1316,18 @@ elseif( ARMEABI ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" ) endif() +if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") ) + set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) + set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) + set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) +else() + set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) + set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) + set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) +endif() + # STL if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" ) - if( ANDROID_STL MATCHES "gnustl" ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) - set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) - set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) - else() - set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) - set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) - set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) - endif() - if ( X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" ) - # workaround "undefined reference to `__dso_handle'" problem - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) - endif() if( EXISTS "${__libstl}" ) set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" ) set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" ) @@ -1285,9 +1346,12 @@ if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" ) set( CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" ) endif() if( ANDROID_STL MATCHES "gnustl" ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} -lm" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} -lm" ) - set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lm" ) + if( NOT EXISTS "${ANDROID_LIBM_PATH}" ) + set( ANDROID_LIBM_PATH -lm ) + endif() + set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" ) + set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" ) + set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" ) endif() endif() @@ -1323,7 +1387,14 @@ if( ARMEABI_V7A ) endif() if( ANDROID_NO_UNDEFINED ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" ) + if( MIPS ) + # there is some sysroot-related problem in mips linker... + if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" ) + set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" ) + endif() + else() + set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" ) + endif() endif() if( ANDROID_SO_UNDEFINED ) @@ -1403,9 +1474,9 @@ set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FL set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" ) - set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" ) - set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" ) - set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) + set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" ) + set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" ) + set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) endif() # configure rtti @@ -1432,6 +1503,43 @@ endif() include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} ) link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ) +# detect if need link crtbegin_so.o explicitly +if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK ) + set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" ) + string( REPLACE "" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" ) + string( REPLACE "" "-shared" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" ) + string( REPLACE "" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + separate_arguments( __cmd ) + foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN ) + if( ${__var} ) + set( __tmp "${${__var}}" ) + separate_arguments( __tmp ) + string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}") + endif() + endforeach() + string( REPLACE "'" "" __cmd "${__cmd}" ) + string( REPLACE "\"" "" __cmd "${__cmd}" ) + execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET ) + if( __cmd_result EQUAL 0 ) + set( ANDROID_EXPLICIT_CRT_LINK ON ) + else() + set( ANDROID_EXPLICIT_CRT_LINK OFF ) + endif() +endif() + +if( ANDROID_EXPLICIT_CRT_LINK ) + set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) + set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) +endif() + # setup output directories set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" ) set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) @@ -1523,6 +1631,7 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) foreach( __var NDK_CCACHE LIBRARY_OUTPUT_PATH_ROOT ANDROID_FORBID_SYGWIN ANDROID_SET_OBSOLETE_VARIABLES ANDROID_NDK_HOST_X64 ANDROID_NDK + ANDROID_NDK_LAYOUT ANDROID_STANDALONE_TOOLCHAIN ANDROID_TOOLCHAIN_NAME ANDROID_ABI @@ -1536,6 +1645,8 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) ANDROID_GOLD_LINKER ANDROID_NOEXECSTACK ANDROID_RELRO + ANDROID_LIBM_PATH + ANDROID_EXPLICIT_CRT_LINK ) if( DEFINED ${__var} ) if( "${__var}" MATCHES " ") @@ -1579,6 +1690,7 @@ endif() # ANDROID_STANDALONE_TOOLCHAIN # ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain # ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems) +# ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID) # LIBRARY_OUTPUT_PATH_ROOT : # NDK_CCACHE : # Obsolete: @@ -1624,6 +1736,7 @@ endif() # ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime # ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used # ANDROID_CLANG_VERSION : version of clang compiler if clang is used +# ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product//obj/lib/libm.so) to workaround unresolved `sincos` # # Defaults: # ANDROID_DEFAULT_NDK_API_LEVEL diff --git a/cmake/OpenCVDetectOpenCL.cmake b/cmake/OpenCVDetectOpenCL.cmake index 014066bc7e..a1e8bbac70 100644 --- a/cmake/OpenCVDetectOpenCL.cmake +++ b/cmake/OpenCVDetectOpenCL.cmake @@ -44,12 +44,18 @@ if(OPENCL_FOUND) set(OPENCL_INCLUDE_DIRS ${OPENCL_INCLUDE_DIR}) set(OPENCL_LIBRARIES ${OPENCL_LIBRARY}) - if (X86_64) + if(WIN64) set(CLAMD_POSSIBLE_LIB_SUFFIXES lib64/import) - elseif (X86) + elseif(WIN32) set(CLAMD_POSSIBLE_LIB_SUFFIXES lib32/import) endif() + if(X86_64 AND UNIX) + set(CLAMD_POSSIBLE_LIB_SUFFIXES lib64) + elseif(X86 AND UNIX) + set(CLAMD_POSSIBLE_LIB_SUFFIXES lib32) + endif() + if(WITH_OPENCLAMDFFT) find_path(CLAMDFFT_ROOT_DIR NAMES include/clAmdFft.h @@ -80,7 +86,7 @@ if(OPENCL_FOUND) if(WITH_OPENCLAMDBLAS) find_path(CLAMDBLAS_ROOT_DIR NAMES include/clAmdBlas.h - PATHS ENV CLAMDFFT_PATH ENV ProgramFiles + PATHS ENV CLAMDBLAS_PATH ENV ProgramFiles PATH_SUFFIXES clAmdBlas AMD/clAmdBlas DOC "AMD FFT root directory" NO_DEFAULT_PATH) diff --git a/cmake/OpenCVFindLibsVideo.cmake b/cmake/OpenCVFindLibsVideo.cmake index dbf2a2b7ea..96d480584e 100644 --- a/cmake/OpenCVFindLibsVideo.cmake +++ b/cmake/OpenCVFindLibsVideo.cmake @@ -110,10 +110,33 @@ endif(WITH_GIGEAPI) # --- Dc1394 --- ocv_clear_vars(HAVE_DC1394 HAVE_DC1394_2) if(WITH_1394) - CHECK_MODULE(libdc1394-2 HAVE_DC1394_2) - if(NOT HAVE_DC1394_2) - CHECK_MODULE(libdc1394 HAVE_DC1394) - endif() + if(WIN32 AND MINGW) + find_path(CMU1394_INCLUDE_PATH "/1394common.h" + PATH_SUFFIXES include + DOC "The path to cmu1394 headers") + find_path(DC1394_2_INCLUDE_PATH "/dc1394/dc1394.h" + PATH_SUFFIXES include + DOC "The path to DC1394 2.x headers") + if(CMU1394_INCLUDE_PATH AND DC1394_2_INCLUDE_PATH) + set(CMU1394_LIB_DIR "${CMU1394_INCLUDE_PATH}/../lib" CACHE PATH "Full path of CMU1394 library directory") + set(DC1394_2_LIB_DIR "${DC1394_2_INCLUDE_PATH}/../lib" CACHE PATH "Full path of DC1394 2.x library directory") + if(EXISTS "${CMU1394_LIB_DIR}/lib1394camera.a" AND EXISTS "${DC1394_2_LIB_DIR}/libdc1394.a") + set(HAVE_DC1394_2 TRUE) + endif() + endif() + if(HAVE_DC1394_2) + ocv_parse_pkg("libdc1394-2" "${DC1394_2_LIB_DIR}/pkgconfig" "") + ocv_include_directories(${DC1394_2_INCLUDE_PATH}) + set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} + "${DC1394_2_LIB_DIR}/libdc1394.a" + "${CMU1394_LIB_DIR}/lib1394camera.a") + endif(HAVE_DC1394_2) + else(WIN32 AND MINGW) + CHECK_MODULE(libdc1394-2 HAVE_DC1394_2) + if(NOT HAVE_DC1394_2) + CHECK_MODULE(libdc1394 HAVE_DC1394) + endif() + endif(WIN32 AND MINGW) endif(WITH_1394) # --- xine --- @@ -226,7 +249,7 @@ endif(WITH_MSMF) # --- Extra HighGUI libs on Windows --- if(WIN32) - list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32 vfw32) + list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32 setupapi ws2_32 vfw32) if(MINGW64) list(APPEND HIGHGUI_LIBRARIES avifil32 avicap32 winmm msvfw32) list(REMOVE_ITEM HIGHGUI_LIBRARIES vfw32) diff --git a/cmake/OpenCVFindXimea.cmake b/cmake/OpenCVFindXimea.cmake index 5600275f47..27e2a78ad4 100644 --- a/cmake/OpenCVFindXimea.cmake +++ b/cmake/OpenCVFindXimea.cmake @@ -9,6 +9,7 @@ # # Created: 5 Aug 2011 by Marian Zajko (marian.zajko@ximea.com) # Updated: 25 June 2012 by Igor Kuzmin (parafin@ximea.com) +# Updated: 22 October 2012 by Marian Zajko (marian.zajko@ximea.com) # set(XIMEA_FOUND) @@ -18,11 +19,15 @@ set(XIMEA_LIBRARY_DIR) if(WIN32) # Try to find the XIMEA API path in registry. GET_FILENAME_COMPONENT(XIMEA_PATH "[HKEY_CURRENT_USER\\Software\\XIMEA\\CamSupport\\API;Path]" ABSOLUTE) - - if(EXISTS XIMEA_PATH) + + if(EXISTS ${XIMEA_PATH}) set(XIMEA_FOUND 1) # set LIB folders - set(XIMEA_LIBRARY_DIR "${XIMEA_PATH}/x86") + if(CMAKE_CL_64) + set(XIMEA_LIBRARY_DIR "${XIMEA_PATH}/x64") + else() + set(XIMEA_LIBRARY_DIR "${XIMEA_PATH}/x86") + endif() else() set(XIMEA_FOUND 0) endif() @@ -38,5 +43,4 @@ endif() mark_as_advanced(FORCE XIMEA_FOUND) mark_as_advanced(FORCE XIMEA_PATH) -mark_as_advanced(FORCE XIMEA_LIBRARY_DIR) - +mark_as_advanced(FORCE XIMEA_LIBRARY_DIR) \ No newline at end of file diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index f44e3df8dc..00eb3cfa4a 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -470,7 +470,8 @@ endmacro() # ocv_create_module() # ocv_create_module(SKIP_LINK) macro(ocv_create_module) - add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES}) + add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} + "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp") if(NOT the_module STREQUAL opencv_ts) set_target_properties(${the_module} PROPERTIES COMPILE_DEFINITIONS OPENCV_NOSTL) endif() diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 5547a113c7..59366eb03b 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -501,6 +501,13 @@ macro(ocv_parse_header2 LIBNAME HDR_PATH VARNAME) endif() endmacro() +# read single version info from the pkg file +macro(ocv_parse_pkg LIBNAME PKG_PATH SCOPE) + if(EXISTS "${PKG_PATH}/${LIBNAME}.pc") + file(STRINGS "${PKG_PATH}/${LIBNAME}.pc" line_to_parse REGEX "^Version:[ \t]+[0-9.]*.*$" LIMIT_COUNT 1) + STRING(REGEX REPLACE ".*Version: ([^ ]+).*" "\\1" ALIASOF_${LIBNAME}_VERSION "${line_to_parse}" ) + endif() +endmacro() ################################################################################################ # short command to setup source group diff --git a/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst b/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst index 9309b05c1d..4b3ffbcae2 100644 --- a/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst +++ b/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.rst @@ -85,7 +85,7 @@ This tutorial code's is shown lines below. You can also download it from `here < std::vector< DMatch > good_matches; for( int i = 0; i < descriptors_1.rows; i++ ) - { if( matches[i].distance < 2*min_dist ) + { if( matches[i].distance <= 2*min_dist ) { good_matches.push_back( matches[i]); } } @@ -127,6 +127,3 @@ Result .. image:: images/Feature_FlannMatcher_Keypoints_Result.jpg :align: center :height: 250pt - - - diff --git a/modules/core/doc/basic_structures.rst b/modules/core/doc/basic_structures.rst index fe13a3462b..70c7c0ebe2 100644 --- a/modules/core/doc/basic_structures.rst +++ b/modules/core/doc/basic_structures.rst @@ -1741,7 +1741,7 @@ Returns the depth of a matrix element. .. ocv:function:: int Mat::depth() const -The method returns the identifier of the matrix element depth (the type of each individual channel). For example, for a 16-bit signed 3-channel array, the method returns ``CV_16S`` . A complete list of matrix types contains the following values: +The method returns the identifier of the matrix element depth (the type of each individual channel). For example, for a 16-bit signed element array, the method returns ``CV_16S`` . A complete list of matrix types contains the following values: * ``CV_8U`` - 8-bit unsigned integers ( ``0..255`` ) diff --git a/modules/core/perf/perf_reduce.cpp b/modules/core/perf/perf_reduce.cpp index 93d3a14166..7b74b0e7e3 100644 --- a/modules/core/perf/perf_reduce.cpp +++ b/modules/core/perf/perf_reduce.cpp @@ -34,7 +34,8 @@ PERF_TEST_P(Size_MatType_ROp, reduceR, declare.in(src, WARMUP_RNG).out(vec); declare.time(100); - TEST_CYCLE() reduce(src, vec, 0, reduceOp, ddepth); + int runs = 15; + TEST_CYCLE_MULTIRUN(runs) reduce(src, vec, 0, reduceOp, ddepth); SANITY_CHECK(vec, 1); } @@ -65,4 +66,3 @@ PERF_TEST_P(Size_MatType_ROp, reduceC, SANITY_CHECK(vec, 1); } - diff --git a/modules/core/src/matmul.cpp b/modules/core/src/matmul.cpp index 158ff8e45c..404c5b4341 100644 --- a/modules/core/src/matmul.cpp +++ b/modules/core/src/matmul.cpp @@ -2850,9 +2850,9 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComp if( _mean.data ) { - CV_Assert( _mean.size() == mean_sz ); + CV_Assert( _mean.size() == mean_sz ); _mean.convertTo(mean, ctype); - covar_flags |= CV_COVAR_USE_AVG; + covar_flags |= CV_COVAR_USE_AVG; } calcCovarMatrix( data, covar, mean, covar_flags, ctype ); @@ -2896,6 +2896,36 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComp return *this; } +template +int computeCumulativeEnergy(const Mat& eigenvalues, double retainedVariance) +{ + CV_DbgAssert( eigenvalues.type() == DataType::type ); + + Mat g(eigenvalues.size(), DataType::type); + + for(int ig = 0; ig < g.rows; ig++) + { + g.at(ig, 0) = 0; + for(int im = 0; im <= ig; im++) + { + g.at(ig,0) += eigenvalues.at(im,0); + } + } + + int L; + + for(L = 0; L < eigenvalues.rows; L++) + { + double energy = g.at(L, 0) / g.at(g.rows - 1, 0); + if(energy > retainedVariance) + break; + } + + L = std::max(2, L); + + return L; +} + PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, double retainedVariance) { Mat data = _data.getMat(), _mean = __mean.getMat(); @@ -2972,26 +3002,11 @@ PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, double reta } // compute the cumulative energy content for each eigenvector - Mat g(eigenvalues.size(), ctype); - - for(int ig = 0; ig < g.rows; ig++) - { - g.at(ig,0) = 0; - for(int im = 0; im <= ig; im++) - { - g.at(ig,0) += eigenvalues.at(im,0); - } - } - int L; - for(L = 0; L < eigenvalues.rows; L++) - { - double energy = g.at(L, 0) / g.at(g.rows - 1, 0); - if(energy > retainedVariance) - break; - } - - L = std::max(2, L); + if (ctype == CV_32F) + L = computeCumulativeEnergy(eigenvalues, retainedVariance); + else + L = computeCumulativeEnergy(eigenvalues, retainedVariance); // use clone() to physically copy the data and thus deallocate the original matrices eigenvalues = eigenvalues.rowRange(0,L).clone(); diff --git a/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst b/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst index 552bf8491b..4c49cad61a 100644 --- a/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst +++ b/modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst @@ -189,7 +189,7 @@ For each query descriptor, finds the training descriptors not farther than the s :param compactResult: Parameter used when the mask (or masks) is not empty. If ``compactResult`` is false, the ``matches`` vector has the same size as ``queryDescriptors`` rows. If ``compactResult`` is true, the ``matches`` vector does not contain matches for fully masked-out query descriptors. - :param maxDistance: Threshold for the distance between matched descriptors. + :param maxDistance: Threshold for the distance between matched descriptors. Distance means here metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured in Pixels)! For each query descriptor, the methods find such training descriptors that the distance between the query descriptor and the training descriptor is equal or smaller than ``maxDistance``. Found matches are returned in the distance increasing order. diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index f473171ef6..824466095c 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -185,7 +185,11 @@ if(HAVE_XIMEA) if(XIMEA_LIBRARY_DIR) link_directories(${XIMEA_LIBRARY_DIR}) endif() - list(APPEND HIGHGUI_LIBRARIES m3api) + if(CMAKE_CL_64) + list(APPEND HIGHGUI_LIBRARIES m3apiX64) + else() + list(APPEND HIGHGUI_LIBRARIES m3api) + endif() endif(HAVE_XIMEA) if(HAVE_FFMPEG) diff --git a/modules/highgui/src/cap_dc1394_v2.cpp b/modules/highgui/src/cap_dc1394_v2.cpp index 2aa494fac7..ea7e4b2b86 100644 --- a/modules/highgui/src/cap_dc1394_v2.cpp +++ b/modules/highgui/src/cap_dc1394_v2.cpp @@ -45,7 +45,16 @@ #include #include -#include +#ifdef WIN32 + // On Windows, we have no sys/select.h, but we need to pick up + // select() which is in winsock2. + #ifndef __SYS_SELECT_H__ + #define __SYS_SELECT_H__ 1 + #include + #endif +#else + #include +#endif /*WIN32*/ #include #include #include diff --git a/modules/highgui/src/cap_dshow.cpp b/modules/highgui/src/cap_dshow.cpp index 42741e83b4..8e5baaa403 100644 --- a/modules/highgui/src/cap_dshow.cpp +++ b/modules/highgui/src/cap_dshow.cpp @@ -3193,8 +3193,10 @@ IplImage* CvCaptureCAM_DShow::retrieveFrame(int) frame = cvCreateImage( cvSize(w,h), 8, 3 ); } - VI.getPixels( index, (uchar*)frame->imageData, false, true ); - return frame; + if (VI.getPixels( index, (uchar*)frame->imageData, false, true )) + return frame; + else + return NULL; } double CvCaptureCAM_DShow::getProperty( int property_id ) diff --git a/modules/highgui/src/cap_ximea.cpp b/modules/highgui/src/cap_ximea.cpp index dbb8f58683..5acf2c09d1 100644 --- a/modules/highgui/src/cap_ximea.cpp +++ b/modules/highgui/src/cap_ximea.cpp @@ -20,25 +20,24 @@ public: virtual IplImage* retrieveFrame(int); virtual int getCaptureDomain() { return CV_CAP_XIAPI; } // Return the type of the capture object: CV_CAP_VFW, etc... -protected: +private: void init(); void errMsg(const char* msg, int errNum); + void resetCvImage(); + int getBpp(); IplImage* frame; HANDLE hmv; DWORD numDevices; - XI_IMG image; - int width; - int height; - int format; int timeout; + XI_IMG image; }; /**********************************************************************************/ CvCapture* cvCreateCameraCapture_XIMEA( int index ) { - CvCaptureCAM_XIMEA* capture = new CvCaptureCAM_XIMEA; + CvCaptureCAM_XIMEA* capture = new CvCaptureCAM_XIMEA; if( capture->open( index )) return capture; @@ -79,18 +78,19 @@ bool CvCaptureCAM_XIMEA::open( int wIndex ) // always use auto white ballance mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, 1); if(mvret != XI_OK) goto error; + + // default image format RGB24 + mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_RGB24); + if(mvret != XI_OK) goto error; + int width = 0; mvret = xiGetParamInt( hmv, XI_PRM_WIDTH, &width); if(mvret != XI_OK) goto error; + int height = 0; mvret = xiGetParamInt( hmv, XI_PRM_HEIGHT, &height); if(mvret != XI_OK) goto error; - // default image format RGB24 - format = XI_RGB24; - mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, format); - if(mvret != XI_OK) goto error; - // allocate frame buffer for RGB24 image frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 3); @@ -103,10 +103,10 @@ bool CvCaptureCAM_XIMEA::open( int wIndex ) errMsg("StartAcquisition XI_DEVICE failed", mvret); goto error; } - return true; error: + errMsg("Open XI_DEVICE failed", mvret); xiCloseDevice(hmv); hmv = NULL; return false; @@ -116,18 +116,19 @@ error: void CvCaptureCAM_XIMEA::close() { - if(hmv) - { - xiStopAcquisition(hmv); - xiCloseDevice(hmv); - hmv = NULL; - } + if(frame) + cvReleaseImage(&frame); + + xiStopAcquisition(hmv); + xiCloseDevice(hmv); + hmv = NULL; } /**********************************************************************************/ bool CvCaptureCAM_XIMEA::grabFrame() { + memset(&image, 0, sizeof(XI_IMG)); image.size = sizeof(XI_IMG); int mvret = xiGetImage( hmv, timeout, &image); @@ -151,31 +152,18 @@ bool CvCaptureCAM_XIMEA::grabFrame() IplImage* CvCaptureCAM_XIMEA::retrieveFrame(int) { // update cvImage after format has changed - if( (int)image.width != width || (int)image.height != height || image.frm != (XI_IMG_FORMAT)format) - { - cvReleaseImage(&frame); - switch( image.frm) - { - case XI_MONO8 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 1); break; - case XI_MONO16 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_16U, 1); break; - case XI_RGB24 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 3); break; - case XI_RGB32 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 4); break; - default : - return frame; - } - // update global image format - format = image.frm; - width = image.width; - height = image.height; - } - + resetCvImage(); + // copy pixel data switch( image.frm) { - case XI_MONO8 : memcpy( frame->imageData, image.bp, image.width*image.height); break; - case XI_MONO16 : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(WORD)); break; - case XI_RGB24 : memcpy( frame->imageData, image.bp, image.width*image.height*3); break; - case XI_RGB32 : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(DWORD)); break; + case XI_MONO8 : + case XI_RAW8 : memcpy( frame->imageData, image.bp, image.width*image.height); break; + case XI_MONO16 : + case XI_RAW16 : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(WORD)); break; + case XI_RGB24 : + case XI_RGB_PLANAR : memcpy( frame->imageData, image.bp, image.width*image.height*3); break; + case XI_RGB32 : memcpy( frame->imageData, image.bp, image.width*image.height*4); break; default: break; } return frame; @@ -183,6 +171,35 @@ IplImage* CvCaptureCAM_XIMEA::retrieveFrame(int) /**********************************************************************************/ +void CvCaptureCAM_XIMEA::resetCvImage() +{ + int width = 0, height = 0, format = 0; + xiGetParamInt( hmv, XI_PRM_WIDTH, &width); + xiGetParamInt( hmv, XI_PRM_HEIGHT, &height); + xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &format); + + if( (int)image.width != width || (int)image.height != height || image.frm != (XI_IMG_FORMAT)format) + { + if(frame) cvReleaseImage(&frame); + frame = NULL; + + switch( image.frm) + { + case XI_MONO8 : + case XI_RAW8 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 1); break; + case XI_MONO16 : + case XI_RAW16 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_16U, 1); break; + case XI_RGB24 : + case XI_RGB_PLANAR : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 3); break; + case XI_RGB32 : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 4); break; + default : + return; + } + } + cvZero(frame); +} +/**********************************************************************************/ + double CvCaptureCAM_XIMEA::getProperty( int property_id ) { if(hmv == NULL) @@ -238,20 +255,14 @@ bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value ) switch(property_id) { // OCV parameters - case CV_CAP_PROP_FRAME_WIDTH : mvret = xiSetParamInt( hmv, XI_PRM_WIDTH, ival); - if(mvret == XI_OK) width = ival; - break; - case CV_CAP_PROP_FRAME_HEIGHT : mvret = xiSetParamInt( hmv, XI_PRM_HEIGHT, ival); - if(mvret == XI_OK) height = ival; - break; + case CV_CAP_PROP_FRAME_WIDTH : mvret = xiSetParamInt( hmv, XI_PRM_WIDTH, ival); break; + case CV_CAP_PROP_FRAME_HEIGHT : mvret = xiSetParamInt( hmv, XI_PRM_HEIGHT, ival); break; case CV_CAP_PROP_FPS : mvret = xiSetParamFloat( hmv, XI_PRM_FRAMERATE, fval); break; case CV_CAP_PROP_GAIN : mvret = xiSetParamFloat( hmv, XI_PRM_GAIN, fval); break; case CV_CAP_PROP_EXPOSURE : mvret = xiSetParamInt( hmv, XI_PRM_EXPOSURE, ival); break; // XIMEA camera properties case CV_CAP_PROP_XI_DOWNSAMPLING : mvret = xiSetParamInt( hmv, XI_PRM_DOWNSAMPLING, ival); break; - case CV_CAP_PROP_XI_DATA_FORMAT : mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, ival); - if(mvret == XI_OK) format = ival; - break; + case CV_CAP_PROP_XI_DATA_FORMAT : mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, ival); break; case CV_CAP_PROP_XI_OFFSET_X : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_X, ival); break; case CV_CAP_PROP_XI_OFFSET_Y : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_Y, ival); break; case CV_CAP_PROP_XI_TRG_SOURCE : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, ival); break; @@ -288,7 +299,7 @@ bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value ) void CvCaptureCAM_XIMEA::errMsg(const char* msg, int errNum) { #if defined WIN32 || defined _WIN32 - char buf[512]; + char buf[512]=""; sprintf( buf, "%s : %d\n", msg, errNum); OutputDebugString(buf); #else @@ -296,4 +307,22 @@ void CvCaptureCAM_XIMEA::errMsg(const char* msg, int errNum) #endif } +/**********************************************************************************/ + +int CvCaptureCAM_XIMEA::getBpp() +{ + switch( image.frm) + { + case XI_MONO8 : + case XI_RAW8 : return 1; + case XI_MONO16 : + case XI_RAW16 : return 2; + case XI_RGB24 : + case XI_RGB_PLANAR : return 3; + case XI_RGB32 : return 4; + default : + return 0; + } +} + /**********************************************************************************/ \ No newline at end of file diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index 701f5f5781..428ef51ef5 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -256,12 +256,17 @@ namespace void cv::imshow( const String& winname, InputArray _img ) { + const Size size = _img.size(); #ifndef HAVE_OPENGL - Mat img = _img.getMat(); - CvMat c_img = img; - cvShowImage(winname.c_str(), &c_img); + CV_Assert(size.width>0 && size.height>0); + { + Mat img = _img.getMat(); + CvMat c_img = img; + cvShowImage(winname.c_str(), &c_img); + } #else const double useGl = getWindowProperty(winname, WND_PROP_OPENGL); + CV_Assert(size.width>0 && size.height>0); if (useGl <= 0) { @@ -275,7 +280,6 @@ void cv::imshow( const String& winname, InputArray _img ) if (autoSize > 0) { - Size size = _img.size(); resizeWindow(winname, size.width, size.height); } diff --git a/modules/imgproc/perf/perf_cvt_color.cpp b/modules/imgproc/perf/perf_cvt_color.cpp index df1456c34e..a8932dd736 100644 --- a/modules/imgproc/perf/perf_cvt_color.cpp +++ b/modules/imgproc/perf/perf_cvt_color.cpp @@ -258,7 +258,8 @@ PERF_TEST_P(Size_CvtMode, cvtColor8u, declare.time(100); declare.in(src, WARMUP_RNG).out(dst); - TEST_CYCLE() cvtColor(src, dst, mode, ch.dcn); + int runs = sz.width <= 320 ? 70 : 1; + TEST_CYCLE_MULTIRUN(runs) cvtColor(src, dst, mode, ch.dcn); SANITY_CHECK(dst, 1); } @@ -334,7 +335,8 @@ PERF_TEST_P(Size_CvtMode3, cvtColorRGB2YUV420p, declare.time(100); declare.in(src, WARMUP_RNG).out(dst); - TEST_CYCLE() cvtColor(src, dst, mode, ch.dcn); + int runs = (sz.width <= 640) ? 10 : 1; + TEST_CYCLE_MULTIRUN(runs) cvtColor(src, dst, mode, ch.dcn); SANITY_CHECK(dst, 1); } diff --git a/modules/imgproc/perf/perf_morph.cpp b/modules/imgproc/perf/perf_morph.cpp index 9aadeaff52..d3dbba38fb 100644 --- a/modules/imgproc/perf/perf_morph.cpp +++ b/modules/imgproc/perf/perf_morph.cpp @@ -19,7 +19,8 @@ PERF_TEST_P(Size_MatType, erode, TYPICAL_MATS_MORPH) declare.in(src, WARMUP_RNG).out(dst); - TEST_CYCLE() erode(src, dst, noArray()); + int runs = (sz.width <= 320) ? 15 : 1; + TEST_CYCLE_MULTIRUN(runs) erode(src, dst, noArray()); SANITY_CHECK(dst); } diff --git a/modules/imgproc/perf/perf_remap.cpp b/modules/imgproc/perf/perf_remap.cpp index 334c5ff960..92c6007a2b 100644 --- a/modules/imgproc/perf/perf_remap.cpp +++ b/modules/imgproc/perf/perf_remap.cpp @@ -63,7 +63,8 @@ PERF_TEST_P( TestRemap, Remap, declare.in(src, WARMUP_RNG).out(dst).time(20); - TEST_CYCLE() remap(src, dst, map1, map2, inter_type); + int runs = (sz.width <= 640) ? 3 : 1; + TEST_CYCLE_MULTIRUN(runs) remap(src, dst, map1, map2, inter_type); SANITY_CHECK(dst); } diff --git a/modules/imgproc/perf/perf_threshold.cpp b/modules/imgproc/perf/perf_threshold.cpp index 61255e2283..01fff2e8cc 100644 --- a/modules/imgproc/perf/perf_threshold.cpp +++ b/modules/imgproc/perf/perf_threshold.cpp @@ -32,7 +32,7 @@ PERF_TEST_P(Size_MatType_ThreshType, threshold, declare.in(src, WARMUP_RNG).out(dst); - int runs = (sz.width <= 640) ? 8 : 1; + int runs = (sz.width <= 640) ? 40 : 1; TEST_CYCLE_MULTIRUN(runs) threshold(src, dst, thresh, maxval, threshType); SANITY_CHECK(dst); diff --git a/modules/java/generator/src/java/android+CameraBridgeViewBase.java b/modules/java/generator/src/java/android+CameraBridgeViewBase.java index b15ae2bd8f..c0c9f5bde7 100644 --- a/modules/java/generator/src/java/android+CameraBridgeViewBase.java +++ b/modules/java/generator/src/java/android+CameraBridgeViewBase.java @@ -80,10 +80,10 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac mMaxHeight = MAX_UNSPECIFIED; styledAttrs.recycle(); } - + /** * Sets the camera index - * @param camera index + * @param cameraIndex new camera index */ public void setCameraIndex(int cameraIndex) { this.mCameraIndex = cameraIndex; diff --git a/modules/java/generator/src/java/core+MatOfByte.java b/modules/java/generator/src/java/core+MatOfByte.java index 0ebdb66733..b3fe5691ee 100644 --- a/modules/java/generator/src/java/core+MatOfByte.java +++ b/modules/java/generator/src/java/core+MatOfByte.java @@ -14,7 +14,7 @@ public class MatOfByte extends Mat { protected MatOfByte(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfByte extends Mat { public MatOfByte(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfDouble.java b/modules/java/generator/src/java/core+MatOfDouble.java index cca5251105..4eb7cbc280 100644 --- a/modules/java/generator/src/java/core+MatOfDouble.java +++ b/modules/java/generator/src/java/core+MatOfDouble.java @@ -14,7 +14,7 @@ public class MatOfDouble extends Mat { protected MatOfDouble(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfDouble extends Mat { public MatOfDouble(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfFloat.java b/modules/java/generator/src/java/core+MatOfFloat.java index ce73b6f638..96bbeab9fb 100644 --- a/modules/java/generator/src/java/core+MatOfFloat.java +++ b/modules/java/generator/src/java/core+MatOfFloat.java @@ -14,7 +14,7 @@ public class MatOfFloat extends Mat { protected MatOfFloat(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfFloat extends Mat { public MatOfFloat(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfFloat4.java b/modules/java/generator/src/java/core+MatOfFloat4.java index 8a3e51014f..aaa97b7990 100644 --- a/modules/java/generator/src/java/core+MatOfFloat4.java +++ b/modules/java/generator/src/java/core+MatOfFloat4.java @@ -14,7 +14,7 @@ public class MatOfFloat4 extends Mat { protected MatOfFloat4(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfFloat4 extends Mat { public MatOfFloat4(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfFloat6.java b/modules/java/generator/src/java/core+MatOfFloat6.java index 1e23101a72..68e6249b6d 100644 --- a/modules/java/generator/src/java/core+MatOfFloat6.java +++ b/modules/java/generator/src/java/core+MatOfFloat6.java @@ -14,7 +14,7 @@ public class MatOfFloat6 extends Mat { protected MatOfFloat6(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfFloat6 extends Mat { public MatOfFloat6(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfInt.java b/modules/java/generator/src/java/core+MatOfInt.java index 80c5b3a5c2..33e5124e4f 100644 --- a/modules/java/generator/src/java/core+MatOfInt.java +++ b/modules/java/generator/src/java/core+MatOfInt.java @@ -15,7 +15,7 @@ public class MatOfInt extends Mat { protected MatOfInt(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -26,7 +26,7 @@ public class MatOfInt extends Mat { public MatOfInt(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfInt4.java b/modules/java/generator/src/java/core+MatOfInt4.java index 60277103cc..c924233a6c 100644 --- a/modules/java/generator/src/java/core+MatOfInt4.java +++ b/modules/java/generator/src/java/core+MatOfInt4.java @@ -15,7 +15,7 @@ public class MatOfInt4 extends Mat { protected MatOfInt4(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -26,7 +26,7 @@ public class MatOfInt4 extends Mat { public MatOfInt4(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfKeyPoint.java b/modules/java/generator/src/java/core+MatOfKeyPoint.java index a30805e18d..48ad3ca65c 100644 --- a/modules/java/generator/src/java/core+MatOfKeyPoint.java +++ b/modules/java/generator/src/java/core+MatOfKeyPoint.java @@ -16,7 +16,7 @@ public class MatOfKeyPoint extends Mat { protected MatOfKeyPoint(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -27,7 +27,7 @@ public class MatOfKeyPoint extends Mat { public MatOfKeyPoint(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfPoint.java b/modules/java/generator/src/java/core+MatOfPoint.java index 23eeed0ebb..6d23ed1162 100644 --- a/modules/java/generator/src/java/core+MatOfPoint.java +++ b/modules/java/generator/src/java/core+MatOfPoint.java @@ -14,7 +14,7 @@ public class MatOfPoint extends Mat { protected MatOfPoint(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfPoint extends Mat { public MatOfPoint(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfPoint2f.java b/modules/java/generator/src/java/core+MatOfPoint2f.java index ba4be4ac5e..0c6960730b 100644 --- a/modules/java/generator/src/java/core+MatOfPoint2f.java +++ b/modules/java/generator/src/java/core+MatOfPoint2f.java @@ -14,7 +14,7 @@ public class MatOfPoint2f extends Mat { protected MatOfPoint2f(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfPoint2f extends Mat { public MatOfPoint2f(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfPoint3.java b/modules/java/generator/src/java/core+MatOfPoint3.java index 16e21301ef..0c8374f250 100644 --- a/modules/java/generator/src/java/core+MatOfPoint3.java +++ b/modules/java/generator/src/java/core+MatOfPoint3.java @@ -14,7 +14,7 @@ public class MatOfPoint3 extends Mat { protected MatOfPoint3(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfPoint3 extends Mat { public MatOfPoint3(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfPoint3f.java b/modules/java/generator/src/java/core+MatOfPoint3f.java index 97e2a95702..b0d50d4500 100644 --- a/modules/java/generator/src/java/core+MatOfPoint3f.java +++ b/modules/java/generator/src/java/core+MatOfPoint3f.java @@ -14,7 +14,7 @@ public class MatOfPoint3f extends Mat { protected MatOfPoint3f(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -25,7 +25,7 @@ public class MatOfPoint3f extends Mat { public MatOfPoint3f(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/java/generator/src/java/core+MatOfRect.java b/modules/java/generator/src/java/core+MatOfRect.java index 2e58bfe897..3844d9dfbf 100644 --- a/modules/java/generator/src/java/core+MatOfRect.java +++ b/modules/java/generator/src/java/core+MatOfRect.java @@ -15,7 +15,7 @@ public class MatOfRect extends Mat { protected MatOfRect(long addr) { super(addr); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } @@ -26,7 +26,7 @@ public class MatOfRect extends Mat { public MatOfRect(Mat m) { super(m, Range.all()); - if(checkVector(_channels, _depth) < 0 ) + if( !empty() && checkVector(_channels, _depth) < 0 ) throw new IllegalArgumentException("Incomatible Mat"); //FIXME: do we need release() here? } diff --git a/modules/ml/src/ann_mlp.cpp b/modules/ml/src/ann_mlp.cpp index bf85425b9c..7323ab57a7 100644 --- a/modules/ml/src/ann_mlp.cpp +++ b/modules/ml/src/ann_mlp.cpp @@ -251,7 +251,7 @@ void CvANN_MLP::create( const CvMat* _layer_sizes, int _activ_func, buf_sz += (l_dst[0] + l_dst[l_count-1]*2)*2; CV_CALL( wbuf = cvCreateMat( 1, buf_sz, CV_64F )); - CV_CALL( weights = (double**)cvAlloc( (l_count+1)*sizeof(weights[0]) )); + CV_CALL( weights = (double**)cvAlloc( (l_count+2)*sizeof(weights[0]) )); weights[0] = wbuf->data.db; weights[1] = weights[0] + l_dst[0]*2; diff --git a/modules/nonfree/src/sift.cpp b/modules/nonfree/src/sift.cpp index ba65690426..68216f58bb 100644 --- a/modules/nonfree/src/sift.cpp +++ b/modules/nonfree/src/sift.cpp @@ -774,9 +774,6 @@ void SIFT::operator()(InputArray _image, InputArray _mask, findScaleSpaceExtrema(gpyr, dogpyr, keypoints); KeyPointsFilter::removeDuplicated( keypoints ); - if( !mask.empty() ) - KeyPointsFilter::runByPixelsMask( keypoints, mask ); - if( nfeatures > 0 ) KeyPointsFilter::retainBest(keypoints, nfeatures); //t = (double)getTickCount() - t; @@ -791,6 +788,9 @@ void SIFT::operator()(InputArray _image, InputArray _mask, kpt.pt *= scale; kpt.size *= scale; } + + if( !mask.empty() ) + KeyPointsFilter::runByPixelsMask( keypoints, mask ); } else { diff --git a/modules/ocl/include/opencv2/ocl.hpp b/modules/ocl/include/opencv2/ocl.hpp index 05a969d4d2..9b5e761abe 100644 --- a/modules/ocl/include/opencv2/ocl.hpp +++ b/modules/ocl/include/opencv2/ocl.hpp @@ -117,9 +117,6 @@ namespace cv //the devnum is the index of the selected device in DeviceName vector of INfo CV_EXPORTS void setDevice(Info &oclinfo, int devnum = 0); - //optional function, if you want save opencl binary kernel to the file, set its path - CV_EXPORTS void setBinpath(const char *path); - //The two functions below enable other opencl program to use ocl module's cl_context and cl_command_queue //returns cl_context * CV_EXPORTS void* getoclContext(); @@ -133,6 +130,9 @@ namespace cv //getDevice also need to be called before this function CV_EXPORTS void setDeviceEx(Info &oclinfo, void *ctx, void *qu, int devnum = 0); + //returns true when global OpenCL context is initialized + CV_EXPORTS bool initialized(); + //////////////////////////////// OpenCL context //////////////////////// //This is a global singleton class used to represent a OpenCL context. class CV_EXPORTS Context @@ -140,7 +140,7 @@ namespace cv protected: Context(); friend class std::auto_ptr; - + friend bool initialized(); private: static std::auto_ptr clCxt; static int val; @@ -178,6 +178,29 @@ namespace cv bool finish = true, bool measureKernelTime = false, bool cleanUp = true); + //! Enable or disable OpenCL program binary caching onto local disk + // After a program (*.cl files in opencl/ folder) is built at runtime, we allow the + // compiled OpenCL program to be cached to the path automatically as "path/*.clb" + // binary file, which will be reused when the OpenCV executable is started again. + // + // Caching mode is controlled by the following enums + // Notes + // 1. the feature is by default enabled when OpenCV is built in release mode. + // 2. the CACHE_DEBUG / CACHE_RELEASE flags only effectively work with MSVC compiler; + // for GNU compilers, the function always treats the build as release mode (enabled by default). + enum + { + CACHE_NONE = 0, // do not cache OpenCL binary + CACHE_DEBUG = 0x1 << 0, // cache OpenCL binary when built in debug mode (only work with MSVC) + CACHE_RELEASE = 0x1 << 1, // default behavior, only cache when built in release mode (only work with MSVC) + CACHE_ALL = CACHE_DEBUG | CACHE_RELEASE, // always cache opencl binary + CACHE_UPDATE = 0x1 << 2 // if the binary cache file with the same name is already on the disk, it will be updated. + }; + CV_EXPORTS void setBinaryDiskCache(int mode = CACHE_RELEASE, cv::String path = "./"); + + //! set where binary cache to be saved to + CV_EXPORTS void setBinpath(const char *path); + class CV_EXPORTS oclMatExpr; //////////////////////////////// oclMat //////////////////////////////// class CV_EXPORTS oclMat @@ -482,6 +505,25 @@ namespace cv CV_EXPORTS void calcHist(const oclMat &mat_src, oclMat &mat_hist); //! only 8UC1 and 256 bins is supported now CV_EXPORTS void equalizeHist(const oclMat &mat_src, oclMat &mat_dst); + + //! only 8UC1 is supported now + class CV_EXPORTS CLAHE + { + public: + virtual void apply(const oclMat &src, oclMat &dst) = 0; + + virtual void setClipLimit(double clipLimit) = 0; + virtual double getClipLimit() const = 0; + + virtual void setTilesGridSize(Size tileGridSize) = 0; + virtual Size getTilesGridSize() const = 0; + + virtual void collectGarbage() = 0; + + virtual ~CLAHE() {} + }; + CV_EXPORTS Ptr createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8)); + //! bilateralFilter // supports 8UC1 8UC4 CV_EXPORTS void bilateralFilter(const oclMat& src, oclMat& dst, int d, double sigmaColor, double sigmaSpave, int borderType=BORDER_DEFAULT); diff --git a/modules/ocl/perf/perf_imgproc.cpp b/modules/ocl/perf/perf_imgproc.cpp index e7c05cc0b7..5ab2f7d242 100644 --- a/modules/ocl/perf/perf_imgproc.cpp +++ b/modules/ocl/perf/perf_imgproc.cpp @@ -922,3 +922,50 @@ PERFTEST(remap) } } +///////////// CLAHE //////////////////////// +PERFTEST(CLAHE) +{ + Mat src, dst, ocl_dst; + cv::ocl::oclMat d_src, d_dst; + int all_type[] = {CV_8UC1}; + std::string type_name[] = {"CV_8UC1"}; + + double clipLimit = 40.0; + + cv::Ptr clahe = cv::createCLAHE(clipLimit); + cv::Ptr d_clahe = cv::ocl::createCLAHE(clipLimit); + + for (int size = Min_Size; size <= Max_Size; size *= Multiple) + { + for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++) + { + SUBTEST << size << 'x' << size << "; " << type_name[j] ; + + gen(src, size, size, all_type[j], 0, 256); + + CPU_ON; + clahe->apply(src, dst); + CPU_OFF; + + d_src.upload(src); + + WARMUP_ON; + d_clahe->apply(d_src, d_dst); + WARMUP_OFF; + + ocl_dst = d_dst; + + TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 1.0); + + GPU_ON; + d_clahe->apply(d_src, d_dst); + GPU_OFF; + + GPU_FULL_ON; + d_src.upload(src); + d_clahe->apply(d_src, d_dst); + d_dst.download(dst); + GPU_FULL_OFF; + } + } +} diff --git a/modules/ocl/src/imgproc.cpp b/modules/ocl/src/imgproc.cpp index 4b8fe58b89..3366cf7261 100644 --- a/modules/ocl/src/imgproc.cpp +++ b/modules/ocl/src/imgproc.cpp @@ -26,6 +26,7 @@ // Wu Zailong, bullet@yeah.net // Wenju He, wenju@multicorewareinc.com // Peng Xiao, pengxiao@outlook.com +// Sen Liu, swjtuls1987@126.com // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -81,6 +82,7 @@ namespace cv extern const char *imgproc_calcMinEigenVal; extern const char *imgproc_convolve; extern const char *imgproc_mulAndScaleSpectrums; + extern const char *imgproc_clahe; ////////////////////////////////////OpenCL call wrappers//////////////////////////// template struct index_and_sizeof; @@ -1505,6 +1507,189 @@ namespace cv openCLExecuteKernel(clCxt, &imgproc_histogram, kernelName, globalThreads, localThreads, args, -1, -1); LUT(mat_src, lut, mat_dst); } + + //////////////////////////////////////////////////////////////////////// + // CLAHE + namespace clahe + { + inline int divUp(int total, int grain) + { + return (total + grain - 1) / grain * grain; + } + + static void calcLut(const oclMat &src, oclMat &dst, + const int tilesX, const int tilesY, const cv::Size tileSize, + const int clipLimit, const float lutScale) + { + cl_int2 tile_size; + tile_size.s[0] = tileSize.width; + tile_size.s[1] = tileSize.height; + + std::vector > args; + args.push_back( std::make_pair( sizeof(cl_mem), (void *)&src.data )); + args.push_back( std::make_pair( sizeof(cl_mem), (void *)&dst.data )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&src.step )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&dst.step )); + args.push_back( std::make_pair( sizeof(cl_int2), (void *)&tile_size )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&tilesX )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&clipLimit )); + args.push_back( std::make_pair( sizeof(cl_float), (void *)&lutScale )); + + String kernelName = "calcLut"; + size_t localThreads[3] = { 32, 8, 1 }; + size_t globalThreads[3] = { tilesX * localThreads[0], tilesY * localThreads[1], 1 }; + bool is_cpu = queryDeviceInfo(); + if (is_cpu) + { + openCLExecuteKernel(Context::getContext(), &imgproc_clahe, kernelName, globalThreads, localThreads, args, -1, -1, (char*)" -D CPU"); + } + else + { + cl_kernel kernel = openCLGetKernelFromSource(Context::getContext(), &imgproc_clahe, kernelName); + int wave_size = queryDeviceInfo(kernel); + openCLSafeCall(clReleaseKernel(kernel)); + + static char opt[20] = {0}; + sprintf(opt, " -D WAVE_SIZE=%d", wave_size); + openCLExecuteKernel(Context::getContext(), &imgproc_clahe, kernelName, globalThreads, localThreads, args, -1, -1, opt); + } + } + + static void transform(const oclMat &src, oclMat &dst, const oclMat &lut, + const int tilesX, const int tilesY, const cv::Size tileSize) + { + cl_int2 tile_size; + tile_size.s[0] = tileSize.width; + tile_size.s[1] = tileSize.height; + + std::vector > args; + args.push_back( std::make_pair( sizeof(cl_mem), (void *)&src.data )); + args.push_back( std::make_pair( sizeof(cl_mem), (void *)&dst.data )); + args.push_back( std::make_pair( sizeof(cl_mem), (void *)&lut.data )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&src.step )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&dst.step )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&lut.step )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&src.cols )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&src.rows )); + args.push_back( std::make_pair( sizeof(cl_int2), (void *)&tile_size )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&tilesX )); + args.push_back( std::make_pair( sizeof(cl_int), (void *)&tilesY )); + + String kernelName = "transform"; + size_t localThreads[3] = { 32, 8, 1 }; + size_t globalThreads[3] = { divUp(src.cols, localThreads[0]), divUp(src.rows, localThreads[1]), 1 }; + + openCLExecuteKernel(Context::getContext(), &imgproc_clahe, kernelName, globalThreads, localThreads, args, -1, -1); + } + } + + namespace + { + class CLAHE_Impl : public cv::ocl::CLAHE + { + public: + CLAHE_Impl(double clipLimit = 40.0, int tilesX = 8, int tilesY = 8); + + cv::AlgorithmInfo* info() const; + + void apply(const oclMat &src, oclMat &dst); + + void setClipLimit(double clipLimit); + double getClipLimit() const; + + void setTilesGridSize(cv::Size tileGridSize); + cv::Size getTilesGridSize() const; + + void collectGarbage(); + + private: + double clipLimit_; + int tilesX_; + int tilesY_; + + oclMat srcExt_; + oclMat lut_; + }; + + CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY) : + clipLimit_(clipLimit), tilesX_(tilesX), tilesY_(tilesY) + { + } + + void CLAHE_Impl::apply(const oclMat &src, oclMat &dst) + { + CV_Assert( src.type() == CV_8UC1 ); + + dst.create( src.size(), src.type() ); + + const int histSize = 256; + + ensureSizeIsEnough(tilesX_ * tilesY_, histSize, CV_8UC1, lut_); + + cv::Size tileSize; + oclMat srcForLut; + + if (src.cols % tilesX_ == 0 && src.rows % tilesY_ == 0) + { + tileSize = cv::Size(src.cols / tilesX_, src.rows / tilesY_); + srcForLut = src; + } + else + { + cv::ocl::copyMakeBorder(src, srcExt_, 0, tilesY_ - (src.rows % tilesY_), 0, tilesX_ - (src.cols % tilesX_), cv::BORDER_REFLECT_101, cv::Scalar()); + + tileSize = cv::Size(srcExt_.cols / tilesX_, srcExt_.rows / tilesY_); + srcForLut = srcExt_; + } + + const int tileSizeTotal = tileSize.area(); + const float lutScale = static_cast(histSize - 1) / tileSizeTotal; + + int clipLimit = 0; + if (clipLimit_ > 0.0) + { + clipLimit = static_cast(clipLimit_ * tileSizeTotal / histSize); + clipLimit = std::max(clipLimit, 1); + } + + clahe::calcLut(srcForLut, lut_, tilesX_, tilesY_, tileSize, clipLimit, lutScale); + //finish(); + clahe::transform(src, dst, lut_, tilesX_, tilesY_, tileSize); + } + + void CLAHE_Impl::setClipLimit(double clipLimit) + { + clipLimit_ = clipLimit; + } + + double CLAHE_Impl::getClipLimit() const + { + return clipLimit_; + } + + void CLAHE_Impl::setTilesGridSize(cv::Size tileGridSize) + { + tilesX_ = tileGridSize.width; + tilesY_ = tileGridSize.height; + } + + cv::Size CLAHE_Impl::getTilesGridSize() const + { + return cv::Size(tilesX_, tilesY_); + } + + void CLAHE_Impl::collectGarbage() + { + srcExt_.release(); + lut_.release(); + } + } + + cv::Ptr createCLAHE(double clipLimit, cv::Size tileGridSize) + { + return new CLAHE_Impl(clipLimit, tileGridSize.width, tileGridSize.height); + } + //////////////////////////////////bilateralFilter//////////////////////////////////////////////////// static void oclbilateralFilter_8u( const oclMat &src, oclMat &dst, int d, diff --git a/modules/ocl/src/initialization.cpp b/modules/ocl/src/initialization.cpp index 53b1c2a77d..5d02423a21 100644 --- a/modules/ocl/src/initialization.cpp +++ b/modules/ocl/src/initialization.cpp @@ -121,8 +121,9 @@ namespace cv cacheSize = 0; } - - struct Info::Impl + // not to be exported to dynamic lib + void setBinaryDiskCacheImpl(int mode, String path, Info::Impl * impl); + struct Info::Impl { cl_platform_id oclplatform; std::vector devices; @@ -140,22 +141,12 @@ namespace cv char extra_options[512]; int double_support; int unified_memory; //1 means integrated GPU, otherwise this value is 0 + bool enable_disk_cache; + bool update_disk_cache; String binpath; int refcounter; - Impl() - { - refcounter = 1; - oclplatform = 0; - oclcontext = 0; - clCmdQueue = 0; - devnum = -1; - maxComputeUnits = 0; - maxWorkGroupSize = 0; - memset(extra_options, 0, 512); - double_support = 0; - unified_memory = 0; - } + Impl(); void setDevice(void *ctx, void *q, int devnum); @@ -180,6 +171,25 @@ namespace cv void releaseResources(); }; + Info::Impl::Impl() + :oclplatform(0), + oclcontext(0), + clCmdQueue(0), + devnum(-1), + maxWorkGroupSize(0), + maxDimensions(0), + maxComputeUnits(0), + double_support(0), + unified_memory(0), + enable_disk_cache(false), + update_disk_cache(false), + binpath("./"), + refcounter(1) + { + memset(extra_options, 0, 512); + setBinaryDiskCacheImpl(CACHE_RELEASE, String("./"), this); + } + void Info::Impl::releaseResources() { devnum = -1; @@ -498,6 +508,24 @@ namespace cv return openCLGetKernelFromSource(clCxt, source, kernelName, NULL); } + void setBinaryDiskCacheImpl(int mode, String path, Info::Impl * impl) + { + impl->update_disk_cache = (mode & CACHE_UPDATE) == CACHE_UPDATE; + impl->enable_disk_cache = +#ifdef _DEBUG + (mode & CACHE_DEBUG) == CACHE_DEBUG; +#else + (mode & CACHE_RELEASE) == CACHE_RELEASE; +#endif + if(impl->enable_disk_cache && !path.empty()) + { + impl->binpath = path; + } + } + void setBinaryDiskCache(int mode, cv::String path) + { + setBinaryDiskCacheImpl(mode, path, Context::getContext()->impl); + } void setBinpath(const char *path) { @@ -577,8 +605,8 @@ namespace cv filename = clCxt->impl->binpath + kernelName + "_" + clCxt->impl->devName[clCxt->impl->devnum] + ".clb"; } - FILE *fp = fopen(filename.c_str(), "rb"); - if(fp == NULL || clCxt->impl->binpath.size() == 0) //we should generate a binary file for the first time. + FILE *fp = clCxt->impl->enable_disk_cache ? fopen(filename.c_str(), "rb") : NULL; + if(fp == NULL || clCxt->impl->update_disk_cache) { if(fp != NULL) fclose(fp); @@ -587,7 +615,7 @@ namespace cv clCxt->impl->oclcontext, 1, source, NULL, &status); openCLVerifyCall(status); status = clBuildProgram(program, 1, &(clCxt->impl->devices[clCxt->impl->devnum]), all_build_options, NULL, NULL); - if(status == CL_SUCCESS && clCxt->impl->binpath.size()) + if(status == CL_SUCCESS && clCxt->impl->enable_disk_cache) savetofile(clCxt, program, filename.c_str()); } else @@ -921,6 +949,14 @@ namespace cv int Context::val = 0; static Mutex cs; static volatile int context_tear_down = 0; + + bool initialized() + { + return *((volatile int*)&Context::val) != 0 && + Context::clCxt->impl->clCmdQueue != NULL&& + Context::clCxt->impl->oclcontext != NULL; + } + Context* Context::getContext() { if(*((volatile int*)&val) != 1) @@ -934,8 +970,6 @@ namespace cv clCxt.reset(new Context); std::vector oclinfo; CV_Assert(getDevice(oclinfo, CVCL_DEVICE_TYPE_ALL) > 0); - oclinfo[0].impl->setDevice(0, 0, 0); - clCxt.get()->impl = oclinfo[0].impl->copy(); *((volatile int*)&val) = 1; } diff --git a/modules/ocl/src/opencl/imgproc_clahe.cl b/modules/ocl/src/opencl/imgproc_clahe.cl new file mode 100644 index 0000000000..0d010f7a5b --- /dev/null +++ b/modules/ocl/src/opencl/imgproc_clahe.cl @@ -0,0 +1,275 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved. +// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// @Authors +// Sen Liu, swjtuls1987@126.com +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other oclMaterials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// 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 Intel Corporation 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. +// +//M*/ + +#ifndef WAVE_SIZE +#define WAVE_SIZE 1 +#endif + +int calc_lut(__local int* smem, int val, int tid) +{ + smem[tid] = val; + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid == 0) + { + for (int i = 1; i < 256; ++i) + { + smem[i] += smem[i - 1]; + } + } + barrier(CLK_LOCAL_MEM_FENCE); + + return smem[tid]; +} + +#ifdef CPU +void reduce(volatile __local int* smem, int val, int tid) +{ + smem[tid] = val; + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 128) + { + smem[tid] = val += smem[tid + 128]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 64) + { + smem[tid] = val += smem[tid + 64]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 32) + { + smem[tid] += smem[tid + 32]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 16) + { + smem[tid] += smem[tid + 16]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 8) + { + smem[tid] += smem[tid + 8]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 4) + { + smem[tid] += smem[tid + 4]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 2) + { + smem[tid] += smem[tid + 2]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 1) + { + smem[256] = smem[tid] + smem[tid + 1]; + } + barrier(CLK_LOCAL_MEM_FENCE); +} +#else +void reduce(__local volatile int* smem, int val, int tid) +{ + smem[tid] = val; + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 128) + { + smem[tid] = val += smem[tid + 128]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 64) + { + smem[tid] = val += smem[tid + 64]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (tid < 32) + { + smem[tid] += smem[tid + 32]; +#if WAVE_SIZE < 32 + } barrier(CLK_LOCAL_MEM_FENCE); + if (tid < 16) { +#endif + smem[tid] += smem[tid + 16]; +#if WAVE_SIZE < 16 + } barrier(CLK_LOCAL_MEM_FENCE); + if (tid < 8) { +#endif + smem[tid] += smem[tid + 8]; + smem[tid] += smem[tid + 4]; + smem[tid] += smem[tid + 2]; + smem[tid] += smem[tid + 1]; + } +} +#endif + +__kernel void calcLut(__global __const uchar * src, __global uchar * lut, + const int srcStep, const int dstStep, + const int2 tileSize, const int tilesX, + const int clipLimit, const float lutScale) +{ + __local int smem[512]; + + const int tx = get_group_id(0); + const int ty = get_group_id(1); + const unsigned int tid = get_local_id(1) * get_local_size(0) + + get_local_id(0); + + smem[tid] = 0; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int i = get_local_id(1); i < tileSize.y; i += get_local_size(1)) + { + __global const uchar* srcPtr = src + mad24( ty * tileSize.y + i, + srcStep, tx * tileSize.x ); + for (int j = get_local_id(0); j < tileSize.x; j += get_local_size(0)) + { + const int data = srcPtr[j]; + atomic_inc(&smem[data]); + } + } + + barrier(CLK_LOCAL_MEM_FENCE); + + int tHistVal = smem[tid]; + + barrier(CLK_LOCAL_MEM_FENCE); + + if (clipLimit > 0) + { + // clip histogram bar + + int clipped = 0; + if (tHistVal > clipLimit) + { + clipped = tHistVal - clipLimit; + tHistVal = clipLimit; + } + + // find number of overall clipped samples + + reduce(smem, clipped, tid); + barrier(CLK_LOCAL_MEM_FENCE); +#ifdef CPU + clipped = smem[256]; +#else + clipped = smem[0]; +#endif + + // broadcast evaluated value + + __local int totalClipped; + + if (tid == 0) + totalClipped = clipped; + barrier(CLK_LOCAL_MEM_FENCE); + + // redistribute clipped samples evenly + + int redistBatch = totalClipped / 256; + tHistVal += redistBatch; + + int residual = totalClipped - redistBatch * 256; + if (tid < residual) + ++tHistVal; + } + + const int lutVal = calc_lut(smem, tHistVal, tid); + uint ires = (uint)convert_int_rte(lutScale * lutVal); + lut[(ty * tilesX + tx) * dstStep + tid] = + convert_uchar(clamp(ires, (uint)0, (uint)255)); +} + +__kernel void transform(__global __const uchar * src, + __global uchar * dst, + __global uchar * lut, + const int srcStep, const int dstStep, const int lutStep, + const int cols, const int rows, + const int2 tileSize, + const int tilesX, const int tilesY) +{ + const int x = get_global_id(0); + const int y = get_global_id(1); + + if (x >= cols || y >= rows) + return; + + const float tyf = (convert_float(y) / tileSize.y) - 0.5f; + int ty1 = convert_int_rtn(tyf); + int ty2 = ty1 + 1; + const float ya = tyf - ty1; + ty1 = max(ty1, 0); + ty2 = min(ty2, tilesY - 1); + + const float txf = (convert_float(x) / tileSize.x) - 0.5f; + int tx1 = convert_int_rtn(txf); + int tx2 = tx1 + 1; + const float xa = txf - tx1; + tx1 = max(tx1, 0); + tx2 = min(tx2, tilesX - 1); + + const int srcVal = src[mad24(y, srcStep, x)]; + + float res = 0; + + res += lut[mad24(ty1 * tilesX + tx1, lutStep, srcVal)] * ((1.0f - xa) * (1.0f - ya)); + res += lut[mad24(ty1 * tilesX + tx2, lutStep, srcVal)] * ((xa) * (1.0f - ya)); + res += lut[mad24(ty2 * tilesX + tx1, lutStep, srcVal)] * ((1.0f - xa) * (ya)); + res += lut[mad24(ty2 * tilesX + tx2, lutStep, srcVal)] * ((xa) * (ya)); + + uint ires = (uint)convert_int_rte(res); + dst[mad24(y, dstStep, x)] = convert_uchar(clamp(ires, (uint)0, (uint)255)); +} diff --git a/modules/ocl/test/test_imgproc.cpp b/modules/ocl/test/test_imgproc.cpp index 7c8b5c829f..85e6052dfe 100644 --- a/modules/ocl/test/test_imgproc.cpp +++ b/modules/ocl/test/test_imgproc.cpp @@ -23,6 +23,7 @@ // Rock Li, Rock.Li@amd.com // Wu Zailong, bullet@yeah.net // Xu Pang, pangxu010@163.com +// Sen Liu, swjtuls1987@126.com // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -1393,6 +1394,46 @@ TEST_P(calcHist, Mat) EXPECT_MAT_NEAR(dst_hist, cpu_hist, 0.0); } } +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// CLAHE +namespace +{ + IMPLEMENT_PARAM_CLASS(ClipLimit, double) +} + +PARAM_TEST_CASE(CLAHE, cv::Size, ClipLimit) +{ + cv::Size size; + double clipLimit; + + cv::Mat src; + cv::Mat dst_gold; + + cv::ocl::oclMat g_src; + cv::ocl::oclMat g_dst; + + virtual void SetUp() + { + size = GET_PARAM(0); + clipLimit = GET_PARAM(1); + + cv::RNG &rng = TS::ptr()->get_rng(); + src = randomMat(rng, size, CV_8UC1, 0, 256, false); + g_src.upload(src); + } +}; + +TEST_P(CLAHE, Accuracy) +{ + cv::Ptr clahe = cv::ocl::createCLAHE(clipLimit); + clahe->apply(g_src, g_dst); + cv::Mat dst(g_dst); + + cv::Ptr clahe_gold = cv::createCLAHE(clipLimit); + clahe_gold->apply(src, dst_gold); + + EXPECT_MAT_NEAR(dst_gold, dst, 1.0); +} ///////////////////////////Convolve////////////////////////////////// PARAM_TEST_CASE(ConvolveTestBase, MatType, bool) @@ -1643,6 +1684,10 @@ INSTANTIATE_TEST_CASE_P(histTestBase, calcHist, Combine( ONE_TYPE(CV_32SC1) //no use )); +INSTANTIATE_TEST_CASE_P(ImgProc, CLAHE, Combine( + Values(cv::Size(128, 128), cv::Size(113, 113), cv::Size(1300, 1300)), + Values(0.0, 40.0))); + //INSTANTIATE_TEST_CASE_P(ConvolveTestBase, Convolve, Combine( // Values(CV_32FC1, CV_32FC1), // Values(false))); // Values(false) is the reserved parameter diff --git a/modules/stitching/src/matchers.cpp b/modules/stitching/src/matchers.cpp index 99c864ae2a..e8b7bf24f9 100644 --- a/modules/stitching/src/matchers.cpp +++ b/modules/stitching/src/matchers.cpp @@ -64,10 +64,6 @@ struct DistIdxPair struct MatchPairsBody : ParallelLoopBody { - MatchPairsBody(const MatchPairsBody& other) - : matcher(other.matcher), features(other.features), - pairwise_matches(other.pairwise_matches), near_pairs(other.near_pairs) {} - MatchPairsBody(FeaturesMatcher &_matcher, const std::vector &_features, std::vector &_pairwise_matches, std::vector > &_near_pairs) : matcher(_matcher), features(_features), diff --git a/modules/stitching/src/motion_estimators.cpp b/modules/stitching/src/motion_estimators.cpp index d7b64e1080..1bb3df7bbc 100644 --- a/modules/stitching/src/motion_estimators.cpp +++ b/modules/stitching/src/motion_estimators.cpp @@ -69,13 +69,13 @@ struct CalcRotation K_from(0,0) = cameras[edge.from].focal; K_from(1,1) = cameras[edge.from].focal * cameras[edge.from].aspect; K_from(0,2) = cameras[edge.from].ppx; - K_from(0,2) = cameras[edge.from].ppy; + K_from(1,2) = cameras[edge.from].ppy; Mat_ K_to = Mat::eye(3, 3, CV_64F); K_to(0,0) = cameras[edge.to].focal; K_to(1,1) = cameras[edge.to].focal * cameras[edge.to].aspect; K_to(0,2) = cameras[edge.to].ppx; - K_to(0,2) = cameras[edge.to].ppy; + K_to(1,2) = cameras[edge.to].ppy; Mat R = K_from.inv() * pairwise_matches[pair_idx].H.inv() * K_to; cameras[edge.to].R = cameras[edge.from].R * R; diff --git a/modules/video/perf/perf_optflowpyrlk.cpp b/modules/video/perf/perf_optflowpyrlk.cpp index aa22531007..339cbd0354 100644 --- a/modules/video/perf/perf_optflowpyrlk.cpp +++ b/modules/video/perf/perf_optflowpyrlk.cpp @@ -165,7 +165,8 @@ PERF_TEST_P(Path_Idx_Cn_NPoints_WSize_Deriv, OpticalFlowPyrLK_self, testing::Com declare.in(pyramid1, pyramid2, inPoints).out(outPoints); declare.time(400); - TEST_CYCLE() + int runs = 3; + TEST_CYCLE_MULTIRUN(runs) { calcOpticalFlowPyrLK(pyramid1, pyramid2, inPoints, outPoints, status, err, Size(winSize, winSize), maxLevel, criteria, @@ -217,4 +218,4 @@ PERF_TEST_P(Path_Win_Deriv_Border_Reuse, OpticalFlowPyrLK_pyr, testing::Combine( } SANITY_CHECK(pyramid); -} \ No newline at end of file +} diff --git a/modules/videostab/src/global_motion.cpp b/modules/videostab/src/global_motion.cpp index 45e2d164ee..d6c291ca70 100644 --- a/modules/videostab/src/global_motion.cpp +++ b/modules/videostab/src/global_motion.cpp @@ -360,6 +360,9 @@ Mat estimateGlobalMotionRansac( const int npoints = points0.getMat().checkVector(2); CV_Assert(points1.getMat().checkVector(2) == npoints); + if (npoints < params.size) + return Mat::eye(3, 3, CV_32F); + const Point2f *points0_ = points0.getMat().ptr(); const Point2f *points1_ = points1.getMat().ptr(); const int niters = params.niters(); @@ -678,6 +681,8 @@ Mat KeypointBasedMotionEstimator::estimate(const Mat &frame0, const Mat &frame1, { // find keypoints detector_->detect(frame0, keypointsPrev_); + if (keypointsPrev_.empty()) + return Mat::eye(3, 3, CV_32F); // extract points from keypoints pointsPrev_.resize(keypointsPrev_.size()); diff --git a/platforms/android/android.toolchain.cmake b/platforms/android/android.toolchain.cmake index 0f7e340678..d7f09c7888 100644 --- a/platforms/android/android.toolchain.cmake +++ b/platforms/android/android.toolchain.cmake @@ -289,6 +289,9 @@ # - March 2013 # [+] updated for NDK r8e (x86 version) # [+] support x86_64 version of NDK +# - April 2013 +# [+] support non-release NDK layouts (from Linaro git and Android git) +# [~] automatically detect if explicit link to crtbegin_*.o is needed # ------------------------------------------------------------------------------ cmake_minimum_required( VERSION 2.6.3 ) @@ -516,24 +519,19 @@ if( NOT ANDROID_NDK ) endif( ANDROID_NDK ) endif( NOT ANDROID_STANDALONE_TOOLCHAIN ) endif( NOT ANDROID_NDK ) + # remember found paths if( ANDROID_NDK ) get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE ) - # try to detect change - if( CMAKE_AR ) - string( LENGTH "${ANDROID_NDK}" __length ) - string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath ) - if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK ) - message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first. - " ) - endif() - unset( __androidNdkPreviousPath ) - unset( __length ) - endif() set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE ) set( BUILD_WITH_ANDROID_NDK True ) - file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? ) - string( REGEX MATCH r[0-9]+[a-z]? ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" ) + if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" ) + file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX r[0-9]+[a-z]? ) + string( REGEX MATCH r[0-9]+[a-z]? ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" ) + else() + set( ANDROID_NDK_RELEASE "r1x" ) + set( ANDROID_NDK_RELEASE_FULL "unreleased" ) + endif() elseif( ANDROID_STANDALONE_TOOLCHAIN ) get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE ) # try to detect change @@ -560,6 +558,51 @@ else() sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" ) endif() +# android NDK layout +if( BUILD_WITH_ANDROID_NDK ) + if( NOT DEFINED ANDROID_NDK_LAYOUT ) + # try to automatically detect the layout + if( EXISTS "${ANDROID_NDK}/RELEASE.TXT") + set( ANDROID_NDK_LAYOUT "RELEASE" ) + elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" ) + set( ANDROID_NDK_LAYOUT "LINARO" ) + elseif( EXISTS "${ANDROID_NDK}/../../gcc/" ) + set( ANDROID_NDK_LAYOUT "ANDROID" ) + endif() + endif() + set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" ) + mark_as_advanced( ANDROID_NDK_LAYOUT ) + if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" ) + set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment + set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" ) + elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" ) + set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment + set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" ) + else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE" + set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" ) + endif() + get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE ) + + # try to detect change of NDK + if( CMAKE_AR ) + string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length ) + string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath ) + if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH ) + message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first. + " ) + endif() + unset( __androidNdkPreviousPath ) + unset( __length ) + endif() +endif() + + # get all the details about standalone toolchain if( BUILD_WITH_STANDALONE_TOOLCHAIN ) __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" ) @@ -587,17 +630,23 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN ) endif() endif() -macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __host_system_name ) +macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath ) foreach( __toolchain ${${__availableToolchainsLst}} ) - if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/" ) + if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" ) string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" ) else() set( __gcc_toolchain "${__toolchain}" ) endif() - __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__gcc_toolchain}/prebuilt/${__host_system_name}" ) + __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" ) if( __machine ) - string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__gcc_toolchain}" ) - string( REGEX MATCH "^[^-]+" __arch "${__gcc_toolchain}" ) + string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" ) + if( __machine MATCHES i686 ) + set( __arch "x86" ) + elseif( __machine MATCHES arm ) + set( __arch "arm" ) + elseif( __machine MATCHES mipsel ) + set( __arch "mipsel" ) + endif() list( APPEND __availableToolchainMachines "${__machine}" ) list( APPEND __availableToolchainArchs "${__arch}" ) list( APPEND __availableToolchainCompilerVersions "${__version}" ) @@ -615,29 +664,29 @@ if( BUILD_WITH_ANDROID_NDK ) set( __availableToolchainMachines "" ) set( __availableToolchainArchs "" ) set( __availableToolchainCompilerVersions "" ) - if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/" ) + if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" ) # do not go through all toolchains if we know the name set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME} ) - if( NOT __availableToolchains AND NOT ANDROID_NDK_HOST_SYSTEM_NAME STREQUAL ANDROID_NDK_HOST_SYSTEM_NAME2 ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) + if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" ) if( __availableToolchains ) - set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} ) endif() endif() endif() if( NOT __availableToolchains ) - file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" ) + file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" ) if( __availableToolchains ) list(SORT __availableToolchainsLst) # we need clang to go after gcc endif() __LIST_FILTER( __availableToolchainsLst "^[.]" ) __LIST_FILTER( __availableToolchainsLst "llvm" ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME} ) - if( NOT __availableToolchains AND NOT ANDROID_NDK_HOST_SYSTEM_NAME STREQUAL ANDROID_NDK_HOST_SYSTEM_NAME2 ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) + if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" ) if( __availableToolchains ) - set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) + set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} ) endif() endif() endif() @@ -768,6 +817,7 @@ else() list( GET __availableToolchainArchs ${__idx} __toolchainArch ) if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME ) list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion ) + string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}") if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion ) set( __toolchainMaxVersion "${__toolchainVersion}" ) set( __toolchainIdx ${__idx} ) @@ -971,11 +1021,11 @@ if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" ) elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" ) string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}") string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-4.6" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) - if( NOT EXISTS "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}/bin/clang${TOOL_OS_SUFFIX}" ) + if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" ) message( FATAL_ERROR "Could not find the Clang compiler driver" ) endif() set( ANDROID_COMPILER_IS_CLANG 1 ) - set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) else() set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) unset( ANDROID_COMPILER_IS_CLANG CACHE ) @@ -989,7 +1039,7 @@ endif() # setup paths and STL for NDK if( BUILD_WITH_ANDROID_NDK ) - set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" ) if( ANDROID_STL STREQUAL "none" ) @@ -1048,11 +1098,11 @@ if( BUILD_WITH_ANDROID_NDK ) endif() # find libsupc++.a - rtti & exceptions if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" ) - if( ANDROID_NDK_RELEASE STRGREATER "r8" ) # r8b - set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) - elseif( NOT ANDROID_NDK_RELEASE STRLESS "r7" AND ANDROID_NDK_RELEASE STRLESS "r8b") - set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) - else( ANDROID_NDK_RELEASE STRLESS "r7" ) + set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer + if( NOT EXISTS "${__libsupcxx}" ) + set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8 + endif() + if( NOT EXISTS "${__libsupcxx}" ) # before r7 if( ARMEABI_V7A ) if( ANDROID_FORCE_ARM_BUILD ) set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" ) @@ -1102,7 +1152,7 @@ unset( _ndk_ccache ) # setup the cross-compiler if( NOT CMAKE_C_COMPILER ) - if( NDK_CCACHE ) + if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" ) set( CMAKE_C_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" ) set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" ) if( ANDROID_COMPILER_IS_CLANG ) @@ -1174,11 +1224,25 @@ set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm ) remove_definitions( -DANDROID ) add_definitions( -DANDROID ) -if(ANDROID_SYSROOT MATCHES "[ ;\"]") - set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) +if( ANDROID_SYSROOT MATCHES "[ ;\"]" ) + if( CMAKE_HOST_WIN32 ) + # try to convert path to 8.3 form + file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" ) + execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}" + OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE __result ERROR_QUIET ) + if( __result EQUAL 0 ) + file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT ) + set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) + else() + set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) + endif() + else() + set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" ) + endif() if( NOT _CMAKE_IN_TRY_COMPILE ) - # quotes will break try_compile and compiler identification - message(WARNING "Your Android system root has non-alphanumeric symbols. It can break compiler features detection and the whole build.") + # quotes can break try_compile and compiler identification + message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n") endif() else() set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) @@ -1249,22 +1313,18 @@ elseif( ARMEABI ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" ) endif() +if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") ) + set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) + set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) + set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) +else() + set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) + set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) + set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) +endif() + # STL if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" ) - if( ANDROID_STL MATCHES "gnustl" ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) - set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) - set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) - else() - set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) - set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) - set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) - endif() - if ( X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" ) - # workaround "undefined reference to `__dso_handle'" problem - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) - endif() if( EXISTS "${__libstl}" ) set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" ) set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" ) @@ -1283,9 +1343,12 @@ if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" ) set( CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" ) endif() if( ANDROID_STL MATCHES "gnustl" ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} -lm" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} -lm" ) - set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lm" ) + if( NOT EXISTS "${ANDROID_LIBM_PATH}" ) + set( ANDROID_LIBM_PATH -lm ) + endif() + set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" ) + set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" ) + set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" ) endif() endif() @@ -1321,7 +1384,14 @@ if( ARMEABI_V7A ) endif() if( ANDROID_NO_UNDEFINED ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" ) + if( MIPS ) + # there is some sysroot-related problem in mips linker... + if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" ) + set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" ) + endif() + else() + set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" ) + endif() endif() if( ANDROID_SO_UNDEFINED ) @@ -1401,9 +1471,9 @@ set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FL set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" ) - set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" ) - set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" ) - set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) + set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" ) + set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" ) + set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) endif() # configure rtti @@ -1430,6 +1500,43 @@ endif() include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} ) link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ) +# detect if need link crtbegin_so.o explicitly +if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK ) + set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" ) + string( REPLACE "" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" ) + string( REPLACE "" "-shared" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + string( REPLACE "" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" ) + string( REPLACE "" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" ) + string( REPLACE "" "" __cmd "${__cmd}" ) + separate_arguments( __cmd ) + foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN ) + if( ${__var} ) + set( __tmp "${${__var}}" ) + separate_arguments( __tmp ) + string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}") + endif() + endforeach() + string( REPLACE "'" "" __cmd "${__cmd}" ) + string( REPLACE "\"" "" __cmd "${__cmd}" ) + execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET ) + if( __cmd_result EQUAL 0 ) + set( ANDROID_EXPLICIT_CRT_LINK ON ) + else() + set( ANDROID_EXPLICIT_CRT_LINK OFF ) + endif() +endif() + +if( ANDROID_EXPLICIT_CRT_LINK ) + set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) + set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) +endif() + # setup output directories set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" ) set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) @@ -1521,6 +1628,7 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) foreach( __var NDK_CCACHE LIBRARY_OUTPUT_PATH_ROOT ANDROID_FORBID_SYGWIN ANDROID_SET_OBSOLETE_VARIABLES ANDROID_NDK_HOST_X64 ANDROID_NDK + ANDROID_NDK_LAYOUT ANDROID_STANDALONE_TOOLCHAIN ANDROID_TOOLCHAIN_NAME ANDROID_ABI @@ -1534,6 +1642,8 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) ANDROID_GOLD_LINKER ANDROID_NOEXECSTACK ANDROID_RELRO + ANDROID_LIBM_PATH + ANDROID_EXPLICIT_CRT_LINK ) if( DEFINED ${__var} ) if( "${__var}" MATCHES " ") @@ -1577,6 +1687,7 @@ endif() # ANDROID_STANDALONE_TOOLCHAIN # ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain # ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems) +# ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID) # LIBRARY_OUTPUT_PATH_ROOT : # NDK_CCACHE : # Obsolete: @@ -1622,6 +1733,7 @@ endif() # ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime # ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used # ANDROID_CLANG_VERSION : version of clang compiler if clang is used +# ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product//obj/lib/libm.so) to workaround unresolved `sincos` # # Defaults: # ANDROID_DEFAULT_NDK_API_LEVEL diff --git a/samples/android/native-activity/.cproject b/samples/android/native-activity/.cproject index 09687f3ac0..44aadfe9af 100644 --- a/samples/android/native-activity/.cproject +++ b/samples/android/native-activity/.cproject @@ -1,75 +1,61 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/android/native-activity/.project b/samples/android/native-activity/.project index cf0823c0b3..c20be83f60 100644 --- a/samples/android/native-activity/.project +++ b/samples/android/native-activity/.project @@ -5,6 +5,64 @@ + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + auto,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + "${NDKROOT}/ndk-build.cmd" + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + true + + + org.eclipse.cdt.make.core.enableCleanBuild + false + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + com.android.ide.eclipse.adt.ResourceManagerBuilder @@ -25,9 +83,19 @@ + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + com.android.ide.eclipse.adt.AndroidNature org.eclipse.jdt.core.javanature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature diff --git a/samples/android/native-activity/jni/native.cpp b/samples/android/native-activity/jni/native.cpp index 66bc006db1..5cfb3a9611 100644 --- a/samples/android/native-activity/jni/native.cpp +++ b/samples/android/native-activity/jni/native.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -60,7 +59,7 @@ static cv::Size calc_optimal_camera_resolution(const char* supported, int width, } } - idx++; // to skip coma symbol + idx++; // to skip comma symbol } while(supported[idx-1] != '\0'); @@ -86,9 +85,9 @@ static void engine_draw_frame(Engine* engine, const cv::Mat& frame) for (int yy = top_indent; yy < std::min(frame.rows+top_indent, buffer.height); yy++) { - unsigned char* line = (unsigned char*)pixels; - memcpy(line+left_indent*4*sizeof(unsigned char), frame.ptr(yy), - std::min(frame.cols, buffer.width)*4*sizeof(unsigned char)); + unsigned char* line = (unsigned char*)pixels + left_indent*4*sizeof(unsigned char); + size_t line_size = std::min(frame.cols, buffer.width)*4*sizeof(unsigned char); + memcpy(line, frame.ptr(yy), line_size); // go to next line pixels = (int32_t*)pixels + buffer.stride; } @@ -139,7 +138,7 @@ static void engine_handle_cmd(android_app* app, int32_t cmd) return; } - LOGI("Camera initialized at resoution %dx%d", camera_resolution.width, camera_resolution.height); + LOGI("Camera initialized at resolution %dx%d", camera_resolution.width, camera_resolution.height); } break; case APP_CMD_TERM_WINDOW: @@ -157,7 +156,8 @@ void android_main(android_app* app) // Make sure glue isn't stripped. app_dummy(); - memset(&engine, 0, sizeof(engine)); + size_t engine_size = sizeof(engine); // for Eclipse CDT parser + memset((void*)&engine, 0, engine_size); app->userData = &engine; app->onAppCmd = engine_handle_cmd; engine.app = app; diff --git a/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp b/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp index 5ec82d5d3f..402d6456ac 100644 --- a/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp +++ b/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp @@ -71,7 +71,7 @@ int main( int argc, char** argv ) std::vector< DMatch > good_matches; for( int i = 0; i < descriptors_1.rows; i++ ) - { if( matches[i].distance < 2*min_dist ) + { if( matches[i].distance <= 2*min_dist ) { good_matches.push_back( matches[i]); } }