diff --git a/3rdparty/tbb/CMakeLists.txt b/3rdparty/tbb/CMakeLists.txt index a76854d4a3..eddeaef56a 100644 --- a/3rdparty/tbb/CMakeLists.txt +++ b/3rdparty/tbb/CMakeLists.txt @@ -5,9 +5,9 @@ if (WIN32 AND NOT ARM) message(FATAL_ERROR "BUILD_TBB option supports Windows on ARM only!\nUse regular official TBB build instead of the BUILD_TBB option!") endif() -set(tbb_ver "tbb43_20141204oss") -set(tbb_url "http://www.threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb43_20141204oss_src.tgz") -set(tbb_md5 "e903dd92d9433701f097fa7ca29a3c1f") +set(tbb_ver "tbb44_20160128oss") +set(tbb_url "http://www.threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb44_20160128oss_src_0.tgz") +set(tbb_md5 "9d8a4cdf43496f1b3f7c473a5248e5cc") set(tbb_version_file "version_string.ver") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4702) ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow) diff --git a/CMakeLists.txt b/CMakeLists.txt index f043acd614..c79338bc20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,13 +81,14 @@ if(POLICY CMP0026) cmake_policy(SET CMP0026 OLD) endif() -if (POLICY CMP0042) - # silence cmake 3.0+ warnings about MACOSX_RPATH - cmake_policy(SET CMP0042 OLD) +if(POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) endif() +include(cmake/OpenCVUtils.cmake) + # must go before the project command -set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) +ocv_update(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) if(DEFINED CMAKE_BUILD_TYPE) set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} ) endif() @@ -100,8 +101,6 @@ if(MSVC) set(CMAKE_USE_RELATIVE_PATHS ON CACHE INTERNAL "" FORCE) endif() -include(cmake/OpenCVUtils.cmake) - ocv_cmake_eval(DEBUG_PRE ONCE) ocv_clear_vars(OpenCVModules_TARGETS) @@ -304,50 +303,50 @@ include(cmake/OpenCVVersion.cmake) # ---------------------------------------------------------------------------- # Save libs and executables in the same place -set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Output directory for applications" ) +set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Output directory for applications") -if (ANDROID) - if (ANDROID_ABI MATCHES "NEON") +if(ANDROID) + if(ANDROID_ABI MATCHES "NEON") set(ENABLE_NEON ON) endif() - if (ANDROID_ABI MATCHES "VFPV3") + if(ANDROID_ABI MATCHES "VFPV3") set(ENABLE_VFPV3 ON) endif() endif() if(ANDROID OR WIN32) - set(OPENCV_DOC_INSTALL_PATH doc) + ocv_update(OPENCV_DOC_INSTALL_PATH doc) else() - set(OPENCV_DOC_INSTALL_PATH share/OpenCV/doc) + ocv_update(OPENCV_DOC_INSTALL_PATH share/OpenCV/doc) endif() if(WIN32 AND CMAKE_HOST_SYSTEM_NAME MATCHES Windows) if(DEFINED OpenCV_RUNTIME AND DEFINED OpenCV_ARCH) - set(OpenCV_INSTALL_BINARIES_PREFIX "${OpenCV_ARCH}/${OpenCV_RUNTIME}/") + ocv_update(OpenCV_INSTALL_BINARIES_PREFIX "${OpenCV_ARCH}/${OpenCV_RUNTIME}/") else() message(STATUS "Can't detect runtime and/or arch") - set(OpenCV_INSTALL_BINARIES_PREFIX "") + ocv_update(OpenCV_INSTALL_BINARIES_PREFIX "") endif() elseif(ANDROID) - set(OpenCV_INSTALL_BINARIES_PREFIX "sdk/native/") + ocv_update(OpenCV_INSTALL_BINARIES_PREFIX "sdk/native/") else() - set(OpenCV_INSTALL_BINARIES_PREFIX "") + ocv_update(OpenCV_INSTALL_BINARIES_PREFIX "") endif() if(ANDROID) - set(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples/${ANDROID_NDK_ABI_NAME}") + ocv_update(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples/${ANDROID_NDK_ABI_NAME}") else() - set(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples") + ocv_update(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples") endif() if(ANDROID) - set(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin/${ANDROID_NDK_ABI_NAME}") + ocv_update(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin/${ANDROID_NDK_ABI_NAME}") else() - set(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin") + ocv_update(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin") endif() if(NOT OPENCV_TEST_INSTALL_PATH) - set(OPENCV_TEST_INSTALL_PATH "${OPENCV_BIN_INSTALL_PATH}") + ocv_update(OPENCV_TEST_INSTALL_PATH "${OPENCV_BIN_INSTALL_PATH}") endif() if (OPENCV_TEST_DATA_PATH) @@ -356,66 +355,74 @@ endif() if(OPENCV_TEST_DATA_PATH AND NOT OPENCV_TEST_DATA_INSTALL_PATH) if(ANDROID) - set(OPENCV_TEST_DATA_INSTALL_PATH "sdk/etc/testdata") + ocv_update(OPENCV_TEST_DATA_INSTALL_PATH "sdk/etc/testdata") elseif(WIN32) - set(OPENCV_TEST_DATA_INSTALL_PATH "testdata") + ocv_update(OPENCV_TEST_DATA_INSTALL_PATH "testdata") else() - set(OPENCV_TEST_DATA_INSTALL_PATH "share/OpenCV/testdata") + ocv_update(OPENCV_TEST_DATA_INSTALL_PATH "share/OpenCV/testdata") endif() endif() if(ANDROID) - set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib/${ANDROID_NDK_ABI_NAME}") - set(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib/${ANDROID_NDK_ABI_NAME}") - set(OPENCV_LIB_INSTALL_PATH sdk/native/libs/${ANDROID_NDK_ABI_NAME}) - set(OPENCV_3P_LIB_INSTALL_PATH sdk/native/3rdparty/libs/${ANDROID_NDK_ABI_NAME}) - set(OPENCV_CONFIG_INSTALL_PATH sdk/native/jni) - set(OPENCV_INCLUDE_INSTALL_PATH sdk/native/jni/include) - set(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native) - set(OPENCV_OTHER_INSTALL_PATH sdk/etc) + set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib/${ANDROID_NDK_ABI_NAME}") + ocv_update(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib/${ANDROID_NDK_ABI_NAME}") + ocv_update(OPENCV_LIB_INSTALL_PATH sdk/native/libs/${ANDROID_NDK_ABI_NAME}) + ocv_update(OPENCV_3P_LIB_INSTALL_PATH sdk/native/3rdparty/libs/${ANDROID_NDK_ABI_NAME}) + ocv_update(OPENCV_CONFIG_INSTALL_PATH sdk/native/jni) + ocv_update(OPENCV_INCLUDE_INSTALL_PATH sdk/native/jni/include) + ocv_update(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native) + ocv_update(OPENCV_OTHER_INSTALL_PATH sdk/etc) else() - set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib") - set(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib${LIB_SUFFIX}") + set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib") + ocv_update(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib${LIB_SUFFIX}") if(WIN32 AND CMAKE_HOST_SYSTEM_NAME MATCHES Windows) if(OpenCV_STATIC) - set(OPENCV_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib${LIB_SUFFIX}") + ocv_update(OPENCV_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib${LIB_SUFFIX}") else() - set(OPENCV_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}lib${LIB_SUFFIX}") + ocv_update(OPENCV_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}lib${LIB_SUFFIX}") endif() - set(OPENCV_3P_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib${LIB_SUFFIX}") - set(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native) - set(OPENCV_JAR_INSTALL_PATH java) - set(OPENCV_OTHER_INSTALL_PATH etc) + ocv_update(OPENCV_3P_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib${LIB_SUFFIX}") + ocv_update(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native) + ocv_update(OPENCV_JAR_INSTALL_PATH java) + ocv_update(OPENCV_OTHER_INSTALL_PATH etc) + ocv_update(OPENCV_CONFIG_INSTALL_PATH ".") else() - set(OPENCV_LIB_INSTALL_PATH lib${LIB_SUFFIX}) - set(OPENCV_3P_LIB_INSTALL_PATH share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH}) - set(OPENCV_SAMPLES_SRC_INSTALL_PATH share/OpenCV/samples) - set(OPENCV_JAR_INSTALL_PATH share/OpenCV/java) - set(OPENCV_OTHER_INSTALL_PATH share/OpenCV) - endif() - set(OPENCV_INCLUDE_INSTALL_PATH "include") + ocv_update(OPENCV_LIB_INSTALL_PATH lib${LIB_SUFFIX}) + ocv_update(OPENCV_3P_LIB_INSTALL_PATH share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH}) + ocv_update(OPENCV_SAMPLES_SRC_INSTALL_PATH share/OpenCV/samples) + ocv_update(OPENCV_JAR_INSTALL_PATH share/OpenCV/java) + ocv_update(OPENCV_OTHER_INSTALL_PATH share/OpenCV) - math(EXPR SIZEOF_VOID_P_BITS "8 * ${CMAKE_SIZEOF_VOID_P}") - if(LIB_SUFFIX AND NOT SIZEOF_VOID_P_BITS EQUAL LIB_SUFFIX) - set(OPENCV_CONFIG_INSTALL_PATH lib${LIB_SUFFIX}/cmake/opencv) - else() - set(OPENCV_CONFIG_INSTALL_PATH share/OpenCV) + if(NOT DEFINED OPENCV_CONFIG_INSTALL_PATH) + math(EXPR SIZEOF_VOID_P_BITS "8 * ${CMAKE_SIZEOF_VOID_P}") + if(LIB_SUFFIX AND NOT SIZEOF_VOID_P_BITS EQUAL LIB_SUFFIX) + ocv_update(OPENCV_CONFIG_INSTALL_PATH lib${LIB_SUFFIX}/cmake/opencv) + else() + ocv_update(OPENCV_CONFIG_INSTALL_PATH share/OpenCV) + endif() + endif() endif() + ocv_update(OPENCV_INCLUDE_INSTALL_PATH "include") endif() -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_LIB_INSTALL_PATH}") +ocv_update(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_LIB_INSTALL_PATH}") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) if(INSTALL_TO_MANGLED_PATHS) set(OPENCV_INCLUDE_INSTALL_PATH ${OPENCV_INCLUDE_INSTALL_PATH}/opencv-${OPENCV_VERSION}) - string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OPENCV_3P_LIB_INSTALL_PATH "${OPENCV_3P_LIB_INSTALL_PATH}") - string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OPENCV_SAMPLES_SRC_INSTALL_PATH "${OPENCV_SAMPLES_SRC_INSTALL_PATH}") - string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OPENCV_CONFIG_INSTALL_PATH "${OPENCV_CONFIG_INSTALL_PATH}") - string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OPENCV_DOC_INSTALL_PATH "${OPENCV_DOC_INSTALL_PATH}") - string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OPENCV_JAR_INSTALL_PATH "${OPENCV_JAR_INSTALL_PATH}") - string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OPENCV_TEST_DATA_INSTALL_PATH "${OPENCV_TEST_DATA_INSTALL_PATH}") - string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" OPENCV_OTHER_INSTALL_PATH "${OPENCV_OTHER_INSTALL_PATH}") + foreach(v + OPENCV_3P_LIB_INSTALL_PATH + OPENCV_SAMPLES_SRC_INSTALL_PATH + OPENCV_CONFIG_INSTALL_PATH + OPENCV_DOC_INSTALL_PATH + OPENCV_JAR_INSTALL_PATH + OPENCV_TEST_DATA_INSTALL_PATH + OPENCV_OTHER_INSTALL_PATH + ) + string(REPLACE "OpenCV" "OpenCV-${OPENCV_VERSION}" ${v} "${${v}}") + string(REPLACE "opencv" "opencv-${OPENCV_VERSION}" ${v} "${${v}}") + endforeach() endif() @@ -440,7 +447,7 @@ endif() # ---------------------------------------------------------------------------- # Path for build/platform -specific headers # ---------------------------------------------------------------------------- -set(OPENCV_CONFIG_FILE_INCLUDE_DIR "${CMAKE_BINARY_DIR}/" CACHE PATH "Where to create the platform-dependant cvconfig.h") +ocv_update(OPENCV_CONFIG_FILE_INCLUDE_DIR "${CMAKE_BINARY_DIR}/" CACHE PATH "Where to create the platform-dependant cvconfig.h") ocv_include_directories(${OPENCV_CONFIG_FILE_INCLUDE_DIR}) # ---------------------------------------------------------------------------- @@ -453,7 +460,7 @@ set(OPENCV_EXTRA_MODULES_PATH "" CACHE PATH "Where to look for additional OpenCV # ---------------------------------------------------------------------------- find_host_package(Git QUIET) -if(GIT_FOUND) +if(NOT DEFINED OPENCV_VCSVERSION AND GIT_FOUND) execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --always --dirty --match "[0-9].[0-9].[0-9]*" WORKING_DIRECTORY "${OpenCV_SOURCE_DIR}" OUTPUT_VARIABLE OPENCV_VCSVERSION @@ -464,7 +471,7 @@ if(GIT_FOUND) if(NOT GIT_RESULT EQUAL 0) set(OPENCV_VCSVERSION "unknown") endif() -else() +elseif(NOT DEFINED OPENCV_VCSVERSION) # We don't have git: set(OPENCV_VCSVERSION "unknown") endif() diff --git a/cmake/OpenCVFindIPP.cmake b/cmake/OpenCVFindIPP.cmake index 3bff766930..43172112f1 100644 --- a/cmake/OpenCVFindIPP.cmake +++ b/cmake/OpenCVFindIPP.cmake @@ -146,7 +146,7 @@ macro(ipp_detect_version) IMPORTED_LOCATION ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX} ) list(APPEND IPP_LIBRARIES ipp${name}) - if (NOT BUILD_SHARED_LIBS OR NOT INSTALL_CREATE_DISTRIB) + if (NOT BUILD_SHARED_LIBS) # CMake doesn't support "install(TARGETS ${IPP_PREFIX}${name} " command with imported targets install(FILES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX} DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) diff --git a/cmake/OpenCVGenConfig.cmake b/cmake/OpenCVGenConfig.cmake index 3770d05b4a..206acfdad9 100644 --- a/cmake/OpenCVGenConfig.cmake +++ b/cmake/OpenCVGenConfig.cmake @@ -11,47 +11,20 @@ else() set(OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE FALSE) endif() -if(NOT OpenCV_CUDA_CC) - set(OpenCV_CUDA_CC_CONFIGCMAKE "\"\"") - set(OpenCV_CUDA_VERSION "") -else() - set(OpenCV_CUDA_CC_CONFIGCMAKE "${OpenCV_CUDA_CC}") - set(OpenCV_CUDA_VERSION ${CUDA_VERSION_STRING}) +if(HAVE_CUDA) + ocv_cmake_configure("${CMAKE_CURRENT_LIST_DIR}/templates/OpenCVConfig-CUDA.cmake.in" CUDA_CONFIGCMAKE @ONLY) endif() -if(NOT ANDROID_NATIVE_API_LEVEL) - set(OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE 0) -else() - set(OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE "${ANDROID_NATIVE_API_LEVEL}") -endif() - -if(CMAKE_GENERATOR MATCHES "Visual" OR CMAKE_GENERATOR MATCHES "Xcode") - set(OpenCV_ADD_DEBUG_RELEASE_CONFIGCMAKE TRUE) -else() - set(OpenCV_ADD_DEBUG_RELEASE_CONFIGCMAKE FALSE) -endif() - - - -if(WIN32) - if(MINGW) - set(OPENCV_LINK_LIBRARY_SUFFIX ".dll.a") +if(ANDROID) + if(NOT ANDROID_NATIVE_API_LEVEL) + set(OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE 0) else() - set(OPENCV_LINK_LIBRARY_SUFFIX ".lib") + set(OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE "${ANDROID_NATIVE_API_LEVEL}") endif() + ocv_cmake_configure("${CMAKE_CURRENT_LIST_DIR}/templates/OpenCVConfig-ANDROID.cmake.in" ANDROID_CONFIGCMAKE @ONLY) endif() -#build list of modules available for the OpenCV user -set(OpenCV_LIB_COMPONENTS "") -foreach(m ${OPENCV_MODULES_PUBLIC}) - list(INSERT OpenCV_LIB_COMPONENTS 0 ${${m}_MODULE_DEPS_OPT} ${m}) -endforeach() -ocv_list_unique(OpenCV_LIB_COMPONENTS) -set(OPENCV_MODULES_CONFIGCMAKE ${OpenCV_LIB_COMPONENTS}) -ocv_list_filterout(OpenCV_LIB_COMPONENTS "^opencv_") -if(OpenCV_LIB_COMPONENTS) - list(REMOVE_ITEM OPENCV_MODULES_CONFIGCMAKE ${OpenCV_LIB_COMPONENTS}) -endif() +set(OPENCV_MODULES_CONFIGCMAKE ${OPENCV_MODULES_PUBLIC}) if(BUILD_FAT_JAVA_LIB AND HAVE_opencv_java) list(APPEND OPENCV_MODULES_CONFIGCMAKE opencv_java) @@ -62,33 +35,20 @@ endif() # ------------------------------------------------------------------------------------------- set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"${OPENCV_CONFIG_FILE_INCLUDE_DIR}\" \"${OpenCV_SOURCE_DIR}/include\" \"${OpenCV_SOURCE_DIR}/include/opencv\"") -set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "") foreach(m ${OPENCV_MODULES_BUILD}) if(EXISTS "${OPENCV_MODULE_${m}_LOCATION}/include") - list(APPEND OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "${OPENCV_MODULE_${m}_LOCATION}/include") + set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "${OpenCV_INCLUDE_DIRS_CONFIGCMAKE} \"${OPENCV_MODULE_${m}_LOCATION}/include\"") endif() endforeach() -if(ANDROID AND NOT BUILD_SHARED_LIBS AND HAVE_TBB) - #export TBB headers location because static linkage of TBB might be troublesome if application wants to use TBB itself - list(APPEND OpenCV2_INCLUDE_DIRS_CONFIGCMAKE ${TBB_INCLUDE_DIRS}) -endif() +export(TARGETS ${OpenCVModules_TARGETS} FILE "${CMAKE_BINARY_DIR}/OpenCVModules.cmake") -set(modules_file_suffix "") -if(ANDROID) - # the REPLACE here is needed, because OpenCVModules_armeabi.cmake includes - # OpenCVModules_armeabi-*.cmake, which would match OpenCVModules_armeabi-v7a*.cmake. - string(REPLACE - _ modules_file_suffix "_${ANDROID_NDK_ABI_NAME}") -endif() - -export(TARGETS ${OpenCVModules_TARGETS} FILE "${CMAKE_BINARY_DIR}/OpenCVModules${modules_file_suffix}.cmake") - -if(TARGET ippicv AND (NOT BUILD_SHARED_LIBS OR NOT INSTALL_CREATE_DISTRIB)) +if(TARGET ippicv AND NOT BUILD_SHARED_LIBS) set(USE_IPPICV TRUE) - file(RELATIVE_PATH INSTALL_PATH_RELATIVE_IPPICV ${CMAKE_BINARY_DIR} ${IPPICV_LOCATION_PATH}) + file(RELATIVE_PATH IPPICV_INSTALL_PATH_RELATIVE_CONFIGCMAKE ${CMAKE_BINARY_DIR} ${IPPICV_LOCATION_PATH}) + ocv_cmake_configure("${CMAKE_CURRENT_LIST_DIR}/templates/OpenCVConfig-IPPICV.cmake.in" IPPICV_CONFIGCMAKE @ONLY) else() set(USE_IPPICV FALSE) - set(INSTALL_PATH_RELATIVE_IPPICV "non-existed-path") endif() configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" @ONLY) @@ -98,58 +58,60 @@ configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake. # -------------------------------------------------------------------------------------------- # Part 2/3: ${BIN_DIR}/unix-install/OpenCVConfig.cmake -> For use *with* "make install" # ------------------------------------------------------------------------------------------- -set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}/opencv" "\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}\"") +file(RELATIVE_PATH OpenCV_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/${OPENCV_CONFIG_INSTALL_PATH}/" ${CMAKE_INSTALL_PREFIX}) +set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}\" \"\${OpenCV_INSTALL_PATH}/${OPENCV_INCLUDE_INSTALL_PATH}/opencv\"") -set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "\"\"") -set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OPENCV_3P_LIB_INSTALL_PATH}\"") +if(USE_IPPICV) + file(RELATIVE_PATH IPPICV_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}" ${IPPICV_INSTALL_PATH}) + ocv_cmake_configure("${CMAKE_CURRENT_LIST_DIR}/templates/OpenCVConfig-IPPICV.cmake.in" IPPICV_CONFIGCMAKE @ONLY) +endif() -if(UNIX) # ANDROID configuration is created here also - #http://www.vtk.org/Wiki/CMake/Tutorials/Packaging reference - # For a command "find_package( [major[.minor]] [EXACT] [REQUIRED|QUIET])" - # cmake will look in the following dir on unix: - # /(share|lib)/cmake/*/ (U) - # /(share|lib)/*/ (U) - # /(share|lib)/*/(cmake|CMake)/ (U) - if(USE_IPPICV) - file(RELATIVE_PATH INSTALL_PATH_RELATIVE_IPPICV "${CMAKE_INSTALL_PREFIX}/${OPENCV_CONFIG_INSTALL_PATH}/" ${IPPICV_INSTALL_PATH}) +function(ocv_gen_config TMP_DIR NESTED_PATH ROOT_NAME) + ocv_path_join(__install_nested "${OPENCV_CONFIG_INSTALL_PATH}" "${NESTED_PATH}") + ocv_path_join(__tmp_nested "${TMP_DIR}" "${NESTED_PATH}") + + file(RELATIVE_PATH OpenCV_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/${__install_nested}" "${CMAKE_INSTALL_PREFIX}/") + + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${TMP_DIR}/OpenCVConfig-version.cmake" @ONLY) + + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${__tmp_nested}/OpenCVConfig.cmake" @ONLY) + install(EXPORT OpenCVModules DESTINATION "${__install_nested}" FILE OpenCVModules.cmake COMPONENT dev) + install(FILES + "${TMP_DIR}/OpenCVConfig-version.cmake" + "${__tmp_nested}/OpenCVConfig.cmake" + DESTINATION "${__install_nested}" COMPONENT dev) + + if(ROOT_NAME) + # Root config file + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/${ROOT_NAME}" "${TMP_DIR}/OpenCVConfig.cmake" @ONLY) + install(FILES + "${TMP_DIR}/OpenCVConfig-version.cmake" + "${TMP_DIR}/OpenCVConfig.cmake" + DESTINATION "${OPENCV_CONFIG_INSTALL_PATH}" COMPONENT dev) endif() - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" @ONLY) - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake" @ONLY) - install(FILES "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ COMPONENT dev) - install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ COMPONENT dev) - install(EXPORT OpenCVModules DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev) +endfunction() + +if(UNIX AND NOT ANDROID) + ocv_gen_config("${CMAKE_BINARY_DIR}/unix-install" "" "") endif() if(ANDROID) - install(FILES "${OpenCV_SOURCE_DIR}/platforms/android/android.toolchain.cmake" DESTINATION ${OPENCV_CONFIG_INSTALL_PATH}/ COMPONENT dev) + ocv_gen_config("${CMAKE_BINARY_DIR}/unix-install" "abi-${ANDROID_NDK_ABI_NAME}" "OpenCVConfig.root-ANDROID.cmake.in") + install(FILES "${OpenCV_SOURCE_DIR}/platforms/android/android.toolchain.cmake" DESTINATION "${OPENCV_CONFIG_INSTALL_PATH}" COMPONENT dev) endif() # -------------------------------------------------------------------------------------------- # Part 3/3: ${BIN_DIR}/win-install/OpenCVConfig.cmake -> For use within binary installers/packages # -------------------------------------------------------------------------------------------- if(WIN32) - set(OpenCV_INCLUDE_DIRS_CONFIGCMAKE "\"\${OpenCV_CONFIG_PATH}/include\" \"\${OpenCV_CONFIG_PATH}/include/opencv\"") - set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "\"\"") - - exec_program(mkdir ARGS "-p \"${CMAKE_BINARY_DIR}/win-install/\"" OUTPUT_VARIABLE RET_VAL) - if(USE_IPPICV) - file(RELATIVE_PATH INSTALL_PATH_RELATIVE_IPPICV "${CMAKE_INSTALL_PREFIX}/${OpenCV_INSTALL_BINARIES_PREFIX}staticlib" ${IPPICV_INSTALL_PATH}) - endif() - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" @ONLY) - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" @ONLY) - if (CMAKE_HOST_SYSTEM_NAME MATCHES Windows) + if(CMAKE_HOST_SYSTEM_NAME MATCHES Windows) if(BUILD_SHARED_LIBS) - install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib" COMPONENT dev) - install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib" FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev) + set(_lib_suffix "lib") else() - install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib" COMPONENT dev) - install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib" FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev) + set(_lib_suffix "staticlib") endif() - install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" DESTINATION ./ COMPONENT dev) - install(FILES "${OpenCV_SOURCE_DIR}/cmake/OpenCVConfig.cmake" DESTINATION ./ COMPONENT dev) - else () - install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib/cmake/opencv-${OPENCV_VERSION}" COMPONENT dev) - install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib/cmake/opencv-${OPENCV_VERSION}" FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev) - install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" DESTINATION "lib/cmake/opencv-${OPENCV_VERSION}" COMPONENT dev) - endif () + ocv_gen_config("${CMAKE_BINARY_DIR}/win-install" "${OpenCV_INSTALL_BINARIES_PREFIX}${_lib_suffix}" "OpenCVConfig.root-WIN32.cmake.in") + else() + ocv_gen_config("${CMAKE_BINARY_DIR}/win-install" "" "") + endif() endif() diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index bd3286c2a2..ee14c7922c 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -859,7 +859,8 @@ macro(_ocv_create_module) endif() get_target_property(_target_type ${the_module} TYPE) - if("${_target_type}" STREQUAL "SHARED_LIBRARY" OR (NOT BUILD_SHARED_LIBS OR NOT INSTALL_CREATE_DISTRIB)) + if(OPENCV_MODULE_${the_module}_CLASS STREQUAL "PUBLIC" AND + ("${_target_type}" STREQUAL "SHARED_LIBRARY" OR (NOT BUILD_SHARED_LIBS OR NOT INSTALL_CREATE_DISTRIB))) ocv_install_target(${the_module} EXPORT OpenCVModules OPTIONAL RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT libs LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs NAMELINK_SKIP diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index a17e255488..33f3dd8454 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -30,6 +30,19 @@ function(ocv_cmake_eval var_name) endif() endfunction() +macro(ocv_cmake_configure file_name var_name) + configure_file(${file_name} "${CMAKE_BINARY_DIR}/CMakeConfig-${var_name}.cmake" ${ARGN}) + file(READ "${CMAKE_BINARY_DIR}/CMakeConfig-${var_name}.cmake" ${var_name}) +endmacro() + +macro(ocv_update VAR) + if(NOT DEFINED ${VAR}) + set(${VAR} ${ARGN}) + else() + #ocv_debug_message("Preserve old value for ${VAR}: ${${VAR}}") + endif() +endmacro() + # Search packages for host system instead of packages for target system # in case of cross compilation thess macro should be defined by toolchain file if(NOT COMMAND find_host_package) @@ -71,6 +84,23 @@ macro(ocv_check_environment_variables) endforeach() endmacro() +macro(ocv_path_join result_var P1 P2) + string(REGEX REPLACE "^[/]+" "" P2 "${P2}") + if("${P1}" STREQUAL "") + if("${P2}" STREQUAL "") + set(${result_var} ".") + else() + set(${result_var} "${P2}") + endif() + elseif("${P1}" STREQUAL "/") + set(${result_var} "/${P2}") + elseif("${P2}" STREQUAL "") + set(${result_var} "${P1}") + else() + set(${result_var} "${P1}/${P2}") + endif() +endmacro() + # rename modules target to world if needed macro(_ocv_fix_target target_var) if(BUILD_opencv_world) @@ -359,7 +389,7 @@ macro(CHECK_MODULE module_name define) endmacro() -set(OPENCV_BUILD_INFO_FILE "${OpenCV_BINARY_DIR}/version_string.tmp") +set(OPENCV_BUILD_INFO_FILE "${CMAKE_BINARY_DIR}/version_string.tmp") file(REMOVE "${OPENCV_BUILD_INFO_FILE}") function(ocv_output_status msg) message(STATUS "${msg}") diff --git a/cmake/templates/OpenCVConfig-ANDROID.cmake.in b/cmake/templates/OpenCVConfig-ANDROID.cmake.in new file mode 100644 index 0000000000..1787acab38 --- /dev/null +++ b/cmake/templates/OpenCVConfig-ANDROID.cmake.in @@ -0,0 +1,13 @@ +# Android API level from which OpenCV has been compiled is remembered +set(OpenCV_ANDROID_NATIVE_API_LEVEL "@OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE@") + +# ============================================================== +# Check OpenCV availability +# ============================================================== +if(OpenCV_ANDROID_NATIVE_API_LEVEL GREATER ANDROID_NATIVE_API_LEVEL) + if(NOT OpenCV_FIND_QUIETLY) + message(WARNING "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}") + endif() + set(OpenCV_FOUND 0) + return() +endif() diff --git a/cmake/templates/OpenCVConfig-CUDA.cmake.in b/cmake/templates/OpenCVConfig-CUDA.cmake.in new file mode 100644 index 0000000000..0d261dd84b --- /dev/null +++ b/cmake/templates/OpenCVConfig-CUDA.cmake.in @@ -0,0 +1,53 @@ +# Version Compute Capability from which OpenCV has been compiled is remembered +set(OpenCV_COMPUTE_CAPABILITIES "@OpenCV_CUDA_CC@") + +set(OpenCV_CUDA_VERSION "@CUDA_VERSION_STRING@") +set(OpenCV_USE_CUBLAS "@HAVE_CUBLAS@") +set(OpenCV_USE_CUFFT "@HAVE_CUFFT@") +set(OpenCV_USE_NVCUVID "@HAVE_NVCUVID@") + +if(NOT CUDA_FOUND) + find_host_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED) +else() + if(NOT CUDA_VERSION_STRING VERSION_EQUAL OpenCV_CUDA_VERSION) + message(FATAL_ERROR "OpenCV static library was compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}") + endif() +endif() + +set(OpenCV_CUDA_LIBS_ABSPATH ${CUDA_LIBRARIES}) + +if(${CUDA_VERSION} VERSION_LESS "5.5") + list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_npp_LIBRARY}) +else() + find_cuda_helper_libs(nppc) + find_cuda_helper_libs(nppi) + find_cuda_helper_libs(npps) + list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nppc_LIBRARY} ${CUDA_nppi_LIBRARY} ${CUDA_npps_LIBRARY}) +endif() + +if(OpenCV_USE_CUBLAS) + list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_CUBLAS_LIBRARIES}) +endif() + +if(OpenCV_USE_CUFFT) + list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_CUFFT_LIBRARIES}) +endif() + +if(OpenCV_USE_NVCUVID) + list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nvcuvid_LIBRARIES}) +endif() + +if(WIN32) + list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nvcuvenc_LIBRARIES}) +endif() + +set(OpenCV_CUDA_LIBS_RELPATH "") +foreach(l ${OpenCV_CUDA_LIBS_ABSPATH}) + get_filename_component(_tmp ${l} PATH) + if(NOT ${_tmp} MATCHES "-Wl.*") + list(APPEND OpenCV_CUDA_LIBS_RELPATH ${_tmp}) + endif() +endforeach() + +list(REMOVE_DUPLICATES OpenCV_CUDA_LIBS_RELPATH) +link_directories(${OpenCV_CUDA_LIBS_RELPATH}) diff --git a/cmake/templates/OpenCVConfig-IPPICV.cmake.in b/cmake/templates/OpenCVConfig-IPPICV.cmake.in new file mode 100644 index 0000000000..33cf2d4374 --- /dev/null +++ b/cmake/templates/OpenCVConfig-IPPICV.cmake.in @@ -0,0 +1,7 @@ +if(NOT TARGET ippicv) + add_library(ippicv STATIC IMPORTED) + set_target_properties(ippicv PROPERTIES + IMPORTED_LINK_INTERFACE_LIBRARIES "" + IMPORTED_LOCATION "${OpenCV_INSTALL_PATH}/@IPPICV_INSTALL_PATH_RELATIVE_CONFIGCMAKE@" + ) +endif() diff --git a/cmake/templates/OpenCVConfig.cmake.in b/cmake/templates/OpenCVConfig.cmake.in index 468732b8b0..dfe9aeafe1 100644 --- a/cmake/templates/OpenCVConfig.cmake.in +++ b/cmake/templates/OpenCVConfig.cmake.in @@ -29,125 +29,15 @@ # # Advanced variables: # - OpenCV_SHARED : Use OpenCV as shared library -# - OpenCV_CONFIG_PATH : Path to this OpenCVConfig.cmake -# - OpenCV_INSTALL_PATH : OpenCV location (not set on Windows) +# - OpenCV_INSTALL_PATH : OpenCV location # - OpenCV_LIB_COMPONENTS : Present OpenCV modules list # - OpenCV_USE_MANGLED_PATHS : Mangled OpenCV path flag -# - OpenCV_MODULES_SUFFIX : The suffix for OpenCVModules-XXX.cmake file # # Deprecated variables: # - OpenCV_VERSION_TWEAK : Always "0" # # =================================================================================== -# Search packages for host system instead of packages for target system. -# in case of cross compilation thess macro should be defined by toolchain file - -if(NOT COMMAND find_host_package) - macro(find_host_package) - find_package(${ARGN}) - endmacro() -endif() - -if(NOT COMMAND find_host_program) - macro(find_host_program) - find_program(${ARGN}) - endmacro() -endif() - -if(NOT DEFINED OpenCV_MODULES_SUFFIX) - if(ANDROID) - string(REPLACE - _ OpenCV_MODULES_SUFFIX "_${ANDROID_NDK_ABI_NAME}") - else() - set(OpenCV_MODULES_SUFFIX "") - endif() -endif() - -if("@USE_IPPICV@" STREQUAL "TRUE") # value is defined by package builder (use STREQUAL to comply new CMake policy CMP0012) - if(NOT TARGET ippicv) - if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_PATH_RELATIVE_IPPICV@") - add_library(ippicv STATIC IMPORTED) - set_target_properties(ippicv PROPERTIES - IMPORTED_LINK_INTERFACE_LIBRARIES "" - IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_PATH_RELATIVE_IPPICV@" - ) - endif() - endif() -endif() - -if(NOT TARGET opencv_core) - # Extract directory name from full path of the file currently being processed. - # Note that CMake 2.8.3 introduced CMAKE_CURRENT_LIST_DIR. We reimplement it - # for older versions of CMake to support these as well. - if(CMAKE_VERSION VERSION_LESS "2.8.3") - get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) - endif() - - include(${CMAKE_CURRENT_LIST_DIR}/OpenCVModules${OpenCV_MODULES_SUFFIX}.cmake) -endif() - -# TODO All things below should be reviewed. What is about of moving this code into related modules (special vars/hooks/files) - -# Version Compute Capability from which OpenCV has been compiled is remembered -set(OpenCV_COMPUTE_CAPABILITIES @OpenCV_CUDA_CC_CONFIGCMAKE@) - -set(OpenCV_CUDA_VERSION @OpenCV_CUDA_VERSION@) -set(OpenCV_USE_CUBLAS @HAVE_CUBLAS@) -set(OpenCV_USE_CUFFT @HAVE_CUFFT@) -set(OpenCV_USE_NVCUVID @HAVE_NVCUVID@) - -# Android API level from which OpenCV has been compiled is remembered -if(ANDROID) - set(OpenCV_ANDROID_NATIVE_API_LEVEL @OpenCV_ANDROID_NATIVE_API_LEVEL_CONFIGCMAKE@) -else() - set(OpenCV_ANDROID_NATIVE_API_LEVEL 0) -endif() - -# Some additional settings are required if OpenCV is built as static libs -set(OpenCV_SHARED @BUILD_SHARED_LIBS@) - -# Enables mangled install paths, that help with side by side installs -set(OpenCV_USE_MANGLED_PATHS @OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE@) - -# Extract the directory where *this* file has been installed (determined at cmake run-time) -if(CMAKE_VERSION VERSION_LESS "2.8.12") - get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE) -else() - get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY CACHE) -endif() - -if(NOT WIN32 OR ANDROID) - if(ANDROID) - set(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../../..") - else() - set(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../..") - endif() - # Get the absolute path with no ../.. relative marks, to eliminate implicit linker warnings - if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8) - get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_INSTALL_PATH}" ABSOLUTE) - else() - get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_INSTALL_PATH}" REALPATH) - endif() -endif() - -# ====================================================== -# Include directories to add to the user project: -# ====================================================== - -# Provide the include directories to the caller -set(OpenCV_INCLUDE_DIRS @OpenCV_INCLUDE_DIRS_CONFIGCMAKE@) - -# ====================================================== -# Link directories to add to the user project: -# ====================================================== - -# Provide the libs directories to the caller -set(OpenCV_LIB_DIR_OPT @OpenCV_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where release OpenCV libraries are located") -set(OpenCV_LIB_DIR_DBG @OpenCV_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where debug OpenCV libraries are located") -set(OpenCV_3RDPARTY_LIB_DIR_OPT @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where release 3rdparty OpenCV dependencies are located") -set(OpenCV_3RDPARTY_LIB_DIR_DBG @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where debug 3rdparty OpenCV dependencies are located") -mark_as_advanced(FORCE OpenCV_LIB_DIR_OPT OpenCV_LIB_DIR_DBG OpenCV_3RDPARTY_LIB_DIR_OPT OpenCV_3RDPARTY_LIB_DIR_DBG OpenCV_CONFIG_PATH) - # ====================================================== # Version variables: # ====================================================== @@ -158,28 +48,48 @@ SET(OpenCV_VERSION_PATCH @OPENCV_VERSION_PATCH@) SET(OpenCV_VERSION_TWEAK 0) SET(OpenCV_VERSION_STATUS "@OPENCV_VERSION_STATUS@") -# ==================================================================== -# Link libraries: e.g. opencv_core;opencv_imgproc; etc... -# ==================================================================== +# Extract directory name from full path of the file currently being processed. +# Note that CMake 2.8.3 introduced CMAKE_CURRENT_LIST_DIR. We reimplement it +# for older versions of CMake to support these as well. +if(CMAKE_VERSION VERSION_LESS "2.8.3") + get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +endif() -SET(OpenCV_LIB_COMPONENTS @OPENCV_MODULES_CONFIGCMAKE@) -list(REMOVE_ITEM OpenCV_LIB_COMPONENTS opencv_hal) -SET(OpenCV_WORLD_COMPONENTS @OPENCV_WORLD_MODULES@) +# Extract the directory where *this* file has been installed (determined at cmake run-time) +# Get the absolute path with no ../.. relative marks, to eliminate implicit linker warnings +set(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_DIR}") +get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/@OpenCV_INSTALL_PATH_RELATIVE_CONFIGCMAKE@" REALPATH) -# ============================================================== -# Extra include directories, needed by OpenCV 2 new structure -# ============================================================== -SET(OpenCV2_INCLUDE_DIRS @OpenCV2_INCLUDE_DIRS_CONFIGCMAKE@) -if(OpenCV2_INCLUDE_DIRS) - list(APPEND OpenCV_INCLUDE_DIRS ${OpenCV2_INCLUDE_DIRS}) +# Search packages for host system instead of packages for target system. +# in case of cross compilation thess macro should be defined by toolchain file +if(NOT COMMAND find_host_package) + macro(find_host_package) + find_package(${ARGN}) + endmacro() +endif() +if(NOT COMMAND find_host_program) + macro(find_host_program) + find_program(${ARGN}) + endmacro() +endif() - set(OpenCV_ADD_DEBUG_RELEASE @OpenCV_ADD_DEBUG_RELEASE_CONFIGCMAKE@) - if(OpenCV_ADD_DEBUG_RELEASE) - set(OpenCV_LIB_DIR_OPT "${OpenCV_LIB_DIR_OPT}/Release") - set(OpenCV_LIB_DIR_DBG "${OpenCV_LIB_DIR_DBG}/Debug") - set(OpenCV_3RDPARTY_LIB_DIR_OPT "${OpenCV_3RDPARTY_LIB_DIR_OPT}/Release") - set(OpenCV_3RDPARTY_LIB_DIR_DBG "${OpenCV_3RDPARTY_LIB_DIR_DBG}/Debug") - endif() + +@CUDA_CONFIGCMAKE@ +@ANDROID_CONFIGCMAKE@ + +@IPPICV_CONFIGCMAKE@ + +# Some additional settings are required if OpenCV is built as static libs +set(OpenCV_SHARED @BUILD_SHARED_LIBS@) + +# Enables mangled install paths, that help with side by side installs +set(OpenCV_USE_MANGLED_PATHS @OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE@) + +set(OpenCV_LIB_COMPONENTS @OPENCV_MODULES_CONFIGCMAKE@) +set(OpenCV_INCLUDE_DIRS @OpenCV_INCLUDE_DIRS_CONFIGCMAKE@) + +if(NOT TARGET opencv_core) + include(${CMAKE_CURRENT_LIST_DIR}/OpenCVModules${OpenCV_MODULES_SUFFIX}.cmake) endif() if(NOT CMAKE_VERSION VERSION_LESS "2.8.11") @@ -196,22 +106,6 @@ if(NOT CMAKE_VERSION VERSION_LESS "2.8.11") endforeach() endif() -# ============================================================== -# Check OpenCV availability -# ============================================================== -if(ANDROID AND OpenCV_ANDROID_NATIVE_API_LEVEL GREATER ANDROID_NATIVE_API_LEVEL) - message(FATAL_ERROR "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}") - #always FATAL_ERROR because we can't say to the caller that OpenCV is not found - #http://www.mail-archive.com/cmake@cmake.org/msg37831.html - if(OpenCV_FIND_REQUIRED) - message(FATAL_ERROR "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}") - elseif(NOT OpenCV_FIND_QUIETLY) - message(WARNING "Minimum required by OpenCV API level is android-${OpenCV_ANDROID_NATIVE_API_LEVEL}") - endif() - set(OpenCV_FOUND "OpenCV_FOUND-NOTFOUND") - return()#Android toolchain requires CMake > 2.6 -endif() - # ============================================================== # Form list of modules (components) to find # ============================================================== @@ -223,6 +117,8 @@ if(NOT OpenCV_FIND_COMPONENTS) endif() endif() +set(OpenCV_WORLD_COMPONENTS @OPENCV_WORLD_MODULES@) + # expand short module names and see if requested components exist set(OpenCV_FIND_COMPONENTS_ "") foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) @@ -276,89 +172,11 @@ foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) endforeach() set(OpenCV_FIND_COMPONENTS ${OpenCV_FIND_COMPONENTS_}) -# ============================================================== -# Resolve dependencies -# ============================================================== -if(OpenCV_USE_MANGLED_PATHS) - set(OpenCV_LIB_SUFFIX ".${OpenCV_VERSION_MAJOR}.${OpenCV_VERSION_MINOR}.${OpenCV_VERSION_PATCH}") -else() - set(OpenCV_LIB_SUFFIX "") -endif() - -foreach(__opttype OPT DBG) - SET(OpenCV_LIBS_${__opttype} "${OpenCV_LIBS}") - SET(OpenCV_EXTRA_LIBS_${__opttype} "") - - # CUDA - if(OpenCV_CUDA_VERSION) - if(NOT CUDA_FOUND) - find_host_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED) - else() - if(NOT CUDA_VERSION_STRING VERSION_EQUAL OpenCV_CUDA_VERSION) - message(FATAL_ERROR "OpenCV static library was compiled with CUDA ${OpenCV_CUDA_VERSION} support. Please, use the same version or rebuild OpenCV with CUDA ${CUDA_VERSION_STRING}") - endif() - endif() - - set(OpenCV_CUDA_LIBS_ABSPATH ${CUDA_LIBRARIES}) - - if(${CUDA_VERSION} VERSION_LESS "5.5") - list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_npp_LIBRARY}) - else() - find_cuda_helper_libs(nppc) - find_cuda_helper_libs(nppi) - find_cuda_helper_libs(npps) - list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nppc_LIBRARY} ${CUDA_nppi_LIBRARY} ${CUDA_npps_LIBRARY}) - endif() - - if(OpenCV_USE_CUBLAS) - list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_CUBLAS_LIBRARIES}) - endif() - - if(OpenCV_USE_CUFFT) - list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_CUFFT_LIBRARIES}) - endif() - - if(OpenCV_USE_NVCUVID) - list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nvcuvid_LIBRARIES}) - endif() - - if(WIN32) - list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nvcuvenc_LIBRARIES}) - endif() - - set(OpenCV_CUDA_LIBS_RELPATH "") - foreach(l ${OpenCV_CUDA_LIBS_ABSPATH}) - get_filename_component(_tmp ${l} PATH) - if(NOT ${_tmp} MATCHES "-Wl.*") - list(APPEND OpenCV_CUDA_LIBS_RELPATH ${_tmp}) - endif() - endforeach() - - list(REMOVE_DUPLICATES OpenCV_CUDA_LIBS_RELPATH) - link_directories(${OpenCV_CUDA_LIBS_RELPATH}) - endif() -endforeach() - # ============================================================== # Compatibility stuff # ============================================================== -if(CMAKE_BUILD_TYPE MATCHES "Debug") - SET(OpenCV_LIB_DIR ${OpenCV_LIB_DIR_DBG} ${OpenCV_3RDPARTY_LIB_DIR_DBG}) -else() - SET(OpenCV_LIB_DIR ${OpenCV_LIB_DIR_OPT} ${OpenCV_3RDPARTY_LIB_DIR_OPT}) -endif() set(OpenCV_LIBRARIES ${OpenCV_LIBS}) -if(CMAKE_CROSSCOMPILING AND OpenCV_SHARED AND (CMAKE_SYSTEM_NAME MATCHES "Linux")) - foreach(dir ${OpenCV_LIB_DIR}) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${dir}") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath-link,${dir}") - set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-rpath-link,${dir}") - endforeach() -endif() - - - # # Some macroses for samples # @@ -376,7 +194,7 @@ endmacro() # adds include directories in such way that directories from the OpenCV source tree go first function(ocv_include_directories) set(__add_before "") - file(TO_CMAKE_PATH "${OpenCV_DIR}" __baseDir) + file(TO_CMAKE_PATH "${OpenCV_INSTALL_PATH}" __baseDir) foreach(dir ${ARGN}) get_filename_component(__abs_dir "${dir}" ABSOLUTE) if("${__abs_dir}" MATCHES "^${__baseDir}") diff --git a/cmake/templates/OpenCVConfig.root-ANDROID.cmake.in b/cmake/templates/OpenCVConfig.root-ANDROID.cmake.in new file mode 100644 index 0000000000..7ceeec4c7f --- /dev/null +++ b/cmake/templates/OpenCVConfig.root-ANDROID.cmake.in @@ -0,0 +1,50 @@ +# =================================================================================== +# The OpenCV CMake configuration file +# +# ** File generated automatically, do not modify ** +# +# Usage from an external project: +# In your CMakeLists.txt, add these lines: +# +# find_package(OpenCV REQUIRED) +# include_directories(${OpenCV_INCLUDE_DIRS}) # Not needed for CMake >= 2.8.11 +# target_link_libraries(MY_TARGET_NAME ${OpenCV_LIBS}) +# +# Or you can search for specific OpenCV modules: +# +# find_package(OpenCV REQUIRED core videoio) +# +# If the module is found then OPENCV__FOUND is set to TRUE. +# +# This file will define the following variables: +# - OpenCV_LIBS : The list of all imported targets for OpenCV modules. +# - OpenCV_INCLUDE_DIRS : The OpenCV include directories. +# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API. +# - OpenCV_VERSION : The version of this OpenCV build: "@OPENCV_VERSION_PLAIN@" +# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "@OPENCV_VERSION_MAJOR@" +# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "@OPENCV_VERSION_MINOR@" +# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION: "@OPENCV_VERSION_PATCH@" +# - OpenCV_VERSION_STATUS : Development status of this build: "@OPENCV_VERSION_STATUS@" +# +# =================================================================================== + +# Extract directory name from full path of the file currently being processed. +# Note that CMake 2.8.3 introduced CMAKE_CURRENT_LIST_DIR. We reimplement it +# for older versions of CMake to support these as well. +if(CMAKE_VERSION VERSION_LESS "2.8.3") + get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +endif() + +if(NOT DEFINED OpenCV_CONFIG_SUBDIR) + set(OpenCV_CONFIG_SUBDIR "/abi-${ANDROID_NDK_ABI_NAME}") +endif() + +set(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_DIR}${OpenCV_CONFIG_SUBDIR}") +if(EXISTS "${OpenCV_CONFIG_PATH}/OpenCVConfig.cmake") + include("${OpenCV_CONFIG_PATH}/OpenCVConfig.cmake") +else() + if(NOT OpenCV_FIND_QUIETLY) + message(WARNING "Found OpenCV Android Pack but it has no binaries compatible with your ABI (can't find: ${OpenCV_CONFIG_SUBDIR})") + endif() + set(OpenCV_FOUND FALSE) +endif() diff --git a/cmake/OpenCVConfig.cmake b/cmake/templates/OpenCVConfig.root-WIN32.cmake.in similarity index 72% rename from cmake/OpenCVConfig.cmake rename to cmake/templates/OpenCVConfig.root-WIN32.cmake.in index fdc371b19f..e40140fb75 100644 --- a/cmake/OpenCVConfig.cmake +++ b/cmake/templates/OpenCVConfig.root-WIN32.cmake.in @@ -17,20 +17,16 @@ # # This file will define the following variables: # - OpenCV_LIBS : The list of libraries to link against. -# - OpenCV_LIB_DIR : The directory(es) where lib files are. Calling LINK_DIRECTORIES -# with this path is NOT needed. # - OpenCV_INCLUDE_DIRS : The OpenCV include directories. # - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability -# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API -# - OpenCV_VERSION : The version of this OpenCV build. Example: "2.4.0" -# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION. Example: "2" -# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION. Example: "4" -# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION. Example: "0" +# - OpenCV_VERSION : The version of this OpenCV build: "@OPENCV_VERSION_PLAIN@" +# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "@OPENCV_VERSION_MAJOR@" +# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "@OPENCV_VERSION_MINOR@" +# - OpenCV_VERSION_PATCH : Patch version part of OpenCV_VERSION: "@OPENCV_VERSION_PATCH@" +# - OpenCV_VERSION_STATUS : Development status of this build: "@OPENCV_VERSION_STATUS@" # # Advanced variables: # - OpenCV_SHARED -# - OpenCV_CONFIG_PATH -# - OpenCV_LIB_COMPONENTS # # =================================================================================== # @@ -64,13 +60,11 @@ endif() if(MSVC) if(CMAKE_CL_64) set(OpenCV_ARCH x64) - set(OpenCV_TBB_ARCH intel64) elseif((CMAKE_GENERATOR MATCHES "ARM") OR ("${arch_hint}" STREQUAL "ARM") OR (CMAKE_VS_EFFECTIVE_PLATFORMS MATCHES "ARM|arm")) # see Modules/CmakeGenericSystem.cmake set(OpenCV_ARCH ARM) else() set(OpenCV_ARCH x86) - set(OpenCV_TBB_ARCH ia32) endif() if(MSVC_VERSION EQUAL 1400) set(OpenCV_RUNTIME vc8) @@ -99,22 +93,13 @@ elseif(MINGW) endif() endif() -if(CMAKE_VERSION VERSION_GREATER 2.6.2) - unset(OpenCV_CONFIG_PATH CACHE) -endif() - if(NOT OpenCV_FIND_QUIETLY) message(STATUS "OpenCV ARCH: ${OpenCV_ARCH}") message(STATUS "OpenCV RUNTIME: ${OpenCV_RUNTIME}") message(STATUS "OpenCV STATIC: ${OpenCV_STATIC}") endif() -if(CMAKE_VERSION VERSION_LESS "2.8.12") - get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE) -else() - get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY CACHE) -endif() - +get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH) if(OpenCV_RUNTIME AND OpenCV_ARCH) if(OpenCV_STATIC AND EXISTS "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib/OpenCVConfig.cmake") if(OpenCV_CUDA AND EXISTS "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}/staticlib/OpenCVConfig.cmake") @@ -132,28 +117,8 @@ if(OpenCV_RUNTIME AND OpenCV_ARCH) endif() if(OpenCV_LIB_PATH AND EXISTS "${OpenCV_LIB_PATH}/OpenCVConfig.cmake") - set(OpenCV_LIB_DIR_OPT "${OpenCV_LIB_PATH}" CACHE PATH "Path where release OpenCV libraries are located" FORCE) - set(OpenCV_LIB_DIR_DBG "${OpenCV_LIB_PATH}" CACHE PATH "Path where debug OpenCV libraries are located" FORCE) - set(OpenCV_3RDPARTY_LIB_DIR_OPT "${OpenCV_LIB_PATH}" CACHE PATH "Path where release 3rdparty OpenCV dependencies are located" FORCE) - set(OpenCV_3RDPARTY_LIB_DIR_DBG "${OpenCV_LIB_PATH}" CACHE PATH "Path where debug 3rdparty OpenCV dependencies are located" FORCE) - include("${OpenCV_LIB_PATH}/OpenCVConfig.cmake") - if(OpenCV_CUDA) - set(_OpenCV_LIBS "") - foreach(_lib ${OpenCV_LIBS}) - string(REPLACE "${OpenCV_CONFIG_PATH}/gpu/${OpenCV_ARCH}/${OpenCV_RUNTIME}" "${OpenCV_CONFIG_PATH}/${OpenCV_ARCH}/${OpenCV_RUNTIME}" _lib2 "${_lib}") - if(NOT EXISTS "${_lib}" AND EXISTS "${_lib2}") - list(APPEND _OpenCV_LIBS "${_lib2}") - else() - list(APPEND _OpenCV_LIBS "${_lib}") - endif() - endforeach() - set(OpenCV_LIBS ${_OpenCV_LIBS}) - endif() - set(OpenCV_FOUND TRUE CACHE BOOL "" FORCE) - set(OPENCV_FOUND TRUE CACHE BOOL "" FORCE) - if(NOT OpenCV_FIND_QUIETLY) message(STATUS "Found OpenCV ${OpenCV_VERSION} in ${OpenCV_LIB_PATH}") if(NOT OpenCV_LIB_PATH MATCHES "/staticlib") @@ -173,6 +138,5 @@ else() You should manually point CMake variable OpenCV_DIR to your build of OpenCV library." ) endif() - set(OpenCV_FOUND FALSE CACHE BOOL "" FORCE) - set(OPENCV_FOUND FALSE CACHE BOOL "" FORCE) + set(OpenCV_FOUND FALSE) endif() diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 171fa9b082..36c4eea5d4 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -1,6 +1,7 @@ set(the_description "The Core Functionality") ocv_add_module(core - PRIVATE_REQUIRED ${ZLIB_LIBRARIES} "${OPENCL_LIBRARIES}" "${VA_LIBRARIES}" "${OPENCV_HAL_LINKER_LIBS}" + "${OPENCV_HAL_LINKER_LIBS}" + PRIVATE_REQUIRED ${ZLIB_LIBRARIES} "${OPENCL_LIBRARIES}" "${VA_LIBRARIES}" OPTIONAL opencv_cudev WRAP java python) diff --git a/modules/core/include/opencv2/core/hal/hal.hpp b/modules/core/include/opencv2/core/hal/hal.hpp index 3829418931..f254b58582 100644 --- a/modules/core/include/opencv2/core/hal/hal.hpp +++ b/modules/core/include/opencv2/core/hal/hal.hpp @@ -89,7 +89,8 @@ CV_EXPORTS void exp64f(const double* src, double* dst, int n); CV_EXPORTS void log32f(const float* src, float* dst, int n); CV_EXPORTS void log64f(const double* src, double* dst, int n); -CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); +CV_EXPORTS void fastAtan32f(const float* y, const float* x, float* dst, int n, bool angleInDegrees); +CV_EXPORTS void fastAtan64f(const double* y, const double* x, double* dst, int n, bool angleInDegrees); CV_EXPORTS void magnitude32f(const float* x, const float* y, float* dst, int n); CV_EXPORTS void magnitude64f(const double* x, const double* y, double* dst, int n); CV_EXPORTS void sqrt32f(const float* src, float* dst, int len); @@ -232,6 +233,7 @@ CV_EXPORTS void exp(const double* src, double* dst, int n); CV_EXPORTS void log(const float* src, float* dst, int n); CV_EXPORTS void log(const double* src, double* dst, int n); +CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n); CV_EXPORTS void magnitude(const double* x, const double* y, double* dst, int n); CV_EXPORTS void sqrt(const float* src, float* dst, int len); diff --git a/modules/core/include/opencv2/core/hal/intrin.hpp b/modules/core/include/opencv2/core/hal/intrin.hpp index 33e14b486a..6da8fdfd1d 100644 --- a/modules/core/include/opencv2/core/hal/intrin.hpp +++ b/modules/core/include/opencv2/core/hal/intrin.hpp @@ -317,4 +317,98 @@ template struct V_SIMD128Traits //! @} +//================================================================================================== + +//! @cond IGNORED + +namespace cv { + +template struct V_RegTrait128; + +template <> struct V_RegTrait128 { + typedef v_uint8x16 reg; + typedef v_uint16x8 w_reg; + typedef v_uint32x4 q_reg; + typedef v_uint8x16 u_reg; + static v_uint8x16 zero() { return v_setzero_u8(); } + static v_uint8x16 all(uchar val) { return v_setall_u8(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_int8x16 reg; + typedef v_int16x8 w_reg; + typedef v_int32x4 q_reg; + typedef v_uint8x16 u_reg; + static v_int8x16 zero() { return v_setzero_s8(); } + static v_int8x16 all(schar val) { return v_setall_s8(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_uint16x8 reg; + typedef v_uint32x4 w_reg; + typedef v_int16x8 int_reg; + typedef v_uint16x8 u_reg; + static v_uint16x8 zero() { return v_setzero_u16(); } + static v_uint16x8 all(ushort val) { return v_setall_u16(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_int16x8 reg; + typedef v_int32x4 w_reg; + typedef v_uint16x8 u_reg; + static v_int16x8 zero() { return v_setzero_s16(); } + static v_int16x8 all(short val) { return v_setall_s16(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_uint32x4 reg; + typedef v_uint64x2 w_reg; + typedef v_int32x4 int_reg; + typedef v_uint32x4 u_reg; + static v_uint32x4 zero() { return v_setzero_u32(); } + static v_uint32x4 all(unsigned val) { return v_setall_u32(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_int32x4 reg; + typedef v_int64x2 w_reg; + typedef v_uint32x4 u_reg; + static v_int32x4 zero() { return v_setzero_s32(); } + static v_int32x4 all(int val) { return v_setall_s32(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_uint64x2 reg; + static v_uint64x2 zero() { return v_setzero_u64(); } + static v_uint64x2 all(uint64 val) { return v_setall_u64(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_int64x2 reg; + static v_int64x2 zero() { return v_setzero_s64(); } + static v_int64x2 all(int64 val) { return v_setall_s64(val); } +}; + +template <> struct V_RegTrait128 { + typedef v_float32x4 reg; + typedef v_int32x4 int_reg; + typedef v_float32x4 u_reg; + static v_float32x4 zero() { return v_setzero_f32(); } + static v_float32x4 all(float val) { return v_setall_f32(val); } +}; + +#if CV_SIMD128_64F +template <> struct V_RegTrait128 { + typedef v_float64x2 reg; + typedef v_int32x4 int_reg; + typedef v_float64x2 u_reg; + static v_float64x2 zero() { return v_setzero_f64(); } + static v_float64x2 all(double val) { return v_setall_f64(val); } +}; +#endif + +} // cv:: + +//! @endcond + #endif diff --git a/modules/core/perf/perf_math.cpp b/modules/core/perf/perf_math.cpp index 267cc9c409..eb3fbb0b24 100644 --- a/modules/core/perf/perf_math.cpp +++ b/modules/core/perf/perf_math.cpp @@ -25,6 +25,20 @@ PERF_TEST_P(VectorLength, phase32f, testing::Values(128, 1000, 128*1024, 512*102 SANITY_CHECK(angle, 5e-5); } +PERF_TEST_P(VectorLength, phase64f, testing::Values(128, 1000, 128*1024, 512*1024, 1024*1024)) +{ + size_t length = GetParam(); + vector X(length); + vector Y(length); + vector angle(length); + + declare.in(X, Y, WARMUP_RNG).out(angle); + + TEST_CYCLE_N(200) cv::phase(X, Y, angle, true); + + SANITY_CHECK(angle, 5e-5); +} + PERF_TEST_P( MaxDim_MaxPoints, kmeans, testing::Combine( testing::Values( 16, 32, 64 ), testing::Values( 300, 400, 500) ) ) diff --git a/modules/core/src/hal_replacement.hpp b/modules/core/src/hal_replacement.hpp index 605ae3863e..7f826b4096 100644 --- a/modules/core/src/hal_replacement.hpp +++ b/modules/core/src/hal_replacement.hpp @@ -376,6 +376,110 @@ inline int hal_ni_merge64s(const int64 **src_data, int64 *dst_data, int len, int #define cv_hal_merge64s hal_ni_merge64s //! @endcond + +/** +@param y,x source Y and X arrays +@param dst destination array +@param len length of arrays +@param angleInDegrees if set to true return angles in degrees, otherwise in radians + */ +//! @addtogroup core_hal_interface_fastAtan Atan calculation +//! @{ +inline int hal_ni_fastAtan32f(const float* y, const float* x, float* dst, int len, bool angleInDegrees) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_fastAtan64f(const double* y, const double* x, double* dst, int len, bool angleInDegrees) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_fastAtan32f hal_ni_fastAtan32f +#define cv_hal_fastAtan64f hal_ni_fastAtan64f +//! @endcond + + +/** +@param x,y source X and Y arrays +@param dst destination array +@param len length of arrays + */ +//! @addtogroup core_hal_interface_magnitude Magnitude calculation +//! @{ +inline int hal_ni_magnitude32f(const float *x, const float *y, float *dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_magnitude64f(const double *x, const double *y, double *dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_magnitude32f hal_ni_magnitude32f +#define cv_hal_magnitude64f hal_ni_magnitude64f +//! @endcond + + +/** +@param src source array +@param dst destination array +@param len length of arrays + */ +//! @addtogroup core_hal_interface_invSqrt Inverse square root calculation +//! @{ +inline int hal_ni_invSqrt32f(const float* src, float* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_invSqrt64f(const double* src, double* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_invSqrt32f hal_ni_invSqrt32f +#define cv_hal_invSqrt64f hal_ni_invSqrt64f +//! @endcond + + +/** +@param src source array +@param dst destination array +@param len length of arrays + */ +//! @addtogroup core_hal_interface_sqrt Square root calculation +//! @{ +inline int hal_ni_sqrt32f(const float* src, float* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_sqrt64f(const double* src, double* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_sqrt32f hal_ni_sqrt32f +#define cv_hal_sqrt64f hal_ni_sqrt64f +//! @endcond + + +/** +@param src source array +@param dst destination array +@param len length of arrays + */ +//! @addtogroup core_hal_interface_log Natural logarithm calculation +//! @{ +inline int hal_ni_log32f(const float* src, float* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_log64f(const double* src, double* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_log32f hal_ni_log32f +#define cv_hal_log64f hal_ni_log64f +//! @endcond + + +/** +@param src source array +@param dst destination array +@param len length of arrays + */ +//! @addtogroup core_hal_interface_exp Exponent calculation +//! @{ +inline int hal_ni_exp32f(const float* src, float* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_exp64f(const double* src, double* dst, int len) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +//! @} + +//! @cond IGNORED +#define cv_hal_exp32f hal_ni_exp32f +#define cv_hal_exp64f hal_ni_exp64f +//! @endcond + + /** @brief Dummy structure storing DFT/DCT context @@ -599,21 +703,25 @@ inline int hal_ni_gemm64fc(const double* src1, size_t src1_step, const double* s //! @cond IGNORED #define CALL_HAL_RET(name, fun, retval, ...) \ +{ \ int res = fun(__VA_ARGS__, &retval); \ if (res == CV_HAL_ERROR_OK) \ return retval; \ else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \ CV_Error_(cv::Error::StsInternal, \ - ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res)); + ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res)); \ +} #define CALL_HAL(name, fun, ...) \ +{ \ int res = fun(__VA_ARGS__); \ if (res == CV_HAL_ERROR_OK) \ return; \ else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \ CV_Error_(cv::Error::StsInternal, \ - ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res)); + ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res)); \ +} //! @endcond #endif diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index 495711f8dd..e974776c85 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -51,11 +51,6 @@ namespace cv typedef void (*MathFunc)(const void* src, void* dst, int len); -static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI); -static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI); -static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI); -static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI); - #ifdef HAVE_OPENCL enum { OCL_OP_LOG=0, OCL_OP_EXP=1, OCL_OP_MAG=2, OCL_OP_PHASE_DEGREES=3, OCL_OP_PHASE_RADIANS=4 }; @@ -100,29 +95,6 @@ static bool ocl_math_op(InputArray _src1, InputArray _src2, OutputArray _dst, in #endif -float fastAtan2( float y, float x ) -{ - float ax = std::abs(x), ay = std::abs(y); - float a, c, c2; - if( ax >= ay ) - { - c = ay/(ax + (float)DBL_EPSILON); - c2 = c*c; - a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; - } - else - { - c = ax/(ay + (float)DBL_EPSILON); - c2 = c*c; - a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; - } - if( x < 0 ) - a = 180.f - a; - if( y < 0 ) - a = 360.f - a; - return a; -} - /* ************************************************************************** *\ Fast cube root by Ken Turkowski (http://www.worldserver.com/turk/computergraphics/papers.html) @@ -202,7 +174,6 @@ void magnitude( InputArray src1, InputArray src2, OutputArray dst ) } } - void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegrees ) { int type = src1.type(), depth = src1.depth(), cn = src1.channels(); @@ -218,19 +189,8 @@ void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegre const Mat* arrays[] = {&X, &Y, &Angle, 0}; uchar* ptrs[3]; NAryMatIterator it(arrays, ptrs); - cv::AutoBuffer _buf; - float* buf[2] = {0, 0}; - int j, k, total = (int)(it.size*cn), blockSize = total; + int j, total = (int)(it.size*cn), blockSize = total; size_t esz1 = X.elemSize1(); - - if( depth == CV_64F ) - { - blockSize = std::min(blockSize, ((BLOCK_SIZE+cn-1)/cn)*cn); - _buf.allocate(blockSize*2); - buf[0] = _buf; - buf[1] = buf[0] + blockSize; - } - for( size_t i = 0; i < it.nplanes; i++, ++it ) { for( j = 0; j < total; j += blockSize ) @@ -240,53 +200,13 @@ void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegre { const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; float *angle = (float*)ptrs[2]; - hal::fastAtan2( y, x, angle, len, angleInDegrees ); + hal::fastAtan32f( y, x, angle, len, angleInDegrees ); } else { const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; double *angle = (double*)ptrs[2]; - k = 0; - -#if CV_SSE2 - if (USE_SSE2) - { - for ( ; k <= len - 4; k += 4) - { - __m128 v_dst0 = _mm_movelh_ps(_mm_cvtpd_ps(_mm_loadu_pd(x + k)), - _mm_cvtpd_ps(_mm_loadu_pd(x + k + 2))); - __m128 v_dst1 = _mm_movelh_ps(_mm_cvtpd_ps(_mm_loadu_pd(y + k)), - _mm_cvtpd_ps(_mm_loadu_pd(y + k + 2))); - - _mm_storeu_ps(buf[0] + k, v_dst0); - _mm_storeu_ps(buf[1] + k, v_dst1); - } - } -#endif - - for( ; k < len; k++ ) - { - buf[0][k] = (float)x[k]; - buf[1][k] = (float)y[k]; - } - - hal::fastAtan2( buf[1], buf[0], buf[0], len, angleInDegrees ); - k = 0; - -#if CV_SSE2 - if (USE_SSE2) - { - for ( ; k <= len - 4; k += 4) - { - __m128 v_src = _mm_loadu_ps(buf[0] + k); - _mm_storeu_pd(angle + k, _mm_cvtps_pd(v_src)); - _mm_storeu_pd(angle + k + 2, _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_src), 8)))); - } - } -#endif - - for( ; k < len; k++ ) - angle[k] = buf[0][k]; + hal::fastAtan64f(y, x, angle, len, angleInDegrees); } ptrs[0] += len*esz1; ptrs[1] += len*esz1; @@ -353,18 +273,9 @@ void cartToPolar( InputArray src1, InputArray src2, const Mat* arrays[] = {&X, &Y, &Mag, &Angle, 0}; uchar* ptrs[4]; NAryMatIterator it(arrays, ptrs); - cv::AutoBuffer _buf; - float* buf[2] = {0, 0}; - int j, k, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn); + int j, total = (int)(it.size*cn), blockSize = std::min(total, ((BLOCK_SIZE+cn-1)/cn)*cn); size_t esz1 = X.elemSize1(); - if( depth == CV_64F ) - { - _buf.allocate(blockSize*2); - buf[0] = _buf; - buf[1] = buf[0] + blockSize; - } - for( size_t i = 0; i < it.nplanes; i++, ++it ) { for( j = 0; j < total; j += blockSize ) @@ -375,55 +286,14 @@ void cartToPolar( InputArray src1, InputArray src2, const float *x = (const float*)ptrs[0], *y = (const float*)ptrs[1]; float *mag = (float*)ptrs[2], *angle = (float*)ptrs[3]; hal::magnitude32f( x, y, mag, len ); - hal::fastAtan2( y, x, angle, len, angleInDegrees ); + hal::fastAtan32f( y, x, angle, len, angleInDegrees ); } else { const double *x = (const double*)ptrs[0], *y = (const double*)ptrs[1]; double *angle = (double*)ptrs[3]; - hal::magnitude64f(x, y, (double*)ptrs[2], len); - k = 0; - -#if CV_SSE2 - if (USE_SSE2) - { - for ( ; k <= len - 4; k += 4) - { - __m128 v_dst0 = _mm_movelh_ps(_mm_cvtpd_ps(_mm_loadu_pd(x + k)), - _mm_cvtpd_ps(_mm_loadu_pd(x + k + 2))); - __m128 v_dst1 = _mm_movelh_ps(_mm_cvtpd_ps(_mm_loadu_pd(y + k)), - _mm_cvtpd_ps(_mm_loadu_pd(y + k + 2))); - - _mm_storeu_ps(buf[0] + k, v_dst0); - _mm_storeu_ps(buf[1] + k, v_dst1); - } - } -#endif - - for( ; k < len; k++ ) - { - buf[0][k] = (float)x[k]; - buf[1][k] = (float)y[k]; - } - - hal::fastAtan2( buf[1], buf[0], buf[0], len, angleInDegrees ); - k = 0; - -#if CV_SSE2 - if (USE_SSE2) - { - for ( ; k <= len - 4; k += 4) - { - __m128 v_src = _mm_loadu_ps(buf[0] + k); - _mm_storeu_pd(angle + k, _mm_cvtps_pd(v_src)); - _mm_storeu_pd(angle + k + 2, _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_src), 8)))); - } - } -#endif - - for( ; k < len; k++ ) - angle[k] = buf[0][k]; + hal::fastAtan64f(y, x, angle, len, angleInDegrees); } ptrs[0] += len*esz1; ptrs[1] += len*esz1; diff --git a/modules/core/src/mathfuncs_core.cpp b/modules/core/src/mathfuncs_core.cpp index 7b3ec319c9..de292fae94 100644 --- a/modules/core/src/mathfuncs_core.cpp +++ b/modules/core/src/mathfuncs_core.cpp @@ -42,116 +42,188 @@ #include "precomp.hpp" +using namespace std; + #undef HAVE_IPP -namespace cv { namespace hal { +namespace { -///////////////////////////////////// ATAN2 //////////////////////////////////// static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI); static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI); static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI); static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI); -void fastAtan2(const float *Y, const float *X, float *angle, int len, bool angleInDegrees ) -{ - int i = 0; - float scale = angleInDegrees ? 1 : (float)(CV_PI/180); +using namespace cv; -#ifdef HAVE_TEGRA_OPTIMIZATION - if (tegra::useTegra() && tegra::FastAtan2_32f(Y, X, angle, len, scale)) - return; +#if CV_SIMD128 + +template +struct v_atan +{ + typedef V_RegTrait128 Trait; + typedef typename Trait::reg VT; // vector type + enum { WorkWidth = VT::nlanes * 2 }; + + v_atan(const T & scale) + : s(Trait::all(scale)) + { + eps = Trait::all(DBL_EPSILON); + z = Trait::zero(); + p7 = Trait::all(atan2_p7); + p5 = Trait::all(atan2_p5); + p3 = Trait::all(atan2_p3); + p1 = Trait::all(atan2_p1); + val90 = Trait::all(90.f); + val180 = Trait::all(180.f); + val360 = Trait::all(360.f); + } + + inline int operator()(int len, const T * Y, const T * X, T * angle) + { + int i = 0; + const int c = VT::nlanes; + for ( ; i <= len - c * 2; i += c * 2) + { + VT x1 = v_load(X + i); + VT x2 = v_load(X + i + c); + VT y1 = v_load(Y + i); + VT y2 = v_load(Y + i + c); + v_store(&angle[i], s * one(x1, y1)); + v_store(&angle[i + c], s * one(x2, y2)); + } + return i; + } + +private: + inline VT one(VT & x, VT & y) + { + VT ax = v_abs(x); + VT ay = v_abs(y); + VT c = v_min(ax, ay) / (v_max(ax, ay) + eps); + VT cc = c * c; + VT a = (((p7 * cc + p5) * cc + p3) * cc + p1) * c; + a = v_select(ax >= ay, a, val90 - a); + a = v_select(x < z, val180 - a, a); + a = v_select(y < z, val360 - a, a); + return a; + } + +private: + VT eps; + VT z; + VT p7; + VT p5; + VT p3; + VT p1; + VT val90; + VT val180; + VT val360; + VT s; +}; + +#if !CV_SIMD128_64F + +// emulation +template <> +struct v_atan +{ + v_atan(double scale) : impl(static_cast(scale)) {} + inline int operator()(int len, const double * Y, const double * X, double * angle) + { + int i = 0; + const int c = v_atan::WorkWidth; + float bufY[c]; + float bufX[c]; + float bufA[c]; + for ( ; i <= len - c ; i += c) + { + for (int j = 0; j < c; ++j) + { + bufY[j] = static_cast(Y[i + j]); + bufX[j] = static_cast(X[i + j]); + } + impl(c, bufY, bufX, bufA); + for (int j = 0; j < c; ++j) + { + angle[i + j] = bufA[j]; + } + } + return i; + } +private: + v_atan impl; +}; #endif -#if CV_SSE2 - Cv32suf iabsmask; iabsmask.i = 0x7fffffff; - __m128 eps = _mm_set1_ps((float)DBL_EPSILON), absmask = _mm_set1_ps(iabsmask.f); - __m128 _90 = _mm_set1_ps(90.f), _180 = _mm_set1_ps(180.f), _360 = _mm_set1_ps(360.f); - __m128 z = _mm_setzero_ps(), scale4 = _mm_set1_ps(scale); - __m128 p1 = _mm_set1_ps(atan2_p1), p3 = _mm_set1_ps(atan2_p3); - __m128 p5 = _mm_set1_ps(atan2_p5), p7 = _mm_set1_ps(atan2_p7); +#endif - for( ; i <= len - 4; i += 4 ) +template +static inline T atanImpl(T y, T x) +{ + T ax = std::abs(x), ay = std::abs(y); + T a, c, c2; + if( ax >= ay ) { - __m128 x = _mm_loadu_ps(X + i), y = _mm_loadu_ps(Y + i); - __m128 ax = _mm_and_ps(x, absmask), ay = _mm_and_ps(y, absmask); - __m128 mask = _mm_cmplt_ps(ax, ay); - __m128 tmin = _mm_min_ps(ax, ay), tmax = _mm_max_ps(ax, ay); - __m128 c = _mm_div_ps(tmin, _mm_add_ps(tmax, eps)); - __m128 c2 = _mm_mul_ps(c, c); - __m128 a = _mm_mul_ps(c2, p7); - a = _mm_mul_ps(_mm_add_ps(a, p5), c2); - a = _mm_mul_ps(_mm_add_ps(a, p3), c2); - a = _mm_mul_ps(_mm_add_ps(a, p1), c); - - __m128 b = _mm_sub_ps(_90, a); - a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); - - b = _mm_sub_ps(_180, a); - mask = _mm_cmplt_ps(x, z); - a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); - - b = _mm_sub_ps(_360, a); - mask = _mm_cmplt_ps(y, z); - a = _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(a, b), mask)); - - a = _mm_mul_ps(a, scale4); - _mm_storeu_ps(angle + i, a); + c = ay/(ax + static_cast(DBL_EPSILON)); + c2 = c*c; + a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; } -#elif CV_NEON - float32x4_t eps = vdupq_n_f32((float)DBL_EPSILON); - float32x4_t _90 = vdupq_n_f32(90.f), _180 = vdupq_n_f32(180.f), _360 = vdupq_n_f32(360.f); - float32x4_t z = vdupq_n_f32(0.0f), scale4 = vdupq_n_f32(scale); - float32x4_t p1 = vdupq_n_f32(atan2_p1), p3 = vdupq_n_f32(atan2_p3); - float32x4_t p5 = vdupq_n_f32(atan2_p5), p7 = vdupq_n_f32(atan2_p7); - - for( ; i <= len - 4; i += 4 ) + else { - float32x4_t x = vld1q_f32(X + i), y = vld1q_f32(Y + i); - float32x4_t ax = vabsq_f32(x), ay = vabsq_f32(y); - float32x4_t tmin = vminq_f32(ax, ay), tmax = vmaxq_f32(ax, ay); - float32x4_t c = vmulq_f32(tmin, cv_vrecpq_f32(vaddq_f32(tmax, eps))); - float32x4_t c2 = vmulq_f32(c, c); - float32x4_t a = vmulq_f32(c2, p7); - a = vmulq_f32(vaddq_f32(a, p5), c2); - a = vmulq_f32(vaddq_f32(a, p3), c2); - a = vmulq_f32(vaddq_f32(a, p1), c); - - a = vbslq_f32(vcgeq_f32(ax, ay), a, vsubq_f32(_90, a)); - a = vbslq_f32(vcltq_f32(x, z), vsubq_f32(_180, a), a); - a = vbslq_f32(vcltq_f32(y, z), vsubq_f32(_360, a), a); - - vst1q_f32(angle + i, vmulq_f32(a, scale4)); + c = ax/(ay + static_cast(DBL_EPSILON)); + c2 = c*c; + a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; } + if( x < 0 ) + a = 180.f - a; + if( y < 0 ) + a = 360.f - a; + return a; +} + +template +static inline void atanImpl(const T *Y, const T *X, T *angle, int len, bool angleInDegrees) +{ + int i = 0; + T scale = angleInDegrees ? 1 : static_cast(CV_PI/180); + +#if CV_SIMD128 + i = v_atan(scale)(len, Y, X, angle); #endif for( ; i < len; i++ ) { - float x = X[i], y = Y[i]; - float ax = std::abs(x), ay = std::abs(y); - float a, c, c2; - if( ax >= ay ) - { - c = ay/(ax + (float)DBL_EPSILON); - c2 = c*c; - a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; - } - else - { - c = ax/(ay + (float)DBL_EPSILON); - c2 = c*c; - a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c; - } - if( x < 0 ) - a = 180.f - a; - if( y < 0 ) - a = 360.f - a; - angle[i] = (float)(a*scale); + angle[i] = atanImpl(Y[i], X[i]) * scale; } } +} // anonymous:: + +namespace cv { namespace hal { + +///////////////////////////////////// ATAN2 //////////////////////////////////// + +void fastAtan32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees ) +{ + CALL_HAL(fastAtan32f, cv_hal_fastAtan32f, Y, X, angle, len, angleInDegrees); + atanImpl(Y, X, angle, len, angleInDegrees); +} + +void fastAtan64f(const double *Y, const double *X, double *angle, int len, bool angleInDegrees) +{ + CALL_HAL(fastAtan64f, cv_hal_fastAtan64f, Y, X, angle, len, angleInDegrees); + atanImpl(Y, X, angle, len, angleInDegrees); +} + +// deprecated +void fastAtan2(const float *Y, const float *X, float *angle, int len, bool angleInDegrees ) +{ + fastAtan32f(Y, X, angle, len, angleInDegrees); +} void magnitude32f(const float* x, const float* y, float* mag, int len) { + CALL_HAL(magnitude32f, cv_hal_magnitude32f, x, y, mag, len); #if defined HAVE_IPP CV_IPP_CHECK() { @@ -188,6 +260,7 @@ void magnitude32f(const float* x, const float* y, float* mag, int len) void magnitude64f(const double* x, const double* y, double* mag, int len) { + CALL_HAL(magnitude64f, cv_hal_magnitude64f, x, y, mag, len); #if defined(HAVE_IPP) CV_IPP_CHECK() { @@ -225,6 +298,7 @@ void magnitude64f(const double* x, const double* y, double* mag, int len) void invSqrt32f(const float* src, float* dst, int len) { + CALL_HAL(invSqrt32f, cv_hal_invSqrt32f, src, dst, len); #if defined(HAVE_IPP) CV_IPP_CHECK() { @@ -256,6 +330,7 @@ void invSqrt32f(const float* src, float* dst, int len) void invSqrt64f(const double* src, double* dst, int len) { + CALL_HAL(invSqrt64f, cv_hal_invSqrt64f, src, dst, len); int i = 0; #if CV_SSE2 @@ -271,6 +346,7 @@ void invSqrt64f(const double* src, double* dst, int len) void sqrt32f(const float* src, float* dst, int len) { + CALL_HAL(sqrt32f, cv_hal_sqrt32f, src, dst, len); #if defined(HAVE_IPP) CV_IPP_CHECK() { @@ -302,6 +378,7 @@ void sqrt32f(const float* src, float* dst, int len) void sqrt64f(const double* src, double* dst, int len) { + CALL_HAL(sqrt64f, cv_hal_sqrt64f, src, dst, len); #if defined(HAVE_IPP) CV_IPP_CHECK() { @@ -433,6 +510,7 @@ static const double exp_max_val = 3000.*(1 << EXPTAB_SCALE); // log10(DBL_MAX) < void exp32f( const float *_x, float *y, int n ) { + CALL_HAL(exp32f, cv_hal_exp32f, _x, y, n); static const float A4 = (float)(1.000000000000002438532970795181890933776 / EXPPOLY_32F_A0), A3 = (float)(.6931471805521448196800669615864773144641 / EXPPOLY_32F_A0), @@ -632,6 +710,7 @@ void exp32f( const float *_x, float *y, int n ) void exp64f( const double *_x, double *y, int n ) { + CALL_HAL(exp64f, cv_hal_exp64f, _x, y, n); static const double A5 = .99999999999999999998285227504999 / EXPPOLY_32F_A0, A4 = .69314718055994546743029643825322 / EXPPOLY_32F_A0, @@ -1076,6 +1155,7 @@ static const double ln_2 = 0.69314718055994530941723212145818; void log32f( const float *_x, float *y, int n ) { + CALL_HAL(log32f, cv_hal_log32f, _x, y, n); static const float shift[] = { 0, -1.f/512 }; static const float A0 = 0.3333333333333333333333333f, @@ -1220,6 +1300,7 @@ void log32f( const float *_x, float *y, int n ) void log64f( const double *x, double *y, int n ) { + CALL_HAL(log64f, cv_hal_log64f, x, y, n); static const double shift[] = { 0, -1./512 }; static const double A7 = 1.0, @@ -1457,4 +1538,10 @@ void invSqrt(const double* src, double* dst, int len) } -}} // cv::hal:: +} // cv::hal:: +} // cv:: + +float cv::fastAtan2( float y, float x ) +{ + return atanImpl(y, x); +} diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index e3525752e5..339c6aed40 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -2718,19 +2718,25 @@ static bool ipp_norm(Mat &src, int normType, Mat &mask, double &result) ippiMaskNormFuncC3 ippFuncC3 = normType == NORM_INF ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR : +#if IPP_VERSION_X100 < 900 type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8s_C3CMR : +#endif type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR : 0) : normType == NORM_L1 ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR : +#if IPP_VERSION_X100 < 900 type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8s_C3CMR : +#endif type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_32f_C3CMR : 0) : normType == NORM_L2 || normType == NORM_L2SQR ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8u_C3CMR : +#if IPP_VERSION_X100 < 900 type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8s_C3CMR : +#endif type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_32f_C3CMR : 0) : 0; diff --git a/modules/core/test/test_intrin.cpp b/modules/core/test/test_intrin.cpp index 42b0cfcfd9..ca9d3dc7b7 100644 --- a/modules/core/test/test_intrin.cpp +++ b/modules/core/test/test_intrin.cpp @@ -69,8 +69,8 @@ template struct TheTest EXPECT_EQ(d, res); // zero, all - Data resZ = RegTrait::zero(); - Data resV = RegTrait::all(8); + Data resZ = V_RegTrait128::zero(); + Data resV = V_RegTrait128::all(8); for (int i = 0; i < R::nlanes; ++i) { EXPECT_EQ((LaneType)0, resZ[i]); @@ -135,7 +135,7 @@ template struct TheTest // v_expand and v_load_expand TheTest & test_expand() { - typedef typename RegTrait::w_reg Rx2; + typedef typename V_RegTrait128::w_reg Rx2; Data dataA; R a = dataA; @@ -158,7 +158,7 @@ template struct TheTest TheTest & test_expand_q() { - typedef typename RegTrait::q_reg Rx4; + typedef typename V_RegTrait128::q_reg Rx4; Data data; Data out = v_load_expand_q(data.d); const int n = Rx4::nlanes; @@ -232,7 +232,7 @@ template struct TheTest TheTest & test_mul_expand() { - typedef typename RegTrait::w_reg Rx2; + typedef typename V_RegTrait128::w_reg Rx2; Data dataA, dataB(2); R a = dataA, b = dataB; Rx2 c, d; @@ -295,7 +295,7 @@ template struct TheTest TheTest & test_dot_prod() { - typedef typename RegTrait::w_reg Rx2; + typedef typename V_RegTrait128::w_reg Rx2; Data dataA, dataB(2); R a = dataA, b = dataB; @@ -361,7 +361,7 @@ template struct TheTest TheTest & test_absdiff() { - typedef typename RegTrait::u_reg Ru; + typedef typename V_RegTrait128::u_reg Ru; typedef typename Ru::lane_type u_type; Data dataA(std::numeric_limits::max()), dataB(std::numeric_limits::min()); @@ -445,7 +445,7 @@ template struct TheTest template TheTest & test_pack() { - typedef typename RegTrait::w_reg Rx2; + typedef typename V_RegTrait128::w_reg Rx2; typedef typename Rx2::lane_type w_type; Data dataA, dataB; dataA += std::numeric_limits::is_signed ? -10 : 10; @@ -480,8 +480,8 @@ template struct TheTest template TheTest & test_pack_u() { - typedef typename RegTrait::w_reg Rx2; - typedef typename RegTrait::int_reg Ri2; + typedef typename V_TypeTraits::w_type LaneType_w; + typedef typename V_RegTrait128::int_reg Ri2; typedef typename Ri2::lane_type w_type; Data dataA, dataB; @@ -572,7 +572,7 @@ template struct TheTest TheTest & test_float_math() { - typedef typename RegTrait::int_reg Ri; + typedef typename V_RegTrait128::int_reg Ri; Data data1, data2, data3; data1 *= 1.1; data2 += 10; diff --git a/modules/core/test/test_intrin_utils.hpp b/modules/core/test/test_intrin_utils.hpp index a0eab56a53..1f8a78d98d 100644 --- a/modules/core/test/test_intrin_utils.hpp +++ b/modules/core/test/test_intrin_utils.hpp @@ -155,80 +155,4 @@ template std::ostream & operator<<(std::ostream & out, const Data struct RegTrait; - -template <> struct RegTrait { - typedef cv::v_uint16x8 w_reg; - typedef cv::v_uint32x4 q_reg; - typedef cv::v_uint8x16 u_reg; - static cv::v_uint8x16 zero() { return cv::v_setzero_u8(); } - static cv::v_uint8x16 all(uchar val) { return cv::v_setall_u8(val); } -}; -template <> struct RegTrait { - typedef cv::v_int16x8 w_reg; - typedef cv::v_int32x4 q_reg; - typedef cv::v_uint8x16 u_reg; - static cv::v_int8x16 zero() { return cv::v_setzero_s8(); } - static cv::v_int8x16 all(schar val) { return cv::v_setall_s8(val); } -}; - -template <> struct RegTrait { - typedef cv::v_uint32x4 w_reg; - typedef cv::v_int16x8 int_reg; - typedef cv::v_uint16x8 u_reg; - static cv::v_uint16x8 zero() { return cv::v_setzero_u16(); } - static cv::v_uint16x8 all(ushort val) { return cv::v_setall_u16(val); } -}; - -template <> struct RegTrait { - typedef cv::v_int32x4 w_reg; - typedef cv::v_uint16x8 u_reg; - static cv::v_int16x8 zero() { return cv::v_setzero_s16(); } - static cv::v_int16x8 all(short val) { return cv::v_setall_s16(val); } -}; - -template <> struct RegTrait { - typedef cv::v_uint64x2 w_reg; - typedef cv::v_int32x4 int_reg; - typedef cv::v_uint32x4 u_reg; - static cv::v_uint32x4 zero() { return cv::v_setzero_u32(); } - static cv::v_uint32x4 all(unsigned val) { return cv::v_setall_u32(val); } -}; - -template <> struct RegTrait { - typedef cv::v_int64x2 w_reg; - typedef cv::v_uint32x4 u_reg; - static cv::v_int32x4 zero() { return cv::v_setzero_s32(); } - static cv::v_int32x4 all(int val) { return cv::v_setall_s32(val); } -}; - -template <> struct RegTrait { - static cv::v_uint64x2 zero() { return cv::v_setzero_u64(); } - static cv::v_uint64x2 all(uint64 val) { return cv::v_setall_u64(val); } -}; - -template <> struct RegTrait { - static cv::v_int64x2 zero() { return cv::v_setzero_s64(); } - static cv::v_int64x2 all(int64 val) { return cv::v_setall_s64(val); } -}; - -template <> struct RegTrait { - typedef cv::v_int32x4 int_reg; - typedef cv::v_float32x4 u_reg; - static cv::v_float32x4 zero() { return cv::v_setzero_f32(); } - static cv::v_float32x4 all(float val) { return cv::v_setall_f32(val); } -}; - -#if CV_SIMD128_64F -template <> struct RegTrait { - typedef cv::v_int32x4 int_reg; - typedef cv::v_float64x2 u_reg; - static cv::v_float64x2 zero() { return cv::v_setzero_f64(); } - static cv::v_float64x2 all(double val) { return cv::v_setall_f64(val); } -}; - -#endif - #endif diff --git a/modules/core/test/test_math.cpp b/modules/core/test/test_math.cpp index 65e3861ed8..288c0c1f48 100644 --- a/modules/core/test/test_math.cpp +++ b/modules/core/test/test_math.cpp @@ -2411,8 +2411,9 @@ TEST(Core_SolvePoly, regression_5599) class Core_PhaseTest : public cvtest::BaseTest { + int t; public: - Core_PhaseTest() {} + Core_PhaseTest(int t_) : t(t_) {} ~Core_PhaseTest() {} protected: virtual void run(int) @@ -2421,9 +2422,9 @@ protected: const int axisCount = 8; const int dim = theRNG().uniform(1,10); const float scale = theRNG().uniform(1.f, 100.f); - Mat x(axisCount + 1, dim, CV_32FC1), - y(axisCount + 1, dim, CV_32FC1); - Mat anglesInDegrees(axisCount + 1, dim, CV_32FC1); + Mat x(axisCount + 1, dim, t), + y(axisCount + 1, dim, t); + Mat anglesInDegrees(axisCount + 1, dim, t); // fill the data x.row(0).setTo(Scalar(0)); @@ -2696,8 +2697,8 @@ TEST(Core_SVD, accuracy) { Core_SVDTest test; test.safe_run(); } TEST(Core_SVBkSb, accuracy) { Core_SVBkSbTest test; test.safe_run(); } TEST(Core_Trace, accuracy) { Core_TraceTest test; test.safe_run(); } TEST(Core_SolvePoly, accuracy) { Core_SolvePolyTest test; test.safe_run(); } -TEST(Core_Phase, accuracy) { Core_PhaseTest test; test.safe_run(); } - +TEST(Core_Phase, accuracy32f) { Core_PhaseTest test(CV_32FC1); test.safe_run(); } +TEST(Core_Phase, accuracy64f) { Core_PhaseTest test(CV_64FC1); test.safe_run(); } TEST(Core_SVD, flt) { diff --git a/modules/features2d/src/kaze/AKAZEFeatures.cpp b/modules/features2d/src/kaze/AKAZEFeatures.cpp index 6f1b610ccf..d5a0299440 100644 --- a/modules/features2d/src/kaze/AKAZEFeatures.cpp +++ b/modules/features2d/src/kaze/AKAZEFeatures.cpp @@ -812,7 +812,7 @@ void AKAZEFeatures::Compute_Main_Orientation(KeyPoint& kpt, const std::vector(float)(2.0*CV_PI) ? ang1 - (float)(5.0*CV_PI / 3.0) : ang1 + (float)(CV_PI / 3.0)); diff --git a/modules/imgproc/include/opencv2/imgproc/hal/hal.hpp b/modules/imgproc/include/opencv2/imgproc/hal/hal.hpp index 6ed492bcb6..0943a2dfa2 100644 --- a/modules/imgproc/include/opencv2/imgproc/hal/hal.hpp +++ b/modules/imgproc/include/opencv2/imgproc/hal/hal.hpp @@ -75,6 +75,108 @@ CV_EXPORTS void warpPerspectve(int src_type, uchar * dst_data, size_t dst_step, int dst_width, int dst_height, const double M[9], int interpolation, int borderType, const double borderValue[4]); +CV_EXPORTS void cvtBGRtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, int dcn, bool swapBlue); + +CV_EXPORTS void cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int scn, bool swapBlue, int greenBits); + +CV_EXPORTS void cvtBGR5x5toBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int dcn, bool swapBlue, int greenBits); + +CV_EXPORTS void cvtBGRtoGray(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue); + +CV_EXPORTS void cvtGraytoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn); + +CV_EXPORTS void cvtBGR5x5toGray(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int greenBits); + +CV_EXPORTS void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int greenBits); +CV_EXPORTS void cvtBGRtoYUV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isCbCr); + +CV_EXPORTS void cvtYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isCbCr); + +CV_EXPORTS void cvtBGRtoXYZ(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue); + +CV_EXPORTS void cvtXYZtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue); + +CV_EXPORTS void cvtBGRtoHSV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isFullRange, bool isHSV); + +CV_EXPORTS void cvtHSVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV); + +CV_EXPORTS void cvtBGRtoLab(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isLab, bool srgb); + +CV_EXPORTS void cvtLabtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isLab, bool srgb); + +CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int dst_width, int dst_height, + int dcn, bool swapBlue, int uIdx); + +CV_EXPORTS void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int dst_width, int dst_height, + int dcn, bool swapBlue, int uIdx); + +CV_EXPORTS void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int scn, bool swapBlue, int uIdx); + +CV_EXPORTS void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int dcn, bool swapBlue, int uIdx, int ycn); + +CV_EXPORTS void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height); + +CV_EXPORTS void cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height); + //! @} }} diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index 95197ec03c..cb71a13407 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -93,6 +93,7 @@ #include "precomp.hpp" #include "opencl_kernels_imgproc.hpp" #include +#include "hal_replacement.hpp" #define CV_DESCALE(x,n) (((x) + (1 << ((n)-1))) >> (n)) @@ -171,32 +172,38 @@ class CvtColorLoop_Invoker : public ParallelLoopBody typedef typename Cvt::channel_type _Tp; public: - CvtColorLoop_Invoker(const Mat& _src, Mat& _dst, const Cvt& _cvt) : - ParallelLoopBody(), src(_src), dst(_dst), cvt(_cvt) + CvtColorLoop_Invoker(const uchar * src_data_, size_t src_step_, uchar * dst_data_, size_t dst_step_, int width_, const Cvt& _cvt) : + ParallelLoopBody(), src_data(src_data_), src_step(src_step_), dst_data(dst_data_), dst_step(dst_step_), + width(width_), cvt(_cvt) { } virtual void operator()(const Range& range) const { - const uchar* yS = src.ptr(range.start); - uchar* yD = dst.ptr(range.start); + const uchar* yS = src_data + static_cast(range.start) * src_step; + uchar* yD = dst_data + static_cast(range.start) * dst_step; - for( int i = range.start; i < range.end; ++i, yS += src.step, yD += dst.step ) - cvt((const _Tp*)yS, (_Tp*)yD, src.cols); + for( int i = range.start; i < range.end; ++i, yS += src_step, yD += dst_step ) + cvt(reinterpret_cast(yS), reinterpret_cast<_Tp*>(yD), width); } private: - const Mat& src; - Mat& dst; + const uchar * src_data; + size_t src_step; + uchar * dst_data; + size_t dst_step; + int width; const Cvt& cvt; const CvtColorLoop_Invoker& operator= (const CvtColorLoop_Invoker&); }; template -void CvtColorLoop(const Mat& src, Mat& dst, const Cvt& cvt) +void CvtColorLoop(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt) { - parallel_for_(Range(0, src.rows), CvtColorLoop_Invoker(src, dst, cvt), src.total()/(double)(1<<16) ); + parallel_for_(Range(0, height), + CvtColorLoop_Invoker(src_data, src_step, dst_data, dst_step, width, cvt), + (width * height) / static_cast(1<<16)); } #if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700) @@ -211,17 +218,17 @@ class CvtColorIPPLoop_Invoker : { public: - CvtColorIPPLoop_Invoker(const Mat& _src, Mat& _dst, const Cvt& _cvt, bool *_ok) : - ParallelLoopBody(), src(_src), dst(_dst), cvt(_cvt), ok(_ok) + CvtColorIPPLoop_Invoker(const uchar * src_data_, size_t src_step_, uchar * dst_data_, size_t dst_step_, int width_, const Cvt& _cvt, bool *_ok) : + ParallelLoopBody(), src_data(src_data_), src_step(src_step_), dst_data(dst_data_), dst_step(dst_step_), width(width_), cvt(_cvt), ok(_ok) { *ok = true; } virtual void operator()(const Range& range) const { - const void *yS = src.ptr(range.start); - void *yD = dst.ptr(range.start); - if( !cvt(yS, (int)src.step[0], yD, (int)dst.step[0], src.cols, range.end - range.start) ) + const void *yS = src_data + src_step * range.start; + void *yD = dst_data + dst_step * range.start; + if( !cvt(yS, static_cast(src_step), yD, static_cast(dst_step), width, range.end - range.start) ) *ok = false; else { @@ -230,8 +237,11 @@ public: } private: - const Mat& src; - Mat& dst; + const uchar * src_data; + size_t src_step; + uchar * dst_data; + size_t dst_step; + int width; const Cvt& cvt; bool *ok; @@ -239,25 +249,28 @@ private: }; template -bool CvtColorIPPLoop(const Mat& src, Mat& dst, const Cvt& cvt) +bool CvtColorIPPLoop(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt) { bool ok; - parallel_for_(Range(0, src.rows), CvtColorIPPLoop_Invoker(src, dst, cvt, &ok), src.total()/(double)(1<<16) ); + parallel_for_(Range(0, height), CvtColorIPPLoop_Invoker(src_data, src_step, dst_data, dst_step, width, cvt, &ok), (width * height)/(double)(1<<16) ); return ok; } template -bool CvtColorIPPLoopCopy(Mat& src, Mat& dst, const Cvt& cvt) +bool CvtColorIPPLoopCopy(const uchar * src_data, size_t src_step, int src_type, uchar * dst_data, size_t dst_step, int width, int height, const Cvt& cvt) { Mat temp; - Mat &source = src; - if( src.data == dst.data ) + Mat src(Size(width, height), src_type, const_cast(src_data), src_step); + Mat source = src; + if( src_data == dst_data ) { src.copyTo(temp); source = temp; } bool ok; - parallel_for_(Range(0, source.rows), CvtColorIPPLoop_Invoker(source, dst, cvt, &ok), + parallel_for_(Range(0, source.rows), + CvtColorIPPLoop_Invoker(source.data, source.step, dst_data, dst_step, + source.cols, cvt, &ok), source.total()/(double)(1<<16) ); return ok; } @@ -354,11 +367,13 @@ static ippiGeneralFunc ippiXYZ2RGBTab[] = 0, (ippiGeneralFunc)ippiXYZToRGB_32f_C3R, 0, 0 }; +#if IPP_DISABLE_BLOCK static ippiGeneralFunc ippiRGB2HSVTab[] = { (ippiGeneralFunc)ippiRGBToHSV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHSV_16u_C3R, 0, 0, 0, 0, 0 }; +#endif static ippiGeneralFunc ippiHSV2RGBTab[] = { @@ -6106,12 +6121,14 @@ const int ITUR_BT_601_CBV = -74448; template struct YUV420sp2RGB888Invoker : ParallelLoopBody { - Mat* dst; + uchar * dst_data; + size_t dst_step; + int width; const uchar* my1, *muv; - int width, stride; + size_t stride; - YUV420sp2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv) - : dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {} + YUV420sp2RGB888Invoker(uchar * _dst_data, size_t _dst_step, int _dst_width, size_t _stride, const uchar* _y1, const uchar* _uv) + : dst_data(_dst_data), dst_step(_dst_step), width(_dst_width), my1(_y1), muv(_uv), stride(_stride) {} void operator()(const Range& range) const { @@ -6128,15 +6145,10 @@ struct YUV420sp2RGB888Invoker : ParallelLoopBody const uchar* y1 = my1 + rangeBegin * stride, *uv = muv + rangeBegin * stride / 2; -#ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtYUV4202RGB(bIdx, uIdx, 3, y1, uv, stride, dst->ptr(rangeBegin), dst->step, rangeEnd - rangeBegin, dst->cols)) - return; -#endif - for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, uv += stride) { - uchar* row1 = dst->ptr(j); - uchar* row2 = dst->ptr(j + 1); + uchar* row1 = dst_data + dst_step * j; + uchar* row2 = dst_data + dst_step * (j + 1); const uchar* y2 = y1 + stride; for (int i = 0; i < width; i += 2, row1 += 6, row2 += 6) @@ -6175,12 +6187,14 @@ struct YUV420sp2RGB888Invoker : ParallelLoopBody template struct YUV420sp2RGBA8888Invoker : ParallelLoopBody { - Mat* dst; + uchar * dst_data; + size_t dst_step; + int width; const uchar* my1, *muv; - int width, stride; + size_t stride; - YUV420sp2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv) - : dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {} + YUV420sp2RGBA8888Invoker(uchar * _dst_data, size_t _dst_step, int _dst_width, size_t _stride, const uchar* _y1, const uchar* _uv) + : dst_data(_dst_data), dst_step(_dst_step), width(_dst_width), my1(_y1), muv(_uv), stride(_stride) {} void operator()(const Range& range) const { @@ -6197,15 +6211,10 @@ struct YUV420sp2RGBA8888Invoker : ParallelLoopBody const uchar* y1 = my1 + rangeBegin * stride, *uv = muv + rangeBegin * stride / 2; -#ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtYUV4202RGB(bIdx, uIdx, 4, y1, uv, stride, dst->ptr(rangeBegin), dst->step, rangeEnd - rangeBegin, dst->cols)) - return; -#endif - for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, uv += stride) { - uchar* row1 = dst->ptr(j); - uchar* row2 = dst->ptr(j + 1); + uchar* row1 = dst_data + dst_step * j; + uchar* row2 = dst_data + dst_step * (j + 1); const uchar* y2 = y1 + stride; for (int i = 0; i < width; i += 2, row1 += 8, row2 += 8) @@ -6248,20 +6257,22 @@ struct YUV420sp2RGBA8888Invoker : ParallelLoopBody template struct YUV420p2RGB888Invoker : ParallelLoopBody { - Mat* dst; + uchar * dst_data; + size_t dst_step; + int width; const uchar* my1, *mu, *mv; - int width, stride; + size_t stride; int ustepIdx, vstepIdx; - YUV420p2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx) - : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {} + YUV420p2RGB888Invoker(uchar * _dst_data, size_t _dst_step, int _dst_width, size_t _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx) + : dst_data(_dst_data), dst_step(_dst_step), width(_dst_width), my1(_y1), mu(_u), mv(_v), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {} void operator()(const Range& range) const { const int rangeBegin = range.start * 2; const int rangeEnd = range.end * 2; - int uvsteps[2] = {width/2, stride - width/2}; + int uvsteps[2] = {width/2, static_cast(stride) - width/2}; int usIdx = ustepIdx, vsIdx = vstepIdx; const uchar* y1 = my1 + rangeBegin * stride; @@ -6276,8 +6287,8 @@ struct YUV420p2RGB888Invoker : ParallelLoopBody for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += uvsteps[(usIdx++) & 1], v1 += uvsteps[(vsIdx++) & 1]) { - uchar* row1 = dst->ptr(j); - uchar* row2 = dst->ptr(j + 1); + uchar* row1 = dst_data + dst_step * j; + uchar* row2 = dst_data + dst_step * (j + 1); const uchar* y2 = y1 + stride; for (int i = 0; i < width / 2; i += 1, row1 += 6, row2 += 6) @@ -6316,20 +6327,22 @@ struct YUV420p2RGB888Invoker : ParallelLoopBody template struct YUV420p2RGBA8888Invoker : ParallelLoopBody { - Mat* dst; + uchar * dst_data; + size_t dst_step; + int width; const uchar* my1, *mu, *mv; - int width, stride; + size_t stride; int ustepIdx, vstepIdx; - YUV420p2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx) - : dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {} + YUV420p2RGBA8888Invoker(uchar * _dst_data, size_t _dst_step, int _dst_width, size_t _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int _ustepIdx, int _vstepIdx) + : dst_data(_dst_data), dst_step(_dst_step), width(_dst_width), my1(_y1), mu(_u), mv(_v), stride(_stride), ustepIdx(_ustepIdx), vstepIdx(_vstepIdx) {} void operator()(const Range& range) const { int rangeBegin = range.start * 2; int rangeEnd = range.end * 2; - int uvsteps[2] = {width/2, stride - width/2}; + int uvsteps[2] = {width/2, static_cast(stride) - width/2}; int usIdx = ustepIdx, vsIdx = vstepIdx; const uchar* y1 = my1 + rangeBegin * stride; @@ -6344,8 +6357,8 @@ struct YUV420p2RGBA8888Invoker : ParallelLoopBody for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += uvsteps[(usIdx++) & 1], v1 += uvsteps[(vsIdx++) & 1]) { - uchar* row1 = dst->ptr(j); - uchar* row2 = dst->ptr(j + 1); + uchar* row1 = dst_data + dst_step * j; + uchar* row2 = dst_data + dst_step * (j + 1); const uchar* y2 = y1 + stride; for (int i = 0; i < width / 2; i += 1, row1 += 8, row2 += 8) @@ -6388,70 +6401,78 @@ struct YUV420p2RGBA8888Invoker : ParallelLoopBody #define MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION (320*240) template -inline void cvtYUV420sp2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv) +inline void cvtYUV420sp2RGB(uchar * dst_data, size_t dst_step, int dst_width, int dst_height, size_t _stride, const uchar* _y1, const uchar* _uv) { - YUV420sp2RGB888Invoker converter(&_dst, _stride, _y1, _uv); - if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) - parallel_for_(Range(0, _dst.rows/2), converter); + YUV420sp2RGB888Invoker converter(dst_data, dst_step, dst_width, _stride, _y1, _uv); + if (dst_width * dst_height >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for_(Range(0, dst_height/2), converter); else - converter(Range(0, _dst.rows/2)); + converter(Range(0, dst_height/2)); } template -inline void cvtYUV420sp2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv) +inline void cvtYUV420sp2RGBA(uchar * dst_data, size_t dst_step, int dst_width, int dst_height, size_t _stride, const uchar* _y1, const uchar* _uv) { - YUV420sp2RGBA8888Invoker converter(&_dst, _stride, _y1, _uv); - if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) - parallel_for_(Range(0, _dst.rows/2), converter); + YUV420sp2RGBA8888Invoker converter(dst_data, dst_step, dst_width, _stride, _y1, _uv); + if (dst_width * dst_height >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for_(Range(0, dst_height/2), converter); else - converter(Range(0, _dst.rows/2)); + converter(Range(0, dst_height/2)); } template -inline void cvtYUV420p2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx) +inline void cvtYUV420p2RGB(uchar * dst_data, size_t dst_step, int dst_width, int dst_height, size_t _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx) { - YUV420p2RGB888Invoker converter(&_dst, _stride, _y1, _u, _v, ustepIdx, vstepIdx); - if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) - parallel_for_(Range(0, _dst.rows/2), converter); + YUV420p2RGB888Invoker converter(dst_data, dst_step, dst_width, _stride, _y1, _u, _v, ustepIdx, vstepIdx); + if (dst_width * dst_height >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for_(Range(0, dst_height/2), converter); else - converter(Range(0, _dst.rows/2)); + converter(Range(0, dst_height/2)); } template -inline void cvtYUV420p2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx) +inline void cvtYUV420p2RGBA(uchar * dst_data, size_t dst_step, int dst_width, int dst_height, size_t _stride, const uchar* _y1, const uchar* _u, const uchar* _v, int ustepIdx, int vstepIdx) { - YUV420p2RGBA8888Invoker converter(&_dst, _stride, _y1, _u, _v, ustepIdx, vstepIdx); - if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) - parallel_for_(Range(0, _dst.rows/2), converter); + YUV420p2RGBA8888Invoker converter(dst_data, dst_step, dst_width, _stride, _y1, _u, _v, ustepIdx, vstepIdx); + if (dst_width * dst_height >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION) + parallel_for_(Range(0, dst_height/2), converter); else - converter(Range(0, _dst.rows/2)); + converter(Range(0, dst_height/2)); } ///////////////////////////////////// RGB -> YUV420p ///////////////////////////////////// -template +template +inline void swapUV(uchar * &, uchar * &) {} +template<> +inline void swapUV<2>(uchar * & u, uchar * & v) { std::swap(u, v); } + +template struct RGB888toYUV420pInvoker: public ParallelLoopBody { - RGB888toYUV420pInvoker( const Mat& src, Mat* dst, const int uIdx ) - : src_(src), - dst_(dst), - uIdx_(uIdx) { } + RGB888toYUV420pInvoker(const uchar * _src_data, size_t _src_step, uchar * _dst_data, size_t _dst_step, + int _src_width, int _src_height, int _scn) + : src_data(_src_data), src_step(_src_step), + dst_data(_dst_data), dst_step(_dst_step), + src_width(_src_width), src_height(_src_height), + scn(_scn) { } void operator()(const Range& rowRange) const { - const int w = src_.cols; - const int h = src_.rows; + const int w = src_width; + const int h = src_height; - const int cn = src_.channels(); + const int cn = scn; for( int i = rowRange.start; i < rowRange.end; i++ ) { - const uchar* row0 = src_.ptr(2 * i); - const uchar* row1 = src_.ptr(2 * i + 1); + const uchar* row0 = src_data + src_step * (2 * i); + const uchar* row1 = src_data + src_step * (2 * i + 1); - uchar* y = dst_->ptr(2*i); - uchar* u = dst_->ptr(h + i/2) + (i % 2) * (w/2); - uchar* v = dst_->ptr(h + (i + h/2)/2) + ((i + h/2) % 2) * (w/2); - if( uIdx_ == 2 ) std::swap(u, v); + uchar* y = dst_data + dst_step * (2*i); + uchar* u = dst_data + dst_step * (h + i/2) + (i % 2) * (w/2); + uchar* v = dst_data + dst_step * (h + (i + h/2)/2) + ((i + h/2) % 2) * (w/2); + + swapUV(u, v); for( int j = 0, k = 0; j < w * cn; j += 2 * cn, k++ ) { @@ -6469,8 +6490,8 @@ struct RGB888toYUV420pInvoker: public ParallelLoopBody y[2*k + 0] = saturate_cast(y00 >> ITUR_BT_601_SHIFT); y[2*k + 1] = saturate_cast(y01 >> ITUR_BT_601_SHIFT); - y[2*k + dst_->step + 0] = saturate_cast(y10 >> ITUR_BT_601_SHIFT); - y[2*k + dst_->step + 1] = saturate_cast(y11 >> ITUR_BT_601_SHIFT); + y[2*k + dst_step + 0] = saturate_cast(y10 >> ITUR_BT_601_SHIFT); + y[2*k + dst_step + 1] = saturate_cast(y11 >> ITUR_BT_601_SHIFT); const int shifted128 = (128 << ITUR_BT_601_SHIFT); int u00 = ITUR_BT_601_CRU * r00 + ITUR_BT_601_CGU * g00 + ITUR_BT_601_CBU * b00 + halfShift + shifted128; @@ -6482,27 +6503,33 @@ struct RGB888toYUV420pInvoker: public ParallelLoopBody } } - static bool isFit( const Mat& src ) + static bool isFit( int src_width, int src_height ) { - return (src.total() >= 320*240); + return (src_width * src_height >= 320*240); } private: RGB888toYUV420pInvoker& operator=(const RGB888toYUV420pInvoker&); - const Mat& src_; - Mat* const dst_; - const int uIdx_; + const uchar * src_data; + size_t src_step; + uchar * dst_data; + size_t dst_step; + int src_width; + int src_height; + const int scn; }; template -static void cvtRGBtoYUV420p(const Mat& src, Mat& dst) +static void cvtRGBtoYUV420p(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int src_width, int src_height, int scn) { - RGB888toYUV420pInvoker colorConverter(src, &dst, uIdx); - if( RGB888toYUV420pInvoker::isFit(src) ) - parallel_for_(Range(0, src.rows/2), colorConverter); + RGB888toYUV420pInvoker colorConverter(src_data, src_step, dst_data, dst_step, src_width, src_height, scn); + if( RGB888toYUV420pInvoker::isFit(src_width, src_height) ) + parallel_for_(Range(0, src_height/2), colorConverter); else - colorConverter(Range(0, src.rows/2)); + colorConverter(Range(0, src_height/2)); } ///////////////////////////////////// YUV422 -> RGB ///////////////////////////////////// @@ -6510,12 +6537,16 @@ static void cvtRGBtoYUV420p(const Mat& src, Mat& dst) template struct YUV422toRGB888Invoker : ParallelLoopBody { - Mat* dst; - const uchar* src; - int width, stride; + uchar * dst_data; + size_t dst_step; + const uchar * src_data; + size_t src_step; + int width; - YUV422toRGB888Invoker(Mat* _dst, int _stride, const uchar* _yuv) - : dst(_dst), src(_yuv), width(_dst->cols), stride(_stride) {} + YUV422toRGB888Invoker(uchar * _dst_data, size_t _dst_step, + const uchar * _src_data, size_t _src_step, + int _width) + : dst_data(_dst_data), dst_step(_dst_step), src_data(_src_data), src_step(_src_step), width(_width) {} void operator()(const Range& range) const { @@ -6524,11 +6555,11 @@ struct YUV422toRGB888Invoker : ParallelLoopBody const int uidx = 1 - yIdx + uIdx * 2; const int vidx = (2 + uidx) % 4; - const uchar* yuv_src = src + rangeBegin * stride; + const uchar* yuv_src = src_data + rangeBegin * src_step; - for (int j = rangeBegin; j < rangeEnd; j++, yuv_src += stride) + for (int j = rangeBegin; j < rangeEnd; j++, yuv_src += src_step) { - uchar* row = dst->ptr(j); + uchar* row = dst_data + dst_step * j; for (int i = 0; i < 2 * width; i += 4, row += 6) { @@ -6556,12 +6587,16 @@ struct YUV422toRGB888Invoker : ParallelLoopBody template struct YUV422toRGBA8888Invoker : ParallelLoopBody { - Mat* dst; - const uchar* src; - int width, stride; + uchar * dst_data; + size_t dst_step; + const uchar * src_data; + size_t src_step; + int width; - YUV422toRGBA8888Invoker(Mat* _dst, int _stride, const uchar* _yuv) - : dst(_dst), src(_yuv), width(_dst->cols), stride(_stride) {} + YUV422toRGBA8888Invoker(uchar * _dst_data, size_t _dst_step, + const uchar * _src_data, size_t _src_step, + int _width) + : dst_data(_dst_data), dst_step(_dst_step), src_data(_src_data), src_step(_src_step), width(_width) {} void operator()(const Range& range) const { @@ -6570,11 +6605,11 @@ struct YUV422toRGBA8888Invoker : ParallelLoopBody const int uidx = 1 - yIdx + uIdx * 2; const int vidx = (2 + uidx) % 4; - const uchar* yuv_src = src + rangeBegin * stride; + const uchar* yuv_src = src_data + rangeBegin * src_step; - for (int j = rangeBegin; j < rangeEnd; j++, yuv_src += stride) + for (int j = rangeBegin; j < rangeEnd; j++, yuv_src += src_step) { - uchar* row = dst->ptr(j); + uchar* row = dst_data + dst_step * j; for (int i = 0; i < 2 * width; i += 4, row += 8) { @@ -6604,23 +6639,25 @@ struct YUV422toRGBA8888Invoker : ParallelLoopBody #define MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION (320*240) template -inline void cvtYUV422toRGB(Mat& _dst, int _stride, const uchar* _yuv) +inline void cvtYUV422toRGB(uchar * dst_data, size_t dst_step, const uchar * src_data, size_t src_step, + int width, int height) { - YUV422toRGB888Invoker converter(&_dst, _stride, _yuv); - if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION) - parallel_for_(Range(0, _dst.rows), converter); + YUV422toRGB888Invoker converter(dst_data, dst_step, src_data, src_step, width); + if (width * height >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION) + parallel_for_(Range(0, height), converter); else - converter(Range(0, _dst.rows)); + converter(Range(0, height)); } template -inline void cvtYUV422toRGBA(Mat& _dst, int _stride, const uchar* _yuv) +inline void cvtYUV422toRGBA(uchar * dst_data, size_t dst_step, const uchar * src_data, size_t src_step, + int width, int height) { - YUV422toRGBA8888Invoker converter(&_dst, _stride, _yuv); - if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION) - parallel_for_(Range(0, _dst.rows), converter); + YUV422toRGBA8888Invoker converter(dst_data, dst_step, src_data, src_step, width); + if (width * height >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION) + parallel_for_(Range(0, height), converter); else - converter(Range(0, _dst.rows)); + converter(Range(0, height)); } /////////////////////////// RGBA <-> mRGBA (alpha premultiplied) ////////////// @@ -7324,598 +7361,1025 @@ static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) #endif -#ifdef HAVE_IPP -static bool ipp_cvtColor( Mat &src, OutputArray _dst, int code, int dcn ) +} + +// +// HAL functions +// + +namespace cv { +namespace hal { + +// 8u, 16u, 32f +void cvtBGRtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, int dcn, bool swapBlue) { - int stype = src.type(); - int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype); + CALL_HAL(cvtBGRtoBGR, cv_hal_cvtBGRtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, scn, dcn, swapBlue); - Mat dst; - Size sz = src.size(); - - switch( code ) +#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700 + CV_IPP_CHECK() { -#if IPP_VERSION_X100 >= 700 - case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR: - case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA: - CV_Assert( scn == 3 || scn == 4 ); - dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3; - _dst.create( sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( code == CV_BGR2BGRA) - { - if ( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 0, 1, 2)) ) - return true; - } - else if( code == CV_BGRA2BGR ) - { - if ( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiCopyAC4C3RTab[depth])) ) - return true; - } - else if( code == CV_BGR2RGBA ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 2, 1, 0)) ) - return true; - } - else if( code == CV_RGBA2BGR ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC4C3RTab[depth], 2, 1, 0)) ) - return true; - } - else if( code == CV_RGB2BGR ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderFunctor(ippiSwapChannelsC3RTab[depth], 2, 1, 0)) ) - return true; - } + if(scn == 3 && dcn == 4 && !swapBlue) + { + if ( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 0, 1, 2)) ) + return; + } + else if(scn == 4 && dcn == 3 && !swapBlue) + { + if ( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiCopyAC4C3RTab[depth])) ) + return; + } + else if(scn == 3 && dcn == 4 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 2, 1, 0)) ) + return; + } + else if(scn == 4 && dcn == 3 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderFunctor(ippiSwapChannelsC4C3RTab[depth], 2, 1, 0)) ) + return; + } + else if(scn == 3 && dcn == 3 && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height, + IPPReorderFunctor(ippiSwapChannelsC3RTab[depth], 2, 1, 0)) ) + return; + } #if IPP_VERSION_X100 >= 810 - else if( code == CV_RGBA2BGRA ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderFunctor(ippiSwapChannelsC4RTab[depth], 2, 1, 0)) ) - return true; - } + else if(scn == 4 && dcn == 4 && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height, + IPPReorderFunctor(ippiSwapChannelsC4RTab[depth], 2, 1, 0)) ) + return; + } + } #endif - return false; #endif + int blueIdx = swapBlue ? 2 : 0; + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB(scn, dcn, blueIdx)); + else if( depth == CV_16U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB(scn, dcn, blueIdx)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB(scn, dcn, blueIdx)); +} + +// only 8u +void cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int scn, bool swapBlue, int greenBits) +{ + CALL_HAL(cvtBGRtoBGR5x5, cv_hal_cvtBGRtoBGR5x5, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, greenBits); + +#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK // breaks OCL accuracy tests + CV_IPP_CHECK() + { + CV_SUPPRESS_DEPRECATED_START; + if (scn == 3 && greenBits == 6 && !swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R))) + return; + } + else if (scn == 4 && greenBits == 6 && !swapBlue) + { + if (CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(CV_8U, scn), dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[CV_8U], + (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 0, 1, 2, CV_8U))) + return; + } + else if (scn == 3 && greenBits == 6 && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(CV_8U, scn), dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[CV_8U], + (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, CV_8U)) ) + return; + } + else if (scn == 4 && greenBits == 6 && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(CV_8U, scn), dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[CV_8U], + (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, CV_8U)) ) + return; + } + CV_SUPPRESS_DEPRECATED_END; + } +#endif + + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB5x5(scn, swapBlue ? 2 : 0, greenBits)); +} + +// only 8u +void cvtBGR5x5toBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int dcn, bool swapBlue, int greenBits) +{ + CALL_HAL(cvtBGR5x5toBGR, cv_hal_cvtBGR5x5toBGR, src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, greenBits); + +#if defined(HAVE_IPP) && IPP_VERSION_X100 < 900 + CV_IPP_CHECK() + { + CV_SUPPRESS_DEPRECATED_START; + if (dcn == 3 && greenBits == 6 && !swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R))) + return; + } + else if (dcn == 3 && greenBits == 6 && swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, + ippiSwapChannelsC3RTab[CV_8U], 2, 1, 0, CV_8U))) + return; + } + else if (dcn == 4 && greenBits == 6 && !swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, + ippiSwapChannelsC3C4RTab[CV_8U], 0, 1, 2, CV_8U))) + return; + } + else if (dcn == 4 && greenBits == 6 && swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, + ippiSwapChannelsC3C4RTab[CV_8U], 2, 1, 0, CV_8U))) + return; + } + CV_SUPPRESS_DEPRECATED_END; + } +#endif + + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB5x52RGB(dcn, swapBlue ? 2 : 0, greenBits)); +} + +// 8u, 16u, 32f +void cvtBGRtoGray(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue) +{ + CALL_HAL(cvtBGRtoGray, cv_hal_cvtBGRtoGray, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue); + +#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700 + CV_IPP_CHECK() + { + if(depth == CV_32F && scn == 3 && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) ) + return; + } + else if(depth == CV_32F && scn == 3 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) ) + return; + } + else if(depth == CV_32F && scn == 4 && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) ) + return; + } + else if(depth == CV_32F && scn == 4 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) ) + return; + } + } +#endif + + int blueIdx = swapBlue ? 2 : 0; + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray(scn, blueIdx, 0)); + else if( depth == CV_16U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray(scn, blueIdx, 0)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray(scn, blueIdx, 0)); +} + +// 8u, 16u, 32f +void cvtGraytoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn) +{ + CALL_HAL(cvtGraytoBGR, cv_hal_cvtGraytoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn); + +#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700 + CV_IPP_CHECK() + { + if(dcn == 3) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGray2BGRFunctor(ippiCopyP3C3RTab[depth])) ) + return; + } + else if(dcn == 4) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGray2BGRAFunctor(ippiCopyP3C3RTab[depth], ippiSwapChannelsC3C4RTab[depth], depth)) ) + return; + } + } +#endif + + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB(dcn)); + else if( depth == CV_16U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB(dcn)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB(dcn)); +} + +// only 8u +void cvtBGR5x5toGray(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int greenBits) +{ + CALL_HAL(cvtBGR5x5toGray, cv_hal_cvtBGR5x5toGray, src_data, src_step, dst_data, dst_step, width, height, greenBits); + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB5x52Gray(greenBits)); +} + +// only 8u +void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int greenBits) +{ + CALL_HAL(cvtGraytoBGR5x5, cv_hal_cvtGraytoBGR5x5, src_data, src_step, dst_data, dst_step, width, height, greenBits); + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB5x5(greenBits)); +} + +// 8u, 16u, 32f +void cvtBGRtoYUV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isCbCr) +{ + CALL_HAL(cvtBGRtoYUV, cv_hal_cvtBGRtoYUV, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isCbCr); + +#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK + CV_IPP_CHECK() + { + if (scn == 3 && depth == CV_8U && swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor((ippiGeneralFunc)ippiRGBToYUV_8u_C3R))) + return; + } + else if (scn == 3 && depth == CV_8U && !swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], + (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) + return; + } + else if (scn == 4 && depth == CV_8U && swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 0, 1, 2, depth))) + return; + } + else if (scn == 4 && depth == CV_8U && !swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) + return; + } + } +#endif + + static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; + static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 }; + const float* coeffs_f = isCbCr ? 0 : yuv_f; + const int* coeffs_i = isCbCr ? 0 : yuv_i; + int blueIdx = swapBlue ? 2 : 0; + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_i(scn, blueIdx, coeffs_i)); + else if( depth == CV_16U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_i(scn, blueIdx, coeffs_i)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_f(scn, blueIdx, coeffs_f)); +} + +void cvtYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isCbCr) +{ + CALL_HAL(cvtYUVtoBGR, cv_hal_cvtYUVtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isCbCr); + + +#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK + CV_IPP_CHECK() + { + if (dcn == 3 && depth == CV_8U && swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R))) + return; + } + else if (dcn == 3 && depth == CV_8U && !swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, + ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth))) + return; + } + else if (dcn == 4 && depth == CV_8U && swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth))) + return; + } + else if (dcn == 4 && depth == CV_8U && !swapBlue && !isCbCr) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth))) + return; + } + } +#endif + + static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f }; + static const int yuv_i[] = { 33292, -6472, -9519, 18678 }; + const float* coeffs_f = isCbCr ? 0 : yuv_f; + const int* coeffs_i = isCbCr ? 0 : yuv_i; + int blueIdx = swapBlue ? 2 : 0; + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_i(dcn, blueIdx, coeffs_i)); + else if( depth == CV_16U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_i(dcn, blueIdx, coeffs_i)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_f(dcn, blueIdx, coeffs_f)); +} + +void cvtBGRtoXYZ(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue) +{ + CALL_HAL(cvtBGRtoXYZ, cv_hal_cvtBGRtoXYZ, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue); + +#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700 + CV_IPP_CHECK() + { + if(scn == 3 && depth != CV_32F && !swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) + return; + } + else if(scn == 4 && depth != CV_32F && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) + return; + } + else if(scn == 3 && depth != CV_32F && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiRGB2XYZTab[depth])) ) + return; + } + else if(scn == 4 && depth != CV_32F && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 0, 1, 2, depth)) ) + return; + } + } +#endif + + int blueIdx = swapBlue ? 2 : 0; + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2XYZ_i(scn, blueIdx, 0)); + else if( depth == CV_16U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2XYZ_i(scn, blueIdx, 0)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2XYZ_f(scn, blueIdx, 0)); +} + +void cvtXYZtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue) +{ + CALL_HAL(cvtXYZtoBGR, cv_hal_cvtXYZtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue); + +#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700 + CV_IPP_CHECK() + { + if(dcn == 3 && depth != CV_32F && !swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return; + } + else if(dcn == 4 && depth != CV_32F && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return; + } + if(dcn == 3 && depth != CV_32F && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiXYZ2RGBTab[depth])) ) + return; + } + else if(dcn == 4 && depth != CV_32F && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return; + } + } +#endif + + int blueIdx = swapBlue ? 2 : 0; + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, XYZ2RGB_i(dcn, blueIdx, 0)); + else if( depth == CV_16U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, XYZ2RGB_i(dcn, blueIdx, 0)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, XYZ2RGB_f(dcn, blueIdx, 0)); +} + +// 8u, 32f +void cvtBGRtoHSV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isFullRange, bool isHSV) +{ + CALL_HAL(cvtBGRtoHSV, cv_hal_cvtBGRtoHSV, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isFullRange, isHSV); + +#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700 + CV_IPP_CHECK() + { + if (depth == CV_8U && isFullRange) + { + if (isHSV) + { #if IPP_DISABLE_BLOCK // breaks OCL accuracy tests - case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555: - case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555: - CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U ); - _dst.create(sz, CV_8UC2); - dst = _dst.getMat(); - - CV_SUPPRESS_DEPRECATED_START - - if (code == CV_BGR2BGR565 && scn == 3) + if(scn == 3 && !swapBlue) { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R))) - return true; + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) + return; } - else if (code == CV_BGRA2BGR565 && scn == 4) + else if(scn == 4 && !swapBlue) { - if (CvtColorIPPLoopCopy(src, dst, - IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 0, 1, 2, depth))) - return true; + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) + return; } - else if (code == CV_RGB2BGR565 && scn == 3) + else if(scn == 4 && swapBlue) { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, depth)) ) - return true; + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) ) + return; } - else if (code == CV_RGBA2BGR565 && scn == 4) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, depth)) ) - return true; - } - CV_SUPPRESS_DEPRECATED_END - return false; #endif - -#if IPP_VERSION_X100 < 900 - case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652RGB: case CV_BGR5552RGB: - case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA: - if(dcn <= 0) dcn = (code==CV_BGR5652BGRA || code==CV_BGR5552BGRA || code==CV_BGR5652RGBA || code==CV_BGR5552RGBA) ? 4 : 3; - CV_Assert( (dcn == 3 || dcn == 4) && scn == 2 && depth == CV_8U ); - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - CV_SUPPRESS_DEPRECATED_START - if (code == CV_BGR5652BGR && dcn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R))) - return true; - } - else if (code == CV_BGR5652RGB && dcn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth))) - return true; - } - else if (code == CV_BGR5652BGRA && dcn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth))) - return true; - } - else if (code == CV_BGR5652RGBA && dcn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth))) - return true; - } - CV_SUPPRESS_DEPRECATED_END - return false; -#endif - -#if IPP_VERSION_X100 >= 700 - case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY: - CV_Assert( scn == 3 || scn == 4 ); - _dst.create(sz, CV_MAKETYPE(depth, 1)); - dst = _dst.getMat(); - - if( code == CV_BGR2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) ) - return true; - } - else if( code == CV_RGB2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) ) - return true; - } - else if( code == CV_BGRA2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) ) - return true; - } - else if( code == CV_RGBA2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) ) - return true; - } - return false; - - case CV_GRAY2BGR: case CV_GRAY2BGRA: - if( dcn <= 0 ) dcn = (code==CV_GRAY2BGRA) ? 4 : 3; - CV_Assert( scn == 1 && (dcn == 3 || dcn == 4)); - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( code == CV_GRAY2BGR ) - { - if( CvtColorIPPLoop(src, dst, IPPGray2BGRFunctor(ippiCopyP3C3RTab[depth])) ) - return true; - } - else if( code == CV_GRAY2BGRA ) - { - if( CvtColorIPPLoop(src, dst, IPPGray2BGRAFunctor(ippiCopyP3C3RTab[depth], ippiSwapChannelsC3C4RTab[depth], depth)) ) - return true; - } - return false; -#endif - -#if IPP_DISABLE_BLOCK - case CV_BGR2YCrCb: case CV_RGB2YCrCb: - case CV_BGR2YUV: case CV_RGB2YUV: - { - CV_Assert( scn == 3 || scn == 4 ); - static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; - static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 }; - const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f; - const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i; - - _dst.create(sz, CV_MAKETYPE(depth, 3)); - dst = _dst.getMat(); - - if (code == CV_RGB2YUV && scn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiRGBToYUV_8u_C3R))) - return true; - } - else if (code == CV_BGR2YUV && scn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) - return true; - } - else if (code == CV_RGB2YUV && scn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 0, 1, 2, depth))) - return true; - } - else if (code == CV_BGR2YUV && scn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) - return true; - } - return false; } -#endif - -#if IPP_DISABLE_BLOCK - case CV_YCrCb2BGR: case CV_YCrCb2RGB: - case CV_YUV2BGR: case CV_YUV2RGB: + else { - if( dcn <= 0 ) dcn = 3; - CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); - static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f }; - static const int yuv_i[] = { 33292, -6472, -9519, 18678 }; - const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f; - const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i; - - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if (code == CV_YUV2RGB && dcn == 3 && depth == CV_8U) + if(scn == 3 && !swapBlue) { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R))) - return true; + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) + return; } - else if (code == CV_YUV2BGR && dcn == 3 && depth == CV_8U) + else if(scn == 4 && !swapBlue) { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth))) - return true; + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) + return; } - else if (code == CV_YUV2RGB && dcn == 4 && depth == CV_8U) + else if(scn == 3 && swapBlue) { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth))) - return true; + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiRGB2HLSTab[depth])) ) + return; } - else if (code == CV_YUV2BGR && dcn == 4 && depth == CV_8U) + else if(scn == 4 && swapBlue) { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth))) - return true; + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) ) + return; } - return false; } + } + } #endif -#if IPP_VERSION_X100 >= 700 - case CV_BGR2XYZ: case CV_RGB2XYZ: - CV_Assert( scn == 3 || scn == 4 ); - _dst.create(sz, CV_MAKETYPE(depth, 3)); - dst = _dst.getMat(); - - if( code == CV_BGR2XYZ && scn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_BGR2XYZ && scn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_RGB2XYZ && scn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2XYZTab[depth])) ) - return true; - } - else if( code == CV_RGB2XYZ && scn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 0, 1, 2, depth)) ) - return true; - } - return false; -#endif - -#if IPP_VERSION_X100 >= 700 - case CV_XYZ2BGR: case CV_XYZ2RGB: - if( dcn <= 0 ) dcn = 3; - CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); - - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( code == CV_XYZ2BGR && dcn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_XYZ2BGR && dcn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - return true; - } - if( code == CV_XYZ2RGB && dcn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiXYZ2RGBTab[depth])) ) - return true; - } - else if( code == CV_XYZ2RGB && dcn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - return true; - } - return false; -#endif - -#if IPP_VERSION_X100 >= 700 - case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL: - case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL: - { - CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); - _dst.create(sz, CV_MAKETYPE(depth, 3)); - dst = _dst.getMat(); - - if( depth == CV_8U || depth == CV_16U ) - { -#if IPP_DISABLE_BLOCK // breaks OCL accuracy tests - if( code == CV_BGR2HSV_FULL && scn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_BGR2HSV_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_RGB2HSV_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) ) - return true; - } else -#endif - if( code == CV_RGB2HSV_FULL && scn == 3 && depth == CV_16U ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2HSVTab[depth])) ) - return true; - } - else if( code == CV_BGR2HLS_FULL && scn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_BGR2HLS_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_RGB2HLS_FULL && scn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2HLSTab[depth])) ) - return true; - } - else if( code == CV_RGB2HLS_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) ) - return true; - } - } - return false; - } -#endif - -#if IPP_VERSION_X100 >= 700 - case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL: - case CV_HLS2BGR: case CV_HLS2RGB: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL: - { - if( dcn <= 0 ) dcn = 3; - CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( depth == CV_8U || depth == CV_16U ) - { - if( code == CV_HSV2BGR_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_HSV2BGR_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_HSV2RGB_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiHSV2RGBTab[depth])) ) - return true; - } - else if( code == CV_HSV2RGB_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - return true; - } - else if( code == CV_HLS2BGR_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_HLS2BGR_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_HLS2RGB_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiHLS2RGBTab[depth])) ) - return true; - } - else if( code == CV_HLS2RGB_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - return true; - } - } - return false; - } -#endif - -#if IPP_DISABLE_BLOCK - case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab: - case CV_BGR2Luv: case CV_RGB2Luv: case CV_LBGR2Luv: case CV_LRGB2Luv: - { - CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); - bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab || - code == CV_BGR2Luv || code == CV_RGB2Luv; - - _dst.create(sz, CV_MAKETYPE(depth, 3)); - dst = _dst.getMat(); - - if (code == CV_LBGR2Lab && scn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToLab_8u_C3R))) - return true; - } - else if (code == CV_LBGR2Lab && scn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 0, 1, 2, depth))) - return true; - } - else - if (code == CV_LRGB2Lab && scn == 3 && depth == CV_8U) // slower than OpenCV - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) - return true; - } - else if (code == CV_LRGB2Lab && scn == 4 && depth == CV_8U) // slower than OpenCV - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) - return true; - } - else if (code == CV_LRGB2Luv && scn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGBToLUVTab[depth]))) - return true; - } - else if (code == CV_LRGB2Luv && scn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - ippiRGBToLUVTab[depth], 0, 1, 2, depth))) - return true; - } - else if (code == CV_LBGR2Luv && scn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - ippiRGBToLUVTab[depth], 2, 1, 0, depth))) - return true; - } - else if (code == CV_LBGR2Luv && scn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - ippiRGBToLUVTab[depth], 2, 1, 0, depth))) - return true; - } - return false; - } -#endif - -#if IPP_DISABLE_BLOCK - case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB: - case CV_Luv2BGR: case CV_Luv2RGB: case CV_Luv2LBGR: case CV_Luv2LRGB: - { - if( dcn <= 0 ) dcn = 3; - CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); - bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB || - code == CV_Luv2BGR || code == CV_Luv2RGB; - - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( code == CV_Lab2LBGR && dcn == 3 && depth == CV_8U) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R)) ) - return true; - } - else if( code == CV_Lab2LBGR && dcn == 4 && depth == CV_8U ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - return true; - } - if( code == CV_Lab2LRGB && dcn == 3 && depth == CV_8U ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_Lab2LRGB && dcn == 4 && depth == CV_8U ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - return true; - } - if( code == CV_Luv2LRGB && dcn == 3 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiLUVToRGBTab[depth])) ) - return true; - } - else if( code == CV_Luv2LRGB && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - return true; - } - if( code == CV_Luv2LBGR && dcn == 3 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - return true; - } - else if( code == CV_Luv2LBGR && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - return true; - } - return false; - } -#endif - - case CV_YUV2GRAY_420: - { - if (dcn <= 0) dcn = 1; - - CV_Assert( dcn == 1 ); - CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); - - Size dstSz(sz.width, sz.height * 2 / 3); - _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if (ippStsNoErr == ippiCopy_8u_C1R(src.data, (int)src.step, dst.data, (int)dst.step, - ippiSize(dstSz.width, dstSz.height))) - return true; - return false; - } - - case CV_RGBA2mRGBA: - { - if (dcn <= 0) dcn = 4; - CV_Assert( scn == 4 && dcn == 4 ); - - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( depth == CV_8U ) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiAlphaPremul_8u_AC4R))) - return true; - return false; - } - - return false; - } - - default: - return false; + int hrange = depth == CV_32F ? 360 : isFullRange ? 256 : 180; + int blueIdx = swapBlue ? 2 : 0; + if(isHSV) + { + if(depth == CV_8U) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2HSV_b(scn, blueIdx, hrange)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2HSV_f(scn, blueIdx, static_cast(hrange))); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2HLS_b(scn, blueIdx, hrange)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2HLS_f(scn, blueIdx, static_cast(hrange))); } } + +// 8u, 32f +void cvtHSVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV) +{ + CALL_HAL(cvtHSVtoBGR, cv_hal_cvtHSVtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isFullRange, isHSV); + +#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700 + CV_IPP_CHECK() + { + if (depth == CV_8U && isFullRange) + { + if (isHSV) + { + if(dcn == 3 && !swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return; + } + else if(dcn == 4 && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return; + } + else if(dcn == 3 && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiHSV2RGBTab[depth])) ) + return; + } + else if(dcn == 4 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return; + } + } + else + { + if(dcn == 3 && !swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return; + } + else if(dcn == 4 && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return; + } + else if(dcn == 3 && swapBlue) + { + if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height, + IPPGeneralFunctor(ippiHLS2RGBTab[depth])) ) + return; + } + else if(dcn == 4 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return; + } + } + } + } #endif + + int hrange = depth == CV_32F ? 360 : isFullRange ? 255 : 180; + int blueIdx = swapBlue ? 2 : 0; + if(isHSV) + { + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, HSV2RGB_b(dcn, blueIdx, hrange)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, HSV2RGB_f(dcn, blueIdx, static_cast(hrange))); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, HLS2RGB_b(dcn, blueIdx, hrange)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, HLS2RGB_f(dcn, blueIdx, static_cast(hrange))); + } +} + +// 8u, 32f +void cvtBGRtoLab(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isLab, bool srgb) +{ + CALL_HAL(cvtBGRtoLab, cv_hal_cvtBGRtoLab, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isLab, srgb); + +#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK + CV_IPP_CHECK() + { + if (!srgb) + { + if (isLab) + { + if (scn == 3 && depth == CV_8U && !swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToLab_8u_C3R))) + return; + } + else if (scn == 4 && depth == CV_8U && !swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 0, 1, 2, depth))) + return; + } + else if (scn == 3 && depth == CV_8U && swapBlue) // slower than OpenCV + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], + (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) + return; + } + else if (scn == 4 && depth == CV_8U && swapBlue) // slower than OpenCV + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) + return; + } + } + else + { + if (scn == 3 && swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralFunctor(ippiRGBToLUVTab[depth]))) + return; + } + else if (scn == 4 && swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + ippiRGBToLUVTab[depth], 0, 1, 2, depth))) + return; + } + else if (scn == 3 && !swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], + ippiRGBToLUVTab[depth], 2, 1, 0, depth))) + return; + } + else if (scn == 4 && !swapBlue) + { + if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + ippiRGBToLUVTab[depth], 2, 1, 0, depth))) + return; + } + } + } + } +#endif + + + int blueIdx = swapBlue ? 2 : 0; + if(isLab) + { + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Lab_b(scn, blueIdx, 0, 0, srgb)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Lab_f(scn, blueIdx, 0, 0, srgb)); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Luv_b(scn, blueIdx, 0, 0, srgb)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Luv_f(scn, blueIdx, 0, 0, srgb)); + } +} + +// 8u, 32f +void cvtLabtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isLab, bool srgb) +{ + CALL_HAL(cvtLabtoBGR, cv_hal_cvtLabtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isLab, srgb); + +#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK + CV_IPP_CHECK() + { + if (!srgb) + { + if (isLab) + { + if( dcn == 3 && depth == CV_8U && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R)) ) + return; + } + else if( dcn == 4 && depth == CV_8U && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return; + } + if( dcn == 3 && depth == CV_8U && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, + ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return; + } + else if( dcn == 4 && depth == CV_8U && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return; + } + } + else + { + if( dcn == 3 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralFunctor(ippiLUVToRGBTab[depth])) ) + return; + } + else if( dcn == 4 && swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], + ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return; + } + if( dcn == 3 && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], + ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return; + } + else if( dcn == 4 && !swapBlue) + { + if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height, + IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], + ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return; + } + } + } + } +#endif + + int blueIdx = swapBlue ? 2 : 0; + if(isLab) + { + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Lab2RGB_b(dcn, blueIdx, 0, 0, srgb)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Lab2RGB_f(dcn, blueIdx, 0, 0, srgb)); + } + else + { + if( depth == CV_8U ) + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Luv2RGB_b(dcn, blueIdx, 0, 0, srgb)); + else + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Luv2RGB_f(dcn, blueIdx, 0, 0, srgb)); + } +} + +void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int dst_width, int dst_height, + int dcn, bool swapBlue, int uIdx) +{ + CALL_HAL(cvtTwoPlaneYUVtoBGR, cv_hal_cvtTwoPlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx); + int blueIdx = swapBlue ? 2 : 0; + const uchar* uv = src_data + src_step * static_cast(dst_height); + switch(dcn*100 + blueIdx * 10 + uIdx) + { + case 300: cvtYUV420sp2RGB<0, 0> (dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + case 301: cvtYUV420sp2RGB<0, 1> (dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + case 320: cvtYUV420sp2RGB<2, 0> (dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + case 321: cvtYUV420sp2RGB<2, 1> (dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + case 400: cvtYUV420sp2RGBA<0, 0>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + case 401: cvtYUV420sp2RGBA<0, 1>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + case 420: cvtYUV420sp2RGBA<2, 0>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + case 421: cvtYUV420sp2RGBA<2, 1>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, uv); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; +} + +void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int dst_width, int dst_height, + int dcn, bool swapBlue, int uIdx) +{ + CALL_HAL(cvtThreePlaneYUVtoBGR, cv_hal_cvtThreePlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, dst_width, dst_height, dcn, swapBlue, uIdx); + const uchar* u = src_data + src_step * static_cast(dst_height); + const uchar* v = src_data + src_step * static_cast(dst_height + dst_height/4) + (dst_width/2) * ((dst_height % 4)/2); + + int ustepIdx = 0; + int vstepIdx = dst_height % 4 == 2 ? 1 : 0; + + if(uIdx == 1) { std::swap(u ,v), std::swap(ustepIdx, vstepIdx); } + int blueIdx = swapBlue ? 2 : 0; + + switch(dcn*10 + blueIdx) + { + case 30: cvtYUV420p2RGB<0>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, u, v, ustepIdx, vstepIdx); break; + case 32: cvtYUV420p2RGB<2>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, u, v, ustepIdx, vstepIdx); break; + case 40: cvtYUV420p2RGBA<0>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, u, v, ustepIdx, vstepIdx); break; + case 42: cvtYUV420p2RGBA<2>(dst_data, dst_step, dst_width, dst_height, src_step, src_data, u, v, ustepIdx, vstepIdx); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; +} + +void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int scn, bool swapBlue, int uIdx) +{ + CALL_HAL(cvtBGRtoThreePlaneYUV, cv_hal_cvtBGRtoThreePlaneYUV, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, uIdx); + int blueIdx = swapBlue ? 2 : 0; + switch(blueIdx + uIdx*10) + { + case 10: cvtRGBtoYUV420p<0, 1>(src_data, src_step, dst_data, dst_step, width, height, scn); break; + case 12: cvtRGBtoYUV420p<2, 1>(src_data, src_step, dst_data, dst_step, width, height, scn); break; + case 20: cvtRGBtoYUV420p<0, 2>(src_data, src_step, dst_data, dst_step, width, height, scn); break; + case 22: cvtRGBtoYUV420p<2, 2>(src_data, src_step, dst_data, dst_step, width, height, scn); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; +} + +void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int dcn, bool swapBlue, int uIdx, int ycn) +{ + CALL_HAL(cvtOnePlaneYUVtoBGR, cv_hal_cvtOnePlaneYUVtoBGR, src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, uIdx, ycn); + int blueIdx = swapBlue ? 2 : 0; + switch(dcn*1000 + blueIdx*100 + uIdx*10 + ycn) + { + case 3000: cvtYUV422toRGB<0,0,0>(dst_data, dst_step, src_data, src_step, width, height); break; + case 3001: cvtYUV422toRGB<0,0,1>(dst_data, dst_step, src_data, src_step, width, height); break; + case 3010: cvtYUV422toRGB<0,1,0>(dst_data, dst_step, src_data, src_step, width, height); break; + case 3200: cvtYUV422toRGB<2,0,0>(dst_data, dst_step, src_data, src_step, width, height); break; + case 3201: cvtYUV422toRGB<2,0,1>(dst_data, dst_step, src_data, src_step, width, height); break; + case 3210: cvtYUV422toRGB<2,1,0>(dst_data, dst_step, src_data, src_step, width, height); break; + case 4000: cvtYUV422toRGBA<0,0,0>(dst_data, dst_step, src_data, src_step, width, height); break; + case 4001: cvtYUV422toRGBA<0,0,1>(dst_data, dst_step, src_data, src_step, width, height); break; + case 4010: cvtYUV422toRGBA<0,1,0>(dst_data, dst_step, src_data, src_step, width, height); break; + case 4200: cvtYUV422toRGBA<2,0,0>(dst_data, dst_step, src_data, src_step, width, height); break; + case 4201: cvtYUV422toRGBA<2,0,1>(dst_data, dst_step, src_data, src_step, width, height); break; + case 4210: cvtYUV422toRGBA<2,1,0>(dst_data, dst_step, src_data, src_step, width, height); break; + default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; + }; +} + +void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height) +{ + CALL_HAL(cvtRGBAtoMultipliedRGBA, cv_hal_cvtRGBAtoMultipliedRGBA, src_data, src_step, dst_data, dst_step, width, height); + +#ifdef HAVE_IPP + CV_IPP_CHECK() + { + if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, + IPPGeneralFunctor((ippiGeneralFunc)ippiAlphaPremul_8u_AC4R))) + return; + } +#endif + + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGBA2mRGBA()); +} + +void cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height) +{ + CALL_HAL(cvtMultipliedRGBAtoRGBA, cv_hal_cvtMultipliedRGBAtoRGBA, src_data, src_step, dst_data, dst_step, width, height); + CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, mRGBA2RGBA()); +} + +}} // cv::hal:: + +// +// Helper functions +// + +inline bool isHSV(int code) +{ + switch(code) + { + case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL: + case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL: + return true; + default: + return false; + } +} + +inline bool isLab(int code) +{ + switch (code) + { + case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB: + case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab: + return true; + default: + return false; + } +} + +inline bool issRGB(int code) +{ + switch (code) + { + case CV_BGR2Lab: case CV_RGB2Lab: case CV_BGR2Luv: case CV_RGB2Luv: + case CV_Lab2BGR: case CV_Lab2RGB: case CV_Luv2BGR: case CV_Luv2RGB: + return true; + default: + return false; + } +} + +inline bool swapBlue(int code) +{ + switch (code) + { + case CV_BGR2BGRA: case CV_BGRA2BGR: + case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_BGRA2BGR565: case CV_BGRA2BGR555: + case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652BGRA: case CV_BGR5552BGRA: + case CV_BGR2GRAY: case CV_BGRA2GRAY: + case CV_BGR2YCrCb: case CV_BGR2YUV: + case CV_YCrCb2BGR: case CV_YUV2BGR: + case CV_BGR2XYZ: case CV_XYZ2BGR: + case CV_BGR2HSV: case CV_BGR2HLS: case CV_BGR2HSV_FULL: case CV_BGR2HLS_FULL: + case CV_YUV2BGR_YV12: case CV_YUV2BGRA_YV12: case CV_YUV2BGR_IYUV: case CV_YUV2BGRA_IYUV: + case CV_YUV2BGR_NV21: case CV_YUV2BGRA_NV21: case CV_YUV2BGR_NV12: case CV_YUV2BGRA_NV12: + case CV_Lab2BGR: case CV_Luv2BGR: case CV_Lab2LBGR: case CV_Luv2LBGR: + case CV_BGR2Lab: case CV_BGR2Luv: case CV_LBGR2Lab: case CV_LBGR2Luv: + case CV_HSV2BGR: case CV_HLS2BGR: case CV_HSV2BGR_FULL: case CV_HLS2BGR_FULL: + case CV_YUV2BGR_UYVY: case CV_YUV2BGRA_UYVY: case CV_YUV2BGR_YUY2: + case CV_YUV2BGRA_YUY2: case CV_YUV2BGR_YVYU: case CV_YUV2BGRA_YVYU: + case CV_BGR2YUV_IYUV: case CV_BGRA2YUV_IYUV: case CV_BGR2YUV_YV12: case CV_BGRA2YUV_YV12: + return false; + default: + return true; + } +} + +inline bool isFullRange(int code) +{ + switch (code) + { + case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL: + case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL: + return true; + default: + return false; + } } ////////////////////////////////////////////////////////////////////////////////////////// @@ -7925,7 +8389,7 @@ static bool ipp_cvtColor( Mat &src, OutputArray _dst, int code, int dcn ) void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) { int stype = _src.type(); - int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype), bidx; + int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype), uidx, gbits, ycn; CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat() && !(depth == CV_8U && (code == CV_Luv2BGR || code == CV_Luv2RGB)), ocl_cvtColor(_src, _dst, code, dcn) ) @@ -7934,95 +8398,55 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) Size sz = src.size(); CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F ); - CV_IPP_RUN(true, ipp_cvtColor(src, _dst, code, dcn)); - switch( code ) { case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR: case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA: CV_Assert( scn == 3 || scn == 4 ); dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3; - bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2; - _dst.create( sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); - - if( depth == CV_8U ) - { -#ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtBGR2RGB(src, dst, bidx)) - break; -#endif - CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); - } - else if( depth == CV_16U ) - CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); - else - CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); + hal::cvtBGRtoBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, scn, dcn, swapBlue(code)); break; case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555: case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555: CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U ); + gbits = code == CV_BGR2BGR565 || code == CV_RGB2BGR565 || + code == CV_BGRA2BGR565 || code == CV_RGBA2BGR565 ? 6 : 5; _dst.create(sz, CV_8UC2); dst = _dst.getMat(); - -#ifdef HAVE_TEGRA_OPTIMIZATION - if(code == CV_BGR2BGR565 || code == CV_BGRA2BGR565 || code == CV_RGB2BGR565 || code == CV_RGBA2BGR565) - if(tegra::useTegra() && tegra::cvtRGB2RGB565(src, dst, code == CV_RGB2BGR565 || code == CV_RGBA2BGR565 ? 0 : 2)) - break; -#endif - - CvtColorLoop(src, dst, RGB2RGB5x5(scn, - code == CV_BGR2BGR565 || code == CV_BGR2BGR555 || - code == CV_BGRA2BGR565 || code == CV_BGRA2BGR555 ? 0 : 2, - code == CV_BGR2BGR565 || code == CV_RGB2BGR565 || - code == CV_BGRA2BGR565 || code == CV_RGBA2BGR565 ? 6 : 5 // green bits - )); + hal::cvtBGRtoBGR5x5(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + scn, swapBlue(code), gbits); break; case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652RGB: case CV_BGR5552RGB: case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA: if(dcn <= 0) dcn = (code==CV_BGR5652BGRA || code==CV_BGR5552BGRA || code==CV_BGR5652RGBA || code==CV_BGR5552RGBA) ? 4 : 3; CV_Assert( (dcn == 3 || dcn == 4) && scn == 2 && depth == CV_8U ); + gbits = code == CV_BGR5652BGR || code == CV_BGR5652RGB || + code == CV_BGR5652BGRA || code == CV_BGR5652RGBA ? 6 : 5; _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); - - CvtColorLoop(src, dst, RGB5x52RGB(dcn, - code == CV_BGR5652BGR || code == CV_BGR5552BGR || - code == CV_BGR5652BGRA || code == CV_BGR5552BGRA ? 0 : 2, // blue idx - code == CV_BGR5652BGR || code == CV_BGR5652RGB || - code == CV_BGR5652BGRA || code == CV_BGR5652RGBA ? 6 : 5 // green bits - )); + hal::cvtBGR5x5toBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + dcn, swapBlue(code), gbits); break; case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY: CV_Assert( scn == 3 || scn == 4 ); _dst.create(sz, CV_MAKETYPE(depth, 1)); dst = _dst.getMat(); - - bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2; - - if( depth == CV_8U ) - { -#ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtRGB2Gray(src, dst, bidx)) - break; -#endif - CvtColorLoop(src, dst, RGB2Gray(scn, bidx, 0)); - } - else if( depth == CV_16U ) - CvtColorLoop(src, dst, RGB2Gray(scn, bidx, 0)); - else - CvtColorLoop(src, dst, RGB2Gray(scn, bidx, 0)); + hal::cvtBGRtoGray(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, scn, swapBlue(code)); break; case CV_BGR5652GRAY: case CV_BGR5552GRAY: CV_Assert( scn == 2 && depth == CV_8U ); + gbits = code == CV_BGR5652GRAY ? 6 : 5; _dst.create(sz, CV_8UC1); dst = _dst.getMat(); - - CvtColorLoop(src, dst, RGB5x52Gray(code == CV_BGR5652GRAY ? 6 : 5)); + hal::cvtBGR5x5toGray(src.data, src.step, dst.data, dst.step, src.cols, src.rows, gbits); break; case CV_GRAY2BGR: case CV_GRAY2BGRA: @@ -8030,235 +8454,87 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) CV_Assert( scn == 1 && (dcn == 3 || dcn == 4)); _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); - - if( depth == CV_8U ) - { -#ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtGray2RGB(src, dst)) - break; -#endif - CvtColorLoop(src, dst, Gray2RGB(dcn)); - } - else if( depth == CV_16U ) - CvtColorLoop(src, dst, Gray2RGB(dcn)); - else - CvtColorLoop(src, dst, Gray2RGB(dcn)); + hal::cvtGraytoBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, depth, dcn); break; case CV_GRAY2BGR565: case CV_GRAY2BGR555: CV_Assert( scn == 1 && depth == CV_8U ); + gbits = code == CV_GRAY2BGR565 ? 6 : 5; _dst.create(sz, CV_8UC2); dst = _dst.getMat(); - - CvtColorLoop(src, dst, Gray2RGB5x5(code == CV_GRAY2BGR565 ? 6 : 5)); + hal::cvtGraytoBGR5x5(src.data, src.step, dst.data, dst.step, src.cols, src.rows, gbits); break; case CV_BGR2YCrCb: case CV_RGB2YCrCb: case CV_BGR2YUV: case CV_RGB2YUV: - { CV_Assert( scn == 3 || scn == 4 ); - bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2; - static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; - static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 }; - const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f; - const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i; - _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); - - if( depth == CV_8U ) - { -#ifdef HAVE_TEGRA_OPTIMIZATION - if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::useTegra() && tegra::cvtRGB2YCrCb(src, dst, bidx)) - break; -#endif - CvtColorLoop(src, dst, RGB2YCrCb_i(scn, bidx, coeffs_i)); - } - else if( depth == CV_16U ) - CvtColorLoop(src, dst, RGB2YCrCb_i(scn, bidx, coeffs_i)); - else - CvtColorLoop(src, dst, RGB2YCrCb_f(scn, bidx, coeffs_f)); - } + hal::cvtBGRtoYUV(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, scn, swapBlue(code), code == CV_BGR2YCrCb || code == CV_RGB2YCrCb); break; case CV_YCrCb2BGR: case CV_YCrCb2RGB: case CV_YUV2BGR: case CV_YUV2RGB: - { if( dcn <= 0 ) dcn = 3; CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); - bidx = code == CV_YCrCb2BGR || code == CV_YUV2BGR ? 0 : 2; - static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f }; - static const int yuv_i[] = { 33292, -6472, -9519, 18678 }; - const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f; - const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i; - _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); - - if( depth == CV_8U ) - CvtColorLoop(src, dst, YCrCb2RGB_i(dcn, bidx, coeffs_i)); - else if( depth == CV_16U ) - CvtColorLoop(src, dst, YCrCb2RGB_i(dcn, bidx, coeffs_i)); - else - CvtColorLoop(src, dst, YCrCb2RGB_f(dcn, bidx, coeffs_f)); - } + hal::cvtYUVtoBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, dcn, swapBlue(code), code == CV_YCrCb2BGR || code == CV_YCrCb2RGB); break; case CV_BGR2XYZ: case CV_RGB2XYZ: CV_Assert( scn == 3 || scn == 4 ); - bidx = code == CV_BGR2XYZ ? 0 : 2; - _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); - - if( depth == CV_8U ) - CvtColorLoop(src, dst, RGB2XYZ_i(scn, bidx, 0)); - else if( depth == CV_16U ) - CvtColorLoop(src, dst, RGB2XYZ_i(scn, bidx, 0)); - else - CvtColorLoop(src, dst, RGB2XYZ_f(scn, bidx, 0)); + hal::cvtBGRtoXYZ(src.data, src.step, dst.data, dst.step, src.cols, src.rows, depth, scn, swapBlue(code)); break; case CV_XYZ2BGR: case CV_XYZ2RGB: if( dcn <= 0 ) dcn = 3; CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); - bidx = code == CV_XYZ2BGR ? 0 : 2; - _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); - - if( depth == CV_8U ) - CvtColorLoop(src, dst, XYZ2RGB_i(dcn, bidx, 0)); - else if( depth == CV_16U ) - CvtColorLoop(src, dst, XYZ2RGB_i(dcn, bidx, 0)); - else - CvtColorLoop(src, dst, XYZ2RGB_f(dcn, bidx, 0)); + hal::cvtXYZtoBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, depth, dcn, swapBlue(code)); break; case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL: case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL: - { CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); - bidx = code == CV_BGR2HSV || code == CV_BGR2HLS || - code == CV_BGR2HSV_FULL || code == CV_BGR2HLS_FULL ? 0 : 2; - int hrange = depth == CV_32F ? 360 : code == CV_BGR2HSV || code == CV_RGB2HSV || - code == CV_BGR2HLS || code == CV_RGB2HLS ? 180 : 256; - _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); - - if( code == CV_BGR2HSV || code == CV_RGB2HSV || - code == CV_BGR2HSV_FULL || code == CV_RGB2HSV_FULL ) - { -#ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtRGB2HSV(src, dst, bidx, hrange)) - break; -#endif - if( depth == CV_8U ) - CvtColorLoop(src, dst, RGB2HSV_b(scn, bidx, hrange)); - else - CvtColorLoop(src, dst, RGB2HSV_f(scn, bidx, (float)hrange)); - } - else - { - if( depth == CV_8U ) - CvtColorLoop(src, dst, RGB2HLS_b(scn, bidx, hrange)); - else - CvtColorLoop(src, dst, RGB2HLS_f(scn, bidx, (float)hrange)); - } - } + hal::cvtBGRtoHSV(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, scn, swapBlue(code), isFullRange(code), isHSV(code)); break; case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL: case CV_HLS2BGR: case CV_HLS2RGB: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL: - { if( dcn <= 0 ) dcn = 3; CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); - bidx = code == CV_HSV2BGR || code == CV_HLS2BGR || - code == CV_HSV2BGR_FULL || code == CV_HLS2BGR_FULL ? 0 : 2; - int hrange = depth == CV_32F ? 360 : code == CV_HSV2BGR || code == CV_HSV2RGB || - code == CV_HLS2BGR || code == CV_HLS2RGB ? 180 : 255; - _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); - - if( code == CV_HSV2BGR || code == CV_HSV2RGB || - code == CV_HSV2BGR_FULL || code == CV_HSV2RGB_FULL ) - { - if( depth == CV_8U ) - CvtColorLoop(src, dst, HSV2RGB_b(dcn, bidx, hrange)); - else - CvtColorLoop(src, dst, HSV2RGB_f(dcn, bidx, (float)hrange)); - } - else - { - if( depth == CV_8U ) - CvtColorLoop(src, dst, HLS2RGB_b(dcn, bidx, hrange)); - else - CvtColorLoop(src, dst, HLS2RGB_f(dcn, bidx, (float)hrange)); - } - } + hal::cvtHSVtoBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, dcn, swapBlue(code), isFullRange(code), isHSV(code)); break; case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab: case CV_BGR2Luv: case CV_RGB2Luv: case CV_LBGR2Luv: case CV_LRGB2Luv: - { CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); - bidx = code == CV_BGR2Lab || code == CV_BGR2Luv || - code == CV_LBGR2Lab || code == CV_LBGR2Luv ? 0 : 2; - bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab || - code == CV_BGR2Luv || code == CV_RGB2Luv; - _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); - - if( code == CV_BGR2Lab || code == CV_RGB2Lab || - code == CV_LBGR2Lab || code == CV_LRGB2Lab ) - { - if( depth == CV_8U ) - CvtColorLoop(src, dst, RGB2Lab_b(scn, bidx, 0, 0, srgb)); - else - CvtColorLoop(src, dst, RGB2Lab_f(scn, bidx, 0, 0, srgb)); - } - else - { - if( depth == CV_8U ) - CvtColorLoop(src, dst, RGB2Luv_b(scn, bidx, 0, 0, srgb)); - else - CvtColorLoop(src, dst, RGB2Luv_f(scn, bidx, 0, 0, srgb)); - } - } + hal::cvtBGRtoLab(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, scn, swapBlue(code), isLab(code), issRGB(code)); break; case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB: case CV_Luv2BGR: case CV_Luv2RGB: case CV_Luv2LBGR: case CV_Luv2LRGB: - { if( dcn <= 0 ) dcn = 3; CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); - bidx = code == CV_Lab2BGR || code == CV_Luv2BGR || - code == CV_Lab2LBGR || code == CV_Luv2LBGR ? 0 : 2; - bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB || - code == CV_Luv2BGR || code == CV_Luv2RGB; - _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); - - if( code == CV_Lab2BGR || code == CV_Lab2RGB || - code == CV_Lab2LBGR || code == CV_Lab2LRGB ) - { - if( depth == CV_8U ) - CvtColorLoop(src, dst, Lab2RGB_b(dcn, bidx, 0, 0, srgb)); - else - CvtColorLoop(src, dst, Lab2RGB_f(dcn, bidx, 0, 0, srgb)); - } - else - { - if( depth == CV_8U ) - CvtColorLoop(src, dst, Luv2RGB_b(dcn, bidx, 0, 0, srgb)); - else - CvtColorLoop(src, dst, Luv2RGB_f(dcn, bidx, 0, 0, srgb)); - } - } + hal::cvtLabtoBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + depth, dcn, swapBlue(code), isLab(code), issRGB(code)); break; case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: case CV_BayerRG2GRAY: case CV_BayerGR2GRAY: @@ -8270,76 +8546,31 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) case CV_YUV2BGR_NV21: case CV_YUV2RGB_NV21: case CV_YUV2BGR_NV12: case CV_YUV2RGB_NV12: case CV_YUV2BGRA_NV21: case CV_YUV2RGBA_NV21: case CV_YUV2BGRA_NV12: case CV_YUV2RGBA_NV12: - { - // http://www.fourcc.org/yuv.php#NV21 == yuv420sp -> a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2x2 subsampled chroma samples - // http://www.fourcc.org/yuv.php#NV12 -> a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples - - if (dcn <= 0) dcn = (code==CV_YUV420sp2BGRA || code==CV_YUV420sp2RGBA || code==CV_YUV2BGRA_NV12 || code==CV_YUV2RGBA_NV12) ? 4 : 3; - const int bIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2BGR_NV12 || code==CV_YUV2BGRA_NV12) ? 0 : 2; - const int uIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2RGB_NV21 || code==CV_YUV2RGBA_NV21) ? 1 : 0; - - CV_Assert( dcn == 3 || dcn == 4 ); - CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); - - Size dstSz(sz.width, sz.height * 2 / 3); - _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - int srcstep = (int)src.step; - const uchar* y = src.ptr(); - const uchar* uv = y + srcstep * dstSz.height; - - switch(dcn*100 + bIdx * 10 + uIdx) - { - case 300: cvtYUV420sp2RGB<0, 0> (dst, srcstep, y, uv); break; - case 301: cvtYUV420sp2RGB<0, 1> (dst, srcstep, y, uv); break; - case 320: cvtYUV420sp2RGB<2, 0> (dst, srcstep, y, uv); break; - case 321: cvtYUV420sp2RGB<2, 1> (dst, srcstep, y, uv); break; - case 400: cvtYUV420sp2RGBA<0, 0>(dst, srcstep, y, uv); break; - case 401: cvtYUV420sp2RGBA<0, 1>(dst, srcstep, y, uv); break; - case 420: cvtYUV420sp2RGBA<2, 0>(dst, srcstep, y, uv); break; - case 421: cvtYUV420sp2RGBA<2, 1>(dst, srcstep, y, uv); break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; - }; - } + // http://www.fourcc.org/yuv.php#NV21 == yuv420sp -> a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2x2 subsampled chroma samples + // http://www.fourcc.org/yuv.php#NV12 -> a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples + if (dcn <= 0) dcn = (code==CV_YUV420sp2BGRA || code==CV_YUV420sp2RGBA || code==CV_YUV2BGRA_NV12 || code==CV_YUV2RGBA_NV12) ? 4 : 3; + uidx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2RGB_NV21 || code==CV_YUV2RGBA_NV21) ? 1 : 0; + CV_Assert( dcn == 3 || dcn == 4 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); + _dst.create(Size(sz.width, sz.height * 2 / 3), CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + hal::cvtTwoPlaneYUVtoBGR(src.data, src.step, dst.data, dst.step, dst.cols, dst.rows, + dcn, swapBlue(code), uidx); break; case CV_YUV2BGR_YV12: case CV_YUV2RGB_YV12: case CV_YUV2BGRA_YV12: case CV_YUV2RGBA_YV12: case CV_YUV2BGR_IYUV: case CV_YUV2RGB_IYUV: case CV_YUV2BGRA_IYUV: case CV_YUV2RGBA_IYUV: - { - //http://www.fourcc.org/yuv.php#YV12 == yuv420p -> It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes. - //http://www.fourcc.org/yuv.php#IYUV == I420 -> It comprises an NxN Y plane followed by (N/2)x(N/2) U and V planes - - if (dcn <= 0) dcn = (code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12 || code==CV_YUV2RGBA_IYUV || code==CV_YUV2BGRA_IYUV) ? 4 : 3; - const int bIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2BGR_IYUV || code==CV_YUV2BGRA_IYUV) ? 0 : 2; - const int uIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2RGB_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12) ? 1 : 0; - - CV_Assert( dcn == 3 || dcn == 4 ); - CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); - - Size dstSz(sz.width, sz.height * 2 / 3); - _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - int srcstep = (int)src.step; - const uchar* y = src.ptr(); - const uchar* u = y + srcstep * dstSz.height; - const uchar* v = y + srcstep * (dstSz.height + dstSz.height/4) + (dstSz.width/2) * ((dstSz.height % 4)/2); - - int ustepIdx = 0; - int vstepIdx = dstSz.height % 4 == 2 ? 1 : 0; - - if(uIdx == 1) { std::swap(u ,v), std::swap(ustepIdx, vstepIdx); } - - switch(dcn*10 + bIdx) - { - case 30: cvtYUV420p2RGB<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; - case 32: cvtYUV420p2RGB<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; - case 40: cvtYUV420p2RGBA<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; - case 42: cvtYUV420p2RGBA<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; - }; - } + //http://www.fourcc.org/yuv.php#YV12 == yuv420p -> It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes. + //http://www.fourcc.org/yuv.php#IYUV == I420 -> It comprises an NxN Y plane followed by (N/2)x(N/2) U and V planes + if (dcn <= 0) dcn = (code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12 || code==CV_YUV2RGBA_IYUV || code==CV_YUV2BGRA_IYUV) ? 4 : 3; + uidx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2RGB_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12) ? 1 : 0; + CV_Assert( dcn == 3 || dcn == 4 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); + _dst.create(Size(sz.width, sz.height * 2 / 3), CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + hal::cvtThreePlaneYUVtoBGR(src.data, src.step, dst.data, dst.step, dst.cols, dst.rows, + dcn, swapBlue(code), uidx); break; + case CV_YUV2GRAY_420: { if (dcn <= 0) dcn = 1; @@ -8350,74 +8581,41 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) Size dstSz(sz.width, sz.height * 2 / 3); _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); +#ifdef HAVE_IPP + if (ippStsNoErr == ippiCopy_8u_C1R(src.data, (int)src.step, dst.data, (int)dst.step, + ippiSize(dstSz.width, dstSz.height))) + break; +#endif src(Range(0, dstSz.height), Range::all()).copyTo(dst); } break; case CV_RGB2YUV_YV12: case CV_BGR2YUV_YV12: case CV_RGBA2YUV_YV12: case CV_BGRA2YUV_YV12: case CV_RGB2YUV_IYUV: case CV_BGR2YUV_IYUV: case CV_RGBA2YUV_IYUV: case CV_BGRA2YUV_IYUV: - { - if (dcn <= 0) dcn = 1; - const int bIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_BGR2YUV_YV12 || code == CV_BGRA2YUV_YV12) ? 0 : 2; - const int uIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_RGB2YUV_IYUV || code == CV_RGBA2YUV_IYUV) ? 1 : 2; - - CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U ); - CV_Assert( dcn == 1 ); - CV_Assert( sz.width % 2 == 0 && sz.height % 2 == 0 ); - - Size dstSz(sz.width, sz.height / 2 * 3); - _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - switch(bIdx + uIdx*10) - { - case 10: cvtRGBtoYUV420p<0, 1>(src, dst); break; - case 12: cvtRGBtoYUV420p<2, 1>(src, dst); break; - case 20: cvtRGBtoYUV420p<0, 2>(src, dst); break; - case 22: cvtRGBtoYUV420p<2, 2>(src, dst); break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; - }; - } + if (dcn <= 0) dcn = 1; + uidx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_RGB2YUV_IYUV || code == CV_RGBA2YUV_IYUV) ? 1 : 2; + CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U ); + CV_Assert( dcn == 1 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 2 == 0 ); + _dst.create(Size(sz.width, sz.height / 2 * 3), CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + hal::cvtBGRtoThreePlaneYUV(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + scn, swapBlue(code), uidx); break; case CV_YUV2RGB_UYVY: case CV_YUV2BGR_UYVY: case CV_YUV2RGBA_UYVY: case CV_YUV2BGRA_UYVY: case CV_YUV2RGB_YUY2: case CV_YUV2BGR_YUY2: case CV_YUV2RGB_YVYU: case CV_YUV2BGR_YVYU: case CV_YUV2RGBA_YUY2: case CV_YUV2BGRA_YUY2: case CV_YUV2RGBA_YVYU: case CV_YUV2BGRA_YVYU: - { - //http://www.fourcc.org/yuv.php#UYVY - //http://www.fourcc.org/yuv.php#YUY2 - //http://www.fourcc.org/yuv.php#YVYU - - if (dcn <= 0) dcn = (code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2RGBA_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 4 : 3; - const int bIdx = (code==CV_YUV2BGR_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2BGR_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2BGR_YVYU || code==CV_YUV2BGRA_YVYU) ? 0 : 2; - const int ycn = (code==CV_YUV2RGB_UYVY || code==CV_YUV2BGR_UYVY || code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY) ? 1 : 0; - const int uIdx = (code==CV_YUV2RGB_YVYU || code==CV_YUV2BGR_YVYU || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 1 : 0; - - CV_Assert( dcn == 3 || dcn == 4 ); - CV_Assert( scn == 2 && depth == CV_8U ); - - _dst.create(sz, CV_8UC(dcn)); - dst = _dst.getMat(); - - switch(dcn*1000 + bIdx*100 + uIdx*10 + ycn) - { - case 3000: cvtYUV422toRGB<0,0,0>(dst, (int)src.step, src.ptr()); break; - case 3001: cvtYUV422toRGB<0,0,1>(dst, (int)src.step, src.ptr()); break; - case 3010: cvtYUV422toRGB<0,1,0>(dst, (int)src.step, src.ptr()); break; - case 3011: cvtYUV422toRGB<0,1,1>(dst, (int)src.step, src.ptr()); break; - case 3200: cvtYUV422toRGB<2,0,0>(dst, (int)src.step, src.ptr()); break; - case 3201: cvtYUV422toRGB<2,0,1>(dst, (int)src.step, src.ptr()); break; - case 3210: cvtYUV422toRGB<2,1,0>(dst, (int)src.step, src.ptr()); break; - case 3211: cvtYUV422toRGB<2,1,1>(dst, (int)src.step, src.ptr()); break; - case 4000: cvtYUV422toRGBA<0,0,0>(dst, (int)src.step, src.ptr()); break; - case 4001: cvtYUV422toRGBA<0,0,1>(dst, (int)src.step, src.ptr()); break; - case 4010: cvtYUV422toRGBA<0,1,0>(dst, (int)src.step, src.ptr()); break; - case 4011: cvtYUV422toRGBA<0,1,1>(dst, (int)src.step, src.ptr()); break; - case 4200: cvtYUV422toRGBA<2,0,0>(dst, (int)src.step, src.ptr()); break; - case 4201: cvtYUV422toRGBA<2,0,1>(dst, (int)src.step, src.ptr()); break; - case 4210: cvtYUV422toRGBA<2,1,0>(dst, (int)src.step, src.ptr()); break; - case 4211: cvtYUV422toRGBA<2,1,1>(dst, (int)src.step, src.ptr()); break; - default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break; - }; - } + //http://www.fourcc.org/yuv.php#UYVY + //http://www.fourcc.org/yuv.php#YUY2 + //http://www.fourcc.org/yuv.php#YVYU + if (dcn <= 0) dcn = (code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2RGBA_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 4 : 3; + ycn = (code==CV_YUV2RGB_UYVY || code==CV_YUV2BGR_UYVY || code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY) ? 1 : 0; + uidx = (code==CV_YUV2RGB_YVYU || code==CV_YUV2BGR_YVYU || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 1 : 0; + CV_Assert( dcn == 3 || dcn == 4 ); + CV_Assert( scn == 2 && depth == CV_8U ); + _dst.create(sz, CV_8UC(dcn)); + dst = _dst.getMat(); + hal::cvtOnePlaneYUVtoBGR(src.data, src.step, dst.data, dst.step, src.cols, src.rows, + dcn, swapBlue(code), uidx, ycn); break; case CV_YUV2GRAY_UYVY: case CV_YUV2GRAY_YUY2: { @@ -8431,42 +8629,22 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) } break; case CV_RGBA2mRGBA: - { - if (dcn <= 0) dcn = 4; - CV_Assert( scn == 4 && dcn == 4 ); - - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( depth == CV_8U ) - { - CvtColorLoop(src, dst, RGBA2mRGBA()); - } - else - { - CV_Error( CV_StsBadArg, "Unsupported image depth" ); - } - } + if (dcn <= 0) dcn = 4; + CV_Assert( scn == 4 && dcn == 4 && depth == CV_8U ); + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + hal::cvtRGBAtoMultipliedRGBA(src.data, src.step, dst.data, dst.step, src.cols, src.rows); break; case CV_mRGBA2RGBA: - { - if (dcn <= 0) dcn = 4; - CV_Assert( scn == 4 && dcn == 4 ); - - _dst.create(sz, CV_MAKETYPE(depth, dcn)); - dst = _dst.getMat(); - - if( depth == CV_8U ) - CvtColorLoop(src, dst, mRGBA2RGBA()); - else - { - CV_Error( CV_StsBadArg, "Unsupported image depth" ); - } - } + if (dcn <= 0) dcn = 4; + CV_Assert( scn == 4 && dcn == 4 && depth == CV_8U ); + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + hal::cvtMultipliedRGBAtoRGBA(src.data, src.step, dst.data, dst.step, src.cols, src.rows); break; default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); - } + } } CV_IMPL void diff --git a/modules/imgproc/src/hal_replacement.hpp b/modules/imgproc/src/hal_replacement.hpp index e42cc44ad9..ecc11fb0b4 100644 --- a/modules/imgproc/src/hal_replacement.hpp +++ b/modules/imgproc/src/hal_replacement.hpp @@ -46,6 +46,7 @@ #define OPENCV_IMGPROC_HAL_REPLACEMENT_HPP #include "opencv2/core/hal/interface.h" +#include "opencv2/imgproc/hal/interface.h" #if defined __GNUC__ # pragma GCC diagnostic push @@ -298,6 +299,294 @@ inline int hal_ni_warpPerspectve(int src_type, const uchar *src_data, size_t src #define cv_hal_warpPerspective hal_ni_warpPerspectve //! @endcond +/** + @brief hal_cvtBGRtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U, CV_16U, CV_32F) + @param scn source image channels (3 or 4) + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R channels will be swapped (BGR->RGB or RGB->BGR) + Convert between BGR, BGRA, RGB and RGBA image formats. + */ +inline int hal_ni_cvtBGRtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int scn, int dcn, bool swapBlue) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGRtoBGR5x5 + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param scn source image channels (3 or 4) + @param swapBlue if set to true B and R source channels will be swapped (treat as RGB) + @param greenBits number of bits for green channel (5 or 6) + Convert from BGR, BGRA, RGB and RGBA to packed BGR or RGB (16 bits per pixel, 555 or 565). + Support only CV_8U images (input 3 or 4 channels, output 2 channels). + */ +inline int hal_ni_cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int scn, bool swapBlue, int greenBits) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGR5x5toBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + @param greenBits number of bits for green channel (5 or 6) + Convert from packed BGR or RGB (16 bits per pixel, 555 or 565) to BGR, BGRA, RGB and RGBA. + Support only CV_8U images (input 2 channels, output 3 or 4 channels). + */ +inline int hal_ni_cvtBGR5x5toBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int dcn, bool swapBlue, int greenBits) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGRtoGray + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U, CV_16U or CV_32F) + @param scn source image channels (3 or 4) + @param swapBlue if set to true B and R source channels will be swapped (treat as RGB) + Convert from BGR, BGRA, RGB or RGBA to 1-channel gray. + */ +inline int hal_ni_cvtBGRtoGray(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtGraytoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U, CV_16U or CV_32F) + @param dcn destination image channels (3 or 4) + Convert from 1-channel gray to BGR, RGB, RGBA or BGRA. + */ +inline int hal_ni_cvtGraytoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int dcn) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGR5x5toGray + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param greenBits number of bits for green channel (5 or 6) + Convert from packed BGR (16 bits per pixel, 555 or 565) to 1-channel gray. + Support only CV_8U images. + */ +inline int hal_ni_cvtBGR5x5toGray(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int greenBits) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtGraytoBGR5x5 + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param greenBits number of bits for green channel (5 or 6) + Convert from 1-channel gray to packed BGR (16 bits per pixel, 555 or 565). + Support only CV_8U images. + */ +inline int hal_ni_cvtGraytoBGR5x5(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int greenBits) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGRtoYUV + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U, CV_16U or CV_32F) + @param scn source image channels (3 or 4) + @param swapBlue if set to true B and R source channels will be swapped (treat as RGB) + @param isCbCr if set to true write output in YCbCr format + Convert from BGR, RGB, BGRA or RGBA to YUV or YCbCr. + */ +inline int hal_ni_cvtBGRtoYUV(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue, bool isCbCr) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtYUVtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U, CV_16U or CV_32F) + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + @param isCbCr if set to true treat source as YCbCr + Convert from YUV or YCbCr to BGR, RGB, BGRA or RGBA. + */ +inline int hal_ni_cvtYUVtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue, bool isCbCr) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGRtoXYZ + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U, CV_16U or CV_32F) + @param scn source image channels (3 or 4) + @param swapBlue if set to true B and R source channels will be swapped (treat as RGB) + Convert from BGR, RGB, BGRA or RGBA to XYZ. + */ +inline int hal_ni_cvtBGRtoXYZ(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtXYZtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U, CV_16U or CV_32F) + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + Convert from XYZ to BGR, RGB, BGRA or RGBA. + */ +inline int hal_ni_cvtXYZtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGRtoHSV + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U or CV_32F) + @param scn source image channels (3 or 4) + @param swapBlue if set to true B and R source channels will be swapped (treat as RGB) + @param isFullRange if set to true write hue in range 0-255 (0-360 for float) otherwise in range 0-180 + @param isHSV if set to true write HSV otherwise HSL + Convert from BGR, RGB, BGRA or RGBA to HSV or HSL. + */ +inline int hal_ni_cvtBGRtoHSV(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue, bool isFullRange, bool isHSV) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtHSVtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U or CV_32F) + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + @param isFullRange if set to true read hue in range 0-255 (0-360 for float) otherwise in range 0-180 + @param isHSV if set to true treat source as HSV otherwise HSL + Convert from HSV or HSL to BGR, RGB, BGRA or RGBA. + */ +inline int hal_ni_cvtHSVtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGRtoLab + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U or CV_32F) + @param scn source image channels (3 or 4) + @param swapBlue if set to true B and R source channels will be swapped (treat as RGB) + @param isLab if set to true write Lab otherwise Luv + @param srgb if set to true use sRGB gamma correction + Convert from BGR, RGB, BGRA or RGBA to Lab or Luv. + */ +inline int hal_ni_cvtBGRtoLab(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue, bool isLab, bool srgb) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtLabtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param depth image depth (one of CV_8U or CV_32F) + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + @param isLab if set to true treat input as Lab otherwise Luv + @param srgb if set to true use sRGB gamma correction + Convert from Lab or Luv to BGR, RGB, BGRA or RGBA. + */ +inline int hal_ni_cvtLabtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue, bool isLab, bool srgb) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtTwoPlaneYUVtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param dst_width,dst_height destination image size + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + @param uIdx U-channel index in the interleaved U/V plane (0 or 1) + Convert from YUV (YUV420sp (or NV12/NV21) - Y plane followed by interleaved U/V plane) to BGR, RGB, BGRA or RGBA. + Only for CV_8U. + */ +inline int hal_ni_cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int dst_width, int dst_height, int dcn, bool swapBlue, int uIdx) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtThreePlaneYUVtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param dst_width,dst_height destination image size + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + @param uIdx U-channel plane index (0 or 1) + Convert from YUV (YUV420p (or YV12/YV21) - Y plane followed by U and V planes) to BGR, RGB, BGRA or RGBA. + Only for CV_8U. + */ +inline int hal_ni_cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int dst_width, int dst_height, int dcn, bool swapBlue, int uIdx) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtBGRtoThreePlaneYUV + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param scn source image channels (3 or 4) + @param swapBlue if set to true B and R source channels will be swapped (treat as RGB) + @param uIdx U-channel plane index (0 or 1) + Convert from BGR, RGB, BGRA or RGBA to YUV (YUV420p (or YV12/YV21) - Y plane followed by U and V planes). + Only for CV_8U. + */ +inline int hal_ni_cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int scn, bool swapBlue, int uIdx) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtOnePlaneYUVtoBGR + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + @param dcn destination image channels (3 or 4) + @param swapBlue if set to true B and R destination channels will be swapped (write RGB) + @param uIdx U-channel index (0 or 1) + @param ycn Y-channel index (0 or 1) + Convert from UYVY, YUY2 or YVYU to BGR, RGB, BGRA or RGBA. + Only for CV_8U. + */ +inline int hal_ni_cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height, int dcn, bool swapBlue, int uIdx, int ycn) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + + +/** + @brief hal_cvtRGBAtoMultipliedRGBA + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + Convert from BGRA or RGBA to format with multiplied alpha channel. + Only for CV_8U. + */ +inline int hal_ni_cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +/** + @brief hal_cvtMultipliedRGBAtoRGBA + @param src_data,src_step source image data and step + @param dst_data,dst_step destination image data and step + @param width,height image size + Convert from format with multiplied alpha channel to BGRA or RGBA. + Only for CV_8U. + */ +inline int hal_ni_cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED +#define cv_hal_cvtBGRtoBGR hal_ni_cvtBGRtoBGR +#define cv_hal_cvtBGRtoBGR5x5 hal_ni_cvtBGRtoBGR5x5 +#define cv_hal_cvtBGR5x5toBGR hal_ni_cvtBGR5x5toBGR +#define cv_hal_cvtBGRtoGray hal_ni_cvtBGRtoGray +#define cv_hal_cvtGraytoBGR hal_ni_cvtGraytoBGR +#define cv_hal_cvtBGR5x5toGray hal_ni_cvtBGR5x5toGray +#define cv_hal_cvtGraytoBGR5x5 hal_ni_cvtGraytoBGR5x5 +#define cv_hal_cvtBGRtoYUV hal_ni_cvtBGRtoYUV +#define cv_hal_cvtYUVtoBGR hal_ni_cvtYUVtoBGR +#define cv_hal_cvtBGRtoXYZ hal_ni_cvtBGRtoXYZ +#define cv_hal_cvtXYZtoBGR hal_ni_cvtXYZtoBGR +#define cv_hal_cvtBGRtoHSV hal_ni_cvtBGRtoHSV +#define cv_hal_cvtHSVtoBGR hal_ni_cvtHSVtoBGR +#define cv_hal_cvtBGRtoLab hal_ni_cvtBGRtoLab +#define cv_hal_cvtLabtoBGR hal_ni_cvtLabtoBGR +#define cv_hal_cvtTwoPlaneYUVtoBGR hal_ni_cvtTwoPlaneYUVtoBGR +#define cv_hal_cvtThreePlaneYUVtoBGR hal_ni_cvtThreePlaneYUVtoBGR +#define cv_hal_cvtBGRtoThreePlaneYUV hal_ni_cvtBGRtoThreePlaneYUV +#define cv_hal_cvtOnePlaneYUVtoBGR hal_ni_cvtOnePlaneYUVtoBGR +#define cv_hal_cvtRGBAtoMultipliedRGBA hal_ni_cvtRGBAtoMultipliedRGBA +#define cv_hal_cvtMultipliedRGBAtoRGBA hal_ni_cvtMultipliedRGBAtoRGBA +//! @endcond + //! @} #if defined __GNUC__ @@ -306,7 +595,6 @@ inline int hal_ni_warpPerspectve(int src_type, const uchar *src_data, size_t src # pragma warning( pop ) #endif - #include "custom_hal.hpp" //! @cond IGNORED diff --git a/platforms/android/build-tests/test_cmake_build.py b/platforms/android/build-tests/test_cmake_build.py index 0e84928f0a..f02915c611 100644 --- a/platforms/android/build-tests/test_cmake_build.py +++ b/platforms/android/build-tests/test_cmake_build.py @@ -2,6 +2,9 @@ import unittest import os, sys, subprocess, argparse, shutil, re +import logging as log + +log.basicConfig(format='%(message)s', level=log.DEBUG) CMAKE_TEMPLATE='''\ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) @@ -83,10 +86,12 @@ class TestCmakeBuild(unittest.TestCase): "-DANDROID_TOOLCHAIN_NAME=%s" % self.toolchain, self.srcdir ] + log.info("Executing: %s" % cmd) retcode = subprocess.call(cmd) self.assertEqual(retcode, 0, "cmake failed") cmd = ["ninja"] + log.info("Executing: %s" % cmd) retcode = subprocess.call(cmd) self.assertEqual(retcode, 0, "make failed") diff --git a/platforms/android/build_sdk.py b/platforms/android/build_sdk.py index 812b465e7b..61c9f7d34f 100755 --- a/platforms/android/build_sdk.py +++ b/platforms/android/build_sdk.py @@ -73,8 +73,7 @@ class ABI: def __str__(self): return "%s (%s)" % (self.name, self.toolchain) def haveIPP(self): - return False - # return self.name == "x86" or self.name == "x86_64" + return self.name == "x86" or self.name == "x86_64" ABIs = [ ABI("2", "armeabi-v7a", "arm-linux-androideabi-4.8", cmake_name="armeabi-v7a with NEON"), @@ -143,7 +142,7 @@ class Builder: cmd.append(self.opencvdir) if self.use_ccache == True: - cmd.extend(["-DNDK_CCACHE=ccache", "-DENABLE_PRECOMPILED_HEADERS=OFF"]) + cmd.append("-DNDK_CCACHE=ccache") if do_install: cmd.extend(["-DBUILD_TESTS=ON", "-DINSTALL_TESTS=ON"]) execute(cmd) @@ -238,15 +237,6 @@ class Builder: log.info("Copy docs: %s", self.docdest) shutil.copytree(self.docdest, os.path.join(self.resultdest, "sdk", "java", "javadoc")) - # Patch cmake config - with open(os.path.join(self.resultdest, "sdk", "native", "jni", "OpenCVConfig.cmake"), "r+t") as f: - contents = f.read() - contents, count = re.subn(r'OpenCV_ANDROID_NATIVE_API_LEVEL \d+', "OpenCV_ANDROID_NATIVE_API_LEVEL 8", contents) - f.seek(0) - f.write(contents) - f.truncate() - log.info("Patch cmake config: %s (%d changes)", f.name, count) - # Clean samples path = os.path.join(self.resultdest, "samples") for item in os.listdir(path):