mirror of
https://github.com/opencv/opencv.git
synced 2026-09-25 04:09:57 +03:00
Resize IPP HAL: atomic status flag and compile-time dispatch tables
This commit is contained in:
+33
-14
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "iw++/iw.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <cfloat>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -21,7 +22,7 @@ template <typename IwiOp>
|
||||
class ipp_resizeParallelT: public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ipp_resizeParallelT(::ipp::IwiImage &src, ::ipp::IwiImage &dst, bool &ok):
|
||||
ipp_resizeParallelT(::ipp::IwiImage &src, ::ipp::IwiImage &dst, std::atomic_bool &ok):
|
||||
m_src(src), m_dst(dst), m_ok(ok) {}
|
||||
|
||||
void Init(IppiInterpolationType inter)
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
|
||||
void Init(IppiInterpolationType inter, double scaleX, double scaleY)
|
||||
{
|
||||
double shift = (inter == ippNearest)?-1e-10:-0.5;
|
||||
double shift = (inter == ippNearest) ? -1e-10 : -0.5;
|
||||
double coeffs[2][3] = {
|
||||
{scaleX, 0, shift+0.5*scaleX},
|
||||
{0, scaleY, shift+0.5*scaleY}
|
||||
@@ -69,7 +70,7 @@ private:
|
||||
|
||||
mutable IwiOp iwiOp;
|
||||
|
||||
volatile bool &m_ok;
|
||||
std::atomic_bool &m_ok;
|
||||
ipp_resizeParallelT& operator= (const ipp_resizeParallelT&);
|
||||
};
|
||||
|
||||
@@ -86,20 +87,38 @@ int ipp_hal_resize(int src_type, const uchar *src_data, size_t src_step, int src
|
||||
|
||||
IppDataType ippDataType = ippiGetDataType(depth);
|
||||
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
|
||||
if((int)ippInter < 0)
|
||||
int interpIdx = interpolation & cv::InterpolationFlags::INTER_MAX;
|
||||
if((int)ippInter < 0 || interpIdx > 4 || channels > 4)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
// Resize which doesn't match OpenCV exactly
|
||||
if (!cv::ipp::useIPP_NotExact())
|
||||
{
|
||||
if (ippInter == ippNearest || ippInter == ippSuper || (ippDataType == ipp8u && ippInter == ippLinear))
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#if defined(IPP_CALLS_ENFORCED)
|
||||
|
||||
if(ippInter != ippLinear && ippDataType == ipp64f)
|
||||
const char impl[CV_DEPTH_MAX][4][5] = { /* N L C S Z */
|
||||
/* 8U */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}},
|
||||
/* 8S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}},
|
||||
/* 16U */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}},
|
||||
/* 16S */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}},
|
||||
/* 32S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}},
|
||||
/* 32F */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}},
|
||||
/* 64F */ {{0, 1, 0, 0, 0},{0, 0, 0, 0, 0},{0, 1, 0, 0, 0},{0, 1, 0, 0, 0}},
|
||||
/* 16F */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}};
|
||||
#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation
|
||||
|
||||
const char impl[CV_DEPTH_MAX][4][5] = { /* N L C S Z */
|
||||
/* 8U */ {{0, 0, 1, 0, 1},{0, 0, 0, 0, 0},{0, 0, 1, 0, 1},{0, 0, 1, 0, 1}},
|
||||
/* 8S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}},
|
||||
/* 16U */ {{0, 1, 1, 0, 1},{0, 0, 0, 0, 0},{0, 1, 1, 0, 1},{0, 1, 1, 0, 1}},
|
||||
/* 16S */ {{0, 1, 1, 0, 1},{0, 0, 0, 0, 0},{0, 1, 1, 0, 1},{0, 1, 1, 0, 1}},
|
||||
/* 32S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}},
|
||||
/* 32F */ {{0, 1, 1, 0, 1},{0, 0, 0, 0, 0},{0, 1, 1, 0, 1},{0, 1, 1, 0, 1}},
|
||||
/* 64F */ {{0, 1, 0, 0, 0},{0, 0, 0, 0, 0},{0, 1, 0, 0, 0},{0, 1, 0, 0, 0}},
|
||||
/* 16F */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}};
|
||||
#endif
|
||||
|
||||
if (impl[depth][channels - 1][interpIdx] == 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
#if IPP_VERSION_X100 < 201801 && !defined(IPP_CALLS_ENFORCED)
|
||||
// Degradations on int^2 linear downscale
|
||||
if (ippDataType != ipp64f && ippInter == ippLinear && inv_scale_x < 1 && inv_scale_y < 1) // if downscale
|
||||
{
|
||||
@@ -114,7 +133,7 @@ int ipp_hal_resize(int src_type, const uchar *src_data, size_t src_step, int src
|
||||
#endif
|
||||
|
||||
bool affine = false;
|
||||
const double IPP_RESIZE_EPS = (depth == CV_64F)?0:1e-10;
|
||||
const double IPP_RESIZE_EPS = (depth == CV_64F) ? 0 : 1e-10;
|
||||
double ex = fabs((double)dst_width / src_width - inv_scale_x) / inv_scale_x;
|
||||
double ey = fabs((double)dst_height / src_height - inv_scale_y) / inv_scale_y;
|
||||
|
||||
@@ -131,7 +150,7 @@ int ipp_hal_resize(int src_type, const uchar *src_data, size_t src_step, int src
|
||||
::ipp::IwiImage iwSrc(::ipp::IwiSize(src_width, src_height), ippDataType, channels, 0, (void*)src_data, src_step);
|
||||
::ipp::IwiImage iwDst(::ipp::IwiSize(dst_width, dst_height), ippDataType, channels, 0, (void*)dst_data, dst_step);
|
||||
|
||||
bool ok;
|
||||
std::atomic_bool ok{true};
|
||||
int threads = ippiSuggestThreadsNum(iwDst, 1+((double)(src_width*src_height)/(dst_width*dst_height)));
|
||||
cv::Range range(0, dst_height);
|
||||
ipp_resizeParallel invokerGeneral(iwSrc, iwDst, ok);
|
||||
|
||||
Reference in New Issue
Block a user