vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b

This commit is contained in:
Gitea Mirror Bot
2026-08-22 00:10:33 +08:00
commit f7f077da11
6933 changed files with 2335208 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
project(ipphal)
set(IPP_HAL_VERSION 0.0.1 CACHE INTERNAL "")
set(IPP_HAL_LIBRARIES "ipphal" CACHE INTERNAL "")
set(IPP_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" CACHE INTERNAL "")
set(IPP_HAL_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/include/ipp_hal_core.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/ipp_hal_imgproc.hpp"
CACHE INTERNAL "")
add_library(ipphal STATIC
"${CMAKE_CURRENT_SOURCE_DIR}/src/mean_ipp.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/minmax_ipp.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/norm_ipp.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/cart_polar_ipp.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/transforms_ipp.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/warp_ipp.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/sum_ipp.cpp"
)
#TODO: HAVE_IPP_ICV and HAVE_IPP_IW added as private macro till OpenCV itself is
# source of IPP and public definitions lead to redefinition warning
# The macro should be redefined as PUBLIC when IPP part is removed from core
# to make HAL the source of IPP integration. The same is true for WITH_IPP_CALLS_ENFORCED
if(HAVE_IPP_ICV)
target_compile_definitions(ipphal PRIVATE HAVE_IPP_ICV)
endif()
if(HAVE_IPP_IW)
target_compile_definitions(ipphal PRIVATE HAVE_IPP_IW)
endif()
if(WITH_IPP_CALLS_ENFORCED)
target_compile_definitions(ipphal PRIVATE IPP_CALLS_ENFORCED)
message("WITH_IPP_CALLS_ENFORCED=${WITH_IPP_CALLS_ENFORCED}: enforced IPP calls are enabled in IPP HAL")
endif()
target_include_directories(ipphal PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-suggest-override)
target_include_directories(ipphal PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src"
${CMAKE_SOURCE_DIR}/modules/core/include
${CMAKE_SOURCE_DIR}/modules/imgproc/include
${IPP_INCLUDE_DIRS}
)
target_link_libraries(ipphal PUBLIC ${IPP_IW_LIBRARIES} ${IPP_LIBRARIES})
set_target_properties(ipphal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH} DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}")
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(ipphal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(ipphal PROPERTIES FOLDER "3rdparty")
endif()
+79
View File
@@ -0,0 +1,79 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef __IPP_HAL_CORE_HPP__
#define __IPP_HAL_CORE_HPP__
#include <opencv2/core/base.hpp>
#include "ipp_utils.hpp"
#if (IPP_VERSION_X100 >= 700)
int ipp_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int height, int src_type,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
#undef cv_hal_meanStdDev
#define cv_hal_meanStdDev ipp_hal_meanStdDev
int ipp_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width, int height, int depth,
double* _minVal, double* _maxVal, int* _minIdx, int* _maxIdx, uchar* mask, size_t mask_step);
#undef cv_hal_minMaxIdxMaskStep
#define cv_hal_minMaxIdxMaskStep ipp_hal_minMaxIdxMaskStep
#if (IPP_VERSION_X100 == 202200)
# define IPP_DISABLE_NORM_8U 1 // accuracy difference in perf test sanity check
# else
# define IPP_DISABLE_NORM_8U 0
#endif
#if (IPP_VERSION_X100 >= 202200 && IPP_VERSION_X100 < 202220)
# define IPP_DISABLE_NORM_INF_16U_C1MR 1 // segmentation fault in accuracy test
# else
# define IPP_DISABLE_NORM_INF_16U_C1MR 0
#endif
int ipp_hal_norm(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step,
int width, int height, int type, int norm_type, double* result);
#undef cv_hal_norm
#define cv_hal_norm ipp_hal_norm
int ipp_hal_normDiff(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask,
size_t mask_step, int width, int height, int type, int norm_type, double* result);
#undef cv_hal_normDiff
#define cv_hal_normDiff ipp_hal_normDiff
int ipp_hal_sum(const uchar *src_data, size_t src_step, int src_type, int width, int height, double *result);
#undef cv_hal_sum
#define cv_hal_sum ipp_hal_sum
#endif
int ipp_hal_polarToCart32f(const float* mag, const float* angle, float* x, float* y, int len, bool angleInDegrees);
int ipp_hal_polarToCart64f(const double* mag, const double* angle, double* x, double* y, int len, bool angleInDegrees);
#undef cv_hal_polarToCart32f
#define cv_hal_polarToCart32f ipp_hal_polarToCart32f
#undef cv_hal_polarToCart64f
#define cv_hal_polarToCart64f ipp_hal_polarToCart64f
#ifdef HAVE_IPP_IW
int ipp_hal_flip(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
uchar* dst_data, size_t dst_step, int flip_mode);
#undef cv_hal_flip
#define cv_hal_flip ipp_hal_flip
#endif
int ipp_hal_transpose2d(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int src_width,
int src_height, int element_size);
#undef cv_hal_transpose2d
#define cv_hal_transpose2d ipp_hal_transpose2d
//! @endcond
#endif
+42
View File
@@ -0,0 +1,42 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef __IPP_HAL_IMGPROC_HPP__
#define __IPP_HAL_IMGPROC_HPP__
#include <opencv2/core/base.hpp>
#include "ipp_utils.hpp"
#if IPP_VERSION_X100 >= 810
#if defined(HAVE_IPP_IW)
int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width,
int dst_height, const double M[6], int interpolation, int borderType, const double borderValue[4]);
// Does not pass tests in 5.x branch
//#undef cv_hal_warpAffine
//#define cv_hal_warpAffine ipp_hal_warpAffine
#endif
#if IPP_VERSION_X100 >= 202600
int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, 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]);
// Does not pass tests in 5.x branch
//#undef cv_hal_warpPerspective
//#define cv_hal_warpPerspective ipp_hal_warpPerspective
#endif // IPP_VERSION_X100 >= 202600
int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
float* mapx, size_t mapx_step, float* mapy, size_t mapy_step,
int interpolation, int border_type, const double border_value[4]);
#undef cv_hal_remap32f
#define cv_hal_remap32f ipp_hal_remap32f
#endif //IPP_VERSION_X100 >= 810
#endif //__IPP_HAL_IMGPROC_HPP__
+30
View File
@@ -0,0 +1,30 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef __IPP_HAL_UTILS_HPP__
#define __IPP_HAL_UTILS_HPP__
#include "ippversion.h"
#ifndef IPP_VERSION_UPDATE // prior to 7.1
#define IPP_VERSION_UPDATE 0
#endif
#define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR*10 + IPP_VERSION_UPDATE)
#ifdef HAVE_IPP_ICV
# define ICV_BASE
#if IPP_VERSION_X100 >= 201700
# include "ippicv.h"
#else
# include "ipp.h"
#endif
#else
# include "ipp.h"
#endif
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
#define CV_HAL_CHECK_USE_IPP() if(!cv::ipp::useIPP()) return CV_HAL_ERROR_NOT_IMPLEMENTED;
#endif
+34
View File
@@ -0,0 +1,34 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "ipp_hal_core.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/core/base.hpp>
int ipp_hal_polarToCart32f(const float* mag, const float* angle, float* x, float* y, int len, bool angleInDegrees)
{
CV_HAL_CHECK_USE_IPP();
const bool isInPlace = (x == mag) || (x == angle) || (y == mag) || (y == angle);
if (isInPlace || angleInDegrees)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_32f, mag, angle, x, y, len) < 0)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
return CV_HAL_ERROR_OK;
}
int ipp_hal_polarToCart64f(const double* mag, const double* angle, double* x, double* y, int len, bool angleInDegrees)
{
CV_HAL_CHECK_USE_IPP();
const bool isInPlace = (x == mag) || (x == angle) || (y == mag) || (y == angle);
if (isInPlace || angleInDegrees)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if (CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_64f, mag, angle, x, y, len) < 0)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
return CV_HAL_ERROR_OK;
}
+211
View File
@@ -0,0 +1,211 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "ipp_hal_core.hpp"
#include <opencv2/core.hpp>
#include <opencv2/core/base.hpp>
#if IPP_VERSION_X100 >= 700
static int ipp_mean(const uchar* src_data, size_t src_step, int width, int height,
int src_type, double* mean_val, uchar* mask, size_t mask_step)
{
int cn = CV_MAT_CN(src_type);
if (cn > 4)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
if((src_step == 1 || src_step == static_cast<size_t>(width)) && (mask_step == 1 || mask_step == static_cast<size_t>(width)))
{
IppiSize sz = { width, height };
if( mask )
{
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskMeanFuncC1 ippiMean_C1MR =
src_type == CV_8UC1 ? (ippiMaskMeanFuncC1)ippiMean_8u_C1MR :
src_type == CV_16UC1 ? (ippiMaskMeanFuncC1)ippiMean_16u_C1MR :
src_type == CV_32FC1 ? (ippiMaskMeanFuncC1)ippiMean_32f_C1MR :
0;
if( ippiMean_C1MR )
{
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C1MR, src_data, (int)src_step, mask, (int)mask_step, sz, mean_val) >= 0 )
{
return CV_HAL_ERROR_OK;
}
}
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
ippiMaskMeanFuncC3 ippiMean_C3MR =
src_type == CV_8UC3 ? (ippiMaskMeanFuncC3)ippiMean_8u_C3CMR :
src_type == CV_16UC3 ? (ippiMaskMeanFuncC3)ippiMean_16u_C3CMR :
src_type == CV_32FC3 ? (ippiMaskMeanFuncC3)ippiMean_32f_C3CMR :
0;
if( ippiMean_C3MR )
{
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 1, &mean_val[0]) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 2, &mean_val[1]) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 3, &mean_val[2]) >= 0 )
{
return CV_HAL_ERROR_OK;
}
}
}
else
{
typedef IppStatus (CV_STDCALL* ippiMeanFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm);
typedef IppStatus (CV_STDCALL* ippiMeanFuncNoHint)(const void*, int, IppiSize, double *);
ippiMeanFuncHint ippiMeanHint =
src_type == CV_32FC1 ? (ippiMeanFuncHint)ippiMean_32f_C1R :
src_type == CV_32FC3 ? (ippiMeanFuncHint)ippiMean_32f_C3R :
src_type == CV_32FC4 ? (ippiMeanFuncHint)ippiMean_32f_C4R :
0;
ippiMeanFuncNoHint ippiMean =
src_type == CV_8UC1 ? (ippiMeanFuncNoHint)ippiMean_8u_C1R :
src_type == CV_8UC3 ? (ippiMeanFuncNoHint)ippiMean_8u_C3R :
src_type == CV_8UC4 ? (ippiMeanFuncNoHint)ippiMean_8u_C4R :
src_type == CV_16UC1 ? (ippiMeanFuncNoHint)ippiMean_16u_C1R :
src_type == CV_16UC3 ? (ippiMeanFuncNoHint)ippiMean_16u_C3R :
src_type == CV_16UC4 ? (ippiMeanFuncNoHint)ippiMean_16u_C4R :
src_type == CV_16SC1 ? (ippiMeanFuncNoHint)ippiMean_16s_C1R :
src_type == CV_16SC3 ? (ippiMeanFuncNoHint)ippiMean_16s_C3R :
src_type == CV_16SC4 ? (ippiMeanFuncNoHint)ippiMean_16s_C4R :
0;
// Make sure only zero or one version of the function pointer is valid
CV_Assert(!ippiMeanHint || !ippiMean);
if( ippiMeanHint || ippiMean )
{
IppStatus status = ippiMeanHint ? CV_INSTRUMENT_FUN_IPP(ippiMeanHint, src_data, (int)src_step, sz, mean_val, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiMean, src_data, (int)src_step, sz, mean_val);
if( status >= 0 )
{
return CV_HAL_ERROR_OK;
}
}
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
static int ipp_meanStdDev(const uchar* src_data, size_t src_step, int width, int height,
int src_type, double* mean_val, double* stddev_val, uchar* mask, size_t mask_step)
{
int cn = CV_MAT_CN(src_type);
if((src_step == 1 || src_step == static_cast<size_t>(width)) && (mask_step == 1 || mask_step == static_cast<size_t>(width)))
{
Ipp64f mean_temp[3];
Ipp64f stddev_temp[3];
Ipp64f *pmean = &mean_temp[0];
Ipp64f *pstddev = &stddev_temp[0];
int dcn_mean = -1;
if( mean_val )
{
dcn_mean = cn;
pmean = mean_val;
}
int dcn_stddev = -1;
if( stddev_val )
{
dcn_stddev = cn;
pstddev = stddev_val;
}
for( int c = cn; c < dcn_mean; c++ )
pmean[c] = 0;
for( int c = cn; c < dcn_stddev; c++ )
pstddev[c] = 0;
IppiSize sz = { width, height };
if( !mask )
{
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *, Ipp64f *);
ippiMaskMeanStdDevFuncC1 ippiMean_StdDev_C1MR =
src_type == CV_8UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_8u_C1MR :
src_type == CV_16UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_16u_C1MR :
src_type == CV_32FC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_32f_C1MR :
nullptr;
if( ippiMean_StdDev_C1MR )
{
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1MR, src_data, (int)src_step, mask, (int)mask_step, sz, pmean, pstddev) >= 0 )
{
return CV_HAL_ERROR_OK;
}
}
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
ippiMaskMeanStdDevFuncC3 ippiMean_StdDev_C3CMR =
src_type == CV_8UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CMR :
src_type == CV_16UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CMR :
src_type == CV_32FC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CMR :
nullptr;
if( ippiMean_StdDev_C3CMR )
{
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 3, &pmean[2], &pstddev[2]) >= 0 )
{
return CV_HAL_ERROR_OK;
}
}
}
else
{
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC1)(const void *, int, IppiSize, Ipp64f *, Ipp64f *);
ippiMeanStdDevFuncC1 ippiMean_StdDev_C1R =
src_type == CV_8UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_8u_C1R :
src_type == CV_16UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_16u_C1R :
#if (IPP_VERSION_X100 >= 810)
src_type == CV_32FC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_32f_C1R ://Aug 2013: bug in IPP 7.1, 8.0
#endif
nullptr;
if( ippiMean_StdDev_C1R )
{
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1R, src_data, (int)src_step, sz, pmean, pstddev) >= 0 )
{
return CV_HAL_ERROR_OK;
}
}
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC3)(const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
ippiMeanStdDevFuncC3 ippiMean_StdDev_C3CR =
src_type == CV_8UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CR :
src_type == CV_16UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CR :
src_type == CV_32FC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CR :
nullptr;
if( ippiMean_StdDev_C3CR )
{
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 3, &pmean[2], &pstddev[2]) >= 0 )
{
return CV_HAL_ERROR_OK;
}
}
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
int ipp_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int height, int src_type,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step)
{
CV_HAL_CHECK_USE_IPP();
if (stddev_val)
{
return ipp_meanStdDev(src_data, src_step, width, height, src_type, mean_val, stddev_val, mask, mask_step);
}
else
{
return ipp_mean(src_data, src_step, width, height, src_type, mean_val, mask, mask_step);
}
}
#endif // IPP_VERSION_X100 >= 700
+257
View File
@@ -0,0 +1,257 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "ipp_hal_core.hpp"
#include <opencv2/core.hpp>
#include <opencv2/core/base.hpp>
#define IPP_DISABLE_MINMAXIDX_MANY_ROWS 1 // see Core_MinMaxIdx.rows_overflow test
static inline IppDataType ippiGetDataType(int depth)
{
depth = CV_MAT_DEPTH(depth);
return depth == CV_8U ? ipp8u :
depth == CV_8S ? ipp8s :
depth == CV_16U ? ipp16u :
depth == CV_16S ? ipp16s :
depth == CV_32S ? ipp32s :
depth == CV_32F ? ipp32f :
depth == CV_64F ? ipp64f :
(IppDataType)-1;
}
#if IPP_VERSION_X100 >= 700
static IppStatus ipp_minMaxIndex_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint* pMinIndex, IppiPoint* pMaxIndex, const Ipp8u*, int)
{
switch(dataType)
{
case ipp8u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp16u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
default: return ippStsDataTypeErr;
}
}
static IppStatus ipp_minMaxIndexMask_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint* pMinIndex, IppiPoint* pMaxIndex, const Ipp8u* pMask, int maskStep)
{
switch(dataType)
{
case ipp8u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_8u_C1MR, (const Ipp8u*)pSrc, srcStep, pMask, maskStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp16u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_16u_C1MR, (const Ipp16u*)pSrc, srcStep, pMask, maskStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_32f_C1MR, (const Ipp32f*)pSrc, srcStep, pMask, maskStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
default: return ippStsDataTypeErr;
}
}
static IppStatus ipp_minMax_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint*, IppiPoint*, const Ipp8u*, int)
{
IppStatus status;
switch(dataType)
{
#if IPP_VERSION_X100 > 201701 // wrong min values
case ipp8u:
{
Ipp8u val[2];
status = CV_INSTRUMENT_FUN_IPP(ippiMinMax_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, &val[0], &val[1]);
*pMinVal = val[0];
*pMaxVal = val[1];
return status;
}
#endif
case ipp16u:
{
Ipp16u val[2];
status = CV_INSTRUMENT_FUN_IPP(ippiMinMax_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, &val[0], &val[1]);
*pMinVal = val[0];
*pMaxVal = val[1];
return status;
}
case ipp16s:
{
Ipp16s val[2];
status = CV_INSTRUMENT_FUN_IPP(ippiMinMax_16s_C1R, (const Ipp16s*)pSrc, srcStep, size, &val[0], &val[1]);
*pMinVal = val[0];
*pMaxVal = val[1];
return status;
}
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinMax_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMinVal, pMaxVal);
default: return ipp_minMaxIndex_wrap(pSrc, srcStep, size, dataType, pMinVal, pMaxVal, NULL, NULL, NULL, 0);
}
}
static IppStatus ipp_minIdx_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float*, IppiPoint* pMinIndex, IppiPoint*, const Ipp8u*, int)
{
IppStatus status;
switch(dataType)
{
case ipp8u:
{
Ipp8u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMinIndx_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, &val, &pMinIndex->x, &pMinIndex->y);
*pMinVal = val;
return status;
}
case ipp16u:
{
Ipp16u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMinIndx_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, &val, &pMinIndex->x, &pMinIndex->y);
*pMinVal = val;
return status;
}
case ipp16s:
{
Ipp16s val;
status = CV_INSTRUMENT_FUN_IPP(ippiMinIndx_16s_C1R, (const Ipp16s*)pSrc, srcStep, size, &val, &pMinIndex->x, &pMinIndex->y);
*pMinVal = val;
return status;
}
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinIndx_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMinVal, &pMinIndex->x, &pMinIndex->y);
default: return ipp_minMaxIndex_wrap(pSrc, srcStep, size, dataType, pMinVal, NULL, pMinIndex, NULL, NULL, 0);
}
}
static IppStatus ipp_maxIdx_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float*, float* pMaxVal, IppiPoint*, IppiPoint* pMaxIndex, const Ipp8u*, int)
{
IppStatus status;
switch(dataType)
{
case ipp8u:
{
Ipp8u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, &val, &pMaxIndex->x, &pMaxIndex->y);
*pMaxVal = val;
return status;
}
case ipp16u:
{
Ipp16u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, &val, &pMaxIndex->x, &pMaxIndex->y);
*pMaxVal = val;
return status;
}
case ipp16s:
{
Ipp16s val;
status = CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_16s_C1R, (const Ipp16s*)pSrc, srcStep, size, &val, &pMaxIndex->x, &pMaxIndex->y);
*pMaxVal = val;
return status;
}
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMaxVal, &pMaxIndex->x, &pMaxIndex->y);
default: return ipp_minMaxIndex_wrap(pSrc, srcStep, size, dataType, NULL, pMaxVal, NULL, pMaxIndex, NULL, 0);
}
}
typedef IppStatus (*IppMinMaxSelector)(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint* pMinIndex, IppiPoint* pMaxIndex, const Ipp8u* pMask, int maskStep);
int ipp_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width, int height, int depth,
double* _minVal, double* _maxVal, int* _minIdx, int* _maxIdx, uchar* mask, size_t mask_step)
{
CV_HAL_CHECK_USE_IPP();
#if IPP_VERSION_X100 < 201800
// cv::minMaxIdx problem with NaN input
// Disable 32F processing only
if(depth == CV_32F && cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
#endif
#if IPP_VERSION_X100 < 201801
// cv::minMaxIdx problem with index positions on AVX
if(mask && _maxIdx && cv::ipp::getIppTopFeatures() != ippCPUID_SSE42)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
#endif
IppStatus status;
IppDataType dataType = ippiGetDataType(depth);
float minVal = 0;
float maxVal = 0;
IppiPoint minIdx = {-1, -1};
IppiPoint maxIdx = {-1, -1};
float *pMinVal = (_minVal || _minIdx)?&minVal:NULL;
float *pMaxVal = (_maxVal || _maxIdx)?&maxVal:NULL;
IppiPoint *pMinIdx = (_minIdx)?&minIdx:NULL;
IppiPoint *pMaxIdx = (_maxIdx)?&maxIdx:NULL;
IppMinMaxSelector ippMinMaxFun = ipp_minMaxIndexMask_wrap;
if(!mask)
{
if(_maxVal && _maxIdx && !_minVal && !_minIdx)
ippMinMaxFun = ipp_maxIdx_wrap;
else if(!_maxVal && !_maxIdx && _minVal && _minIdx)
ippMinMaxFun = ipp_minIdx_wrap;
else if(_maxVal && !_maxIdx && _minVal && !_minIdx)
ippMinMaxFun = ipp_minMax_wrap;
else if(!_maxVal && !_maxIdx && !_minVal && !_minIdx)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
else
ippMinMaxFun = ipp_minMaxIndex_wrap;
}
IppiSize size = { width, height };
#if defined(_WIN32) && !defined(_WIN64) && IPP_VERSION_X100 == 201900 && IPP_DISABLE_MINMAXIDX_MANY_ROWS
if (size.height > 65536)
return CV_HAL_ERROR_NOT_IMPLEMENTED; // test: Core_MinMaxIdx.rows_overflow
#endif
status = ippMinMaxFun(src_data, (int)src_step, size, dataType, pMinVal, pMaxVal, pMinIdx, pMaxIdx, (Ipp8u*)mask, (int)mask_step);
if(status < 0)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
if(_minVal)
*_minVal = minVal;
if(_maxVal)
*_maxVal = maxVal;
if(_minIdx)
{
#if IPP_VERSION_X100 < 201801
// Should be just ippStsNoOperation check, but there is a bug in the function so we need additional checks
if(status == ippStsNoOperation && mask && !pMinIdx->x && !pMinIdx->y)
#else
if(status == ippStsNoOperation)
#endif
{
_minIdx[0] = -1;
_minIdx[1] = -1;
}
else
{
_minIdx[0] = minIdx.y;
_minIdx[1] = minIdx.x;
}
}
if(_maxIdx)
{
#if IPP_VERSION_X100 < 201801
// Should be just ippStsNoOperation check, but there is a bug in the function so we need additional checks
if(status == ippStsNoOperation && mask && !pMaxIdx->x && !pMaxIdx->y)
#else
if(status == ippStsNoOperation)
#endif
{
_maxIdx[0] = -1;
_maxIdx[1] = -1;
}
else
{
_maxIdx[0] = maxIdx.y;
_maxIdx[1] = maxIdx.x;
}
}
return CV_HAL_ERROR_OK;
}
#endif // IPP_VERSION_X100 >= 700
+355
View File
@@ -0,0 +1,355 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "ipp_hal_core.hpp"
#include <opencv2/core.hpp>
#include <opencv2/core/base.hpp>
#if IPP_VERSION_X100 >= 700
int ipp_hal_norm(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step,
int width, int height, int type, int norm_type, double* result)
{
CV_HAL_CHECK_USE_IPP();
if( mask )
{
IppiSize sz = { width, height };
typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskNormFuncC1 ippiNorm_C1MR =
norm_type == cv::NORM_INF ?
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_8u_C1MR :
#if (!IPP_DISABLE_NORM_INF_16U_C1MR)
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_16u_C1MR :
#endif
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_32f_C1MR :
0) :
norm_type == cv::NORM_L1 ?
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_32f_C1MR :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_32f_C1MR :
0) : 0;
if( ippiNorm_C1MR )
{
Ipp64f norm;
if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C1MR, src, (int)src_step, mask, (int)mask_step, sz, &norm) >= 0 )
{
*result = (norm_type == cv::NORM_L2SQR ? (double)(norm * norm) : (double)norm);
return CV_HAL_ERROR_OK;
}
}
typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
ippiMaskNormFuncC3 ippiNorm_C3CMR =
norm_type == cv::NORM_INF ?
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR :
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR :
0) :
norm_type == cv::NORM_L1 ?
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR :
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_32f_C3CMR :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8u_C3CMR :
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_32f_C3CMR :
0) : 0;
if( ippiNorm_C3CMR )
{
Ipp64f norm1, norm2, norm3;
if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src, (int)src_step, mask, (int)mask_step, sz, 1, &norm1) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src, (int)src_step, mask, (int)mask_step, sz, 2, &norm2) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src, (int)src_step, mask, (int)mask_step, sz, 3, &norm3) >= 0)
{
Ipp64f norm =
norm_type == cv::NORM_INF ? std::max(std::max(norm1, norm2), norm3) :
norm_type == cv::NORM_L1 ? norm1 + norm2 + norm3 :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) :
0;
*result = (norm_type == cv::NORM_L2SQR ? (double)(norm * norm) : (double)norm);
return CV_HAL_ERROR_OK;
}
}
}
else
{
int cn = CV_MAT_CN(type);
IppiSize sz = { width*cn, height };
typedef IppStatus (CV_STDCALL* ippiNormFuncHint)(const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
typedef IppStatus (CV_STDCALL* ippiNormFuncNoHint)(const void *, int, IppiSize, Ipp64f *);
ippiNormFuncHint ippiNormHint =
norm_type == cv::NORM_L1 ?
(type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L1_32f_C1R :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L2_32f_C1R :
0) : 0;
ippiNormFuncNoHint ippiNorm =
norm_type == cv::NORM_INF ?
(type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_8u_C1R :
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16u_C1R :
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16s_C1R :
type == CV_32FC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_32f_C1R :
0) :
norm_type == cv::NORM_L1 ?
(type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_8u_C1R :
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16u_C1R :
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16s_C1R :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(
#if (!IPP_DISABLE_NORM_8U)
type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_8u_C1R :
#endif
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16u_C1R :
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16s_C1R :
0) : 0;
if( ippiNormHint || ippiNorm )
{
Ipp64f norm;
IppStatus ret = ippiNormHint ? CV_INSTRUMENT_FUN_IPP(ippiNormHint, src, (int)src_step, sz, &norm, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNorm, src, (int)src_step, sz, &norm);
if( ret >= 0 )
{
*result = (norm_type == cv::NORM_L2SQR) ? norm * norm : norm;
return CV_HAL_ERROR_OK;
}
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
int ipp_hal_normDiff(const uchar* src1, size_t src1_step, const uchar* src2, size_t src2_step, const uchar* mask,
size_t mask_step, int width, int height, int type, int norm_type, double* result)
{
CV_HAL_CHECK_USE_IPP();
if( norm_type & cv::NORM_RELATIVE )
{
norm_type &= cv::NORM_TYPE_MASK;
if( mask )
{
IppiSize sz = { width, height };
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskNormDiffFuncC1 ippiNormRel_C1MR =
norm_type == cv::NORM_INF ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_8u_C1MR :
#if (!IPP_DISABLE_NORM_INF_16U_C1MR)
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_16u_C1MR :
#endif
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_32f_C1MR :
0) :
norm_type == cv::NORM_L1 ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_32f_C1MR :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_32f_C1MR :
0) : 0;
if( ippiNormRel_C1MR )
{
Ipp64f norm;
if( CV_INSTRUMENT_FUN_IPP(ippiNormRel_C1MR, src1, (int)src1_step, src2, (int)src2_step, mask, (int)mask_step, sz, &norm) >= 0 )
{
*result = (norm_type == cv::NORM_L2SQR ? (double)(norm * norm) : (double)norm);
return CV_HAL_ERROR_OK;
}
}
}
else
{
int cn = CV_MAT_CN(type);
type = CV_MAT_DEPTH(type);
IppiSize sz = { width*cn, height };
typedef IppStatus (CV_STDCALL* ippiNormRelFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
typedef IppStatus (CV_STDCALL* ippiNormRelFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiNormRelFuncHint ippiNormRelHint =
norm_type == cv::NORM_L1 ?
(type == CV_32F ? (ippiNormRelFuncHint)ippiNormRel_L1_32f_C1R :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_32F ? (ippiNormRelFuncHint)ippiNormRel_L2_32f_C1R :
0) : 0;
ippiNormRelFuncNoHint ippiNormRel =
norm_type == cv::NORM_INF ?
(
#if (!IPP_DISABLE_NORM_8U)
type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_8u_C1R :
#endif
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16u_C1R :
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16s_C1R :
type == CV_32F ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_32f_C1R :
0) :
norm_type == cv::NORM_L1 ?
(
#if (!IPP_DISABLE_NORM_8U)
type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_L1_8u_C1R :
#endif
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16u_C1R :
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16s_C1R :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(
#if (!IPP_DISABLE_NORM_8U)
type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_L2_8u_C1R :
#endif
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16u_C1R :
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16s_C1R :
0) : 0;
if( ippiNormRelHint || ippiNormRel )
{
Ipp64f norm;
IppStatus ret = ippiNormRelHint ? CV_INSTRUMENT_FUN_IPP(ippiNormRelHint, src1, (int)src1_step, src2, (int)src2_step, sz, &norm, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNormRel, src1, (int)src1_step, src2, (int)src2_step, sz, &norm);
if( ret >= 0 )
{
*result = (norm_type == cv::NORM_L2SQR) ? norm * norm : norm;
return CV_HAL_ERROR_OK;
}
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
norm_type &= cv::NORM_TYPE_MASK;
if( mask )
{
IppiSize sz = { width, height };
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskNormDiffFuncC1 ippiNormDiff_C1MR =
norm_type == cv::NORM_INF ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_8u_C1MR :
#if (!IPP_DISABLE_NORM_INF_16U_C1MR)
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_16u_C1MR :
#endif
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_32f_C1MR :
0) :
norm_type == cv::NORM_L1 ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_32f_C1MR :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_32f_C1MR :
0) : 0;
if( ippiNormDiff_C1MR )
{
Ipp64f norm;
if( CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C1MR, src1, (int)src1_step, src2, (int)src2_step, mask, (int)mask_step, sz, &norm) >= 0 )
{
*result = (norm_type == cv::NORM_L2SQR ? (double)(norm * norm) : (double)norm);
return CV_HAL_ERROR_OK;
}
}
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC3)(const void *, int, const void *, int, const void *, int, IppiSize, int, Ipp64f *);
ippiMaskNormDiffFuncC3 ippiNormDiff_C3CMR =
norm_type == cv::NORM_INF ?
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_8u_C3CMR :
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_32f_C3CMR :
0) :
norm_type == cv::NORM_L1 ?
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_8u_C3CMR :
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_32f_C3CMR :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_8u_C3CMR :
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_32f_C3CMR :
0) : 0;
if( ippiNormDiff_C3CMR )
{
Ipp64f norm1, norm2, norm3;
if( CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C3CMR, src1, (int)src1_step, src2, (int)src2_step, mask, (int)mask_step, sz, 1, &norm1) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C3CMR, src1, (int)src1_step, src2, (int)src2_step, mask, (int)mask_step, sz, 2, &norm2) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C3CMR, src1, (int)src1_step, src2, (int)src2_step, mask, (int)mask_step, sz, 3, &norm3) >= 0)
{
Ipp64f norm =
norm_type == cv::NORM_INF ? std::max(std::max(norm1, norm2), norm3) :
norm_type == cv::NORM_L1 ? norm1 + norm2 + norm3 :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) :
0;
*result = (norm_type == cv::NORM_L2SQR ? (double)(norm * norm) : (double)norm);
return CV_HAL_ERROR_OK;
}
}
}
else
{
int cn = CV_MAT_CN(type);
type = CV_MAT_DEPTH(type);
IppiSize sz = { width*cn, height };
typedef IppStatus (CV_STDCALL* ippiNormDiffFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
typedef IppStatus (CV_STDCALL* ippiNormDiffFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiNormDiffFuncHint ippiNormDiffHint =
norm_type == cv::NORM_L1 ?
(type == CV_32F ? (ippiNormDiffFuncHint)ippiNormDiff_L1_32f_C1R :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(type == CV_32F ? (ippiNormDiffFuncHint)ippiNormDiff_L2_32f_C1R :
0) : 0;
ippiNormDiffFuncNoHint ippiNormDiff =
norm_type == cv::NORM_INF ?
(
#if (!IPP_DISABLE_NORM_8U)
type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_8u_C1R :
#endif
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16u_C1R :
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16s_C1R :
type == CV_32F ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_32f_C1R :
0) :
norm_type == cv::NORM_L1 ?
(
#if (!IPP_DISABLE_NORM_8U)
type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_8u_C1R :
#endif
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C1R :
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C1R :
0) :
norm_type == cv::NORM_L2 || norm_type == cv::NORM_L2SQR ?
(
#if (!IPP_DISABLE_NORM_8U)
type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_8u_C1R :
#endif
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16u_C1R :
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16s_C1R :
0) : 0;
if( ippiNormDiffHint || ippiNormDiff )
{
Ipp64f norm;
IppStatus ret = ippiNormDiffHint ? CV_INSTRUMENT_FUN_IPP(ippiNormDiffHint, src1, (int)src1_step, src2, (int)src2_step, sz, &norm, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNormDiff, src1, (int)src1_step, src2, (int)src2_step, sz, &norm);
if( ret >= 0 )
{
*result = (norm_type == cv::NORM_L2SQR) ? norm * norm : norm;
return CV_HAL_ERROR_OK;
}
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
#endif
+109
View File
@@ -0,0 +1,109 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef __PRECOMP_IPP_HPP__
#define __PRECOMP_IPP_HPP__
#include <opencv2/imgproc.hpp>
#ifdef HAVE_IPP_IW
#include "iw++/iw.hpp"
#endif
static inline IppiSize ippiSize(size_t width, size_t height)
{
IppiSize size = { (int)width, (int)height };
return size;
}
static inline IppiSize ippiSize(const cv::Size & _size)
{
IppiSize size = { _size.width, _size.height };
return size;
}
static inline IppDataType ippiGetDataType(int depth)
{
depth = CV_MAT_DEPTH(depth);
return depth == CV_8U ? ipp8u :
depth == CV_8S ? ipp8s :
depth == CV_16U ? ipp16u :
depth == CV_16S ? ipp16s :
depth == CV_32S ? ipp32s :
depth == CV_32F ? ipp32f :
depth == CV_64F ? ipp64f :
(IppDataType)-1;
}
static inline IppiInterpolationType ippiGetInterpolation(int inter)
{
inter &= cv::InterpolationFlags::INTER_MAX;
return inter == cv::InterpolationFlags::INTER_NEAREST ? ippNearest :
inter == cv::InterpolationFlags::INTER_LINEAR ? ippLinear :
inter == cv::InterpolationFlags::INTER_CUBIC ? ippCubic :
inter == cv::InterpolationFlags::INTER_LANCZOS4 ? ippLanczos :
inter == cv::InterpolationFlags::INTER_AREA ? ippSuper :
(IppiInterpolationType)-1;
}
static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
{
return borderTypeNI == cv::BorderTypes::BORDER_CONSTANT ? ippBorderConst :
borderTypeNI == cv::BorderTypes::BORDER_TRANSPARENT ? ippBorderTransp :
borderTypeNI == cv::BorderTypes::BORDER_REPLICATE ? ippBorderRepl :
(IppiBorderType)-1;
}
static inline int ippiSuggestThreadsNum(size_t width, size_t height, size_t elemSize, double multiplier)
{
int threads = cv::getNumThreads();
if(threads > 1 && height >= 64)
{
size_t opMemory = (int)(width*height*elemSize*multiplier);
int l2cache = 0;
#if IPP_VERSION_X100 >= 201700
ippGetL2CacheSize(&l2cache);
#endif
if(!l2cache)
l2cache = 1 << 18;
return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
}
return 1;
}
static inline int ippiSuggestRowThreadsNum(size_t width, size_t height, size_t elemSize, size_t payloadSize)
{
int num_threads = cv::getNumThreads();
if(num_threads > 1)
{
long rowThreads = static_cast<long>(height);
// row-based range shall not allow to split rows
num_threads = (rowThreads < num_threads) ? rowThreads : num_threads;
long rows_per_thread = (rowThreads + num_threads - 1) / num_threads;
size_t item_size = width * elemSize; // row size in bytes
if(static_cast<size_t>(item_size * rows_per_thread) < payloadSize)
{
long items_per_thread = IPP_MAX(1L, static_cast<long>(payloadSize / item_size ));
num_threads = static_cast<int>((height + items_per_thread - 1L) / items_per_thread);
}
}
return num_threads;
}
#ifdef HAVE_IPP_IW
static inline int ippiSuggestThreadsNum(const ::ipp::IwiImage &image, double multiplier)
{
return ippiSuggestThreadsNum(image.m_size.width, image.m_size.height, image.m_typeSize*image.m_channels, multiplier);
}
static inline int ippiSuggestRowThreadsNum(const ::ipp::IwiImage &image, size_t payloadSize)
{
return ippiSuggestRowThreadsNum(image.m_size.width, image.m_size.height, image.m_typeSize*image.m_channels, payloadSize);
}
#endif
#endif //__PRECOMP_IPP_HPP__
+60
View File
@@ -0,0 +1,60 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "ipp_hal_core.hpp"
#include <opencv2/core.hpp>
#include <opencv2/core/base.hpp>
#if IPP_VERSION_X100 >= 700
int ipp_hal_sum(const uchar *src_data, size_t src_step, int src_type, int width, int height, double *result)
{
CV_HAL_CHECK_USE_IPP();
int cn = CV_MAT_CN(src_type);
if (cn > 4)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
IppiSize sz = { width, height };
typedef IppStatus (CV_STDCALL* ippiSumFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm);
typedef IppStatus (CV_STDCALL* ippiSumFuncNoHint)(const void*, int, IppiSize, double *);
ippiSumFuncHint ippiSumHint =
src_type == CV_32FC1 ? (ippiSumFuncHint)ippiSum_32f_C1R :
src_type == CV_32FC3 ? (ippiSumFuncHint)ippiSum_32f_C3R :
src_type == CV_32FC4 ? (ippiSumFuncHint)ippiSum_32f_C4R :
0;
ippiSumFuncNoHint ippiSum =
src_type == CV_8UC1 ? (ippiSumFuncNoHint)ippiSum_8u_C1R :
src_type == CV_8UC3 ? (ippiSumFuncNoHint)ippiSum_8u_C3R :
src_type == CV_8UC4 ? (ippiSumFuncNoHint)ippiSum_8u_C4R :
src_type == CV_16UC1 ? (ippiSumFuncNoHint)ippiSum_16u_C1R :
src_type == CV_16UC3 ? (ippiSumFuncNoHint)ippiSum_16u_C3R :
src_type == CV_16UC4 ? (ippiSumFuncNoHint)ippiSum_16u_C4R :
src_type == CV_16SC1 ? (ippiSumFuncNoHint)ippiSum_16s_C1R :
src_type == CV_16SC3 ? (ippiSumFuncNoHint)ippiSum_16s_C3R :
src_type == CV_16SC4 ? (ippiSumFuncNoHint)ippiSum_16s_C4R :
0;
if( ippiSumHint || ippiSum )
{
IppStatus ret = ippiSumHint ?
CV_INSTRUMENT_FUN_IPP(ippiSumHint, src_data, (int)src_step, sz, result, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiSum, src_data, (int)src_step, sz, result);
if( ret >= 0 )
{
return CV_HAL_ERROR_OK;
}
else
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
#endif
+136
View File
@@ -0,0 +1,136 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "ipp_hal_core.hpp"
#include "precomp_ipp.hpp"
#include <opencv2/core.hpp>
#include <opencv2/core/base.hpp>
#ifdef HAVE_IPP_IW
#include "iw++/iw.hpp"
#endif
// HACK: Should be removed, when IPP management moved to HAL
namespace cv
{
namespace ipp
{
unsigned long long getIppTopFeatures(); // Returns top major enabled IPP feature flag
}
}
//bool ipp_transpose( Mat &src, Mat &dst )
int ipp_hal_transpose2d(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int src_width,
int src_height, int element_size)
{
CV_HAL_CHECK_USE_IPP();
typedef IppStatus (CV_STDCALL * IppiTranspose)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * IppiTransposeI)(const void * pSrcDst, int srcDstStep, IppiSize roiSize);
IppiTranspose ippiTranspose = nullptr;
IppiTransposeI ippiTranspose_I = nullptr;
if (dst_data == src_data && src_width == src_height)
{
CV_SUPPRESS_DEPRECATED_START
ippiTranspose_I =
element_size == 1*sizeof(char) ? (IppiTransposeI)ippiTranspose_8u_C1IR :
element_size == 3*sizeof(char) ? (IppiTransposeI)ippiTranspose_8u_C3IR :
element_size == 1*sizeof(short) ? (IppiTransposeI)ippiTranspose_16u_C1IR :
element_size == 4*sizeof(char) ? (IppiTransposeI)ippiTranspose_8u_C4IR :
element_size == 3*sizeof(short) ? (IppiTransposeI)ippiTranspose_16u_C3IR :
element_size == 4*sizeof(short) ? (IppiTransposeI)ippiTranspose_16u_C4IR :
element_size == 3*sizeof(int) ? (IppiTransposeI)ippiTranspose_32s_C3IR :
element_size == 4*sizeof(int) ? (IppiTransposeI)ippiTranspose_32s_C4IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
else
{
ippiTranspose =
element_size == 1*sizeof(char) ? (IppiTranspose)ippiTranspose_8u_C1R :
element_size == 3*sizeof(char) ? (IppiTranspose)ippiTranspose_8u_C3R :
element_size == 4*sizeof(char) ? (IppiTranspose)ippiTranspose_8u_C4R :
element_size == 1*sizeof(short) ? (IppiTranspose)ippiTranspose_16u_C1R :
element_size == 3*sizeof(short) ? (IppiTranspose)ippiTranspose_16u_C3R :
element_size == 4*sizeof(short) ? (IppiTranspose)ippiTranspose_16u_C4R :
element_size == 1*sizeof(int) ? (IppiTranspose)ippiTranspose_32s_C1R :
element_size == 3*sizeof(int) ? (IppiTranspose)ippiTranspose_32s_C3R :
element_size == 4*sizeof(int) ? (IppiTranspose)ippiTranspose_32s_C4R : 0;
}
IppiSize roiSize = { src_width, src_height };
if (ippiTranspose != 0)
{
if (CV_INSTRUMENT_FUN_IPP(ippiTranspose, src_data, (int)src_step, dst_data, (int)dst_step, roiSize) >= 0)
return CV_HAL_ERROR_OK;
}
else if (ippiTranspose_I != 0)
{
if (CV_INSTRUMENT_FUN_IPP(ippiTranspose_I, dst_data, (int)dst_step, roiSize) >= 0)
return CV_HAL_ERROR_OK;
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
#ifdef HAVE_IPP_IW
static inline ::ipp::IwiImage ippiGetImage(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height)
{
::ipp::IwiImage dst;
::ipp::IwiBorderSize inMemBorder;
// if(src.isSubmatrix()) // already have physical border
// {
// cv::Size origSize;
// cv::Point offset;
// src.locateROI(origSize, offset);
//
// inMemBorder.left = (IwSize)offset.x;
// inMemBorder.top = (IwSize)offset.y;
// inMemBorder.right = (IwSize)(origSize.width - src.cols - offset.x);
// inMemBorder.bottom = (IwSize)(origSize.height - src.rows - offset.y);
// }
dst.Init({src_width, src_height}, ippiGetDataType(CV_MAT_DEPTH(src_type)),
CV_MAT_CN(src_type), inMemBorder, (void*)src_data, src_step);
return dst;
}
int ipp_hal_flip(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height,
uchar* dst_data, size_t dst_step, int flip_mode)
{
CV_HAL_CHECK_USE_IPP();
int64_t total = src_step*src_height*CV_ELEM_SIZE(src_type);
// Details: https://github.com/opencv/opencv/issues/12943
if (flip_mode <= 0 /* swap rows */
&& total > 0 && total >= CV_BIG_INT(0x80000000)/*2Gb*/
&& cv::ipp::getIppTopFeatures() != ippCPUID_SSE42)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
IppiAxis ippMode;
if(flip_mode < 0)
ippMode = ippAxsBoth;
else if(flip_mode == 0)
ippMode = ippAxsHorizontal;
else
ippMode = ippAxsVertical;
try
{
::ipp::IwiImage iwSrc = ippiGetImage(src_type, src_data, src_step, src_width, src_height);
::ipp::IwiImage iwDst = ippiGetImage(src_type, dst_data, dst_step, src_width, src_height);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiMirror, iwSrc, iwDst, ippMode);
}
catch(const ::ipp::IwException &)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_OK;
}
#endif
+457
View File
@@ -0,0 +1,457 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "ipp_hal_imgproc.hpp"
#if IPP_VERSION_X100 >= 810 // integrated IPP warping/remap ABI is available since IPP v8.1
#include <opencv2/core.hpp>
#include "precomp_ipp.hpp"
#include <atomic>
// Uncomment to enforce IPP calls for all supported by IPP configurations
// #define IPP_CALLS_ENFORCED
#define CV_TYPE(src_type) (src_type & (CV_DEPTH_MAX - 1))
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
template <int channels, typename Type>
bool IPPSetSimple(const double value[4], void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
{
//CV_INSTRUMENT_REGION_IPP();
Type values[channels];
for( int i = 0; i < channels; i++ )
values[i] = cv::saturate_cast<Type>(value[i]);
return CV_INSTRUMENT_FUN_IPP(func, values, dataPointer, step, size) >= 0;
}
static bool IPPSet(const double value[4], void *dataPointer, int step, IppiSize &size, int channels, int depth)
{
//CV_INSTRUMENT_REGION_IPP();
if( channels == 1 )
{
switch( depth )
{
case CV_8U:
return CV_INSTRUMENT_FUN_IPP(ippiSet_8u_C1R, cv::saturate_cast<Ipp8u>(value[0]), (Ipp8u *)dataPointer, step, size) >= 0;
case CV_16U:
return CV_INSTRUMENT_FUN_IPP(ippiSet_16u_C1R, cv::saturate_cast<Ipp16u>(value[0]), (Ipp16u *)dataPointer, step, size) >= 0;
case CV_32F:
return CV_INSTRUMENT_FUN_IPP(ippiSet_32f_C1R, cv::saturate_cast<Ipp32f>(value[0]), (Ipp32f *)dataPointer, step, size) >= 0;
}
}
else
{
if( channels == 3 )
{
switch( depth )
{
case CV_8U:
return IPPSetSimple<3, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C3R);
case CV_16U:
return IPPSetSimple<3, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C3R);
case CV_32F:
return IPPSetSimple<3, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C3R);
}
}
else if( channels == 4 )
{
switch( depth )
{
case CV_8U:
return IPPSetSimple<4, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C4R);
case CV_16U:
return IPPSetSimple<4, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C4R);
case CV_32F:
return IPPSetSimple<4, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C4R);
}
}
}
return false;
}
#ifdef HAVE_IPP_IW
#include "iw++/iw.hpp"
int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step,
int dst_width, int dst_height, const double M[6], int interpolation, int borderType, const double borderValue[4])
{
//CV_INSTRUMENT_REGION_IPP();
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
if((int)ippInter < 0 || interpolation > 2)
return CV_HAL_ERROR_NOT_IMPLEMENTED;
#if defined(IPP_CALLS_ENFORCED)
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3]={{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //16U
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //16S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32S
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}, //32F
{{1, 1, 0}, {0, 0, 0}, {1, 1, 0}, {1, 1, 0}}}; //64F
#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 0, 0}}, //16U
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}, //16S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F
{{1, 0, 0}, {0, 0, 0}, {1, 0, 0}, {1, 0, 0}}}; //64F
#endif
if(impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// Acquire data and begin processing
double coeffs[2][3];
for( int i = 0; i < 2; i++ )
for( int j = 0; j < 3; j++ )
coeffs[i][j] = M[i*3 + j];
try
{
std::atomic_bool ok{true};
cv::Range cv_range(0, dst_height);
::ipp::IwiImage iwSrc;
iwSrc.Init(IwiSize{src_width, src_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), src_data, IwSize(src_step));
::ipp::IwiImage iwDst(IwiSize{dst_width, dst_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), dst_data, IwSize(dst_step));
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), {borderValue, 4});
// OpenCV inverts the affine matrix before calling the HAL (lines 2401-2411 of imgwarp.cpp), so the HAL receives the inverse transform.
IwTransDirection iwTransDirection = iwTransInverse;
if ((int)ippBorder == -1)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// The lambda function is used to invoke IPP warping function in parallel for different image stripes.
// The function is exception safe and sets the 'ok' flag to false if any exception occurs during processing.
// The 'ok' flag is checked before and after parallel processing to determine if the operation was successful or
// if it should fall back to a non-IPP implementation.
auto IPPWarpAffineInvokerLambda = [&iwSrc, &iwDst, dst_width, ippInter, &coeffs, ippBorder, iwTransDirection, &ok](const cv::Range& range)
{
//CV_INSTRUMENT_REGION_IPP();
if (!ok.load(std::memory_order_relaxed))
{
return;
}
try
{
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst_width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, iwSrc, iwDst, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpAffineParams(), ippBorder, tile);
}
catch (const ::ipp::IwException &)
{
ok.store(false, std::memory_order_relaxed);
return;
}
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
};
int min_payload = 1 << 16; // 64KB shall be minimal per thread to maximize scalability for warping functions
const int num_threads = ippiSuggestRowThreadsNum(iwDst, min_payload);
if (num_threads > 1)
{
parallel_for_(cv_range, IPPWarpAffineInvokerLambda, num_threads);
}
else
{
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpAffine, iwSrc, iwDst, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpAffineParams(), ippBorder);
}
if (!ok)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}
catch (const ::ipp::IwException &)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_OK;
}
#if IPP_VERSION_X100 >= 202600
int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, 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_INSTRUMENT_REGION_IPP();
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
if (src_height <= 1 || src_width <= 1)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
int mode =
interpolation == cv::InterpolationFlags::INTER_NEAREST ? IPPI_INTER_NN :
interpolation == cv::InterpolationFlags::INTER_LINEAR ? IPPI_INTER_LINEAR : 0;
if (mode == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// Unsupported source type
if (src_type != CV_8UC1 && src_type != CV_8UC3 && src_type != CV_8UC4 &&
src_type != CV_16UC1 && src_type != CV_16UC3 && src_type != CV_16UC4 &&
src_type != CV_16SC1 && src_type != CV_16SC3 && src_type != CV_16SC4 &&
src_type != CV_32FC1 && src_type != CV_32FC3 && src_type != CV_32FC4)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
#if defined(IPP_CALLS_ENFORCED)
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][2]={{{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //8U
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //8S
{{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //16U
{{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //16S
{{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //32S
{{1, 1}, {0, 0}, {1, 1}, {1, 1}}, //32F
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}}; //64F
#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][2]={{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //8U
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, //8S
{{0, 0}, {0, 0}, {0, 0}, {0, 1}}, //16U
{{1, 1}, {0, 0}, {1, 0}, {1, 1}}, //16S
{{1, 1}, {0, 0}, {1, 0}, {1, 1}}, //32S
{{0, 0}, {0, 0}, {0, 0}, {1, 0}}, //32F
{{0, 0}, {0, 0}, {0, 0}, {0, 0}}}; //64F
#endif
if (impl[CV_TYPE(src_type)][CV_MAT_CN(src_type)-1][interpolation] == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// Acquire data and begin processing
double coeffs[3][3];
for( int i = 0; i < 3; i++ )
for( int j = 0; j < 3; j++ )
coeffs[i][j] = M[i*3 + j];
try
{
std::atomic_bool ok{true};
cv::Range cv_range(0, dst_height);
::ipp::IwiImage iwSrc; // src_data is const pointer. So, we need to call an init function
iwSrc.Init(IwiSize{src_width, src_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), src_data, IwSize(src_step));
::ipp::IwiImage iwDst(IwiSize{dst_width, dst_height}, ippiGetDataType(src_type), CV_MAT_CN(src_type), IwiBorderSize(), dst_data, IwSize(dst_step));
::ipp::IwiBorderType ippBorder(ippiGetBorderType(borderType), {borderValue, 4});
IwTransDirection iwTransDirection = iwTransInverse; //fixed for IPP
if ((int)ippBorder == -1)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// The lambda function is used to invoke IPP warping function in parallel for different image stripes.
// The function is exception safe and sets the 'ok' flag to false if any exception occurs during processing.
// The 'ok' flag is checked before and after parallel processing to determine
// if the operation was successful or if it should fall back to a non-IPP implementation.
auto IPPWarpPerspectiveInvokerLambda = [&iwSrc, &iwDst, dst_width, ippInter, &coeffs, ippBorder, iwTransDirection, &ok](const cv::Range& range)
{
//CV_INSTRUMENT_REGION_IPP();
if (!ok.load(std::memory_order_relaxed))
{
return;
}
try
{
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst_width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpPerspective, iwSrc, iwDst, ippRectInfinite, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpPerspectiveParams(), ippBorder, tile);
}
catch (const ::ipp::IwException &)
{
ok.store(false, std::memory_order_relaxed);
return;
}
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
};
int min_payload = 1 << 16; // 64KB shall be minimal per thread to maximize scalability for warping functions
const char type_size[CV_DEPTH_MAX] = {1,1,2,2,4,4,8};
const int num_threads = ippiSuggestRowThreadsNum(dst_width, dst_height, type_size[CV_TYPE(src_type)]*CV_MAT_CN(src_type), min_payload);
if (num_threads > 1)
{
parallel_for_(cv_range, IPPWarpPerspectiveInvokerLambda, num_threads);
}
else
{
CV_INSTRUMENT_FUN_IPP(::ipp::iwiWarpPerspective, iwSrc, iwDst, ippRectInfinite, coeffs, iwTransDirection, ippInter, ::ipp::IwiWarpPerspectiveParams(), ippBorder);
}
if (!ok)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}
catch (const ::ipp::IwException &)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
return CV_HAL_ERROR_OK;
}
#endif // IPP_VERSION_X100 >= 202600
#endif // HAVE_IPP_IW
// Remap section
typedef IppStatus(CV_STDCALL *ippiRemap)(const void *pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
const Ipp32f *pxMap, int xMapStep, const Ipp32f *pyMap, int yMapStep,
void *pDst, int dstStep, IppiSize dstRoiSize, int interpolation);
class IPPRemapInvoker : public cv::ParallelLoopBody
{
public:
IPPRemapInvoker(int _src_type, const uchar *_src_data, size_t _src_step, int _src_width, int _src_height,
uchar *_dst_data, size_t _dst_step, int _dst_width, float *_mapx, size_t _mapx_step, float *_mapy,
size_t _mapy_step, ippiRemap _ippFunc, int _ippInterpolation, int _borderType, const double _borderValue[4], std::atomic_bool *_ok) :
src_type(_src_type), src(_src_data), src_step(_src_step), src_width(_src_width), src_height(_src_height),
dst(_dst_data), dst_step(_dst_step), dst_width(_dst_width), mapx(_mapx), mapx_step(_mapx_step), mapy(_mapy),
mapy_step(_mapy_step), ippFunc(_ippFunc), ippInterpolation(_ippInterpolation), borderType(_borderType), ok(_ok)
{
memcpy(this->borderValue, _borderValue, sizeof(this->borderValue));
}
virtual void operator()(const cv::Range &range) const
{
//CV_INSTRUMENT_REGION_IPP();
if(!ok->load(std::memory_order_relaxed))
return;
IppiRect srcRoiRect = {0, 0, src_width, src_height};
uchar *dst_roi_data = dst + range.start * dst_step;
IppiSize dstRoiSize = ippiSize(dst_width, range.size());
int depth = CV_MAT_DEPTH(src_type), cn = CV_MAT_CN(src_type);
if (borderType == cv::BORDER_CONSTANT &&
!IPPSet(borderValue, dst_roi_data, (int)dst_step, dstRoiSize, cn, depth))
{
ok->store(false, std::memory_order_relaxed);
return;
}
if (ippStsNoErr != CV_INSTRUMENT_FUN_IPP(ippFunc, src, {src_width, src_height}, (int)src_step, srcRoiRect,
mapx, (int)mapx_step, mapy, (int)mapy_step,
dst_roi_data, (int)dst_step, dstRoiSize, ippInterpolation))
{
ok->store(false, std::memory_order_relaxed);
return;
}
CV_IMPL_ADD(CV_IMPL_IPP | CV_IMPL_MT);
}
private:
int src_type;
const uchar *src;
size_t src_step;
int src_width, src_height;
uchar *dst;
size_t dst_step;
int dst_width;
float *mapx;
size_t mapx_step;
float *mapy;
size_t mapy_step;
ippiRemap ippFunc;
int ippInterpolation, borderType;
double borderValue[4];
std::atomic_bool *ok;
};
int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
float *mapx, size_t mapx_step, float *mapy, size_t mapy_step,
int interpolation, int border_type, const double border_value[4])
{
if (!((interpolation == cv::INTER_LINEAR || interpolation == cv::INTER_CUBIC || interpolation == cv::INTER_NEAREST) &&
(border_type == cv::BORDER_CONSTANT || border_type == cv::BORDER_TRANSPARENT)))
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
int ippInterpolation = ippiGetInterpolation(interpolation);
#if defined(IPP_CALLS_ENFORCED)
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3] = {{{1, 1, 1}, {0, 0, 0}, {1, 1, 1}, {1, 1, 1}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{1, 1, 1}, {0, 0, 0}, {1, 1, 1}, {1, 1, 1}}, //16U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
{{1, 1, 1}, {0, 0, 0}, {1, 1, 1}, {1, 1, 1}}, //32F
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; //64F
#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3] = {{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; //64F
#endif
const char type_size[CV_DEPTH_MAX] = {1,1,2,2,4,4,8};
if (impl[CV_TYPE(src_type)][CV_MAT_CN(src_type) - 1][interpolation] == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
ippiRemap ippFunc =
src_type == CV_8UC1 ? (ippiRemap)ippiRemap_8u_C1R :
src_type == CV_8UC3 ? (ippiRemap)ippiRemap_8u_C3R :
src_type == CV_8UC4 ? (ippiRemap)ippiRemap_8u_C4R :
src_type == CV_16UC1 ? (ippiRemap)ippiRemap_16u_C1R :
src_type == CV_16UC3 ? (ippiRemap)ippiRemap_16u_C3R :
src_type == CV_16UC4 ? (ippiRemap)ippiRemap_16u_C4R :
src_type == CV_32FC1 ? (ippiRemap)ippiRemap_32f_C1R :
src_type == CV_32FC3 ? (ippiRemap)ippiRemap_32f_C3R :
src_type == CV_32FC4 ? (ippiRemap)ippiRemap_32f_C4R : 0;
if (ippFunc)
{
std::atomic_bool ok{true};
IPPRemapInvoker invoker(src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width,
mapx, mapx_step, mapy, mapy_step, ippFunc, ippInterpolation, border_type, border_value, &ok);
cv::Range range(0, dst_height);
int min_payload = 1 << 16; // 64KB shall be minimal per thread to maximize scalability for warping functions
int num_threads = ippiSuggestRowThreadsNum(dst_width, dst_height, type_size[CV_TYPE(src_type)]*CV_MAT_CN(src_type), min_payload);
cv::parallel_for_(range, invoker, num_threads);
if (ok)
{
CV_IMPL_ADD(CV_IMPL_IPP | CV_IMPL_MT);
return CV_HAL_ERROR_OK;
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
// End of Remap section
#endif // IPP_VERSION_X100 >= 810