diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index 5a189867c2..1a2eb3d997 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -920,6 +920,32 @@ static BinaryFuncC* getAddTab() return addTab; } +static int sub8u32fWrapper(const uchar* src1, size_t step1, const uchar* src2, size_t step2, + uchar* dst, size_t step, int width, int height, void* ) +{ + int res = cv_hal_sub8u32f(src1, step1, src2, step2, (float *)dst, step, width, height); + if (res == CV_HAL_ERROR_OK || res == CV_HAL_ERROR_NOT_IMPLEMENTED) + return res; + else + { + CV_Error_(cv::Error::StsInternal, ("HAL implementation sub8u32f ==> " CVAUX_STR(cv_hal_sub8u32f) + " returned %d (0x%08x)", res, res)); + } +} + +static int sub8s32fWrapper(const uchar* src1, size_t step1, const uchar* src2, size_t step2, + uchar* dst, size_t step, int width, int height, void* ) +{ + int res = cv_hal_sub8s32f((schar*)src1, step1, (schar*)src2, step2, (float *)dst, step, width, height); + if (res == CV_HAL_ERROR_OK || res == CV_HAL_ERROR_NOT_IMPLEMENTED) + return res; + else + { + CV_Error_(cv::Error::StsInternal, ("HAL implementation sub8s32f ==> " CVAUX_STR(cv_hal_sub8s32f) + " returned %d (0x%08x)", res, res)); + } +} + static BinaryFuncC* getSubTab() { static BinaryFuncC subTab[CV_DEPTH_MAX] = @@ -934,6 +960,22 @@ static BinaryFuncC* getSubTab() return subTab; } +static ExtendedTypeFunc getSubExtFunc(int src1Type, int src2Type, int dstType) +{ + if (src1Type == CV_8U && src2Type == CV_8U && dstType == CV_32F) + { + return sub8u32fWrapper; + } + else if (src1Type == CV_8S && src2Type == CV_8S && dstType == CV_32F) + { + return sub8s32fWrapper; + } + else + { + return nullptr; + } +} + static BinaryFuncC* getAbsDiffTab() { static BinaryFuncC absDiffTab[CV_DEPTH_MAX] = @@ -959,11 +1001,13 @@ void cv::add( InputArray src1, InputArray src2, OutputArray dst, } void cv::subtract( InputArray _src1, InputArray _src2, OutputArray _dst, - InputArray mask, int dtype ) + InputArray mask, int dtype ) { CV_INSTRUMENT_REGION(); - arithm_op(_src1, _src2, _dst, mask, dtype, getSubTab(), false, 0, OCL_OP_SUB ); + ExtendedTypeFunc subExtFunc = getSubExtFunc(_src1.depth(), _src2.depth(), dtype < 0 ? _dst.depth() : dtype); + arithm_op(_src1, _src2, _dst, mask, dtype, getSubTab(), false, 0, OCL_OP_SUB, + /* extendedFunc */ subExtFunc); } void cv::absdiff( InputArray src1, InputArray src2, OutputArray dst ) diff --git a/modules/core/src/hal_replacement.hpp b/modules/core/src/hal_replacement.hpp index d73c0e2db8..f78608dbad 100644 --- a/modules/core/src/hal_replacement.hpp +++ b/modules/core/src/hal_replacement.hpp @@ -95,6 +95,9 @@ inline int hal_ni_sub16s(const short *src1_data, size_t src1_step, const short * inline int hal_ni_sub32s(const int *src1_data, size_t src1_step, const int *src2_data, size_t src2_step, int *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } inline int hal_ni_sub32f(const float *src1_data, size_t src1_step, const float *src2_data, size_t src2_step, float *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } inline int hal_ni_sub64f(const double *src1_data, size_t src1_step, const double *src2_data, size_t src2_step, double *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +inline int hal_ni_sub8u32f(const uchar *src1_data, size_t src1_step, const uchar *src2_data, size_t src2_step, float *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_sub8s32f(const schar *src1_data, size_t src1_step, const schar *src2_data, size_t src2_step, float *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } //! @} /** @@ -187,6 +190,8 @@ inline int hal_ni_not8u(const uchar *src_data, size_t src_step, uchar *dst_data, #define cv_hal_sub32s hal_ni_sub32s #define cv_hal_sub32f hal_ni_sub32f #define cv_hal_sub64f hal_ni_sub64f +#define cv_hal_sub8u32f hal_ni_sub8u32f +#define cv_hal_sub8s32f hal_ni_sub8s32f #define cv_hal_max8u hal_ni_max8u #define cv_hal_max8s hal_ni_max8s #define cv_hal_max16u hal_ni_max16u